From 756fa28b6ac1b89404580af68fa40972d4c9bf77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=AC=E9=9B=A8?= <389625819@qq.com> Date: Wed, 1 Apr 2020 11:42:47 +0800 Subject: [PATCH] no message --- vendor/.gitignore | 1 - vendor/autoload.php | 7 + vendor/bin/var-dump-server | 14 + vendor/bin/var-dump-server.bat | 4 + vendor/composer/ClassLoader.php | 445 ++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 9 + vendor/composer/autoload_files.php | 15 + vendor/composer/autoload_namespaces.php | 10 + vendor/composer/autoload_psr4.php | 26 + vendor/composer/autoload_real.php | 70 + vendor/composer/autoload_static.php | 143 + vendor/composer/installed.json | 1148 ++++ .../flysystem-cached-adapter/.editorconfig | 10 + .../flysystem-cached-adapter/.gitignore | 4 + .../league/flysystem-cached-adapter/.php_cs | 7 + .../flysystem-cached-adapter/.scrutinizer.yml | 34 + .../flysystem-cached-adapter/.travis.yml | 29 + .../league/flysystem-cached-adapter/LICENSE | 19 + .../clover/.gitignore | 2 + .../flysystem-cached-adapter/composer.json | 30 + .../flysystem-cached-adapter/phpspec.yml | 6 + .../flysystem-cached-adapter/phpunit.php | 3 + .../flysystem-cached-adapter/phpunit.xml | 29 + .../league/flysystem-cached-adapter/readme.md | 20 + .../spec/CachedAdapterSpec.php | 435 ++ .../src/CacheInterface.php | 101 + .../src/CachedAdapter.php | 324 ++ .../src/Storage/AbstractCache.php | 417 ++ .../src/Storage/Adapter.php | 115 + .../src/Storage/Memcached.php | 59 + .../src/Storage/Memory.php | 22 + .../src/Storage/Noop.php | 171 + .../src/Storage/PhpRedis.php | 62 + .../src/Storage/Predis.php | 75 + .../src/Storage/Psr6Cache.php | 59 + .../src/Storage/Stash.php | 60 + .../tests/AdapterCacheTests.php | 104 + .../tests/InspectionTests.php | 16 + .../tests/MemcachedTests.php | 35 + .../tests/MemoryCacheTests.php | 255 + .../tests/NoopCacheTests.php | 35 + .../tests/PhpRedisTests.php | 45 + .../tests/PredisTests.php | 55 + .../tests/Psr6CacheTest.php | 45 + .../tests/StashTest.php | 43 + vendor/league/flysystem/LICENSE | 19 + vendor/league/flysystem/composer.json | 64 + vendor/league/flysystem/deprecations.md | 19 + .../flysystem/src/Adapter/AbstractAdapter.php | 72 + .../src/Adapter/AbstractFtpAdapter.php | 693 +++ .../src/Adapter/CanOverwriteFiles.php | 12 + vendor/league/flysystem/src/Adapter/Ftp.php | 572 ++ vendor/league/flysystem/src/Adapter/Ftpd.php | 45 + vendor/league/flysystem/src/Adapter/Local.php | 528 ++ .../flysystem/src/Adapter/NullAdapter.php | 144 + .../Polyfill/NotSupportingVisibilityTrait.php | 33 + .../Adapter/Polyfill/StreamedCopyTrait.php | 51 + .../Adapter/Polyfill/StreamedReadingTrait.php | 44 + .../src/Adapter/Polyfill/StreamedTrait.php | 9 + .../Adapter/Polyfill/StreamedWritingTrait.php | 60 + .../flysystem/src/Adapter/SynologyFtp.php | 8 + .../league/flysystem/src/AdapterInterface.php | 118 + vendor/league/flysystem/src/Config.php | 107 + .../league/flysystem/src/ConfigAwareTrait.php | 49 + vendor/league/flysystem/src/Directory.php | 31 + vendor/league/flysystem/src/Exception.php | 8 + vendor/league/flysystem/src/File.php | 205 + .../flysystem/src/FileExistsException.php | 37 + .../flysystem/src/FileNotFoundException.php | 37 + vendor/league/flysystem/src/Filesystem.php | 408 ++ .../flysystem/src/FilesystemInterface.php | 284 + .../src/FilesystemNotFoundException.php | 12 + vendor/league/flysystem/src/Handler.php | 137 + vendor/league/flysystem/src/MountManager.php | 648 +++ .../flysystem/src/NotSupportedException.php | 37 + .../flysystem/src/Plugin/AbstractPlugin.php | 24 + .../league/flysystem/src/Plugin/EmptyDir.php | 34 + .../flysystem/src/Plugin/ForcedCopy.php | 44 + .../flysystem/src/Plugin/ForcedRename.php | 44 + .../flysystem/src/Plugin/GetWithMetadata.php | 51 + .../league/flysystem/src/Plugin/ListFiles.php | 35 + .../league/flysystem/src/Plugin/ListPaths.php | 36 + .../league/flysystem/src/Plugin/ListWith.php | 60 + .../flysystem/src/Plugin/PluggableTrait.php | 97 + .../src/Plugin/PluginNotFoundException.php | 10 + .../league/flysystem/src/PluginInterface.php | 20 + vendor/league/flysystem/src/ReadInterface.php | 88 + .../flysystem/src/RootViolationException.php | 10 + vendor/league/flysystem/src/SafeStorage.php | 39 + .../flysystem/src/UnreadableFileException.php | 18 + vendor/league/flysystem/src/Util.php | 349 ++ .../src/Util/ContentListingFormatter.php | 122 + vendor/league/flysystem/src/Util/MimeType.php | 245 + .../flysystem/src/Util/StreamHasher.php | 36 + vendor/opis/closure/CHANGELOG.md | 207 + vendor/opis/closure/LICENSE | 20 + vendor/opis/closure/NOTICE | 9 + vendor/opis/closure/README.md | 98 + vendor/opis/closure/autoload.php | 39 + vendor/opis/closure/composer.json | 40 + vendor/opis/closure/functions.php | 38 + vendor/opis/closure/src/Analyzer.php | 59 + vendor/opis/closure/src/ClosureContext.php | 34 + vendor/opis/closure/src/ClosureScope.php | 25 + vendor/opis/closure/src/ClosureStream.php | 94 + vendor/opis/closure/src/ISecurityProvider.php | 25 + vendor/opis/closure/src/ReflectionClosure.php | 939 ++++ vendor/opis/closure/src/SecurityException.php | 18 + vendor/opis/closure/src/SecurityProvider.php | 42 + vendor/opis/closure/src/SelfReference.php | 31 + .../opis/closure/src/SerializableClosure.php | 668 +++ vendor/phpmailer/phpmailer/COMMITMENT | 46 + vendor/phpmailer/phpmailer/LICENSE | 502 ++ vendor/phpmailer/phpmailer/README.md | 221 + vendor/phpmailer/phpmailer/SECURITY.md | 28 + vendor/phpmailer/phpmailer/VERSION | 1 + vendor/phpmailer/phpmailer/composer.json | 51 + .../phpmailer/phpmailer/get_oauth_token.php | 144 + .../phpmailer/language/phpmailer.lang-af.php | 25 + .../phpmailer/language/phpmailer.lang-am.php | 26 + .../phpmailer/language/phpmailer.lang-ar.php | 27 + .../phpmailer/language/phpmailer.lang-az.php | 26 + .../phpmailer/language/phpmailer.lang-ba.php | 26 + .../phpmailer/language/phpmailer.lang-be.php | 26 + .../phpmailer/language/phpmailer.lang-bg.php | 26 + .../phpmailer/language/phpmailer.lang-ca.php | 26 + .../phpmailer/language/phpmailer.lang-ch.php | 26 + .../phpmailer/language/phpmailer.lang-cs.php | 25 + .../phpmailer/language/phpmailer.lang-da.php | 28 + .../phpmailer/language/phpmailer.lang-de.php | 25 + .../phpmailer/language/phpmailer.lang-el.php | 25 + .../phpmailer/language/phpmailer.lang-eo.php | 25 + .../phpmailer/language/phpmailer.lang-es.php | 26 + .../phpmailer/language/phpmailer.lang-et.php | 27 + .../phpmailer/language/phpmailer.lang-fa.php | 27 + .../phpmailer/language/phpmailer.lang-fi.php | 27 + .../phpmailer/language/phpmailer.lang-fo.php | 26 + .../phpmailer/language/phpmailer.lang-fr.php | 29 + .../phpmailer/language/phpmailer.lang-gl.php | 26 + .../phpmailer/language/phpmailer.lang-he.php | 26 + .../phpmailer/language/phpmailer.lang-hi.php | 26 + .../phpmailer/language/phpmailer.lang-hr.php | 26 + .../phpmailer/language/phpmailer.lang-hu.php | 26 + .../phpmailer/language/phpmailer.lang-id.php | 27 + .../phpmailer/language/phpmailer.lang-it.php | 27 + .../phpmailer/language/phpmailer.lang-ja.php | 27 + .../phpmailer/language/phpmailer.lang-ka.php | 26 + .../phpmailer/language/phpmailer.lang-ko.php | 26 + .../phpmailer/language/phpmailer.lang-lt.php | 26 + .../phpmailer/language/phpmailer.lang-lv.php | 26 + .../phpmailer/language/phpmailer.lang-mg.php | 25 + .../phpmailer/language/phpmailer.lang-ms.php | 26 + .../phpmailer/language/phpmailer.lang-nb.php | 25 + .../phpmailer/language/phpmailer.lang-nl.php | 28 + .../phpmailer/language/phpmailer.lang-pl.php | 26 + .../phpmailer/language/phpmailer.lang-pt.php | 26 + .../language/phpmailer.lang-pt_br.php | 29 + .../phpmailer/language/phpmailer.lang-ro.php | 26 + .../phpmailer/language/phpmailer.lang-ru.php | 27 + .../phpmailer/language/phpmailer.lang-sk.php | 27 + .../phpmailer/language/phpmailer.lang-sl.php | 27 + .../phpmailer/language/phpmailer.lang-sr.php | 27 + .../phpmailer/language/phpmailer.lang-sv.php | 26 + .../phpmailer/language/phpmailer.lang-tl.php | 27 + .../phpmailer/language/phpmailer.lang-tr.php | 30 + .../phpmailer/language/phpmailer.lang-uk.php | 27 + .../phpmailer/language/phpmailer.lang-vi.php | 26 + .../phpmailer/language/phpmailer.lang-zh.php | 28 + .../language/phpmailer.lang-zh_cn.php | 28 + vendor/phpmailer/phpmailer/src/Exception.php | 39 + vendor/phpmailer/phpmailer/src/OAuth.php | 138 + vendor/phpmailer/phpmailer/src/PHPMailer.php | 4820 +++++++++++++++++ vendor/phpmailer/phpmailer/src/POP3.php | 421 ++ vendor/phpmailer/phpmailer/src/SMTP.php | 1371 +++++ vendor/psr/cache/CHANGELOG.md | 16 + vendor/psr/cache/LICENSE.txt | 19 + vendor/psr/cache/README.md | 9 + vendor/psr/cache/composer.json | 25 + vendor/psr/cache/src/CacheException.php | 10 + vendor/psr/cache/src/CacheItemInterface.php | 105 + .../psr/cache/src/CacheItemPoolInterface.php | 138 + .../cache/src/InvalidArgumentException.php | 13 + vendor/psr/container/.gitignore | 3 + vendor/psr/container/LICENSE | 21 + vendor/psr/container/README.md | 5 + vendor/psr/container/composer.json | 27 + .../src/ContainerExceptionInterface.php | 13 + .../psr/container/src/ContainerInterface.php | 37 + .../src/NotFoundExceptionInterface.php | 13 + vendor/psr/log/.gitignore | 1 + vendor/psr/log/LICENSE | 19 + vendor/psr/log/Psr/Log/AbstractLogger.php | 128 + .../log/Psr/Log/InvalidArgumentException.php | 7 + vendor/psr/log/Psr/Log/LogLevel.php | 18 + .../psr/log/Psr/Log/LoggerAwareInterface.php | 18 + vendor/psr/log/Psr/Log/LoggerAwareTrait.php | 26 + vendor/psr/log/Psr/Log/LoggerInterface.php | 123 + vendor/psr/log/Psr/Log/LoggerTrait.php | 140 + vendor/psr/log/Psr/Log/NullLogger.php | 28 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 144 + vendor/psr/log/Psr/Log/Test/TestLogger.php | 146 + vendor/psr/log/README.md | 52 + vendor/psr/log/composer.json | 26 + vendor/psr/simple-cache/.editorconfig | 12 + vendor/psr/simple-cache/LICENSE.md | 21 + vendor/psr/simple-cache/README.md | 8 + vendor/psr/simple-cache/composer.json | 25 + .../psr/simple-cache/src/CacheException.php | 10 + .../psr/simple-cache/src/CacheInterface.php | 114 + .../src/InvalidArgumentException.php | 13 + vendor/services.php | 8 + vendor/symfony/polyfill-mbstring/LICENSE | 19 + vendor/symfony/polyfill-mbstring/Mbstring.php | 829 +++ vendor/symfony/polyfill-mbstring/README.md | 13 + .../Resources/unidata/lowerCase.php | 1096 ++++ .../Resources/unidata/titleCaseRegexp.php | 5 + .../Resources/unidata/upperCase.php | 1104 ++++ .../symfony/polyfill-mbstring/bootstrap.php | 62 + .../symfony/polyfill-mbstring/composer.json | 34 + vendor/symfony/polyfill-php72/LICENSE | 19 + vendor/symfony/polyfill-php72/Php72.php | 216 + vendor/symfony/polyfill-php72/README.md | 27 + vendor/symfony/polyfill-php72/bootstrap.php | 36 + vendor/symfony/polyfill-php72/composer.json | 31 + vendor/symfony/var-dumper/.gitignore | 3 + vendor/symfony/var-dumper/CHANGELOG.md | 42 + .../symfony/var-dumper/Caster/AmqpCaster.php | 210 + vendor/symfony/var-dumper/Caster/ArgsStub.php | 80 + vendor/symfony/var-dumper/Caster/Caster.php | 163 + .../symfony/var-dumper/Caster/ClassStub.php | 106 + .../symfony/var-dumper/Caster/ConstStub.php | 33 + .../var-dumper/Caster/CutArrayStub.php | 30 + vendor/symfony/var-dumper/Caster/CutStub.php | 59 + .../symfony/var-dumper/Caster/DOMCaster.php | 302 ++ .../symfony/var-dumper/Caster/DateCaster.php | 122 + .../var-dumper/Caster/DoctrineCaster.php | 60 + vendor/symfony/var-dumper/Caster/DsCaster.php | 68 + .../symfony/var-dumper/Caster/DsPairStub.php | 28 + vendor/symfony/var-dumper/Caster/EnumStub.php | 30 + .../var-dumper/Caster/ExceptionCaster.php | 357 ++ .../symfony/var-dumper/Caster/FrameStub.php | 30 + .../symfony/var-dumper/Caster/GmpCaster.php | 30 + .../symfony/var-dumper/Caster/IntlCaster.php | 170 + vendor/symfony/var-dumper/Caster/LinkStub.php | 108 + .../var-dumper/Caster/MemcachedCaster.php | 79 + .../symfony/var-dumper/Caster/PdoCaster.php | 120 + .../symfony/var-dumper/Caster/PgSqlCaster.php | 154 + .../var-dumper/Caster/ProxyManagerCaster.php | 31 + .../symfony/var-dumper/Caster/RedisCaster.php | 150 + .../var-dumper/Caster/ReflectionCaster.php | 388 ++ .../var-dumper/Caster/ResourceCaster.php | 98 + .../symfony/var-dumper/Caster/SplCaster.php | 226 + .../symfony/var-dumper/Caster/StubCaster.php | 82 + .../var-dumper/Caster/SymfonyCaster.php | 51 + .../symfony/var-dumper/Caster/TraceStub.php | 36 + .../var-dumper/Caster/XmlReaderCaster.php | 77 + .../var-dumper/Caster/XmlResourceCaster.php | 61 + .../var-dumper/Cloner/AbstractCloner.php | 362 ++ .../var-dumper/Cloner/ClonerInterface.php | 27 + vendor/symfony/var-dumper/Cloner/Cursor.php | 43 + vendor/symfony/var-dumper/Cloner/Data.php | 427 ++ .../var-dumper/Cloner/DumperInterface.php | 60 + vendor/symfony/var-dumper/Cloner/Stub.php | 67 + .../symfony/var-dumper/Cloner/VarCloner.php | 302 ++ .../Command/Descriptor/CliDescriptor.php | 88 + .../Descriptor/DumpDescriptorInterface.php | 23 + .../Command/Descriptor/HtmlDescriptor.php | 119 + .../var-dumper/Command/ServerDumpCommand.php | 99 + .../var-dumper/Dumper/AbstractDumper.php | 213 + .../symfony/var-dumper/Dumper/CliDumper.php | 643 +++ .../ContextProvider/CliContextProvider.php | 32 + .../ContextProviderInterface.php | 25 + .../RequestContextProvider.php | 51 + .../ContextProvider/SourceContextProvider.php | 126 + .../var-dumper/Dumper/DataDumperInterface.php | 24 + .../symfony/var-dumper/Dumper/HtmlDumper.php | 969 ++++ .../var-dumper/Dumper/ServerDumper.php | 53 + .../Exception/ThrowingCasterException.php | 26 + vendor/symfony/var-dumper/LICENSE | 19 + vendor/symfony/var-dumper/README.md | 15 + .../var-dumper/Resources/bin/var-dump-server | 63 + .../Resources/css/htmlDescriptor.css | 130 + .../var-dumper/Resources/functions/dump.php | 43 + .../var-dumper/Resources/js/htmlDescriptor.js | 10 + .../symfony/var-dumper/Server/Connection.php | 95 + .../symfony/var-dumper/Server/DumpServer.php | 107 + .../var-dumper/Test/VarDumperTestTrait.php | 61 + .../var-dumper/Tests/Caster/CasterTest.php | 178 + .../Tests/Caster/DateCasterTest.php | 390 ++ .../Tests/Caster/ExceptionCasterTest.php | 244 + .../var-dumper/Tests/Caster/GmpCasterTest.php | 48 + .../Tests/Caster/IntlCasterTest.php | 297 + .../Tests/Caster/MemcachedCasterTest.php | 93 + .../var-dumper/Tests/Caster/PdoCasterTest.php | 64 + .../Tests/Caster/RedisCasterTest.php | 70 + .../Tests/Caster/ReflectionCasterTest.php | 256 + .../var-dumper/Tests/Caster/SplCasterTest.php | 226 + .../Tests/Caster/StubCasterTest.php | 213 + .../Tests/Caster/XmlReaderCasterTest.php | 248 + .../var-dumper/Tests/Cloner/DataTest.php | 115 + .../var-dumper/Tests/Cloner/VarClonerTest.php | 509 ++ .../Command/Descriptor/CliDescriptorTest.php | 173 + .../Command/Descriptor/HtmlDescriptorTest.php | 195 + .../var-dumper/Tests/Dumper/CliDumperTest.php | 534 ++ .../var-dumper/Tests/Dumper/FunctionsTest.php | 57 + .../Tests/Dumper/HtmlDumperTest.php | 163 + .../Tests/Dumper/ServerDumperTest.php | 95 + .../Tests/Fixtures/FooInterface.php | 11 + .../Tests/Fixtures/GeneratorDemo.php | 21 + .../Tests/Fixtures/NotLoadableClass.php | 7 + .../var-dumper/Tests/Fixtures/Php74.php | 14 + .../var-dumper/Tests/Fixtures/Twig.php | 38 + .../var-dumper/Tests/Fixtures/dumb-var.php | 40 + .../var-dumper/Tests/Fixtures/dump_server.php | 38 + .../var-dumper/Tests/Fixtures/xml_reader.xml | 10 + .../Tests/Server/ConnectionTest.php | 88 + .../Tests/Test/VarDumperTestTraitTest.php | 46 + vendor/symfony/var-dumper/VarDumper.php | 56 + vendor/symfony/var-dumper/composer.json | 54 + vendor/symfony/var-dumper/phpunit.xml.dist | 33 + vendor/topthink/framework/.gitignore | 7 + vendor/topthink/framework/.travis.yml | 34 + vendor/topthink/framework/CONTRIBUTING.md | 119 + vendor/topthink/framework/LICENSE.txt | 32 + vendor/topthink/framework/README.md | 86 + vendor/topthink/framework/composer.json | 55 + vendor/topthink/framework/logo.png | Bin 0 -> 6995 bytes vendor/topthink/framework/phpunit.xml.dist | 25 + vendor/topthink/framework/src/helper.php | 663 +++ vendor/topthink/framework/src/lang/zh-cn.php | 148 + vendor/topthink/framework/src/think/App.php | 610 +++ vendor/topthink/framework/src/think/Cache.php | 197 + .../topthink/framework/src/think/Config.php | 193 + .../topthink/framework/src/think/Console.php | 732 +++ .../framework/src/think/Container.php | 551 ++ .../topthink/framework/src/think/Cookie.php | 230 + vendor/topthink/framework/src/think/Db.php | 114 + vendor/topthink/framework/src/think/Env.php | 181 + vendor/topthink/framework/src/think/Event.php | 301 + .../framework/src/think/Exception.php | 60 + .../topthink/framework/src/think/Facade.php | 98 + vendor/topthink/framework/src/think/File.php | 187 + .../framework/src/think/Filesystem.php | 89 + vendor/topthink/framework/src/think/Http.php | 285 + vendor/topthink/framework/src/think/Lang.php | 277 + vendor/topthink/framework/src/think/Log.php | 342 ++ .../topthink/framework/src/think/Manager.php | 176 + .../framework/src/think/Middleware.php | 257 + .../topthink/framework/src/think/Pipeline.php | 106 + .../topthink/framework/src/think/Request.php | 2129 ++++++++ .../topthink/framework/src/think/Response.php | 410 ++ vendor/topthink/framework/src/think/Route.php | 894 +++ .../topthink/framework/src/think/Service.php | 66 + .../topthink/framework/src/think/Session.php | 65 + .../topthink/framework/src/think/Validate.php | 1677 ++++++ vendor/topthink/framework/src/think/View.php | 187 + .../framework/src/think/cache/Driver.php | 347 ++ .../framework/src/think/cache/TagSet.php | 130 + .../framework/src/think/cache/driver/File.php | 304 ++ .../src/think/cache/driver/Memcache.php | 209 + .../src/think/cache/driver/Memcached.php | 221 + .../src/think/cache/driver/Redis.php | 248 + .../src/think/cache/driver/Wincache.php | 175 + .../framework/src/think/console/Command.php | 504 ++ .../framework/src/think/console/Input.php | 465 ++ .../framework/src/think/console/LICENSE | 19 + .../framework/src/think/console/Output.php | 224 + .../framework/src/think/console/Table.php | 300 + .../framework/src/think/console/bin/README.md | 1 + .../src/think/console/bin/hiddeninput.exe | Bin 0 -> 9216 bytes .../src/think/console/command/Clear.php | 64 + .../src/think/console/command/Help.php | 69 + .../src/think/console/command/Lists.php | 73 + .../src/think/console/command/Make.php | 99 + .../src/think/console/command/RouteList.php | 129 + .../src/think/console/command/RunServer.php | 57 + .../think/console/command/ServiceDiscover.php | 48 + .../think/console/command/VendorPublish.php | 66 + .../src/think/console/command/Version.php | 33 + .../think/console/command/make/Command.php | 55 + .../think/console/command/make/Controller.php | 56 + .../src/think/console/command/make/Event.php | 35 + .../think/console/command/make/Listener.php | 35 + .../think/console/command/make/Middleware.php | 36 + .../src/think/console/command/make/Model.php | 36 + .../think/console/command/make/Service.php | 36 + .../think/console/command/make/Subscribe.php | 35 + .../think/console/command/make/Validate.php | 39 + .../console/command/make/stubs/command.stub | 26 + .../command/make/stubs/controller.api.stub | 64 + .../command/make/stubs/controller.plain.stub | 9 + .../command/make/stubs/controller.stub | 85 + .../console/command/make/stubs/event.stub | 8 + .../console/command/make/stubs/listener.stub | 17 + .../command/make/stubs/middleware.stub | 19 + .../console/command/make/stubs/model.stub | 14 + .../console/command/make/stubs/service.stub | 29 + .../console/command/make/stubs/subscribe.stub | 8 + .../console/command/make/stubs/validate.stub | 25 + .../think/console/command/optimize/Route.php | 67 + .../think/console/command/optimize/Schema.php | 116 + .../src/think/console/input/Argument.php | 115 + .../src/think/console/input/Definition.php | 375 ++ .../src/think/console/input/Option.php | 190 + .../src/think/console/output/Ask.php | 336 ++ .../src/think/console/output/Descriptor.php | 319 ++ .../src/think/console/output/Formatter.php | 198 + .../src/think/console/output/Question.php | 211 + .../console/output/descriptor/Console.php | 153 + .../think/console/output/driver/Buffer.php | 52 + .../think/console/output/driver/Console.php | 368 ++ .../think/console/output/driver/Nothing.php | 33 + .../think/console/output/formatter/Stack.php | 116 + .../think/console/output/formatter/Style.php | 190 + .../think/console/output/question/Choice.php | 163 + .../console/output/question/Confirmation.php | 57 + .../think/contract/CacheHandlerInterface.php | 88 + .../think/contract/LogHandlerInterface.php | 28 + .../think/contract/ModelRelationInterface.php | 99 + .../contract/SessionHandlerInterface.php | 23 + .../contract/TemplateHandlerInterface.php | 61 + .../framework/src/think/event/AppInit.php | 19 + .../framework/src/think/event/HttpEnd.php | 19 + .../framework/src/think/event/HttpRun.php | 19 + .../framework/src/think/event/LogWrite.php | 31 + .../framework/src/think/event/RouteLoaded.php | 21 + .../exception/ClassNotFoundException.php | 39 + .../src/think/exception/ErrorException.php | 57 + .../src/think/exception/FileException.php | 17 + .../think/exception/FuncNotFoundException.php | 30 + .../framework/src/think/exception/Handle.php | 334 ++ .../src/think/exception/HttpException.php | 42 + .../think/exception/HttpResponseException.php | 37 + .../exception/InvalidArgumentException.php | 22 + .../exception/RouteNotFoundException.php | 26 + .../src/think/exception/ValidateException.php | 37 + .../framework/src/think/facade/App.php | 33 + .../framework/src/think/facade/Cache.php | 33 + .../framework/src/think/facade/Config.php | 33 + .../framework/src/think/facade/Console.php | 33 + .../framework/src/think/facade/Cookie.php | 33 + .../framework/src/think/facade/Env.php | 33 + .../framework/src/think/facade/Event.php | 33 + .../framework/src/think/facade/Filesystem.php | 28 + .../framework/src/think/facade/Lang.php | 33 + .../framework/src/think/facade/Log.php | 33 + .../framework/src/think/facade/Middleware.php | 33 + .../framework/src/think/facade/Request.php | 33 + .../framework/src/think/facade/Route.php | 33 + .../framework/src/think/facade/Session.php | 33 + .../framework/src/think/facade/Validate.php | 39 + .../framework/src/think/facade/View.php | 33 + .../framework/src/think/file/UploadedFile.php | 143 + .../src/think/filesystem/CacheStore.php | 54 + .../framework/src/think/filesystem/Driver.php | 133 + .../src/think/filesystem/driver/Local.php | 41 + .../src/think/initializer/BootService.php | 26 + .../framework/src/think/initializer/Error.php | 117 + .../src/think/initializer/RegisterService.php | 48 + .../framework/src/think/log/Channel.php | 282 + .../framework/src/think/log/ChannelSet.php | 39 + .../framework/src/think/log/driver/File.php | 205 + .../framework/src/think/log/driver/Socket.php | 306 ++ .../src/think/middleware/AllowCrossDomain.php | 66 + .../think/middleware/CheckRequestCache.php | 163 + .../src/think/middleware/FormTokenCheck.php | 45 + .../src/think/middleware/LoadLangPack.php | 61 + .../src/think/middleware/SessionInit.php | 80 + .../framework/src/think/response/File.php | 145 + .../framework/src/think/response/Html.php | 34 + .../framework/src/think/response/Json.php | 62 + .../framework/src/think/response/Jsonp.php | 74 + .../framework/src/think/response/Redirect.php | 98 + .../framework/src/think/response/View.php | 149 + .../framework/src/think/response/Xml.php | 127 + .../framework/src/think/route/Dispatch.php | 265 + .../framework/src/think/route/Domain.php | 183 + .../framework/src/think/route/Resource.php | 251 + .../framework/src/think/route/Rule.php | 925 ++++ .../framework/src/think/route/RuleGroup.php | 541 ++ .../framework/src/think/route/RuleItem.php | 330 ++ .../framework/src/think/route/RuleName.php | 195 + .../framework/src/think/route/Url.php | 512 ++ .../src/think/route/dispatch/Callback.php | 30 + .../src/think/route/dispatch/Controller.php | 180 + .../src/think/route/dispatch/Redirect.php | 27 + .../src/think/route/dispatch/Response.php | 27 + .../src/think/route/dispatch/Url.php | 118 + .../src/think/route/dispatch/View.php | 28 + .../src/think/service/ModelService.php | 47 + .../src/think/service/PaginatorService.php | 52 + .../src/think/service/ValidateService.php | 31 + .../framework/src/think/session/Store.php | 340 ++ .../src/think/session/driver/Cache.php | 50 + .../src/think/session/driver/File.php | 249 + .../src/think/validate/ValidateRule.php | 172 + .../framework/src/think/view/driver/Php.php | 191 + .../framework/src/tpl/think_exception.tpl | 502 ++ vendor/topthink/framework/tests/AppTest.php | 215 + vendor/topthink/framework/tests/CacheTest.php | 149 + .../topthink/framework/tests/ConfigTest.php | 46 + .../framework/tests/ContainerTest.php | 313 ++ vendor/topthink/framework/tests/DbTest.php | 44 + vendor/topthink/framework/tests/EnvTest.php | 82 + vendor/topthink/framework/tests/EventTest.php | 143 + .../framework/tests/FilesystemTest.php | 131 + vendor/topthink/framework/tests/HttpTest.php | 154 + vendor/topthink/framework/tests/LogTest.php | 143 + .../framework/tests/MiddlewareTest.php | 121 + .../topthink/framework/tests/SessionTest.php | 225 + vendor/topthink/framework/tests/ViewTest.php | 127 + vendor/topthink/framework/tests/bootstrap.php | 3 + vendor/topthink/think-captcha/.gitignore | 3 + vendor/topthink/think-captcha/LICENSE | 32 + vendor/topthink/think-captcha/README.md | 57 + .../topthink/think-captcha/assets/bgs/1.jpg | Bin 0 -> 30428 bytes .../topthink/think-captcha/assets/bgs/2.jpg | Bin 0 -> 29677 bytes .../topthink/think-captcha/assets/bgs/3.jpg | Bin 0 -> 32109 bytes .../topthink/think-captcha/assets/bgs/4.jpg | Bin 0 -> 29081 bytes .../topthink/think-captcha/assets/bgs/5.jpg | Bin 0 -> 27940 bytes .../topthink/think-captcha/assets/bgs/6.jpg | Bin 0 -> 31381 bytes .../topthink/think-captcha/assets/bgs/7.jpg | Bin 0 -> 30234 bytes .../topthink/think-captcha/assets/bgs/8.jpg | Bin 0 -> 30188 bytes .../topthink/think-captcha/assets/ttfs/1.ttf | Bin 0 -> 46124 bytes .../topthink/think-captcha/assets/ttfs/2.ttf | Bin 0 -> 30352 bytes .../topthink/think-captcha/assets/ttfs/3.ttf | Bin 0 -> 319636 bytes .../topthink/think-captcha/assets/ttfs/4.ttf | Bin 0 -> 217360 bytes .../topthink/think-captcha/assets/ttfs/5.ttf | Bin 0 -> 162876 bytes .../topthink/think-captcha/assets/ttfs/6.ttf | Bin 0 -> 353824 bytes .../think-captcha/assets/zhttfs/1.ttf | Bin 0 -> 2183628 bytes vendor/topthink/think-captcha/composer.json | 33 + vendor/topthink/think-captcha/src/Captcha.php | 340 ++ .../think-captcha/src/CaptchaController.php | 20 + .../think-captcha/src/CaptchaService.php | 21 + vendor/topthink/think-captcha/src/config.php | 39 + .../think-captcha/src/facade/Captcha.php | 18 + vendor/topthink/think-captcha/src/helper.php | 52 + vendor/topthink/think-helper/.gitignore | 3 + vendor/topthink/think-helper/LICENSE | 201 + vendor/topthink/think-helper/README.md | 33 + vendor/topthink/think-helper/composer.json | 22 + .../topthink/think-helper/src/Collection.php | 651 +++ .../think-helper/src/contract/Arrayable.php | 8 + .../think-helper/src/contract/Jsonable.php | 8 + vendor/topthink/think-helper/src/helper.php | 279 + .../topthink/think-helper/src/helper/Arr.php | 634 +++ .../topthink/think-helper/src/helper/Str.php | 234 + vendor/topthink/think-multi-app/LICENSE | 201 + vendor/topthink/think-multi-app/README.md | 14 + vendor/topthink/think-multi-app/composer.json | 28 + .../topthink/think-multi-app/src/MultiApp.php | 255 + .../topthink/think-multi-app/src/Service.php | 29 + vendor/topthink/think-multi-app/src/Url.php | 224 + .../think-multi-app/src/command/Build.php | 180 + .../src/command/stubs/controller.stub | 12 + vendor/topthink/think-orm/.gitignore | 3 + vendor/topthink/think-orm/LICENSE | 201 + vendor/topthink/think-orm/README.md | 27 + vendor/topthink/think-orm/composer.json | 28 + vendor/topthink/think-orm/src/DbManager.php | 406 ++ vendor/topthink/think-orm/src/Model.php | 981 ++++ vendor/topthink/think-orm/src/Paginator.php | 497 ++ .../topthink/think-orm/src/db/BaseQuery.php | 1270 +++++ vendor/topthink/think-orm/src/db/Builder.php | 1281 +++++ .../topthink/think-orm/src/db/CacheItem.php | 209 + .../topthink/think-orm/src/db/Connection.php | 275 + .../think-orm/src/db/ConnectionInterface.php | 196 + vendor/topthink/think-orm/src/db/Fetch.php | 493 ++ vendor/topthink/think-orm/src/db/Mongo.php | 715 +++ .../think-orm/src/db/PDOConnection.php | 1686 ++++++ vendor/topthink/think-orm/src/db/Query.php | 493 ++ vendor/topthink/think-orm/src/db/Raw.php | 52 + vendor/topthink/think-orm/src/db/Where.php | 182 + .../think-orm/src/db/builder/Mongo.php | 675 +++ .../think-orm/src/db/builder/Mysql.php | 421 ++ .../think-orm/src/db/builder/Oracle.php | 95 + .../think-orm/src/db/builder/Pgsql.php | 118 + .../think-orm/src/db/builder/Sqlite.php | 97 + .../think-orm/src/db/builder/Sqlsrv.php | 184 + .../src/db/concern/AggregateQuery.php | 107 + .../src/db/concern/JoinAndViewQuery.php | 229 + .../src/db/concern/ModelRelationQuery.php | 516 ++ .../think-orm/src/db/concern/ParamsBind.php | 106 + .../src/db/concern/ResultOperation.php | 248 + .../src/db/concern/TableFieldInfo.php | 99 + .../src/db/concern/TimeFieldQuery.php | 214 + .../think-orm/src/db/concern/Transaction.php | 117 + .../think-orm/src/db/concern/WhereQuery.php | 540 ++ .../think-orm/src/db/connector/Mongo.php | 1055 ++++ .../think-orm/src/db/connector/Mysql.php | 162 + .../think-orm/src/db/connector/Oracle.php | 117 + .../think-orm/src/db/connector/Pgsql.php | 108 + .../think-orm/src/db/connector/Sqlite.php | 96 + .../think-orm/src/db/connector/Sqlsrv.php | 122 + .../think-orm/src/db/connector/pgsql.sql | 117 + .../src/db/exception/BindParamException.php | 35 + .../db/exception/DataNotFoundException.php | 43 + .../src/db/exception/DbException.php | 81 + .../db/exception/InvalidArgumentException.php | 21 + .../src/db/exception/ModelEventException.php | 19 + .../db/exception/ModelNotFoundException.php | 44 + .../src/db/exception/PDOException.php | 41 + vendor/topthink/think-orm/src/facade/Db.php | 86 + .../think-orm/src/model/Collection.php | 250 + vendor/topthink/think-orm/src/model/Pivot.php | 53 + .../topthink/think-orm/src/model/Relation.php | 258 + .../think-orm/src/model/concern/Attribute.php | 651 +++ .../src/model/concern/Conversion.php | 278 + .../src/model/concern/ModelEvent.php | 88 + .../think-orm/src/model/concern/OptimLock.php | 85 + .../src/model/concern/RelationShip.php | 781 +++ .../src/model/concern/SoftDelete.php | 246 + .../think-orm/src/model/concern/TimeStamp.php | 208 + .../src/model/relation/BelongsTo.php | 331 ++ .../src/model/relation/BelongsToMany.php | 708 +++ .../think-orm/src/model/relation/HasMany.php | 367 ++ .../src/model/relation/HasManyThrough.php | 382 ++ .../think-orm/src/model/relation/HasOne.php | 300 + .../src/model/relation/HasOneThrough.php | 163 + .../src/model/relation/MorphMany.php | 353 ++ .../think-orm/src/model/relation/MorphOne.php | 280 + .../think-orm/src/model/relation/MorphTo.php | 333 ++ .../think-orm/src/model/relation/OneToOne.php | 332 ++ .../src/paginator/driver/Bootstrap.php | 209 + vendor/topthink/think-template/.gitignore | 1 + vendor/topthink/think-template/LICENSE | 201 + vendor/topthink/think-template/README.md | 70 + vendor/topthink/think-template/composer.json | 20 + .../topthink/think-template/src/Template.php | 1320 +++++ .../think-template/src/facade/Template.php | 83 + .../think-template/src/template/TagLib.php | 349 ++ .../src/template/driver/File.php | 83 + .../exception/TemplateNotFoundException.php | 33 + .../think-template/src/template/taglib/Cx.php | 715 +++ vendor/topthink/think-trace/.gitignore | 1 + vendor/topthink/think-trace/LICENSE | 201 + vendor/topthink/think-trace/README.md | 15 + vendor/topthink/think-trace/composer.json | 31 + vendor/topthink/think-trace/src/Console.php | 170 + vendor/topthink/think-trace/src/Html.php | 125 + vendor/topthink/think-trace/src/Service.php | 21 + .../topthink/think-trace/src/TraceDebug.php | 109 + vendor/topthink/think-trace/src/config.php | 10 + .../think-trace/src/tpl/page_trace.tpl | 71 + vendor/topthink/think-view/.gitignore | 1 + vendor/topthink/think-view/LICENSE | 201 + vendor/topthink/think-view/README.md | 36 + vendor/topthink/think-view/composer.json | 20 + vendor/topthink/think-view/src/Think.php | 263 + 650 files changed, 99228 insertions(+), 1 deletion(-) create mode 100644 vendor/autoload.php create mode 100644 vendor/bin/var-dump-server create mode 100644 vendor/bin/var-dump-server.bat create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/league/flysystem-cached-adapter/.editorconfig create mode 100644 vendor/league/flysystem-cached-adapter/.gitignore create mode 100644 vendor/league/flysystem-cached-adapter/.php_cs create mode 100644 vendor/league/flysystem-cached-adapter/.scrutinizer.yml create mode 100644 vendor/league/flysystem-cached-adapter/.travis.yml create mode 100644 vendor/league/flysystem-cached-adapter/LICENSE create mode 100644 vendor/league/flysystem-cached-adapter/clover/.gitignore create mode 100644 vendor/league/flysystem-cached-adapter/composer.json create mode 100644 vendor/league/flysystem-cached-adapter/phpspec.yml create mode 100644 vendor/league/flysystem-cached-adapter/phpunit.php create mode 100644 vendor/league/flysystem-cached-adapter/phpunit.xml create mode 100644 vendor/league/flysystem-cached-adapter/readme.md create mode 100644 vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php create mode 100644 vendor/league/flysystem-cached-adapter/src/CacheInterface.php create mode 100644 vendor/league/flysystem-cached-adapter/src/CachedAdapter.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Memory.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Noop.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/PhpRedis.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Predis.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php create mode 100644 vendor/league/flysystem-cached-adapter/src/Storage/Stash.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/InspectionTests.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/PredisTests.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php create mode 100644 vendor/league/flysystem-cached-adapter/tests/StashTest.php create mode 100644 vendor/league/flysystem/LICENSE create mode 100644 vendor/league/flysystem/composer.json create mode 100644 vendor/league/flysystem/deprecations.md create mode 100644 vendor/league/flysystem/src/Adapter/AbstractAdapter.php create mode 100644 vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php create mode 100644 vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php create mode 100644 vendor/league/flysystem/src/Adapter/Ftp.php create mode 100644 vendor/league/flysystem/src/Adapter/Ftpd.php create mode 100644 vendor/league/flysystem/src/Adapter/Local.php create mode 100644 vendor/league/flysystem/src/Adapter/NullAdapter.php create mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php create mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedCopyTrait.php create mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php create mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php create mode 100644 vendor/league/flysystem/src/Adapter/Polyfill/StreamedWritingTrait.php create mode 100644 vendor/league/flysystem/src/Adapter/SynologyFtp.php create mode 100644 vendor/league/flysystem/src/AdapterInterface.php create mode 100644 vendor/league/flysystem/src/Config.php create mode 100644 vendor/league/flysystem/src/ConfigAwareTrait.php create mode 100644 vendor/league/flysystem/src/Directory.php create mode 100644 vendor/league/flysystem/src/Exception.php create mode 100644 vendor/league/flysystem/src/File.php create mode 100644 vendor/league/flysystem/src/FileExistsException.php create mode 100644 vendor/league/flysystem/src/FileNotFoundException.php create mode 100644 vendor/league/flysystem/src/Filesystem.php create mode 100644 vendor/league/flysystem/src/FilesystemInterface.php create mode 100644 vendor/league/flysystem/src/FilesystemNotFoundException.php create mode 100644 vendor/league/flysystem/src/Handler.php create mode 100644 vendor/league/flysystem/src/MountManager.php create mode 100644 vendor/league/flysystem/src/NotSupportedException.php create mode 100644 vendor/league/flysystem/src/Plugin/AbstractPlugin.php create mode 100644 vendor/league/flysystem/src/Plugin/EmptyDir.php create mode 100644 vendor/league/flysystem/src/Plugin/ForcedCopy.php create mode 100644 vendor/league/flysystem/src/Plugin/ForcedRename.php create mode 100644 vendor/league/flysystem/src/Plugin/GetWithMetadata.php create mode 100644 vendor/league/flysystem/src/Plugin/ListFiles.php create mode 100644 vendor/league/flysystem/src/Plugin/ListPaths.php create mode 100644 vendor/league/flysystem/src/Plugin/ListWith.php create mode 100644 vendor/league/flysystem/src/Plugin/PluggableTrait.php create mode 100644 vendor/league/flysystem/src/Plugin/PluginNotFoundException.php create mode 100644 vendor/league/flysystem/src/PluginInterface.php create mode 100644 vendor/league/flysystem/src/ReadInterface.php create mode 100644 vendor/league/flysystem/src/RootViolationException.php create mode 100644 vendor/league/flysystem/src/SafeStorage.php create mode 100644 vendor/league/flysystem/src/UnreadableFileException.php create mode 100644 vendor/league/flysystem/src/Util.php create mode 100644 vendor/league/flysystem/src/Util/ContentListingFormatter.php create mode 100644 vendor/league/flysystem/src/Util/MimeType.php create mode 100644 vendor/league/flysystem/src/Util/StreamHasher.php create mode 100644 vendor/opis/closure/CHANGELOG.md create mode 100644 vendor/opis/closure/LICENSE create mode 100644 vendor/opis/closure/NOTICE create mode 100644 vendor/opis/closure/README.md create mode 100644 vendor/opis/closure/autoload.php create mode 100644 vendor/opis/closure/composer.json create mode 100644 vendor/opis/closure/functions.php create mode 100644 vendor/opis/closure/src/Analyzer.php create mode 100644 vendor/opis/closure/src/ClosureContext.php create mode 100644 vendor/opis/closure/src/ClosureScope.php create mode 100644 vendor/opis/closure/src/ClosureStream.php create mode 100644 vendor/opis/closure/src/ISecurityProvider.php create mode 100644 vendor/opis/closure/src/ReflectionClosure.php create mode 100644 vendor/opis/closure/src/SecurityException.php create mode 100644 vendor/opis/closure/src/SecurityProvider.php create mode 100644 vendor/opis/closure/src/SelfReference.php create mode 100644 vendor/opis/closure/src/SerializableClosure.php create mode 100644 vendor/phpmailer/phpmailer/COMMITMENT create mode 100644 vendor/phpmailer/phpmailer/LICENSE create mode 100644 vendor/phpmailer/phpmailer/README.md create mode 100644 vendor/phpmailer/phpmailer/SECURITY.md create mode 100644 vendor/phpmailer/phpmailer/VERSION create mode 100644 vendor/phpmailer/phpmailer/composer.json create mode 100644 vendor/phpmailer/phpmailer/get_oauth_token.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-am.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ar.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-az.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ba.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-be.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-bg.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ca.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ch.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-cs.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-da.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-el.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-eo.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-es.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-et.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-fa.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-fi.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-fo.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-gl.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-he.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-hi.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-hu.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-id.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ka.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ko.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-lt.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-lv.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-mg.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-nb.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-nl.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-pl.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-pt.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-pt_br.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ro.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-sk.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-sl.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-tl.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-uk.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-vi.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-zh.php create mode 100644 vendor/phpmailer/phpmailer/language/phpmailer.lang-zh_cn.php create mode 100644 vendor/phpmailer/phpmailer/src/Exception.php create mode 100644 vendor/phpmailer/phpmailer/src/OAuth.php create mode 100644 vendor/phpmailer/phpmailer/src/PHPMailer.php create mode 100644 vendor/phpmailer/phpmailer/src/POP3.php create mode 100644 vendor/phpmailer/phpmailer/src/SMTP.php create mode 100644 vendor/psr/cache/CHANGELOG.md create mode 100644 vendor/psr/cache/LICENSE.txt create mode 100644 vendor/psr/cache/README.md create mode 100644 vendor/psr/cache/composer.json create mode 100644 vendor/psr/cache/src/CacheException.php create mode 100644 vendor/psr/cache/src/CacheItemInterface.php create mode 100644 vendor/psr/cache/src/CacheItemPoolInterface.php create mode 100644 vendor/psr/cache/src/InvalidArgumentException.php create mode 100644 vendor/psr/container/.gitignore create mode 100644 vendor/psr/container/LICENSE create mode 100644 vendor/psr/container/README.md create mode 100644 vendor/psr/container/composer.json create mode 100644 vendor/psr/container/src/ContainerExceptionInterface.php create mode 100644 vendor/psr/container/src/ContainerInterface.php create mode 100644 vendor/psr/container/src/NotFoundExceptionInterface.php create mode 100644 vendor/psr/log/.gitignore create mode 100644 vendor/psr/log/LICENSE create mode 100644 vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 vendor/psr/log/Psr/Log/Test/TestLogger.php create mode 100644 vendor/psr/log/README.md create mode 100644 vendor/psr/log/composer.json create mode 100644 vendor/psr/simple-cache/.editorconfig create mode 100644 vendor/psr/simple-cache/LICENSE.md create mode 100644 vendor/psr/simple-cache/README.md create mode 100644 vendor/psr/simple-cache/composer.json create mode 100644 vendor/psr/simple-cache/src/CacheException.php create mode 100644 vendor/psr/simple-cache/src/CacheInterface.php create mode 100644 vendor/psr/simple-cache/src/InvalidArgumentException.php create mode 100644 vendor/services.php create mode 100644 vendor/symfony/polyfill-mbstring/LICENSE create mode 100644 vendor/symfony/polyfill-mbstring/Mbstring.php create mode 100644 vendor/symfony/polyfill-mbstring/README.md create mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php create mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php create mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php create mode 100644 vendor/symfony/polyfill-mbstring/bootstrap.php create mode 100644 vendor/symfony/polyfill-mbstring/composer.json create mode 100644 vendor/symfony/polyfill-php72/LICENSE create mode 100644 vendor/symfony/polyfill-php72/Php72.php create mode 100644 vendor/symfony/polyfill-php72/README.md create mode 100644 vendor/symfony/polyfill-php72/bootstrap.php create mode 100644 vendor/symfony/polyfill-php72/composer.json create mode 100644 vendor/symfony/var-dumper/.gitignore create mode 100644 vendor/symfony/var-dumper/CHANGELOG.md create mode 100644 vendor/symfony/var-dumper/Caster/AmqpCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/ArgsStub.php create mode 100644 vendor/symfony/var-dumper/Caster/Caster.php create mode 100644 vendor/symfony/var-dumper/Caster/ClassStub.php create mode 100644 vendor/symfony/var-dumper/Caster/ConstStub.php create mode 100644 vendor/symfony/var-dumper/Caster/CutArrayStub.php create mode 100644 vendor/symfony/var-dumper/Caster/CutStub.php create mode 100644 vendor/symfony/var-dumper/Caster/DOMCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/DateCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/DoctrineCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/DsCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/DsPairStub.php create mode 100644 vendor/symfony/var-dumper/Caster/EnumStub.php create mode 100644 vendor/symfony/var-dumper/Caster/ExceptionCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/FrameStub.php create mode 100644 vendor/symfony/var-dumper/Caster/GmpCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/IntlCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/LinkStub.php create mode 100644 vendor/symfony/var-dumper/Caster/MemcachedCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/PdoCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/PgSqlCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/RedisCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/ReflectionCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/ResourceCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/SplCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/StubCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/SymfonyCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/TraceStub.php create mode 100644 vendor/symfony/var-dumper/Caster/XmlReaderCaster.php create mode 100644 vendor/symfony/var-dumper/Caster/XmlResourceCaster.php create mode 100644 vendor/symfony/var-dumper/Cloner/AbstractCloner.php create mode 100644 vendor/symfony/var-dumper/Cloner/ClonerInterface.php create mode 100644 vendor/symfony/var-dumper/Cloner/Cursor.php create mode 100644 vendor/symfony/var-dumper/Cloner/Data.php create mode 100644 vendor/symfony/var-dumper/Cloner/DumperInterface.php create mode 100644 vendor/symfony/var-dumper/Cloner/Stub.php create mode 100644 vendor/symfony/var-dumper/Cloner/VarCloner.php create mode 100644 vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php create mode 100644 vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php create mode 100644 vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php create mode 100644 vendor/symfony/var-dumper/Command/ServerDumpCommand.php create mode 100644 vendor/symfony/var-dumper/Dumper/AbstractDumper.php create mode 100644 vendor/symfony/var-dumper/Dumper/CliDumper.php create mode 100644 vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php create mode 100644 vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php create mode 100644 vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php create mode 100644 vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php create mode 100644 vendor/symfony/var-dumper/Dumper/DataDumperInterface.php create mode 100644 vendor/symfony/var-dumper/Dumper/HtmlDumper.php create mode 100644 vendor/symfony/var-dumper/Dumper/ServerDumper.php create mode 100644 vendor/symfony/var-dumper/Exception/ThrowingCasterException.php create mode 100644 vendor/symfony/var-dumper/LICENSE create mode 100644 vendor/symfony/var-dumper/README.md create mode 100644 vendor/symfony/var-dumper/Resources/bin/var-dump-server create mode 100644 vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css create mode 100644 vendor/symfony/var-dumper/Resources/functions/dump.php create mode 100644 vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js create mode 100644 vendor/symfony/var-dumper/Server/Connection.php create mode 100644 vendor/symfony/var-dumper/Server/DumpServer.php create mode 100644 vendor/symfony/var-dumper/Test/VarDumperTestTrait.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/CasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/DateCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/GmpCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/IntlCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/MemcachedCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/PdoCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/RedisCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/SplCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/StubCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Caster/XmlReaderCasterTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Cloner/DataTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Cloner/VarClonerTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Command/Descriptor/CliDescriptorTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Command/Descriptor/HtmlDescriptorTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Dumper/CliDumperTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Dumper/FunctionsTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Dumper/HtmlDumperTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Dumper/ServerDumperTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/FooInterface.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/GeneratorDemo.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/NotLoadableClass.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/Php74.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/Twig.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/dumb-var.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/dump_server.php create mode 100644 vendor/symfony/var-dumper/Tests/Fixtures/xml_reader.xml create mode 100644 vendor/symfony/var-dumper/Tests/Server/ConnectionTest.php create mode 100644 vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php create mode 100644 vendor/symfony/var-dumper/VarDumper.php create mode 100644 vendor/symfony/var-dumper/composer.json create mode 100644 vendor/symfony/var-dumper/phpunit.xml.dist create mode 100644 vendor/topthink/framework/.gitignore create mode 100644 vendor/topthink/framework/.travis.yml create mode 100644 vendor/topthink/framework/CONTRIBUTING.md create mode 100644 vendor/topthink/framework/LICENSE.txt create mode 100644 vendor/topthink/framework/README.md create mode 100644 vendor/topthink/framework/composer.json create mode 100644 vendor/topthink/framework/logo.png create mode 100644 vendor/topthink/framework/phpunit.xml.dist create mode 100644 vendor/topthink/framework/src/helper.php create mode 100644 vendor/topthink/framework/src/lang/zh-cn.php create mode 100644 vendor/topthink/framework/src/think/App.php create mode 100644 vendor/topthink/framework/src/think/Cache.php create mode 100644 vendor/topthink/framework/src/think/Config.php create mode 100644 vendor/topthink/framework/src/think/Console.php create mode 100644 vendor/topthink/framework/src/think/Container.php create mode 100644 vendor/topthink/framework/src/think/Cookie.php create mode 100644 vendor/topthink/framework/src/think/Db.php create mode 100644 vendor/topthink/framework/src/think/Env.php create mode 100644 vendor/topthink/framework/src/think/Event.php create mode 100644 vendor/topthink/framework/src/think/Exception.php create mode 100644 vendor/topthink/framework/src/think/Facade.php create mode 100644 vendor/topthink/framework/src/think/File.php create mode 100644 vendor/topthink/framework/src/think/Filesystem.php create mode 100644 vendor/topthink/framework/src/think/Http.php create mode 100644 vendor/topthink/framework/src/think/Lang.php create mode 100644 vendor/topthink/framework/src/think/Log.php create mode 100644 vendor/topthink/framework/src/think/Manager.php create mode 100644 vendor/topthink/framework/src/think/Middleware.php create mode 100644 vendor/topthink/framework/src/think/Pipeline.php create mode 100644 vendor/topthink/framework/src/think/Request.php create mode 100644 vendor/topthink/framework/src/think/Response.php create mode 100644 vendor/topthink/framework/src/think/Route.php create mode 100644 vendor/topthink/framework/src/think/Service.php create mode 100644 vendor/topthink/framework/src/think/Session.php create mode 100644 vendor/topthink/framework/src/think/Validate.php create mode 100644 vendor/topthink/framework/src/think/View.php create mode 100644 vendor/topthink/framework/src/think/cache/Driver.php create mode 100644 vendor/topthink/framework/src/think/cache/TagSet.php create mode 100644 vendor/topthink/framework/src/think/cache/driver/File.php create mode 100644 vendor/topthink/framework/src/think/cache/driver/Memcache.php create mode 100644 vendor/topthink/framework/src/think/cache/driver/Memcached.php create mode 100644 vendor/topthink/framework/src/think/cache/driver/Redis.php create mode 100644 vendor/topthink/framework/src/think/cache/driver/Wincache.php create mode 100644 vendor/topthink/framework/src/think/console/Command.php create mode 100644 vendor/topthink/framework/src/think/console/Input.php create mode 100644 vendor/topthink/framework/src/think/console/LICENSE create mode 100644 vendor/topthink/framework/src/think/console/Output.php create mode 100644 vendor/topthink/framework/src/think/console/Table.php create mode 100644 vendor/topthink/framework/src/think/console/bin/README.md create mode 100644 vendor/topthink/framework/src/think/console/bin/hiddeninput.exe create mode 100644 vendor/topthink/framework/src/think/console/command/Clear.php create mode 100644 vendor/topthink/framework/src/think/console/command/Help.php create mode 100644 vendor/topthink/framework/src/think/console/command/Lists.php create mode 100644 vendor/topthink/framework/src/think/console/command/Make.php create mode 100644 vendor/topthink/framework/src/think/console/command/RouteList.php create mode 100644 vendor/topthink/framework/src/think/console/command/RunServer.php create mode 100644 vendor/topthink/framework/src/think/console/command/ServiceDiscover.php create mode 100644 vendor/topthink/framework/src/think/console/command/VendorPublish.php create mode 100644 vendor/topthink/framework/src/think/console/command/Version.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Command.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Controller.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Event.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Listener.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Middleware.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Model.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Service.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Subscribe.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/Validate.php create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/command.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/controller.api.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/controller.plain.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/controller.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/event.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/listener.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/middleware.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/model.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/service.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/subscribe.stub create mode 100644 vendor/topthink/framework/src/think/console/command/make/stubs/validate.stub create mode 100644 vendor/topthink/framework/src/think/console/command/optimize/Route.php create mode 100644 vendor/topthink/framework/src/think/console/command/optimize/Schema.php create mode 100644 vendor/topthink/framework/src/think/console/input/Argument.php create mode 100644 vendor/topthink/framework/src/think/console/input/Definition.php create mode 100644 vendor/topthink/framework/src/think/console/input/Option.php create mode 100644 vendor/topthink/framework/src/think/console/output/Ask.php create mode 100644 vendor/topthink/framework/src/think/console/output/Descriptor.php create mode 100644 vendor/topthink/framework/src/think/console/output/Formatter.php create mode 100644 vendor/topthink/framework/src/think/console/output/Question.php create mode 100644 vendor/topthink/framework/src/think/console/output/descriptor/Console.php create mode 100644 vendor/topthink/framework/src/think/console/output/driver/Buffer.php create mode 100644 vendor/topthink/framework/src/think/console/output/driver/Console.php create mode 100644 vendor/topthink/framework/src/think/console/output/driver/Nothing.php create mode 100644 vendor/topthink/framework/src/think/console/output/formatter/Stack.php create mode 100644 vendor/topthink/framework/src/think/console/output/formatter/Style.php create mode 100644 vendor/topthink/framework/src/think/console/output/question/Choice.php create mode 100644 vendor/topthink/framework/src/think/console/output/question/Confirmation.php create mode 100644 vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php create mode 100644 vendor/topthink/framework/src/think/contract/LogHandlerInterface.php create mode 100644 vendor/topthink/framework/src/think/contract/ModelRelationInterface.php create mode 100644 vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php create mode 100644 vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php create mode 100644 vendor/topthink/framework/src/think/event/AppInit.php create mode 100644 vendor/topthink/framework/src/think/event/HttpEnd.php create mode 100644 vendor/topthink/framework/src/think/event/HttpRun.php create mode 100644 vendor/topthink/framework/src/think/event/LogWrite.php create mode 100644 vendor/topthink/framework/src/think/event/RouteLoaded.php create mode 100644 vendor/topthink/framework/src/think/exception/ClassNotFoundException.php create mode 100644 vendor/topthink/framework/src/think/exception/ErrorException.php create mode 100644 vendor/topthink/framework/src/think/exception/FileException.php create mode 100644 vendor/topthink/framework/src/think/exception/FuncNotFoundException.php create mode 100644 vendor/topthink/framework/src/think/exception/Handle.php create mode 100644 vendor/topthink/framework/src/think/exception/HttpException.php create mode 100644 vendor/topthink/framework/src/think/exception/HttpResponseException.php create mode 100644 vendor/topthink/framework/src/think/exception/InvalidArgumentException.php create mode 100644 vendor/topthink/framework/src/think/exception/RouteNotFoundException.php create mode 100644 vendor/topthink/framework/src/think/exception/ValidateException.php create mode 100644 vendor/topthink/framework/src/think/facade/App.php create mode 100644 vendor/topthink/framework/src/think/facade/Cache.php create mode 100644 vendor/topthink/framework/src/think/facade/Config.php create mode 100644 vendor/topthink/framework/src/think/facade/Console.php create mode 100644 vendor/topthink/framework/src/think/facade/Cookie.php create mode 100644 vendor/topthink/framework/src/think/facade/Env.php create mode 100644 vendor/topthink/framework/src/think/facade/Event.php create mode 100644 vendor/topthink/framework/src/think/facade/Filesystem.php create mode 100644 vendor/topthink/framework/src/think/facade/Lang.php create mode 100644 vendor/topthink/framework/src/think/facade/Log.php create mode 100644 vendor/topthink/framework/src/think/facade/Middleware.php create mode 100644 vendor/topthink/framework/src/think/facade/Request.php create mode 100644 vendor/topthink/framework/src/think/facade/Route.php create mode 100644 vendor/topthink/framework/src/think/facade/Session.php create mode 100644 vendor/topthink/framework/src/think/facade/Validate.php create mode 100644 vendor/topthink/framework/src/think/facade/View.php create mode 100644 vendor/topthink/framework/src/think/file/UploadedFile.php create mode 100644 vendor/topthink/framework/src/think/filesystem/CacheStore.php create mode 100644 vendor/topthink/framework/src/think/filesystem/Driver.php create mode 100644 vendor/topthink/framework/src/think/filesystem/driver/Local.php create mode 100644 vendor/topthink/framework/src/think/initializer/BootService.php create mode 100644 vendor/topthink/framework/src/think/initializer/Error.php create mode 100644 vendor/topthink/framework/src/think/initializer/RegisterService.php create mode 100644 vendor/topthink/framework/src/think/log/Channel.php create mode 100644 vendor/topthink/framework/src/think/log/ChannelSet.php create mode 100644 vendor/topthink/framework/src/think/log/driver/File.php create mode 100644 vendor/topthink/framework/src/think/log/driver/Socket.php create mode 100644 vendor/topthink/framework/src/think/middleware/AllowCrossDomain.php create mode 100644 vendor/topthink/framework/src/think/middleware/CheckRequestCache.php create mode 100644 vendor/topthink/framework/src/think/middleware/FormTokenCheck.php create mode 100644 vendor/topthink/framework/src/think/middleware/LoadLangPack.php create mode 100644 vendor/topthink/framework/src/think/middleware/SessionInit.php create mode 100644 vendor/topthink/framework/src/think/response/File.php create mode 100644 vendor/topthink/framework/src/think/response/Html.php create mode 100644 vendor/topthink/framework/src/think/response/Json.php create mode 100644 vendor/topthink/framework/src/think/response/Jsonp.php create mode 100644 vendor/topthink/framework/src/think/response/Redirect.php create mode 100644 vendor/topthink/framework/src/think/response/View.php create mode 100644 vendor/topthink/framework/src/think/response/Xml.php create mode 100644 vendor/topthink/framework/src/think/route/Dispatch.php create mode 100644 vendor/topthink/framework/src/think/route/Domain.php create mode 100644 vendor/topthink/framework/src/think/route/Resource.php create mode 100644 vendor/topthink/framework/src/think/route/Rule.php create mode 100644 vendor/topthink/framework/src/think/route/RuleGroup.php create mode 100644 vendor/topthink/framework/src/think/route/RuleItem.php create mode 100644 vendor/topthink/framework/src/think/route/RuleName.php create mode 100644 vendor/topthink/framework/src/think/route/Url.php create mode 100644 vendor/topthink/framework/src/think/route/dispatch/Callback.php create mode 100644 vendor/topthink/framework/src/think/route/dispatch/Controller.php create mode 100644 vendor/topthink/framework/src/think/route/dispatch/Redirect.php create mode 100644 vendor/topthink/framework/src/think/route/dispatch/Response.php create mode 100644 vendor/topthink/framework/src/think/route/dispatch/Url.php create mode 100644 vendor/topthink/framework/src/think/route/dispatch/View.php create mode 100644 vendor/topthink/framework/src/think/service/ModelService.php create mode 100644 vendor/topthink/framework/src/think/service/PaginatorService.php create mode 100644 vendor/topthink/framework/src/think/service/ValidateService.php create mode 100644 vendor/topthink/framework/src/think/session/Store.php create mode 100644 vendor/topthink/framework/src/think/session/driver/Cache.php create mode 100644 vendor/topthink/framework/src/think/session/driver/File.php create mode 100644 vendor/topthink/framework/src/think/validate/ValidateRule.php create mode 100644 vendor/topthink/framework/src/think/view/driver/Php.php create mode 100644 vendor/topthink/framework/src/tpl/think_exception.tpl create mode 100644 vendor/topthink/framework/tests/AppTest.php create mode 100644 vendor/topthink/framework/tests/CacheTest.php create mode 100644 vendor/topthink/framework/tests/ConfigTest.php create mode 100644 vendor/topthink/framework/tests/ContainerTest.php create mode 100644 vendor/topthink/framework/tests/DbTest.php create mode 100644 vendor/topthink/framework/tests/EnvTest.php create mode 100644 vendor/topthink/framework/tests/EventTest.php create mode 100644 vendor/topthink/framework/tests/FilesystemTest.php create mode 100644 vendor/topthink/framework/tests/HttpTest.php create mode 100644 vendor/topthink/framework/tests/LogTest.php create mode 100644 vendor/topthink/framework/tests/MiddlewareTest.php create mode 100644 vendor/topthink/framework/tests/SessionTest.php create mode 100644 vendor/topthink/framework/tests/ViewTest.php create mode 100644 vendor/topthink/framework/tests/bootstrap.php create mode 100644 vendor/topthink/think-captcha/.gitignore create mode 100644 vendor/topthink/think-captcha/LICENSE create mode 100644 vendor/topthink/think-captcha/README.md create mode 100644 vendor/topthink/think-captcha/assets/bgs/1.jpg create mode 100644 vendor/topthink/think-captcha/assets/bgs/2.jpg create mode 100644 vendor/topthink/think-captcha/assets/bgs/3.jpg create mode 100644 vendor/topthink/think-captcha/assets/bgs/4.jpg create mode 100644 vendor/topthink/think-captcha/assets/bgs/5.jpg create mode 100644 vendor/topthink/think-captcha/assets/bgs/6.jpg create mode 100644 vendor/topthink/think-captcha/assets/bgs/7.jpg create mode 100644 vendor/topthink/think-captcha/assets/bgs/8.jpg create mode 100644 vendor/topthink/think-captcha/assets/ttfs/1.ttf create mode 100644 vendor/topthink/think-captcha/assets/ttfs/2.ttf create mode 100644 vendor/topthink/think-captcha/assets/ttfs/3.ttf create mode 100644 vendor/topthink/think-captcha/assets/ttfs/4.ttf create mode 100644 vendor/topthink/think-captcha/assets/ttfs/5.ttf create mode 100644 vendor/topthink/think-captcha/assets/ttfs/6.ttf create mode 100644 vendor/topthink/think-captcha/assets/zhttfs/1.ttf create mode 100644 vendor/topthink/think-captcha/composer.json create mode 100644 vendor/topthink/think-captcha/src/Captcha.php create mode 100644 vendor/topthink/think-captcha/src/CaptchaController.php create mode 100644 vendor/topthink/think-captcha/src/CaptchaService.php create mode 100644 vendor/topthink/think-captcha/src/config.php create mode 100644 vendor/topthink/think-captcha/src/facade/Captcha.php create mode 100644 vendor/topthink/think-captcha/src/helper.php create mode 100644 vendor/topthink/think-helper/.gitignore create mode 100644 vendor/topthink/think-helper/LICENSE create mode 100644 vendor/topthink/think-helper/README.md create mode 100644 vendor/topthink/think-helper/composer.json create mode 100644 vendor/topthink/think-helper/src/Collection.php create mode 100644 vendor/topthink/think-helper/src/contract/Arrayable.php create mode 100644 vendor/topthink/think-helper/src/contract/Jsonable.php create mode 100644 vendor/topthink/think-helper/src/helper.php create mode 100644 vendor/topthink/think-helper/src/helper/Arr.php create mode 100644 vendor/topthink/think-helper/src/helper/Str.php create mode 100644 vendor/topthink/think-multi-app/LICENSE create mode 100644 vendor/topthink/think-multi-app/README.md create mode 100644 vendor/topthink/think-multi-app/composer.json create mode 100644 vendor/topthink/think-multi-app/src/MultiApp.php create mode 100644 vendor/topthink/think-multi-app/src/Service.php create mode 100644 vendor/topthink/think-multi-app/src/Url.php create mode 100644 vendor/topthink/think-multi-app/src/command/Build.php create mode 100644 vendor/topthink/think-multi-app/src/command/stubs/controller.stub create mode 100644 vendor/topthink/think-orm/.gitignore create mode 100644 vendor/topthink/think-orm/LICENSE create mode 100644 vendor/topthink/think-orm/README.md create mode 100644 vendor/topthink/think-orm/composer.json create mode 100644 vendor/topthink/think-orm/src/DbManager.php create mode 100644 vendor/topthink/think-orm/src/Model.php create mode 100644 vendor/topthink/think-orm/src/Paginator.php create mode 100644 vendor/topthink/think-orm/src/db/BaseQuery.php create mode 100644 vendor/topthink/think-orm/src/db/Builder.php create mode 100644 vendor/topthink/think-orm/src/db/CacheItem.php create mode 100644 vendor/topthink/think-orm/src/db/Connection.php create mode 100644 vendor/topthink/think-orm/src/db/ConnectionInterface.php create mode 100644 vendor/topthink/think-orm/src/db/Fetch.php create mode 100644 vendor/topthink/think-orm/src/db/Mongo.php create mode 100644 vendor/topthink/think-orm/src/db/PDOConnection.php create mode 100644 vendor/topthink/think-orm/src/db/Query.php create mode 100644 vendor/topthink/think-orm/src/db/Raw.php create mode 100644 vendor/topthink/think-orm/src/db/Where.php create mode 100644 vendor/topthink/think-orm/src/db/builder/Mongo.php create mode 100644 vendor/topthink/think-orm/src/db/builder/Mysql.php create mode 100644 vendor/topthink/think-orm/src/db/builder/Oracle.php create mode 100644 vendor/topthink/think-orm/src/db/builder/Pgsql.php create mode 100644 vendor/topthink/think-orm/src/db/builder/Sqlite.php create mode 100644 vendor/topthink/think-orm/src/db/builder/Sqlsrv.php create mode 100644 vendor/topthink/think-orm/src/db/concern/AggregateQuery.php create mode 100644 vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php create mode 100644 vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php create mode 100644 vendor/topthink/think-orm/src/db/concern/ParamsBind.php create mode 100644 vendor/topthink/think-orm/src/db/concern/ResultOperation.php create mode 100644 vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php create mode 100644 vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php create mode 100644 vendor/topthink/think-orm/src/db/concern/Transaction.php create mode 100644 vendor/topthink/think-orm/src/db/concern/WhereQuery.php create mode 100644 vendor/topthink/think-orm/src/db/connector/Mongo.php create mode 100644 vendor/topthink/think-orm/src/db/connector/Mysql.php create mode 100644 vendor/topthink/think-orm/src/db/connector/Oracle.php create mode 100644 vendor/topthink/think-orm/src/db/connector/Pgsql.php create mode 100644 vendor/topthink/think-orm/src/db/connector/Sqlite.php create mode 100644 vendor/topthink/think-orm/src/db/connector/Sqlsrv.php create mode 100644 vendor/topthink/think-orm/src/db/connector/pgsql.sql create mode 100644 vendor/topthink/think-orm/src/db/exception/BindParamException.php create mode 100644 vendor/topthink/think-orm/src/db/exception/DataNotFoundException.php create mode 100644 vendor/topthink/think-orm/src/db/exception/DbException.php create mode 100644 vendor/topthink/think-orm/src/db/exception/InvalidArgumentException.php create mode 100644 vendor/topthink/think-orm/src/db/exception/ModelEventException.php create mode 100644 vendor/topthink/think-orm/src/db/exception/ModelNotFoundException.php create mode 100644 vendor/topthink/think-orm/src/db/exception/PDOException.php create mode 100644 vendor/topthink/think-orm/src/facade/Db.php create mode 100644 vendor/topthink/think-orm/src/model/Collection.php create mode 100644 vendor/topthink/think-orm/src/model/Pivot.php create mode 100644 vendor/topthink/think-orm/src/model/Relation.php create mode 100644 vendor/topthink/think-orm/src/model/concern/Attribute.php create mode 100644 vendor/topthink/think-orm/src/model/concern/Conversion.php create mode 100644 vendor/topthink/think-orm/src/model/concern/ModelEvent.php create mode 100644 vendor/topthink/think-orm/src/model/concern/OptimLock.php create mode 100644 vendor/topthink/think-orm/src/model/concern/RelationShip.php create mode 100644 vendor/topthink/think-orm/src/model/concern/SoftDelete.php create mode 100644 vendor/topthink/think-orm/src/model/concern/TimeStamp.php create mode 100644 vendor/topthink/think-orm/src/model/relation/BelongsTo.php create mode 100644 vendor/topthink/think-orm/src/model/relation/BelongsToMany.php create mode 100644 vendor/topthink/think-orm/src/model/relation/HasMany.php create mode 100644 vendor/topthink/think-orm/src/model/relation/HasManyThrough.php create mode 100644 vendor/topthink/think-orm/src/model/relation/HasOne.php create mode 100644 vendor/topthink/think-orm/src/model/relation/HasOneThrough.php create mode 100644 vendor/topthink/think-orm/src/model/relation/MorphMany.php create mode 100644 vendor/topthink/think-orm/src/model/relation/MorphOne.php create mode 100644 vendor/topthink/think-orm/src/model/relation/MorphTo.php create mode 100644 vendor/topthink/think-orm/src/model/relation/OneToOne.php create mode 100644 vendor/topthink/think-orm/src/paginator/driver/Bootstrap.php create mode 100644 vendor/topthink/think-template/.gitignore create mode 100644 vendor/topthink/think-template/LICENSE create mode 100644 vendor/topthink/think-template/README.md create mode 100644 vendor/topthink/think-template/composer.json create mode 100644 vendor/topthink/think-template/src/Template.php create mode 100644 vendor/topthink/think-template/src/facade/Template.php create mode 100644 vendor/topthink/think-template/src/template/TagLib.php create mode 100644 vendor/topthink/think-template/src/template/driver/File.php create mode 100644 vendor/topthink/think-template/src/template/exception/TemplateNotFoundException.php create mode 100644 vendor/topthink/think-template/src/template/taglib/Cx.php create mode 100644 vendor/topthink/think-trace/.gitignore create mode 100644 vendor/topthink/think-trace/LICENSE create mode 100644 vendor/topthink/think-trace/README.md create mode 100644 vendor/topthink/think-trace/composer.json create mode 100644 vendor/topthink/think-trace/src/Console.php create mode 100644 vendor/topthink/think-trace/src/Html.php create mode 100644 vendor/topthink/think-trace/src/Service.php create mode 100644 vendor/topthink/think-trace/src/TraceDebug.php create mode 100644 vendor/topthink/think-trace/src/config.php create mode 100644 vendor/topthink/think-trace/src/tpl/page_trace.tpl create mode 100644 vendor/topthink/think-view/.gitignore create mode 100644 vendor/topthink/think-view/LICENSE create mode 100644 vendor/topthink/think-view/README.md create mode 100644 vendor/topthink/think-view/composer.json create mode 100644 vendor/topthink/think-view/src/Think.php diff --git a/vendor/.gitignore b/vendor/.gitignore index c96a04f..b722e9e 100644 --- a/vendor/.gitignore +++ b/vendor/.gitignore @@ -1,2 +1 @@ -* !.gitignore \ No newline at end of file diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..6b0be69 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + /dev/null; cd "../symfony/var-dumper/Resources/bin" && pwd) + +if [ -d /proc/cygdrive ]; then + case $(which php) in + $(readlink -n /proc/cygdrive)/*) + # We are in Cygwin using Windows php, so the path must be translated + dir=$(cygpath -m "$dir"); + ;; + esac +fi + +"${dir}/var-dump-server" "$@" diff --git a/vendor/bin/var-dump-server.bat b/vendor/bin/var-dump-server.bat new file mode 100644 index 0000000..46836b5 --- /dev/null +++ b/vendor/bin/var-dump-server.bat @@ -0,0 +1,4 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/../symfony/var-dumper/Resources/bin/var-dump-server +php "%BIN_TARGET%" %* diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php new file mode 100644 index 0000000..fce8549 --- /dev/null +++ b/vendor/composer/ClassLoader.php @@ -0,0 +1,445 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..7a91153 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + $vendorDir . '/topthink/think-helper/src/helper.php', + '538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', + '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', + '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', + '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..7cb803d --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,10 @@ + array($baseDir . '/extend'), +); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php new file mode 100644 index 0000000..7b24b79 --- /dev/null +++ b/vendor/composer/autoload_psr4.php @@ -0,0 +1,26 @@ + array($vendorDir . '/topthink/think-view/src'), + 'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'), + 'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'), + 'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'), + 'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'), + 'app\\' => array($baseDir . '/app'), + 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), + 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), + 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), + 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), + 'PHPMailer\\PHPMailer\\' => array($vendorDir . '/phpmailer/phpmailer/src'), + 'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'), + 'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'), + 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..6357f5b --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,70 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitf79aa87d3682b4ff439571b93fac530f::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInitf79aa87d3682b4ff439571b93fac530f::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequiref79aa87d3682b4ff439571b93fac530f($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequiref79aa87d3682b4ff439571b93fac530f($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 0000000..d10986c --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,143 @@ + __DIR__ . '/..' . '/topthink/think-helper/src/helper.php', + '538ca81a9a966a6716601ecf48f4eaef' => __DIR__ . '/..' . '/opis/closure/functions.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', + '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', + '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', + ); + + public static $prefixLengthsPsr4 = array ( + 't' => + array ( + 'think\\view\\driver\\' => 18, + 'think\\trace\\' => 12, + 'think\\captcha\\' => 14, + 'think\\app\\' => 10, + 'think\\' => 6, + ), + 'a' => + array ( + 'app\\' => 4, + ), + 'S' => + array ( + 'Symfony\\Polyfill\\Php72\\' => 23, + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Component\\VarDumper\\' => 28, + ), + 'P' => + array ( + 'Psr\\SimpleCache\\' => 16, + 'Psr\\Log\\' => 8, + 'Psr\\Container\\' => 14, + 'Psr\\Cache\\' => 10, + 'PHPMailer\\PHPMailer\\' => 20, + ), + 'O' => + array ( + 'Opis\\Closure\\' => 13, + ), + 'L' => + array ( + 'League\\Flysystem\\Cached\\' => 24, + 'League\\Flysystem\\' => 17, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'think\\view\\driver\\' => + array ( + 0 => __DIR__ . '/..' . '/topthink/think-view/src', + ), + 'think\\trace\\' => + array ( + 0 => __DIR__ . '/..' . '/topthink/think-trace/src', + ), + 'think\\captcha\\' => + array ( + 0 => __DIR__ . '/..' . '/topthink/think-captcha/src', + ), + 'think\\app\\' => + array ( + 0 => __DIR__ . '/..' . '/topthink/think-multi-app/src', + ), + 'think\\' => + array ( + 0 => __DIR__ . '/..' . '/topthink/framework/src/think', + 1 => __DIR__ . '/..' . '/topthink/think-helper/src', + 2 => __DIR__ . '/..' . '/topthink/think-orm/src', + 3 => __DIR__ . '/..' . '/topthink/think-template/src', + ), + 'app\\' => + array ( + 0 => __DIR__ . '/../..' . '/app', + ), + 'Symfony\\Polyfill\\Php72\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', + ), + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Component\\VarDumper\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/var-dumper', + ), + 'Psr\\SimpleCache\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/simple-cache/src', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), + 'Psr\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/container/src', + ), + 'Psr\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/cache/src', + ), + 'PHPMailer\\PHPMailer\\' => + array ( + 0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src', + ), + 'Opis\\Closure\\' => + array ( + 0 => __DIR__ . '/..' . '/opis/closure/src', + ), + 'League\\Flysystem\\Cached\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem-cached-adapter/src', + ), + 'League\\Flysystem\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem/src', + ), + ); + + public static $fallbackDirsPsr0 = array ( + 0 => __DIR__ . '/../..' . '/extend', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitf79aa87d3682b4ff439571b93fac530f::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitf79aa87d3682b4ff439571b93fac530f::$prefixDirsPsr4; + $loader->fallbackDirsPsr0 = ComposerStaticInitf79aa87d3682b4ff439571b93fac530f::$fallbackDirsPsr0; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..66b9341 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,1148 @@ +[ + { + "name": "league/flysystem", + "version": "1.0.57", + "version_normalized": "1.0.57.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a", + "reference": "0e9db7f0b96b9f12dcf6f65bc34b72b1a30ea55a", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-fileinfo": "*", + "php": ">=5.5.9" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7.10" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "ext-ftp": "Allows you to use FTP server storage", + "ext-openssl": "Allows you to use FTPS server storage", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", + "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", + "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" + }, + "time": "2019-10-16T21:01:05+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ] + }, + { + "name": "league/flysystem-cached-adapter", + "version": "1.0.9", + "version_normalized": "1.0.9.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-cached-adapter.git", + "reference": "08ef74e9be88100807a3b92cc9048a312bf01d6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/08ef74e9be88100807a3b92cc9048a312bf01d6f", + "reference": "08ef74e9be88100807a3b92cc9048a312bf01d6f", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "league/flysystem": "~1.0", + "psr/cache": "^1.0.0" + }, + "require-dev": { + "mockery/mockery": "~0.9", + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7", + "predis/predis": "~1.0", + "tedivm/stash": "~0.12" + }, + "suggest": { + "ext-phpredis": "Pure C implemented extension for PHP" + }, + "time": "2018-07-09T20:51:04+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\Cached\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "frankdejonge", + "email": "info@frenky.net" + } + ], + "description": "An adapter decorator to enable meta-data caching." + }, + { + "name": "opis/closure", + "version": "3.4.1", + "version_normalized": "3.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/opis/closure.git", + "reference": "e79f851749c3caa836d7ccc01ede5828feb762c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/closure/zipball/e79f851749c3caa836d7ccc01ede5828feb762c7", + "reference": "e79f851749c3caa836d7ccc01ede5828feb762c7", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^5.4 || ^7.0" + }, + "require-dev": { + "jeremeamia/superclosure": "^2.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "time": "2019-10-19T18:38:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Opis\\Closure\\": "src/" + }, + "files": [ + "functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", + "homepage": "https://opis.io/closure", + "keywords": [ + "anonymous functions", + "closure", + "function", + "serializable", + "serialization", + "serialize" + ] + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.1.5", + "version_normalized": "6.1.5.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "a8bf068f64a580302026e484ee29511f661b2ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a8bf068f64a580302026e484ee29511f661b2ad3", + "reference": "a8bf068f64a580302026e484ee29511f661b2ad3", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "doctrine/annotations": "^1.2", + "friendsofphp/php-cs-fixer": "^2.2", + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "time": "2020-03-14T14:23:48+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-08-06T20:24:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ] + }, + { + "name": "psr/container", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2017-02-14T16:28:37+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ] + }, + { + "name": "psr/log", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2018-11-20T15:27:04+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2017-10-23T01:57:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ] + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.12.0", + "version_normalized": "1.12.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2019-08-06T08:03:45+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.12.0", + "version_normalized": "1.12.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "04ce3335667451138df4307d6a9b61565560199e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e", + "reference": "04ce3335667451138df4307d6a9b61565560199e", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2019-08-06T08:03:45+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "symfony/var-dumper", + "version": "v4.3.5", + "version_normalized": "4.3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "bde8957fc415fdc6964f33916a3755737744ff05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/bde8957fc415fdc6964f33916a3755737744ff05", + "reference": "bde8957fc415fdc6964f33916a3755737744ff05", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/console": "<3.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0", + "twig/twig": "~1.34|~2.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "time": "2019-10-04T19:48:13+00:00", + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ] + }, + { + "name": "topthink/framework", + "version": "v6.0.2", + "version_normalized": "6.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/framework.git", + "reference": "1444cce94b40a836958380b160a5fb7bfc165daf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/framework/zipball/1444cce94b40a836958380b160a5fb7bfc165daf", + "reference": "1444cce94b40a836958380b160a5fb7bfc165daf", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "league/flysystem": "^1.0", + "league/flysystem-cached-adapter": "^1.0", + "opis/closure": "^3.1", + "php": ">=7.1.0", + "psr/container": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "topthink/think-helper": "^3.1.1", + "topthink/think-orm": "^2.0" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^7.0" + }, + "time": "2020-01-13T05:48:05+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [], + "psr-4": { + "think\\": "src/think/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP Framework.", + "homepage": "http://thinkphp.cn/", + "keywords": [ + "framework", + "orm", + "thinkphp" + ] + }, + { + "name": "topthink/think-captcha", + "version": "v3.0.2", + "version_normalized": "3.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-captcha.git", + "reference": "0b4305da19e118cefd934007875a8112f9352f01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-captcha/zipball/0b4305da19e118cefd934007875a8112f9352f01", + "reference": "0b4305da19e118cefd934007875a8112f9352f01", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "topthink/framework": "^6.0.0" + }, + "time": "2019-10-03T07:45:11+00:00", + "type": "library", + "extra": { + "think": { + "services": [ + "think\\captcha\\CaptchaService" + ], + "config": { + "captcha": "src/config.php" + } + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\captcha\\": "src/" + }, + "files": [ + "src/helper.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "captcha package for thinkphp" + }, + { + "name": "topthink/think-helper", + "version": "v3.1.3", + "version_normalized": "3.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-helper.git", + "reference": "4d85dfd3778623bbb1de3648f1dcd0c82f4439f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-helper/zipball/4d85dfd3778623bbb1de3648f1dcd0c82f4439f4", + "reference": "4d85dfd3778623bbb1de3648f1dcd0c82f4439f4", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1.0" + }, + "time": "2019-09-30T02:36:48+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\": "src" + }, + "files": [ + "src/helper.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "description": "The ThinkPHP6 Helper Package" + }, + { + "name": "topthink/think-multi-app", + "version": "v1.0.11", + "version_normalized": "1.0.11.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-multi-app.git", + "reference": "215f4a6bb88e53ad41b448c61957336eb55ce6f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/215f4a6bb88e53ad41b448c61957336eb55ce6f9", + "reference": "215f4a6bb88e53ad41b448c61957336eb55ce6f9", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1.0", + "topthink/framework": "^6.0.0" + }, + "time": "2019-10-29T06:34:59+00:00", + "type": "library", + "extra": { + "think": { + "services": [ + "think\\app\\Service" + ] + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\app\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "thinkphp6 multi app support" + }, + { + "name": "topthink/think-orm", + "version": "v2.0.27", + "version_normalized": "2.0.27.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-orm.git", + "reference": "02affaaccade2cdd8bbb2d2f5d15e46113e6eb50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-orm/zipball/02affaaccade2cdd8bbb2d2f5d15e46113e6eb50", + "reference": "02affaaccade2cdd8bbb2d2f5d15e46113e6eb50", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "php": ">=7.1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "topthink/think-helper": "^3.1" + }, + "time": "2019-10-23T02:16:50+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\": "src" + }, + "files": [] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "think orm", + "keywords": [ + "database", + "orm" + ] + }, + { + "name": "topthink/think-template", + "version": "v2.0.7", + "version_normalized": "2.0.7.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-template.git", + "reference": "e98bdbb4a4c94b442f17dfceba81e0134d4fbd19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-template/zipball/e98bdbb4a4c94b442f17dfceba81e0134d4fbd19", + "reference": "e98bdbb4a4c94b442f17dfceba81e0134d4fbd19", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1.0", + "psr/simple-cache": "^1.0" + }, + "time": "2019-09-20T15:31:04+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "the php template engine" + }, + { + "name": "topthink/think-trace", + "version": "v1.2", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-trace.git", + "reference": "4589d06a07945d57478cc2236f4b23d51ff919cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-trace/zipball/4589d06a07945d57478cc2236f4b23d51ff919cc", + "reference": "4589d06a07945d57478cc2236f4b23d51ff919cc", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1.0", + "topthink/framework": "^6.0.0" + }, + "time": "2019-10-17T02:14:09+00:00", + "type": "library", + "extra": { + "think": { + "services": [ + "think\\trace\\Service" + ], + "config": { + "trace": "src/config.php" + } + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\trace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "thinkphp debug trace" + }, + { + "name": "topthink/think-view", + "version": "v1.0.13", + "version_normalized": "1.0.13.0", + "source": { + "type": "git", + "url": "https://github.com/top-think/think-view.git", + "reference": "90803b73f781db5d42619082c4597afc58b2d4c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/top-think/think-view/zipball/90803b73f781db5d42619082c4597afc58b2d4c5", + "reference": "90803b73f781db5d42619082c4597afc58b2d4c5", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.1.0", + "topthink/think-template": "^2.0" + }, + "time": "2019-10-07T12:23:10+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "think\\view\\driver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + } + ], + "description": "thinkphp template driver" + } +] diff --git a/vendor/league/flysystem-cached-adapter/.editorconfig b/vendor/league/flysystem-cached-adapter/.editorconfig new file mode 100644 index 0000000..153cf3e --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/.editorconfig @@ -0,0 +1,10 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +[*.php] +indent_style = space +indent_size = 4 diff --git a/vendor/league/flysystem-cached-adapter/.gitignore b/vendor/league/flysystem-cached-adapter/.gitignore new file mode 100644 index 0000000..7aea75f --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/.gitignore @@ -0,0 +1,4 @@ +coverage +coverage.xml +composer.lock +vendor \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/.php_cs b/vendor/league/flysystem-cached-adapter/.php_cs new file mode 100644 index 0000000..6643a32 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/.php_cs @@ -0,0 +1,7 @@ +level(Symfony\CS\FixerInterface::PSR2_LEVEL) + ->fixers(['-yoda_conditions', 'ordered_use', 'short_array_syntax']) + ->finder(Symfony\CS\Finder\DefaultFinder::create() + ->in(__DIR__.'/src/')); \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/.scrutinizer.yml b/vendor/league/flysystem-cached-adapter/.scrutinizer.yml new file mode 100644 index 0000000..fa39b52 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/.scrutinizer.yml @@ -0,0 +1,34 @@ +filter: + paths: [src/*] +checks: + php: + code_rating: true + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true + fix_doc_comments: true +tools: + external_code_coverage: + timeout: 900 + runs: 6 + php_code_coverage: false + php_code_sniffer: + config: + standard: PSR2 + filter: + paths: ['src'] + php_loc: + enabled: true + excluded_dirs: [vendor, spec, stubs] + php_cpd: + enabled: true + excluded_dirs: [vendor, spec, stubs] \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/.travis.yml b/vendor/league/flysystem-cached-adapter/.travis.yml new file mode 100644 index 0000000..6706449 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/.travis.yml @@ -0,0 +1,29 @@ +language: php + +php: + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - 7.2 + +matrix: + allow_failures: + - php: 5.5 + +env: + - COMPOSER_OPTS="" + - COMPOSER_OPTS="--prefer-lowest" + +install: + - if [[ "${TRAVIS_PHP_VERSION}" == "5.5" ]]; then composer require phpunit/phpunit:^4.8.36 phpspec/phpspec:^2 --prefer-dist --update-with-dependencies; fi + - if [[ "${TRAVIS_PHP_VERSION}" == "7.2" ]]; then composer require phpunit/phpunit:^6.0 --prefer-dist --update-with-dependencies; fi + - travis_retry composer update --prefer-dist $COMPOSER_OPTS + +script: + - vendor/bin/phpspec run + - vendor/bin/phpunit + +after_script: + - wget https://scrutinizer-ci.com/ocular.phar' + - php ocular.phar code-coverage:upload --format=php-clover ./clover/phpunit.xml' diff --git a/vendor/league/flysystem-cached-adapter/LICENSE b/vendor/league/flysystem-cached-adapter/LICENSE new file mode 100644 index 0000000..666f6c8 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Frank de Jonge + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/league/flysystem-cached-adapter/clover/.gitignore b/vendor/league/flysystem-cached-adapter/clover/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/clover/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/vendor/league/flysystem-cached-adapter/composer.json b/vendor/league/flysystem-cached-adapter/composer.json new file mode 100644 index 0000000..df7fb7f --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/composer.json @@ -0,0 +1,30 @@ +{ + "name": "league/flysystem-cached-adapter", + "description": "An adapter decorator to enable meta-data caching.", + "autoload": { + "psr-4": { + "League\\Flysystem\\Cached\\": "src/" + } + }, + "require": { + "league/flysystem": "~1.0", + "psr/cache": "^1.0.0" + }, + "require-dev": { + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7", + "mockery/mockery": "~0.9", + "predis/predis": "~1.0", + "tedivm/stash": "~0.12" + }, + "suggest": { + "ext-phpredis": "Pure C implemented extension for PHP" + }, + "license": "MIT", + "authors": [ + { + "name": "frankdejonge", + "email": "info@frenky.net" + } + ] +} diff --git a/vendor/league/flysystem-cached-adapter/phpspec.yml b/vendor/league/flysystem-cached-adapter/phpspec.yml new file mode 100644 index 0000000..5eabcb2 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/phpspec.yml @@ -0,0 +1,6 @@ +--- +suites: + cached_adapter_suite: + namespace: League\Flysystem\Cached + psr4_prefix: League\Flysystem\Cached +formatter.name: pretty diff --git a/vendor/league/flysystem-cached-adapter/phpunit.php b/vendor/league/flysystem-cached-adapter/phpunit.php new file mode 100644 index 0000000..d109587 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/phpunit.php @@ -0,0 +1,3 @@ + + + + + ./tests/ + + + + + ./src/ + + + + + + + + diff --git a/vendor/league/flysystem-cached-adapter/readme.md b/vendor/league/flysystem-cached-adapter/readme.md new file mode 100644 index 0000000..dd1433d --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/readme.md @@ -0,0 +1,20 @@ +# Flysystem Cached CachedAdapter + +[![Author](http://img.shields.io/badge/author-@frankdejonge-blue.svg?style=flat-square)](https://twitter.com/frankdejonge) +[![Build Status](https://img.shields.io/travis/thephpleague/flysystem-cached-adapter/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/flysystem-cached-adapter) +[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/flysystem-cached-adapter.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/flysystem-cached-adapter/code-structure) +[![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/flysystem-cached-adapter.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/flysystem-cached-adapter) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) +[![Packagist Version](https://img.shields.io/packagist/v/league/flysystem-cached-adapter.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-cached-adapter) +[![Total Downloads](https://img.shields.io/packagist/dt/league/flysystem-cached-adapter.svg?style=flat-square)](https://packagist.org/packages/league/flysystem-cached-adapter) + + +The adapter decorator caches metadata and directory listings. + +```bash +composer require league/flysystem-cached-adapter +``` + +## Usage + +[Check out the docs.](https://flysystem.thephpleague.com/docs/advanced/caching/) diff --git a/vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php b/vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php new file mode 100644 index 0000000..69428d9 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/spec/CachedAdapterSpec.php @@ -0,0 +1,435 @@ +adapter = $adapter; + $this->cache = $cache; + $this->cache->load()->shouldBeCalled(); + $this->beConstructedWith($adapter, $cache); + } + + public function it_is_initializable() + { + $this->shouldHaveType('League\Flysystem\Cached\CachedAdapter'); + $this->shouldHaveType('League\Flysystem\AdapterInterface'); + } + + public function it_should_forward_read_streams() + { + $path = 'path.txt'; + $response = ['path' => $path]; + $this->adapter->readStream($path)->willReturn($response); + $this->readStream($path)->shouldbe($response); + } + + public function it_should_cache_writes() + { + $type = 'file'; + $path = 'path.txt'; + $contents = 'contents'; + $config = new Config(); + $response = compact('path', 'contents', 'type'); + $this->adapter->write($path, $contents, $config)->willReturn($response); + $this->cache->updateObject($path, $response, true)->shouldBeCalled(); + $this->write($path, $contents, $config)->shouldBe($response); + } + + public function it_should_cache_streamed_writes() + { + $type = 'file'; + $path = 'path.txt'; + $stream = tmpfile(); + $config = new Config(); + $response = compact('path', 'stream', 'type'); + $this->adapter->writeStream($path, $stream, $config)->willReturn($response); + $this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled(); + $this->writeStream($path, $stream, $config)->shouldBe($response); + fclose($stream); + } + + public function it_should_cache_streamed_updates() + { + $type = 'file'; + $path = 'path.txt'; + $stream = tmpfile(); + $config = new Config(); + $response = compact('path', 'stream', 'type'); + $this->adapter->updateStream($path, $stream, $config)->willReturn($response); + $this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled(); + $this->updateStream($path, $stream, $config)->shouldBe($response); + fclose($stream); + } + + public function it_should_ignore_failed_writes() + { + $path = 'path.txt'; + $contents = 'contents'; + $config = new Config(); + $this->adapter->write($path, $contents, $config)->willReturn(false); + $this->write($path, $contents, $config)->shouldBe(false); + } + + public function it_should_ignore_failed_streamed_writes() + { + $path = 'path.txt'; + $contents = tmpfile(); + $config = new Config(); + $this->adapter->writeStream($path, $contents, $config)->willReturn(false); + $this->writeStream($path, $contents, $config)->shouldBe(false); + fclose($contents); + } + + public function it_should_cache_updated() + { + $type = 'file'; + $path = 'path.txt'; + $contents = 'contents'; + $config = new Config(); + $response = compact('path', 'contents', 'type'); + $this->adapter->update($path, $contents, $config)->willReturn($response); + $this->cache->updateObject($path, $response, true)->shouldBeCalled(); + $this->update($path, $contents, $config)->shouldBe($response); + } + + public function it_should_ignore_failed_updates() + { + $path = 'path.txt'; + $contents = 'contents'; + $config = new Config(); + $this->adapter->update($path, $contents, $config)->willReturn(false); + $this->update($path, $contents, $config)->shouldBe(false); + } + + public function it_should_ignore_failed_streamed_updates() + { + $path = 'path.txt'; + $contents = tmpfile(); + $config = new Config(); + $this->adapter->updateStream($path, $contents, $config)->willReturn(false); + $this->updateStream($path, $contents, $config)->shouldBe(false); + fclose($contents); + } + + public function it_should_cache_renames() + { + $old = 'old.txt'; + $new = 'new.txt'; + $this->adapter->rename($old, $new)->willReturn(true); + $this->cache->rename($old, $new)->shouldBeCalled(); + $this->rename($old, $new)->shouldBe(true); + } + + public function it_should_ignore_rename_fails() + { + $old = 'old.txt'; + $new = 'new.txt'; + $this->adapter->rename($old, $new)->willReturn(false); + $this->rename($old, $new)->shouldBe(false); + } + + public function it_should_cache_copies() + { + $old = 'old.txt'; + $new = 'new.txt'; + $this->adapter->copy($old, $new)->willReturn(true); + $this->cache->copy($old, $new)->shouldBeCalled(); + $this->copy($old, $new)->shouldBe(true); + } + + public function it_should_ignore_copy_fails() + { + $old = 'old.txt'; + $new = 'new.txt'; + $this->adapter->copy($old, $new)->willReturn(false); + $this->copy($old, $new)->shouldBe(false); + } + + public function it_should_cache_deletes() + { + $delete = 'delete.txt'; + $this->adapter->delete($delete)->willReturn(true); + $this->cache->delete($delete)->shouldBeCalled(); + $this->delete($delete)->shouldBe(true); + } + + public function it_should_ignore_delete_fails() + { + $delete = 'delete.txt'; + $this->adapter->delete($delete)->willReturn(false); + $this->delete($delete)->shouldBe(false); + } + + public function it_should_cache_dir_deletes() + { + $delete = 'delete'; + $this->adapter->deleteDir($delete)->willReturn(true); + $this->cache->deleteDir($delete)->shouldBeCalled(); + $this->deleteDir($delete)->shouldBe(true); + } + + public function it_should_ignore_delete_dir_fails() + { + $delete = 'delete'; + $this->adapter->deleteDir($delete)->willReturn(false); + $this->deleteDir($delete)->shouldBe(false); + } + + public function it_should_cache_dir_creates() + { + $dirname = 'dirname'; + $config = new Config(); + $response = ['path' => $dirname, 'type' => 'dir']; + $this->adapter->createDir($dirname, $config)->willReturn($response); + $this->cache->updateObject($dirname, $response, true)->shouldBeCalled(); + $this->createDir($dirname, $config)->shouldBe($response); + } + + public function it_should_ignore_create_dir_fails() + { + $dirname = 'dirname'; + $config = new Config(); + $this->adapter->createDir($dirname, $config)->willReturn(false); + $this->createDir($dirname, $config)->shouldBe(false); + } + + public function it_should_cache_set_visibility() + { + $path = 'path.txt'; + $visibility = AdapterInterface::VISIBILITY_PUBLIC; + $this->adapter->setVisibility($path, $visibility)->willReturn(true); + $this->cache->updateObject($path, ['path' => $path, 'visibility' => $visibility], true)->shouldBeCalled(); + $this->setVisibility($path, $visibility)->shouldBe(true); + } + + public function it_should_ignore_set_visibility_fails() + { + $dirname = 'delete'; + $visibility = AdapterInterface::VISIBILITY_PUBLIC; + $this->adapter->setVisibility($dirname, $visibility)->willReturn(false); + $this->setVisibility($dirname, $visibility)->shouldBe(false); + } + + public function it_should_indicate_missing_files() + { + $this->cache->has($path = 'path.txt')->willReturn(false); + $this->has($path)->shouldBe(false); + } + + public function it_should_indicate_file_existance() + { + $this->cache->has($path = 'path.txt')->willReturn(true); + $this->has($path)->shouldBe(true); + } + + public function it_should_cache_missing_files() + { + $this->cache->has($path = 'path.txt')->willReturn(null); + $this->adapter->has($path)->willReturn(false); + $this->cache->storeMiss($path)->shouldBeCalled(); + $this->has($path)->shouldBe(false); + } + + public function it_should_delete_when_metadata_is_missing() + { + $path = 'path.txt'; + $this->cache->has($path)->willReturn(true); + $this->cache->getSize($path)->willReturn(['path' => $path]); + $this->adapter->getSize($path)->willReturn($response = ['path' => $path, 'size' => 1024]); + $this->cache->updateObject($path, $response, true)->shouldBeCalled(); + $this->getSize($path)->shouldBe($response); + } + + public function it_should_cache_has() + { + $this->cache->has($path = 'path.txt')->willReturn(null); + $this->adapter->has($path)->willReturn(true); + $this->cache->updateObject($path, compact('path'), true)->shouldBeCalled(); + $this->has($path)->shouldBe(true); + } + + public function it_should_list_cached_contents() + { + $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(true); + $response = [['path' => 'path.txt']]; + $this->cache->listContents($dirname, $recursive)->willReturn($response); + $this->listContents($dirname, $recursive)->shouldBe($response); + } + + public function it_should_ignore_failed_list_contents() + { + $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false); + $this->adapter->listContents($dirname, $recursive)->willReturn(false); + $this->listContents($dirname, $recursive)->shouldBe(false); + } + + public function it_should_cache_contents_listings() + { + $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false); + $response = [['path' => 'path.txt']]; + $this->adapter->listContents($dirname, $recursive)->willReturn($response); + $this->cache->storeContents($dirname, $response, $recursive)->shouldBeCalled(); + $this->listContents($dirname, $recursive)->shouldBe($response); + } + + public function it_should_use_cached_visibility() + { + $this->make_it_use_getter_cache('getVisibility', 'path.txt', [ + 'path' => 'path.txt', + 'visibility' => AdapterInterface::VISIBILITY_PUBLIC, + ]); + } + + public function it_should_cache_get_visibility() + { + $path = 'path.txt'; + $response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path]; + $this->make_it_cache_getter('getVisibility', $path, $response); + } + + public function it_should_ignore_failed_get_visibility() + { + $path = 'path.txt'; + $this->make_it_ignore_failed_getter('getVisibility', $path); + } + + public function it_should_use_cached_timestamp() + { + $this->make_it_use_getter_cache('getTimestamp', 'path.txt', [ + 'path' => 'path.txt', + 'timestamp' => 1234, + ]); + } + + public function it_should_cache_timestamps() + { + $this->make_it_cache_getter('getTimestamp', 'path.txt', [ + 'path' => 'path.txt', + 'timestamp' => 1234, + ]); + } + + public function it_should_ignore_failed_get_timestamps() + { + $this->make_it_ignore_failed_getter('getTimestamp', 'path.txt'); + } + + public function it_should_cache_get_metadata() + { + $path = 'path.txt'; + $response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path]; + $this->make_it_cache_getter('getMetadata', $path, $response); + } + + public function it_should_use_cached_metadata() + { + $this->make_it_use_getter_cache('getMetadata', 'path.txt', [ + 'path' => 'path.txt', + 'timestamp' => 1234, + ]); + } + + public function it_should_ignore_failed_get_metadata() + { + $this->make_it_ignore_failed_getter('getMetadata', 'path.txt'); + } + + public function it_should_cache_get_size() + { + $path = 'path.txt'; + $response = ['size' => 1234, 'path' => $path]; + $this->make_it_cache_getter('getSize', $path, $response); + } + + public function it_should_use_cached_size() + { + $this->make_it_use_getter_cache('getSize', 'path.txt', [ + 'path' => 'path.txt', + 'size' => 1234, + ]); + } + + public function it_should_ignore_failed_get_size() + { + $this->make_it_ignore_failed_getter('getSize', 'path.txt'); + } + + public function it_should_cache_get_mimetype() + { + $path = 'path.txt'; + $response = ['mimetype' => 'text/plain', 'path' => $path]; + $this->make_it_cache_getter('getMimetype', $path, $response); + } + + public function it_should_use_cached_mimetype() + { + $this->make_it_use_getter_cache('getMimetype', 'path.txt', [ + 'path' => 'path.txt', + 'mimetype' => 'text/plain', + ]); + } + + public function it_should_ignore_failed_get_mimetype() + { + $this->make_it_ignore_failed_getter('getMimetype', 'path.txt'); + } + + public function it_should_cache_reads() + { + $path = 'path.txt'; + $response = ['path' => $path, 'contents' => 'contents']; + $this->make_it_cache_getter('read', $path, $response); + } + + public function it_should_use_cached_file_contents() + { + $this->make_it_use_getter_cache('read', 'path.txt', [ + 'path' => 'path.txt', + 'contents' => 'contents' + ]); + } + + public function it_should_ignore_failed_reads() + { + $this->make_it_ignore_failed_getter('read', 'path.txt'); + } + + protected function make_it_use_getter_cache($method, $path, $response) + { + $this->cache->{$method}($path)->willReturn($response); + $this->{$method}($path)->shouldBe($response); + } + + protected function make_it_cache_getter($method, $path, $response) + { + $this->cache->{$method}($path)->willReturn(false); + $this->adapter->{$method}($path)->willReturn($response); + $this->cache->updateObject($path, $response, true)->shouldBeCalled(); + $this->{$method}($path)->shouldBe($response); + } + + protected function make_it_ignore_failed_getter($method, $path) + { + $this->cache->{$method}($path)->willReturn(false); + $this->adapter->{$method}($path)->willReturn(false); + $this->{$method}($path)->shouldBe(false); + } +} diff --git a/vendor/league/flysystem-cached-adapter/src/CacheInterface.php b/vendor/league/flysystem-cached-adapter/src/CacheInterface.php new file mode 100644 index 0000000..de3ab3d --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/CacheInterface.php @@ -0,0 +1,101 @@ +adapter = $adapter; + $this->cache = $cache; + $this->cache->load(); + } + + /** + * Get the underlying Adapter implementation. + * + * @return AdapterInterface + */ + public function getAdapter() + { + return $this->adapter; + } + + /** + * Get the used Cache implementation. + * + * @return CacheInterface + */ + public function getCache() + { + return $this->cache; + } + + /** + * {@inheritdoc} + */ + public function write($path, $contents, Config $config) + { + $result = $this->adapter->write($path, $contents, $config); + + if ($result !== false) { + $result['type'] = 'file'; + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function writeStream($path, $resource, Config $config) + { + $result = $this->adapter->writeStream($path, $resource, $config); + + if ($result !== false) { + $result['type'] = 'file'; + $contents = false; + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function update($path, $contents, Config $config) + { + $result = $this->adapter->update($path, $contents, $config); + + if ($result !== false) { + $result['type'] = 'file'; + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function updateStream($path, $resource, Config $config) + { + $result = $this->adapter->updateStream($path, $resource, $config); + + if ($result !== false) { + $result['type'] = 'file'; + $contents = false; + $this->cache->updateObject($path, $result + compact('path', 'contents'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function rename($path, $newPath) + { + $result = $this->adapter->rename($path, $newPath); + + if ($result !== false) { + $this->cache->rename($path, $newPath); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function copy($path, $newpath) + { + $result = $this->adapter->copy($path, $newpath); + + if ($result !== false) { + $this->cache->copy($path, $newpath); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function delete($path) + { + $result = $this->adapter->delete($path); + + if ($result !== false) { + $this->cache->delete($path); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function deleteDir($dirname) + { + $result = $this->adapter->deleteDir($dirname); + + if ($result !== false) { + $this->cache->deleteDir($dirname); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function createDir($dirname, Config $config) + { + $result = $this->adapter->createDir($dirname, $config); + + if ($result !== false) { + $type = 'dir'; + $path = $dirname; + $this->cache->updateObject($dirname, compact('path', 'type'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function setVisibility($path, $visibility) + { + $result = $this->adapter->setVisibility($path, $visibility); + + if ($result !== false) { + $this->cache->updateObject($path, compact('path', 'visibility'), true); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function has($path) + { + $cacheHas = $this->cache->has($path); + + if ($cacheHas !== null) { + return $cacheHas; + } + + $adapterResponse = $this->adapter->has($path); + + if (! $adapterResponse) { + $this->cache->storeMiss($path); + } else { + $cacheEntry = is_array($adapterResponse) ? $adapterResponse : compact('path'); + $this->cache->updateObject($path, $cacheEntry, true); + } + + return $adapterResponse; + } + + /** + * {@inheritdoc} + */ + public function read($path) + { + return $this->callWithFallback('contents', $path, 'read'); + } + + /** + * {@inheritdoc} + */ + public function readStream($path) + { + return $this->adapter->readStream($path); + } + + /** + * {@inheritdoc} + */ + public function listContents($directory = '', $recursive = false) + { + if ($this->cache->isComplete($directory, $recursive)) { + return $this->cache->listContents($directory, $recursive); + } + + $result = $this->adapter->listContents($directory, $recursive); + + if ($result !== false) { + $this->cache->storeContents($directory, $result, $recursive); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function getMetadata($path) + { + return $this->callWithFallback(null, $path, 'getMetadata'); + } + + /** + * {@inheritdoc} + */ + public function getSize($path) + { + return $this->callWithFallback('size', $path, 'getSize'); + } + + /** + * {@inheritdoc} + */ + public function getMimetype($path) + { + return $this->callWithFallback('mimetype', $path, 'getMimetype'); + } + + /** + * {@inheritdoc} + */ + public function getTimestamp($path) + { + return $this->callWithFallback('timestamp', $path, 'getTimestamp'); + } + + /** + * {@inheritdoc} + */ + public function getVisibility($path) + { + return $this->callWithFallback('visibility', $path, 'getVisibility'); + } + + /** + * Call a method and cache the response. + * + * @param string $property + * @param string $path + * @param string $method + * + * @return mixed + */ + protected function callWithFallback($property, $path, $method) + { + $result = $this->cache->{$method}($path); + + if ($result !== false && ($property === null || array_key_exists($property, $result))) { + return $result; + } + + $result = $this->adapter->{$method}($path); + + if ($result) { + $object = $result + compact('path'); + $this->cache->updateObject($path, $object, true); + } + + return $result; + } +} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php b/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php new file mode 100644 index 0000000..c2076d4 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/Storage/AbstractCache.php @@ -0,0 +1,417 @@ +autosave) { + $this->save(); + } + } + + /** + * Get the autosave setting. + * + * @return bool autosave + */ + public function getAutosave() + { + return $this->autosave; + } + + /** + * Get the autosave setting. + * + * @param bool $autosave + */ + public function setAutosave($autosave) + { + $this->autosave = $autosave; + } + + /** + * Store the contents listing. + * + * @param string $directory + * @param array $contents + * @param bool $recursive + * + * @return array contents listing + */ + public function storeContents($directory, array $contents, $recursive = false) + { + $directories = [$directory]; + + foreach ($contents as $object) { + $this->updateObject($object['path'], $object); + $object = $this->cache[$object['path']]; + + if ($recursive && $this->pathIsInDirectory($directory, $object['path'])) { + $directories[] = $object['dirname']; + } + } + + foreach (array_unique($directories) as $directory) { + $this->setComplete($directory, $recursive); + } + + $this->autosave(); + } + + /** + * Update the metadata for an object. + * + * @param string $path object path + * @param array $object object metadata + * @param bool $autosave whether to trigger the autosave routine + */ + public function updateObject($path, array $object, $autosave = false) + { + if (! $this->has($path)) { + $this->cache[$path] = Util::pathinfo($path); + } + + $this->cache[$path] = array_merge($this->cache[$path], $object); + + if ($autosave) { + $this->autosave(); + } + + $this->ensureParentDirectories($path); + } + + /** + * Store object hit miss. + * + * @param string $path + */ + public function storeMiss($path) + { + $this->cache[$path] = false; + $this->autosave(); + } + + /** + * Get the contents listing. + * + * @param string $dirname + * @param bool $recursive + * + * @return array contents listing + */ + public function listContents($dirname = '', $recursive = false) + { + $result = []; + + foreach ($this->cache as $object) { + if ($object === false) { + continue; + } + if ($object['dirname'] === $dirname) { + $result[] = $object; + } elseif ($recursive && $this->pathIsInDirectory($dirname, $object['path'])) { + $result[] = $object; + } + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function has($path) + { + if ($path !== false && array_key_exists($path, $this->cache)) { + return $this->cache[$path] !== false; + } + + if ($this->isComplete(Util::dirname($path), false)) { + return false; + } + } + + /** + * {@inheritdoc} + */ + public function read($path) + { + if (isset($this->cache[$path]['contents']) && $this->cache[$path]['contents'] !== false) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function readStream($path) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function rename($path, $newpath) + { + if ($this->has($path)) { + $object = $this->cache[$path]; + unset($this->cache[$path]); + $object['path'] = $newpath; + $object = array_merge($object, Util::pathinfo($newpath)); + $this->cache[$newpath] = $object; + $this->autosave(); + } + } + + /** + * {@inheritdoc} + */ + public function copy($path, $newpath) + { + if ($this->has($path)) { + $object = $this->cache[$path]; + $object = array_merge($object, Util::pathinfo($newpath)); + $this->updateObject($newpath, $object, true); + } + } + + /** + * {@inheritdoc} + */ + public function delete($path) + { + $this->storeMiss($path); + } + + /** + * {@inheritdoc} + */ + public function deleteDir($dirname) + { + foreach ($this->cache as $path => $object) { + if ($this->pathIsInDirectory($dirname, $path) || $path === $dirname) { + unset($this->cache[$path]); + } + } + + unset($this->complete[$dirname]); + + $this->autosave(); + } + + /** + * {@inheritdoc} + */ + public function getMimetype($path) + { + if (isset($this->cache[$path]['mimetype'])) { + return $this->cache[$path]; + } + + if (! $result = $this->read($path)) { + return false; + } + + $mimetype = Util::guessMimeType($path, $result['contents']); + $this->cache[$path]['mimetype'] = $mimetype; + + return $this->cache[$path]; + } + + /** + * {@inheritdoc} + */ + public function getSize($path) + { + if (isset($this->cache[$path]['size'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getTimestamp($path) + { + if (isset($this->cache[$path]['timestamp'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getVisibility($path) + { + if (isset($this->cache[$path]['visibility'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getMetadata($path) + { + if (isset($this->cache[$path]['type'])) { + return $this->cache[$path]; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function isComplete($dirname, $recursive) + { + if (! array_key_exists($dirname, $this->complete)) { + return false; + } + + if ($recursive && $this->complete[$dirname] !== 'recursive') { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function setComplete($dirname, $recursive) + { + $this->complete[$dirname] = $recursive ? 'recursive' : true; + } + + /** + * Filter the contents from a listing. + * + * @param array $contents object listing + * + * @return array filtered contents + */ + public function cleanContents(array $contents) + { + $cachedProperties = array_flip([ + 'path', 'dirname', 'basename', 'extension', 'filename', + 'size', 'mimetype', 'visibility', 'timestamp', 'type', + ]); + + foreach ($contents as $path => $object) { + if (is_array($object)) { + $contents[$path] = array_intersect_key($object, $cachedProperties); + } + } + + return $contents; + } + + /** + * {@inheritdoc} + */ + public function flush() + { + $this->cache = []; + $this->complete = []; + $this->autosave(); + } + + /** + * {@inheritdoc} + */ + public function autosave() + { + if ($this->autosave) { + $this->save(); + } + } + + /** + * Retrieve serialized cache data. + * + * @return string serialized data + */ + public function getForStorage() + { + $cleaned = $this->cleanContents($this->cache); + + return json_encode([$cleaned, $this->complete]); + } + + /** + * Load from serialized cache data. + * + * @param string $json + */ + public function setFromStorage($json) + { + list($cache, $complete) = json_decode($json, true); + + if (json_last_error() === JSON_ERROR_NONE && is_array($cache) && is_array($complete)) { + $this->cache = $cache; + $this->complete = $complete; + } + } + + /** + * Ensure parent directories of an object. + * + * @param string $path object path + */ + public function ensureParentDirectories($path) + { + $object = $this->cache[$path]; + + while ($object['dirname'] !== '' && ! isset($this->cache[$object['dirname']])) { + $object = Util::pathinfo($object['dirname']); + $object['type'] = 'dir'; + $this->cache[$object['path']] = $object; + } + } + + /** + * Determines if the path is inside the directory. + * + * @param string $directory + * @param string $path + * + * @return bool + */ + protected function pathIsInDirectory($directory, $path) + { + return $directory === '' || strpos($path, $directory . '/') === 0; + } +} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php b/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php new file mode 100644 index 0000000..3aa8b1a --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/Storage/Adapter.php @@ -0,0 +1,115 @@ +adapter = $adapter; + $this->file = $file; + $this->setExpire($expire); + } + + /** + * Set the expiration time in seconds. + * + * @param int $expire relative expiration time + */ + protected function setExpire($expire) + { + if ($expire) { + $this->expire = $this->getTime($expire); + } + } + + /** + * Get expiration time in seconds. + * + * @param int $time relative expiration time + * + * @return int actual expiration time + */ + protected function getTime($time = 0) + { + return intval(microtime(true)) + $time; + } + + /** + * {@inheritdoc} + */ + public function setFromStorage($json) + { + list($cache, $complete, $expire) = json_decode($json, true); + + if (! $expire || $expire > $this->getTime()) { + $this->cache = $cache; + $this->complete = $complete; + } else { + $this->adapter->delete($this->file); + } + } + + /** + * {@inheritdoc} + */ + public function load() + { + if ($this->adapter->has($this->file)) { + $file = $this->adapter->read($this->file); + if ($file && !empty($file['contents'])) { + $this->setFromStorage($file['contents']); + } + } + } + + /** + * {@inheritdoc} + */ + public function getForStorage() + { + $cleaned = $this->cleanContents($this->cache); + + return json_encode([$cleaned, $this->complete, $this->expire]); + } + + /** + * {@inheritdoc} + */ + public function save() + { + $config = new Config(); + $contents = $this->getForStorage(); + + if ($this->adapter->has($this->file)) { + $this->adapter->update($this->file, $contents, $config); + } else { + $this->adapter->write($this->file, $contents, $config); + } + } +} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php b/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php new file mode 100644 index 0000000..f67d271 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/Storage/Memcached.php @@ -0,0 +1,59 @@ +key = $key; + $this->expire = $expire; + $this->memcached = $memcached; + } + + /** + * {@inheritdoc} + */ + public function load() + { + $contents = $this->memcached->get($this->key); + + if ($contents !== false) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $expiration = $this->expire === null ? 0 : time() + $this->expire; + $this->memcached->set($this->key, $contents, $expiration); + } +} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php b/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php new file mode 100644 index 0000000..d0914fa --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/Storage/Memory.php @@ -0,0 +1,22 @@ +client = $client ?: new Redis(); + $this->key = $key; + $this->expire = $expire; + } + + /** + * {@inheritdoc} + */ + public function load() + { + $contents = $this->client->get($this->key); + + if ($contents !== false) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $this->client->set($this->key, $contents); + + if ($this->expire !== null) { + $this->client->expire($this->key, $this->expire); + } + } +} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php b/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php new file mode 100644 index 0000000..8a29574 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/Storage/Predis.php @@ -0,0 +1,75 @@ +client = $client ?: new Client(); + $this->key = $key; + $this->expire = $expire; + } + + /** + * {@inheritdoc} + */ + public function load() + { + if (($contents = $this->executeCommand('get', [$this->key])) !== null) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $this->executeCommand('set', [$this->key, $contents]); + + if ($this->expire !== null) { + $this->executeCommand('expire', [$this->key, $this->expire]); + } + } + + /** + * Execute a Predis command. + * + * @param string $name + * @param array $arguments + * + * @return string + */ + protected function executeCommand($name, array $arguments) + { + $command = $this->client->createCommand($name, $arguments); + + return $this->client->executeCommand($command); + } +} diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php b/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php new file mode 100644 index 0000000..43be87e --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/Storage/Psr6Cache.php @@ -0,0 +1,59 @@ +pool = $pool; + $this->key = $key; + $this->expire = $expire; + } + + /** + * {@inheritdoc} + */ + public function save() + { + $item = $this->pool->getItem($this->key); + $item->set($this->getForStorage()); + $item->expiresAfter($this->expire); + $this->pool->save($item); + } + + /** + * {@inheritdoc} + */ + public function load() + { + $item = $this->pool->getItem($this->key); + if ($item->isHit()) { + $this->setFromStorage($item->get()); + } + } +} \ No newline at end of file diff --git a/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php b/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php new file mode 100644 index 0000000..e05b832 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/src/Storage/Stash.php @@ -0,0 +1,60 @@ +key = $key; + $this->expire = $expire; + $this->pool = $pool; + } + + /** + * {@inheritdoc} + */ + public function load() + { + $item = $this->pool->getItem($this->key); + $contents = $item->get(); + + if ($item->isMiss() === false) { + $this->setFromStorage($contents); + } + } + + /** + * {@inheritdoc} + */ + public function save() + { + $contents = $this->getForStorage(); + $item = $this->pool->getItem($this->key); + $item->set($contents, $this->expire); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php b/vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php new file mode 100644 index 0000000..b63cba7 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/AdapterCacheTests.php @@ -0,0 +1,104 @@ +shouldReceive('has')->once()->with('file.json')->andReturn(false); + $cache = new Adapter($adapter, 'file.json', 10); + $cache->load(); + $this->assertFalse($cache->isComplete('', false)); + } + + public function testLoadExpired() + { + $response = ['contents' => json_encode([[], ['' => true], 1234567890]), 'path' => 'file.json']; + $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); + $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true); + $adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response); + $adapter->shouldReceive('delete')->once()->with('file.json'); + $cache = new Adapter($adapter, 'file.json', 10); + $cache->load(); + $this->assertFalse($cache->isComplete('', false)); + } + + public function testLoadSuccess() + { + $response = ['contents' => json_encode([[], ['' => true], 9876543210]), 'path' => 'file.json']; + $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); + $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true); + $adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response); + $cache = new Adapter($adapter, 'file.json', 10); + $cache->load(); + $this->assertTrue($cache->isComplete('', false)); + } + + public function testSaveExists() + { + $response = json_encode([[], [], null]); + $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); + $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(true); + $adapter->shouldReceive('update')->once()->with('file.json', $response, Mockery::any()); + $cache = new Adapter($adapter, 'file.json', null); + $cache->save(); + } + + public function testSaveNew() + { + $response = json_encode([[], [], null]); + $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); + $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(false); + $adapter->shouldReceive('write')->once()->with('file.json', $response, Mockery::any()); + $cache = new Adapter($adapter, 'file.json', null); + $cache->save(); + } + + public function testStoreContentsRecursive() + { + $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); + $adapter->shouldReceive('has')->once()->with('file.json')->andReturn(false); + $adapter->shouldReceive('write')->once()->with('file.json', Mockery::any(), Mockery::any()); + + $cache = new Adapter($adapter, 'file.json', null); + + $contents = [ + ['path' => 'foo/bar', 'dirname' => 'foo'], + ['path' => 'afoo/bang', 'dirname' => 'afoo'], + ]; + + $cache->storeContents('foo', $contents, true); + + $this->assertTrue($cache->isComplete('foo', true)); + $this->assertFalse($cache->isComplete('afoo', true)); + } + + public function testDeleteDir() + { + $cache_data = [ + 'foo' => ['path' => 'foo', 'type' => 'dir', 'dirname' => ''], + 'foo/bar' => ['path' => 'foo/bar', 'type' => 'file', 'dirname' => 'foo'], + 'foobaz' => ['path' => 'foobaz', 'type' => 'file', 'dirname' => ''], + ]; + + $response = [ + 'contents' => json_encode([$cache_data, [], null]), + 'path' => 'file.json', + ]; + + $adapter = Mockery::mock('League\Flysystem\AdapterInterface'); + $adapter->shouldReceive('has')->zeroOrMoreTimes()->with('file.json')->andReturn(true); + $adapter->shouldReceive('read')->once()->with('file.json')->andReturn($response); + $adapter->shouldReceive('update')->once()->with('file.json', Mockery::any(), Mockery::any())->andReturn(true); + + $cache = new Adapter($adapter, 'file.json', null); + $cache->load(); + + $cache->deleteDir('foo', true); + + $this->assertSame(1, count($cache->listContents('', true))); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/InspectionTests.php b/vendor/league/flysystem-cached-adapter/tests/InspectionTests.php new file mode 100644 index 0000000..40d4c91 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/InspectionTests.php @@ -0,0 +1,16 @@ +shouldReceive('load')->once(); + $cached_adapter = new CachedAdapter($adapter, $cache); + $this->assertInstanceOf('League\Flysystem\AdapterInterface', $cached_adapter->getAdapter()); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php b/vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php new file mode 100644 index 0000000..e3d9ad9 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/MemcachedTests.php @@ -0,0 +1,35 @@ +shouldReceive('get')->once()->andReturn(false); + $cache = new Memcached($client); + $cache->load(); + $this->assertFalse($cache->isComplete('', false)); + } + + public function testLoadSuccess() + { + $response = json_encode([[], ['' => true]]); + $client = Mockery::mock('Memcached'); + $client->shouldReceive('get')->once()->andReturn($response); + $cache = new Memcached($client); + $cache->load(); + $this->assertTrue($cache->isComplete('', false)); + } + + public function testSave() + { + $response = json_encode([[], []]); + $client = Mockery::mock('Memcached'); + $client->shouldReceive('set')->once()->andReturn($response); + $cache = new Memcached($client); + $cache->save(); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php b/vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php new file mode 100644 index 0000000..3ac58fd --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/MemoryCacheTests.php @@ -0,0 +1,255 @@ +setAutosave(true); + $this->assertTrue($cache->getAutosave()); + $cache->setAutosave(false); + $this->assertFalse($cache->getAutosave()); + } + + public function testCacheMiss() + { + $cache = new Memory(); + $cache->storeMiss('path.txt'); + $this->assertFalse($cache->has('path.txt')); + } + + public function testIsComplete() + { + $cache = new Memory(); + $this->assertFalse($cache->isComplete('dirname', false)); + $cache->setComplete('dirname', false); + $this->assertFalse($cache->isComplete('dirname', true)); + $cache->setComplete('dirname', true); + $this->assertTrue($cache->isComplete('dirname', true)); + } + + public function testCleanContents() + { + $cache = new Memory(); + $input = [[ + 'path' => 'path.txt', + 'visibility' => 'public', + 'invalid' => 'thing', + ]]; + + $expected = [[ + 'path' => 'path.txt', + 'visibility' => 'public', + ]]; + + $output = $cache->cleanContents($input); + $this->assertEquals($expected, $output); + } + + public function testGetForStorage() + { + $cache = new Memory(); + $input = [[ + 'path' => 'path.txt', + 'visibility' => 'public', + 'type' => 'file', + ]]; + + $cache->storeContents('', $input, true); + $contents = $cache->listContents('', true); + $cached = []; + foreach ($contents as $item) { + $cached[$item['path']] = $item; + } + + $this->assertEquals(json_encode([$cached, ['' => 'recursive']]), $cache->getForStorage()); + } + + public function testParentCompleteIsUsedDuringHas() + { + $cache = new Memory(); + $cache->setComplete('dirname', false); + $this->assertFalse($cache->has('dirname/path.txt')); + } + + public function testFlush() + { + $cache = new Memory(); + $cache->setComplete('dirname', true); + $cache->updateObject('path.txt', [ + 'path' => 'path.txt', + 'visibility' => 'public', + ]); + $cache->flush(); + $this->assertFalse($cache->isComplete('dirname', true)); + $this->assertNull($cache->has('path.txt')); + } + + public function testSetFromStorage() + { + $cache = new Memory(); + $json = [[ + 'path.txt' => ['path' => 'path.txt', 'type' => 'file'], + ], ['dirname' => 'recursive']]; + $jsonString = json_encode($json); + $cache->setFromStorage($jsonString); + $this->assertTrue($cache->has('path.txt')); + $this->assertTrue($cache->isComplete('dirname', true)); + } + + public function testGetMetadataFail() + { + $cache = new Memory(); + $this->assertFalse($cache->getMetadata('path.txt')); + } + + public function metaGetterProvider() + { + return [ + ['getTimestamp', 'timestamp', 12344], + ['getMimetype', 'mimetype', 'text/plain'], + ['getSize', 'size', 12], + ['getVisibility', 'visibility', 'private'], + ['read', 'contents', '__contents__'], + ]; + } + + /** + * @dataProvider metaGetterProvider + * + * @param $method + * @param $key + * @param $value + */ + public function testMetaGetters($method, $key, $value) + { + $cache = new Memory(); + $this->assertFalse($cache->{$method}('path.txt')); + $cache->updateObject('path.txt', $object = [ + 'path' => 'path.txt', + 'type' => 'file', + $key => $value, + ] + Util::pathinfo('path.txt'), true); + $this->assertEquals($object, $cache->{$method}('path.txt')); + $this->assertEquals($object, $cache->getMetadata('path.txt')); + } + + public function testGetDerivedMimetype() + { + $cache = new Memory(); + $cache->updateObject('path.txt', [ + 'contents' => 'something', + ]); + $response = $cache->getMimetype('path.txt'); + $this->assertEquals('text/plain', $response['mimetype']); + } + + public function testCopyFail() + { + $cache = new Memory(); + $cache->copy('one', 'two'); + $this->assertNull($cache->has('two')); + $this->assertNull($cache->load()); + } + + public function testStoreContents() + { + $cache = new Memory(); + $cache->storeContents('dirname', [ + ['path' => 'dirname', 'type' => 'dir'], + ['path' => 'dirname/nested', 'type' => 'dir'], + ['path' => 'dirname/nested/deep', 'type' => 'dir'], + ['path' => 'other/nested/deep', 'type' => 'dir'], + ], true); + + $this->isTrue($cache->isComplete('other/nested', true)); + } + + public function testDelete() + { + $cache = new Memory(); + $cache->updateObject('path.txt', ['type' => 'file']); + $this->assertTrue($cache->has('path.txt')); + $cache->delete('path.txt'); + $this->assertFalse($cache->has('path.txt')); + } + + public function testDeleteDir() + { + $cache = new Memory(); + $cache->storeContents('dirname', [ + ['path' => 'dirname/path.txt', 'type' => 'file'], + ]); + $this->assertTrue($cache->isComplete('dirname', false)); + $this->assertTrue($cache->has('dirname/path.txt')); + $cache->deleteDir('dirname'); + $this->assertFalse($cache->isComplete('dirname', false)); + $this->assertNull($cache->has('dirname/path.txt')); + } + + public function testReadStream() + { + $cache = new Memory(); + $this->assertFalse($cache->readStream('path.txt')); + } + + public function testRename() + { + $cache = new Memory(); + $cache->updateObject('path.txt', ['type' => 'file']); + $cache->rename('path.txt', 'newpath.txt'); + $this->assertTrue($cache->has('newpath.txt')); + } + + public function testCopy() + { + $cache = new Memory(); + $cache->updateObject('path.txt', ['type' => 'file']); + $cache->copy('path.txt', 'newpath.txt'); + $this->assertTrue($cache->has('newpath.txt')); + } + + public function testComplextListContents() + { + $cache = new Memory(); + $cache->storeContents('', [ + ['path' => 'dirname', 'type' => 'dir'], + ['path' => 'dirname/file.txt', 'type' => 'file'], + ['path' => 'other', 'type' => 'dir'], + ['path' => 'other/file.txt', 'type' => 'file'], + ['path' => 'other/nested/file.txt', 'type' => 'file'], + ]); + + $this->assertCount(3, $cache->listContents('other', true)); + } + + public function testComplextListContentsWithDeletedFile() + { + $cache = new Memory(); + $cache->storeContents('', [ + ['path' => 'dirname', 'type' => 'dir'], + ['path' => 'dirname/file.txt', 'type' => 'file'], + ['path' => 'other', 'type' => 'dir'], + ['path' => 'other/file.txt', 'type' => 'file'], + ['path' => 'other/another_file.txt', 'type' => 'file'], + ]); + + $cache->delete('other/another_file.txt'); + $this->assertCount(4, $cache->listContents('', true)); + } + + public function testCacheMissIfContentsIsFalse() + { + $cache = new Memory(); + $cache->updateObject('path.txt', [ + 'path' => 'path.txt', + 'contents' => false, + ], true); + + $this->assertFalse($cache->read('path.txt')); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php b/vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php new file mode 100644 index 0000000..148616f --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/NoopCacheTests.php @@ -0,0 +1,35 @@ +assertEquals($cache, $cache->storeMiss('file.txt')); + $this->assertNull($cache->setComplete('', false)); + $this->assertNull($cache->load()); + $this->assertNull($cache->flush()); + $this->assertNull($cache->has('path.txt')); + $this->assertNull($cache->autosave()); + $this->assertFalse($cache->isComplete('', false)); + $this->assertFalse($cache->read('something')); + $this->assertFalse($cache->readStream('something')); + $this->assertFalse($cache->getMetadata('something')); + $this->assertFalse($cache->getMimetype('something')); + $this->assertFalse($cache->getSize('something')); + $this->assertFalse($cache->getTimestamp('something')); + $this->assertFalse($cache->getVisibility('something')); + $this->assertEmpty($cache->listContents('', false)); + $this->assertFalse($cache->rename('', '')); + $this->assertFalse($cache->copy('', '')); + $this->assertNull($cache->save()); + $object = ['path' => 'path.ext']; + $this->assertEquals($object, $cache->updateObject('path.txt', $object)); + $this->assertEquals([['path' => 'some/file.txt']], $cache->storeContents('unknwon', [ + ['path' => 'some/file.txt'], + ], false)); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php b/vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php new file mode 100644 index 0000000..d1ccb65 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/PhpRedisTests.php @@ -0,0 +1,45 @@ +shouldReceive('get')->with('flysystem')->once()->andReturn(false); + $cache = new PhpRedis($client); + $cache->load(); + $this->assertFalse($cache->isComplete('', false)); + } + + public function testLoadSuccess() + { + $response = json_encode([[], ['' => true]]); + $client = Mockery::mock('Redis'); + $client->shouldReceive('get')->with('flysystem')->once()->andReturn($response); + $cache = new PhpRedis($client); + $cache->load(); + $this->assertTrue($cache->isComplete('', false)); + } + + public function testSave() + { + $data = json_encode([[], []]); + $client = Mockery::mock('Redis'); + $client->shouldReceive('set')->with('flysystem', $data)->once(); + $cache = new PhpRedis($client); + $cache->save(); + } + + public function testSaveWithExpire() + { + $data = json_encode([[], []]); + $client = Mockery::mock('Redis'); + $client->shouldReceive('set')->with('flysystem', $data)->once(); + $client->shouldReceive('expire')->with('flysystem', 20)->once(); + $cache = new PhpRedis($client, 'flysystem', 20); + $cache->save(); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/PredisTests.php b/vendor/league/flysystem-cached-adapter/tests/PredisTests.php new file mode 100644 index 0000000..e33e104 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/PredisTests.php @@ -0,0 +1,55 @@ +shouldReceive('createCommand')->with('get', ['flysystem'])->once()->andReturn($command); + $client->shouldReceive('executeCommand')->with($command)->andReturn(null); + $cache = new Predis($client); + $cache->load(); + $this->assertFalse($cache->isComplete('', false)); + } + + public function testLoadSuccess() + { + $response = json_encode([[], ['' => true]]); + $client = Mockery::mock('Predis\Client'); + $command = Mockery::mock('Predis\Command\CommandInterface'); + $client->shouldReceive('createCommand')->with('get', ['flysystem'])->once()->andReturn($command); + $client->shouldReceive('executeCommand')->with($command)->andReturn($response); + $cache = new Predis($client); + $cache->load(); + $this->assertTrue($cache->isComplete('', false)); + } + + public function testSave() + { + $data = json_encode([[], []]); + $client = Mockery::mock('Predis\Client'); + $command = Mockery::mock('Predis\Command\CommandInterface'); + $client->shouldReceive('createCommand')->with('set', ['flysystem', $data])->once()->andReturn($command); + $client->shouldReceive('executeCommand')->with($command)->once(); + $cache = new Predis($client); + $cache->save(); + } + + public function testSaveWithExpire() + { + $data = json_encode([[], []]); + $client = Mockery::mock('Predis\Client'); + $command = Mockery::mock('Predis\Command\CommandInterface'); + $client->shouldReceive('createCommand')->with('set', ['flysystem', $data])->once()->andReturn($command); + $client->shouldReceive('executeCommand')->with($command)->once(); + $expireCommand = Mockery::mock('Predis\Command\CommandInterface'); + $client->shouldReceive('createCommand')->with('expire', ['flysystem', 20])->once()->andReturn($expireCommand); + $client->shouldReceive('executeCommand')->with($expireCommand)->once(); + $cache = new Predis($client, 'flysystem', 20); + $cache->save(); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php b/vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php new file mode 100644 index 0000000..d5e5700 --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/Psr6CacheTest.php @@ -0,0 +1,45 @@ +shouldReceive('isHit')->once()->andReturn(false); + $pool->shouldReceive('getItem')->once()->andReturn($item); + $cache = new Psr6Cache($pool); + $cache->load(); + $this->assertFalse($cache->isComplete('', false)); + } + + public function testLoadSuccess() + { + $response = json_encode([[], ['' => true]]); + $pool = Mockery::mock('Psr\Cache\CacheItemPoolInterface'); + $item = Mockery::mock('Psr\Cache\CacheItemInterface'); + $item->shouldReceive('get')->once()->andReturn($response); + $item->shouldReceive('isHit')->once()->andReturn(true); + $pool->shouldReceive('getItem')->once()->andReturn($item); + $cache = new Psr6Cache($pool); + $cache->load(); + $this->assertTrue($cache->isComplete('', false)); + } + + public function testSave() + { + $response = json_encode([[], []]); + $ttl = 4711; + $pool = Mockery::mock('Psr\Cache\CacheItemPoolInterface'); + $item = Mockery::mock('Psr\Cache\CacheItemInterface'); + $item->shouldReceive('expiresAfter')->once()->with($ttl); + $item->shouldReceive('set')->once()->andReturn($response); + $pool->shouldReceive('getItem')->once()->andReturn($item); + $pool->shouldReceive('save')->once()->with($item); + $cache = new Psr6Cache($pool, 'foo', $ttl); + $cache->save(); + } +} diff --git a/vendor/league/flysystem-cached-adapter/tests/StashTest.php b/vendor/league/flysystem-cached-adapter/tests/StashTest.php new file mode 100644 index 0000000..29e142d --- /dev/null +++ b/vendor/league/flysystem-cached-adapter/tests/StashTest.php @@ -0,0 +1,43 @@ +shouldReceive('get')->once()->andReturn(null); + $item->shouldReceive('isMiss')->once()->andReturn(true); + $pool->shouldReceive('getItem')->once()->andReturn($item); + $cache = new Stash($pool); + $cache->load(); + $this->assertFalse($cache->isComplete('', false)); + } + + public function testLoadSuccess() + { + $response = json_encode([[], ['' => true]]); + $pool = Mockery::mock('Stash\Pool'); + $item = Mockery::mock('Stash\Item'); + $item->shouldReceive('get')->once()->andReturn($response); + $item->shouldReceive('isMiss')->once()->andReturn(false); + $pool->shouldReceive('getItem')->once()->andReturn($item); + $cache = new Stash($pool); + $cache->load(); + $this->assertTrue($cache->isComplete('', false)); + } + + public function testSave() + { + $response = json_encode([[], []]); + $pool = Mockery::mock('Stash\Pool'); + $item = Mockery::mock('Stash\Item'); + $item->shouldReceive('set')->once()->andReturn($response); + $pool->shouldReceive('getItem')->once()->andReturn($item); + $cache = new Stash($pool); + $cache->save(); + } +} diff --git a/vendor/league/flysystem/LICENSE b/vendor/league/flysystem/LICENSE new file mode 100644 index 0000000..f2684c8 --- /dev/null +++ b/vendor/league/flysystem/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2019 Frank de Jonge + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/league/flysystem/composer.json b/vendor/league/flysystem/composer.json new file mode 100644 index 0000000..84229e9 --- /dev/null +++ b/vendor/league/flysystem/composer.json @@ -0,0 +1,64 @@ +{ + "name": "league/flysystem", + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "filesystem", "filesystems", "files", "storage", "dropbox", "aws", + "abstraction", "s3", "ftp", "sftp", "remote", "webdav", + "file systems", "cloud", "cloud files", "rackspace", "copy.com" + ], + "license": "MIT", + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "require": { + "php": ">=5.5.9", + "ext-fileinfo": "*" + }, + "require-dev": { + "phpspec/phpspec": "^3.4", + "phpunit/phpunit": "^5.7.10" + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "League\\Flysystem\\Stub\\": "stub/" + }, + "files": [ + "tests/PHPUnitHacks.php" + ] + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", + "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "ext-ftp": "Allows you to use FTP server storage", + "ext-openssl": "Allows you to use FTPS server storage", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "scripts": { + "phpstan": "php phpstan.php" + } +} diff --git a/vendor/league/flysystem/deprecations.md b/vendor/league/flysystem/deprecations.md new file mode 100644 index 0000000..c336a42 --- /dev/null +++ b/vendor/league/flysystem/deprecations.md @@ -0,0 +1,19 @@ +# Deprecations + +This document lists all the planned deprecations. + +## Handlers will be removed in 2.0 + +The `Handler` type and associated calls will be removed in version 2.0. + +### Upgrade path + +You should create your own implementation for handling OOP usage, +but it's recommended to move away from using an OOP-style wrapper entirely. + +The reason for this is that it's too easy for implementation details (for +your application this is Flysystem) to leak into the application. The most +important part for Flysystem is that it improves portability and creates a +solid boundary between your application core and the infrastructure you use. +The OOP-style handling breaks this principle, therefore I want to stop +promoting it. diff --git a/vendor/league/flysystem/src/Adapter/AbstractAdapter.php b/vendor/league/flysystem/src/Adapter/AbstractAdapter.php new file mode 100644 index 0000000..e577ac4 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/AbstractAdapter.php @@ -0,0 +1,72 @@ +pathPrefix = null; + + return; + } + + $this->pathPrefix = rtrim($prefix, '\\/') . $this->pathSeparator; + } + + /** + * Get the path prefix. + * + * @return string|null path prefix or null if pathPrefix is empty + */ + public function getPathPrefix() + { + return $this->pathPrefix; + } + + /** + * Prefix a path. + * + * @param string $path + * + * @return string prefixed path + */ + public function applyPathPrefix($path) + { + return $this->getPathPrefix() . ltrim($path, '\\/'); + } + + /** + * Remove a path prefix. + * + * @param string $path + * + * @return string path without the prefix + */ + public function removePathPrefix($path) + { + return substr($path, strlen($this->getPathPrefix())); + } +} diff --git a/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php b/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php new file mode 100644 index 0000000..578b491 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php @@ -0,0 +1,693 @@ +safeStorage = new SafeStorage(); + $this->setConfig($config); + } + + /** + * Set the config. + * + * @param array $config + * + * @return $this + */ + public function setConfig(array $config) + { + foreach ($this->configurable as $setting) { + if ( ! isset($config[$setting])) { + continue; + } + + $method = 'set' . ucfirst($setting); + + if (method_exists($this, $method)) { + $this->$method($config[$setting]); + } + } + + return $this; + } + + /** + * Returns the host. + * + * @return string + */ + public function getHost() + { + return $this->host; + } + + /** + * Set the host. + * + * @param string $host + * + * @return $this + */ + public function setHost($host) + { + $this->host = $host; + + return $this; + } + + /** + * Set the public permission value. + * + * @param int $permPublic + * + * @return $this + */ + public function setPermPublic($permPublic) + { + $this->permPublic = $permPublic; + + return $this; + } + + /** + * Set the private permission value. + * + * @param int $permPrivate + * + * @return $this + */ + public function setPermPrivate($permPrivate) + { + $this->permPrivate = $permPrivate; + + return $this; + } + + /** + * Returns the ftp port. + * + * @return int + */ + public function getPort() + { + return $this->port; + } + + /** + * Returns the root folder to work from. + * + * @return string + */ + public function getRoot() + { + return $this->root; + } + + /** + * Set the ftp port. + * + * @param int|string $port + * + * @return $this + */ + public function setPort($port) + { + $this->port = (int) $port; + + return $this; + } + + /** + * Set the root folder to work from. + * + * @param string $root + * + * @return $this + */ + public function setRoot($root) + { + $this->root = rtrim($root, '\\/') . $this->separator; + + return $this; + } + + /** + * Returns the ftp username. + * + * @return string username + */ + public function getUsername() + { + $username = $this->safeStorage->retrieveSafely('username'); + + return $username !== null ? $username : 'anonymous'; + } + + /** + * Set ftp username. + * + * @param string $username + * + * @return $this + */ + public function setUsername($username) + { + $this->safeStorage->storeSafely('username', $username); + + return $this; + } + + /** + * Returns the password. + * + * @return string password + */ + public function getPassword() + { + return $this->safeStorage->retrieveSafely('password'); + } + + /** + * Set the ftp password. + * + * @param string $password + * + * @return $this + */ + public function setPassword($password) + { + $this->safeStorage->storeSafely('password', $password); + + return $this; + } + + /** + * Returns the amount of seconds before the connection will timeout. + * + * @return int + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Set the amount of seconds before the connection should timeout. + * + * @param int $timeout + * + * @return $this + */ + public function setTimeout($timeout) + { + $this->timeout = (int) $timeout; + + return $this; + } + + /** + * Return the FTP system type. + * + * @return string + */ + public function getSystemType() + { + return $this->systemType; + } + + /** + * Set the FTP system type (windows or unix). + * + * @param string $systemType + * + * @return $this + */ + public function setSystemType($systemType) + { + $this->systemType = strtolower($systemType); + + return $this; + } + + /** + * True to enable timestamps for FTP servers that return unix-style listings. + * + * @param bool $bool + * + * @return $this + */ + public function setEnableTimestampsOnUnixListings($bool = false) + { + $this->enableTimestampsOnUnixListings = $bool; + + return $this; + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + return $this->listDirectoryContents($directory, $recursive); + } + + abstract protected function listDirectoryContents($directory, $recursive = false); + + /** + * Normalize a directory listing. + * + * @param array $listing + * @param string $prefix + * + * @return array directory listing + */ + protected function normalizeListing(array $listing, $prefix = '') + { + $base = $prefix; + $result = []; + $listing = $this->removeDotDirectories($listing); + + while ($item = array_shift($listing)) { + if (preg_match('#^.*:$#', $item)) { + $base = preg_replace('~^\./*|:$~', '', $item); + continue; + } + + $result[] = $this->normalizeObject($item, $base); + } + + return $this->sortListing($result); + } + + /** + * Sort a directory listing. + * + * @param array $result + * + * @return array sorted listing + */ + protected function sortListing(array $result) + { + $compare = function ($one, $two) { + return strnatcmp($one['path'], $two['path']); + }; + + usort($result, $compare); + + return $result; + } + + /** + * Normalize a file entry. + * + * @param string $item + * @param string $base + * + * @return array normalized file array + * + * @throws NotSupportedException + */ + protected function normalizeObject($item, $base) + { + $systemType = $this->systemType ?: $this->detectSystemType($item); + + if ($systemType === 'unix') { + return $this->normalizeUnixObject($item, $base); + } elseif ($systemType === 'windows') { + return $this->normalizeWindowsObject($item, $base); + } + + throw NotSupportedException::forFtpSystemType($systemType); + } + + /** + * Normalize a Unix file entry. + * + * Given $item contains: + * '-rw-r--r-- 1 ftp ftp 409 Aug 19 09:01 file1.txt' + * + * This function will return: + * [ + * 'type' => 'file', + * 'path' => 'file1.txt', + * 'visibility' => 'public', + * 'size' => 409, + * 'timestamp' => 1566205260 + * ] + * + * @param string $item + * @param string $base + * + * @return array normalized file array + */ + protected function normalizeUnixObject($item, $base) + { + $item = preg_replace('#\s+#', ' ', trim($item), 7); + + if (count(explode(' ', $item, 9)) !== 9) { + throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts."); + } + + list($permissions, /* $number */, /* $owner */, /* $group */, $size, $month, $day, $timeOrYear, $name) = explode(' ', $item, 9); + $type = $this->detectType($permissions); + $path = $base === '' ? $name : $base . $this->separator . $name; + + if ($type === 'dir') { + return compact('type', 'path'); + } + + $permissions = $this->normalizePermissions($permissions); + $visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE; + $size = (int) $size; + + $result = compact('type', 'path', 'visibility', 'size'); + if ($this->enableTimestampsOnUnixListings) { + $timestamp = $this->normalizeUnixTimestamp($month, $day, $timeOrYear); + $result += compact('timestamp'); + } + + return $result; + } + + /** + * Only accurate to the minute (current year), or to the day. + * + * Inadequacies in timestamp accuracy are due to limitations of the FTP 'LIST' command + * + * Note: The 'MLSD' command is a machine-readable replacement for 'LIST' + * but many FTP servers do not support it :( + * + * @param string $month e.g. 'Aug' + * @param string $day e.g. '19' + * @param string $timeOrYear e.g. '09:01' OR '2015' + * + * @return int + */ + protected function normalizeUnixTimestamp($month, $day, $timeOrYear) + { + if (is_numeric($timeOrYear)) { + $year = $timeOrYear; + $hour = '00'; + $minute = '00'; + $seconds = '00'; + } else { + $year = date('Y'); + list($hour, $minute) = explode(':', $timeOrYear); + $seconds = '00'; + } + $dateTime = DateTime::createFromFormat('Y-M-j-G:i:s', "{$year}-{$month}-{$day}-{$hour}:{$minute}:{$seconds}"); + + return $dateTime->getTimestamp(); + } + + /** + * Normalize a Windows/DOS file entry. + * + * @param string $item + * @param string $base + * + * @return array normalized file array + */ + protected function normalizeWindowsObject($item, $base) + { + $item = preg_replace('#\s+#', ' ', trim($item), 3); + + if (count(explode(' ', $item, 4)) !== 4) { + throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts."); + } + + list($date, $time, $size, $name) = explode(' ', $item, 4); + $path = $base === '' ? $name : $base . $this->separator . $name; + + // Check for the correct date/time format + $format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i'; + $dt = DateTime::createFromFormat($format, $date . $time); + $timestamp = $dt ? $dt->getTimestamp() : (int) strtotime("$date $time"); + + if ($size === '') { + $type = 'dir'; + + return compact('type', 'path', 'timestamp'); + } + + $type = 'file'; + $visibility = AdapterInterface::VISIBILITY_PUBLIC; + $size = (int) $size; + + return compact('type', 'path', 'visibility', 'size', 'timestamp'); + } + + /** + * Get the system type from a listing item. + * + * @param string $item + * + * @return string the system type + */ + protected function detectSystemType($item) + { + return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', $item) ? 'windows' : 'unix'; + } + + /** + * Get the file type from the permissions. + * + * @param string $permissions + * + * @return string file type + */ + protected function detectType($permissions) + { + return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file'; + } + + /** + * Normalize a permissions string. + * + * @param string $permissions + * + * @return int + */ + protected function normalizePermissions($permissions) + { + // remove the type identifier + $permissions = substr($permissions, 1); + + // map the string rights to the numeric counterparts + $map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1']; + $permissions = strtr($permissions, $map); + + // split up the permission groups + $parts = str_split($permissions, 3); + + // convert the groups + $mapper = function ($part) { + return array_sum(str_split($part)); + }; + + // converts to decimal number + return octdec(implode('', array_map($mapper, $parts))); + } + + /** + * Filter out dot-directories. + * + * @param array $list + * + * @return array + */ + public function removeDotDirectories(array $list) + { + $filter = function ($line) { + return $line !== '' && ! preg_match('#.* \.(\.)?$|^total#', $line); + }; + + return array_filter($list, $filter); + } + + /** + * @inheritdoc + */ + public function has($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + return $this->getMetadata($path); + } + + /** + * Ensure a directory exists. + * + * @param string $dirname + */ + public function ensureDirectory($dirname) + { + $dirname = (string) $dirname; + + if ($dirname !== '' && ! $this->has($dirname)) { + $this->createDir($dirname, new Config()); + } + } + + /** + * @return mixed + */ + public function getConnection() + { + $tries = 0; + + while ( ! $this->isConnected() && $tries < 3) { + $tries++; + $this->disconnect(); + $this->connect(); + } + + return $this->connection; + } + + /** + * Get the public permission value. + * + * @return int + */ + public function getPermPublic() + { + return $this->permPublic; + } + + /** + * Get the private permission value. + * + * @return int + */ + public function getPermPrivate() + { + return $this->permPrivate; + } + + /** + * Disconnect on destruction. + */ + public function __destruct() + { + $this->disconnect(); + } + + /** + * Establish a connection. + */ + abstract public function connect(); + + /** + * Close the connection. + */ + abstract public function disconnect(); + + /** + * Check if a connection is active. + * + * @return bool + */ + abstract public function isConnected(); +} diff --git a/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php b/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php new file mode 100644 index 0000000..fd8d216 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/CanOverwriteFiles.php @@ -0,0 +1,12 @@ +transferMode = $mode; + + return $this; + } + + /** + * Set if Ssl is enabled. + * + * @param bool $ssl + * + * @return $this + */ + public function setSsl($ssl) + { + $this->ssl = (bool) $ssl; + + return $this; + } + + /** + * Set if passive mode should be used. + * + * @param bool $passive + */ + public function setPassive($passive = true) + { + $this->passive = $passive; + } + + /** + * @param bool $ignorePassiveAddress + */ + public function setIgnorePassiveAddress($ignorePassiveAddress) + { + $this->ignorePassiveAddress = $ignorePassiveAddress; + } + + /** + * @param bool $recurseManually + */ + public function setRecurseManually($recurseManually) + { + $this->recurseManually = $recurseManually; + } + + /** + * @param bool $utf8 + */ + public function setUtf8($utf8) + { + $this->utf8 = (bool) $utf8; + } + + /** + * Connect to the FTP server. + */ + public function connect() + { + if ($this->ssl) { + $this->connection = ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout()); + } else { + $this->connection = ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout()); + } + + if ( ! $this->connection) { + throw new RuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort()); + } + + $this->login(); + $this->setUtf8Mode(); + $this->setConnectionPassiveMode(); + $this->setConnectionRoot(); + $this->isPureFtpd = $this->isPureFtpdServer(); + } + + /** + * Set the connection to UTF-8 mode. + */ + protected function setUtf8Mode() + { + if ($this->utf8) { + $response = ftp_raw($this->connection, "OPTS UTF8 ON"); + if (substr($response[0], 0, 3) !== '200') { + throw new RuntimeException( + 'Could not set UTF-8 mode for connection: ' . $this->getHost() . '::' . $this->getPort() + ); + } + } + } + + /** + * Set the connections to passive mode. + * + * @throws RuntimeException + */ + protected function setConnectionPassiveMode() + { + if (is_bool($this->ignorePassiveAddress) && defined('FTP_USEPASVADDRESS')) { + ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress); + } + + if ( ! ftp_pasv($this->connection, $this->passive)) { + throw new RuntimeException( + 'Could not set passive mode for connection: ' . $this->getHost() . '::' . $this->getPort() + ); + } + } + + /** + * Set the connection root. + */ + protected function setConnectionRoot() + { + $root = $this->getRoot(); + $connection = $this->connection; + + if ($root && ! ftp_chdir($connection, $root)) { + throw new RuntimeException('Root is invalid or does not exist: ' . $this->getRoot()); + } + + // Store absolute path for further reference. + // This is needed when creating directories and + // initial root was a relative path, else the root + // would be relative to the chdir'd path. + $this->root = ftp_pwd($connection); + } + + /** + * Login. + * + * @throws RuntimeException + */ + protected function login() + { + set_error_handler(function () { + }); + $isLoggedIn = ftp_login( + $this->connection, + $this->getUsername(), + $this->getPassword() + ); + restore_error_handler(); + + if ( ! $isLoggedIn) { + $this->disconnect(); + throw new RuntimeException( + 'Could not login with connection: ' . $this->getHost() . '::' . $this->getPort( + ) . ', username: ' . $this->getUsername() + ); + } + } + + /** + * Disconnect from the FTP server. + */ + public function disconnect() + { + if (is_resource($this->connection)) { + ftp_close($this->connection); + } + + $this->connection = null; + } + + /** + * @inheritdoc + */ + public function write($path, $contents, Config $config) + { + $stream = fopen('php://temp', 'w+b'); + fwrite($stream, $contents); + rewind($stream); + $result = $this->writeStream($path, $stream, $config); + fclose($stream); + + if ($result === false) { + return false; + } + + $result['contents'] = $contents; + $result['mimetype'] = $config->get('mimetype') ?: Util::guessMimeType($path, $contents); + + return $result; + } + + /** + * @inheritdoc + */ + public function writeStream($path, $resource, Config $config) + { + $this->ensureDirectory(Util::dirname($path)); + + if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) { + return false; + } + + if ($visibility = $config->get('visibility')) { + $this->setVisibility($path, $visibility); + } + + $type = 'file'; + + return compact('type', 'path', 'visibility'); + } + + /** + * @inheritdoc + */ + public function update($path, $contents, Config $config) + { + return $this->write($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function updateStream($path, $resource, Config $config) + { + return $this->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + return ftp_rename($this->getConnection(), $path, $newpath); + } + + /** + * @inheritdoc + */ + public function delete($path) + { + return ftp_delete($this->getConnection(), $path); + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + $connection = $this->getConnection(); + $contents = array_reverse($this->listDirectoryContents($dirname, false)); + + foreach ($contents as $object) { + if ($object['type'] === 'file') { + if ( ! ftp_delete($connection, $object['path'])) { + return false; + } + } elseif ( ! $this->deleteDir($object['path'])) { + return false; + } + } + + return ftp_rmdir($connection, $dirname); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, Config $config) + { + $connection = $this->getConnection(); + $directories = explode('/', $dirname); + + foreach ($directories as $directory) { + if (false === $this->createActualDirectory($directory, $connection)) { + $this->setConnectionRoot(); + + return false; + } + + ftp_chdir($connection, $directory); + } + + $this->setConnectionRoot(); + + return ['type' => 'dir', 'path' => $dirname]; + } + + /** + * Create a directory. + * + * @param string $directory + * @param resource $connection + * + * @return bool + */ + protected function createActualDirectory($directory, $connection) + { + // List the current directory + $listing = ftp_nlist($connection, '.') ?: []; + + foreach ($listing as $key => $item) { + if (preg_match('~^\./.*~', $item)) { + $listing[$key] = substr($item, 2); + } + } + + if (in_array($directory, $listing, true)) { + return true; + } + + return (boolean) ftp_mkdir($connection, $directory); + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + if ($path === '') { + return ['type' => 'dir', 'path' => '']; + } + + if (@ftp_chdir($this->getConnection(), $path) === true) { + $this->setConnectionRoot(); + + return ['type' => 'dir', 'path' => $path]; + } + + $listing = $this->ftpRawlist('-A', str_replace('*', '\\*', $path)); + + if (empty($listing) || in_array('total 0', $listing, true)) { + return false; + } + + if (preg_match('/.* not found/', $listing[0])) { + return false; + } + + if (preg_match('/^total [0-9]*$/', $listing[0])) { + array_shift($listing); + } + + return $this->normalizeObject($listing[0], ''); + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + if ( ! $metadata = $this->getMetadata($path)) { + return false; + } + + $metadata['mimetype'] = MimeType::detectByFilename($path); + + return $metadata; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + $timestamp = ftp_mdtm($this->getConnection(), $path); + + return ($timestamp !== -1) ? ['path' => $path, 'timestamp' => $timestamp] : false; + } + + /** + * @inheritdoc + */ + public function read($path) + { + if ( ! $object = $this->readStream($path)) { + return false; + } + + $object['contents'] = stream_get_contents($object['stream']); + fclose($object['stream']); + unset($object['stream']); + + return $object; + } + + /** + * @inheritdoc + */ + public function readStream($path) + { + $stream = fopen('php://temp', 'w+b'); + $result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode); + rewind($stream); + + if ( ! $result) { + fclose($stream); + + return false; + } + + return ['type' => 'file', 'path' => $path, 'stream' => $stream]; + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + $mode = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? $this->getPermPublic() : $this->getPermPrivate(); + + if ( ! ftp_chmod($this->getConnection(), $mode, $path)) { + return false; + } + + return compact('path', 'visibility'); + } + + /** + * @inheritdoc + * + * @param string $directory + */ + protected function listDirectoryContents($directory, $recursive = true) + { + $directory = str_replace('*', '\\*', $directory); + + if ($recursive && $this->recurseManually) { + return $this->listDirectoryContentsRecursive($directory); + } + + $options = $recursive ? '-alnR' : '-aln'; + $listing = $this->ftpRawlist($options, $directory); + + return $listing ? $this->normalizeListing($listing, $directory) : []; + } + + /** + * @inheritdoc + * + * @param string $directory + */ + protected function listDirectoryContentsRecursive($directory) + { + $listing = $this->normalizeListing($this->ftpRawlist('-aln', $directory) ?: [], $directory); + $output = []; + + foreach ($listing as $item) { + $output[] = $item; + if ($item['type'] !== 'dir') { + continue; + } + $output = array_merge($output, $this->listDirectoryContentsRecursive($item['path'])); + } + + return $output; + } + + /** + * Check if the connection is open. + * + * @return bool + * + * @throws ErrorException + */ + public function isConnected() + { + try { + return is_resource($this->connection) && ftp_rawlist($this->connection, $this->getRoot()) !== false; + } catch (ErrorException $e) { + if (strpos($e->getMessage(), 'ftp_rawlist') === false) { + throw $e; + } + + return false; + } + } + + /** + * @return bool + */ + protected function isPureFtpdServer() + { + $response = ftp_raw($this->connection, 'HELP'); + + return stripos(implode(' ', $response), 'Pure-FTPd') !== false; + } + + /** + * The ftp_rawlist function with optional escaping. + * + * @param string $options + * @param string $path + * + * @return array + */ + protected function ftpRawlist($options, $path) + { + $connection = $this->getConnection(); + + if ($this->isPureFtpd) { + $path = str_replace(' ', '\ ', $path); + } + + return ftp_rawlist($connection, $options . ' ' . $path); + } +} diff --git a/vendor/league/flysystem/src/Adapter/Ftpd.php b/vendor/league/flysystem/src/Adapter/Ftpd.php new file mode 100644 index 0000000..d5349e4 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/Ftpd.php @@ -0,0 +1,45 @@ + 'dir', 'path' => '']; + } + if (@ftp_chdir($this->getConnection(), $path) === true) { + $this->setConnectionRoot(); + + return ['type' => 'dir', 'path' => $path]; + } + + if ( ! ($object = ftp_raw($this->getConnection(), 'STAT ' . $path)) || count($object) < 3) { + return false; + } + + if (substr($object[1], 0, 5) === "ftpd:") { + return false; + } + + return $this->normalizeObject($object[1], ''); + } + + /** + * @inheritdoc + */ + protected function listDirectoryContents($directory, $recursive = true) + { + $listing = ftp_rawlist($this->getConnection(), $directory, $recursive); + + if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) { + return []; + } + + return $this->normalizeListing($listing, $directory); + } +} diff --git a/vendor/league/flysystem/src/Adapter/Local.php b/vendor/league/flysystem/src/Adapter/Local.php new file mode 100644 index 0000000..c6e6fa8 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/Local.php @@ -0,0 +1,528 @@ + [ + 'public' => 0644, + 'private' => 0600, + ], + 'dir' => [ + 'public' => 0755, + 'private' => 0700, + ], + ]; + + /** + * @var string + */ + protected $pathSeparator = DIRECTORY_SEPARATOR; + + /** + * @var array + */ + protected $permissionMap; + + /** + * @var int + */ + protected $writeFlags; + + /** + * @var int + */ + private $linkHandling; + + /** + * Constructor. + * + * @param string $root + * @param int $writeFlags + * @param int $linkHandling + * @param array $permissions + * + * @throws LogicException + */ + public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = []) + { + $root = is_link($root) ? realpath($root) : $root; + $this->permissionMap = array_replace_recursive(static::$permissions, $permissions); + $this->ensureDirectory($root); + + if ( ! is_dir($root) || ! is_readable($root)) { + throw new LogicException('The root path ' . $root . ' is not readable.'); + } + + $this->setPathPrefix($root); + $this->writeFlags = $writeFlags; + $this->linkHandling = $linkHandling; + } + + /** + * Ensure the root directory exists. + * + * @param string $root root directory path + * + * @return void + * + * @throws Exception in case the root directory can not be created + */ + protected function ensureDirectory($root) + { + if ( ! is_dir($root)) { + $umask = umask(0); + + if ( ! @mkdir($root, $this->permissionMap['dir']['public'], true)) { + $mkdirError = error_get_last(); + } + + umask($umask); + clearstatcache(false, $root); + + if ( ! is_dir($root)) { + $errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : ''; + throw new Exception(sprintf('Impossible to create the root directory "%s". %s', $root, $errorMessage)); + } + } + } + + /** + * @inheritdoc + */ + public function has($path) + { + $location = $this->applyPathPrefix($path); + + return file_exists($location); + } + + /** + * @inheritdoc + */ + public function write($path, $contents, Config $config) + { + $location = $this->applyPathPrefix($path); + $this->ensureDirectory(dirname($location)); + + if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) { + return false; + } + + $type = 'file'; + $result = compact('contents', 'type', 'size', 'path'); + + if ($visibility = $config->get('visibility')) { + $result['visibility'] = $visibility; + $this->setVisibility($path, $visibility); + } + + return $result; + } + + /** + * @inheritdoc + */ + public function writeStream($path, $resource, Config $config) + { + $location = $this->applyPathPrefix($path); + $this->ensureDirectory(dirname($location)); + $stream = fopen($location, 'w+b'); + + if ( ! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) { + return false; + } + + $type = 'file'; + $result = compact('type', 'path'); + + if ($visibility = $config->get('visibility')) { + $this->setVisibility($path, $visibility); + $result['visibility'] = $visibility; + } + + return $result; + } + + /** + * @inheritdoc + */ + public function readStream($path) + { + $location = $this->applyPathPrefix($path); + $stream = fopen($location, 'rb'); + + return ['type' => 'file', 'path' => $path, 'stream' => $stream]; + } + + /** + * @inheritdoc + */ + public function updateStream($path, $resource, Config $config) + { + return $this->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function update($path, $contents, Config $config) + { + $location = $this->applyPathPrefix($path); + $size = file_put_contents($location, $contents, $this->writeFlags); + + if ($size === false) { + return false; + } + + $type = 'file'; + + $result = compact('type', 'path', 'size', 'contents'); + + if ($mimetype = $config->get('mimetype') ?: Util::guessMimeType($path, $contents)) { + $result['mimetype'] = $mimetype; + } + + return $result; + } + + /** + * @inheritdoc + */ + public function read($path) + { + $location = $this->applyPathPrefix($path); + $contents = @file_get_contents($location); + + if ($contents === false) { + return false; + } + + return ['type' => 'file', 'path' => $path, 'contents' => $contents]; + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + $location = $this->applyPathPrefix($path); + $destination = $this->applyPathPrefix($newpath); + $parentDirectory = $this->applyPathPrefix(Util::dirname($newpath)); + $this->ensureDirectory($parentDirectory); + + return rename($location, $destination); + } + + /** + * @inheritdoc + */ + public function copy($path, $newpath) + { + $location = $this->applyPathPrefix($path); + $destination = $this->applyPathPrefix($newpath); + $this->ensureDirectory(dirname($destination)); + + return copy($location, $destination); + } + + /** + * @inheritdoc + */ + public function delete($path) + { + $location = $this->applyPathPrefix($path); + + return @unlink($location); + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + $result = []; + $location = $this->applyPathPrefix($directory); + + if ( ! is_dir($location)) { + return []; + } + + $iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location); + + foreach ($iterator as $file) { + $path = $this->getFilePath($file); + + if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) { + continue; + } + + $result[] = $this->normalizeFileInfo($file); + } + + return array_filter($result); + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + $location = $this->applyPathPrefix($path); + clearstatcache(false, $location); + $info = new SplFileInfo($location); + + return $this->normalizeFileInfo($info); + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + $location = $this->applyPathPrefix($path); + $finfo = new Finfo(FILEINFO_MIME_TYPE); + $mimetype = $finfo->file($location); + + if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty', 'application/x-empty'])) { + $mimetype = Util\MimeType::detectByFilename($location); + } + + return ['path' => $path, 'type' => 'file', 'mimetype' => $mimetype]; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + return $this->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + $location = $this->applyPathPrefix($path); + clearstatcache(false, $location); + $permissions = octdec(substr(sprintf('%o', fileperms($location)), -4)); + $type = is_dir($location) ? 'dir' : 'file'; + + foreach ($this->permissionMap[$type] as $visibility => $visibilityPermissions) { + if ($visibilityPermissions == $permissions) { + return compact('path', 'visibility'); + } + } + + $visibility = substr(sprintf('%o', fileperms($location)), -4); + + return compact('path', 'visibility'); + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + $location = $this->applyPathPrefix($path); + $type = is_dir($location) ? 'dir' : 'file'; + $success = chmod($location, $this->permissionMap[$type][$visibility]); + + if ($success === false) { + return false; + } + + return compact('path', 'visibility'); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, Config $config) + { + $location = $this->applyPathPrefix($dirname); + $umask = umask(0); + $visibility = $config->get('visibility', 'public'); + $return = ['path' => $dirname, 'type' => 'dir']; + + if ( ! is_dir($location)) { + if (false === @mkdir($location, $this->permissionMap['dir'][$visibility], true) + || false === is_dir($location)) { + $return = false; + } + } + + umask($umask); + + return $return; + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + $location = $this->applyPathPrefix($dirname); + + if ( ! is_dir($location)) { + return false; + } + + $contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST); + + /** @var SplFileInfo $file */ + foreach ($contents as $file) { + $this->guardAgainstUnreadableFileInfo($file); + $this->deleteFileInfoObject($file); + } + + return rmdir($location); + } + + /** + * @param SplFileInfo $file + */ + protected function deleteFileInfoObject(SplFileInfo $file) + { + switch ($file->getType()) { + case 'dir': + rmdir($file->getRealPath()); + break; + case 'link': + unlink($file->getPathname()); + break; + default: + unlink($file->getRealPath()); + } + } + + /** + * Normalize the file info. + * + * @param SplFileInfo $file + * + * @return array|void + * + * @throws NotSupportedException + */ + protected function normalizeFileInfo(SplFileInfo $file) + { + if ( ! $file->isLink()) { + return $this->mapFileInfo($file); + } + + if ($this->linkHandling & self::DISALLOW_LINKS) { + throw NotSupportedException::forLink($file); + } + } + + /** + * Get the normalized path from a SplFileInfo object. + * + * @param SplFileInfo $file + * + * @return string + */ + protected function getFilePath(SplFileInfo $file) + { + $location = $file->getPathname(); + $path = $this->removePathPrefix($location); + + return trim(str_replace('\\', '/', $path), '/'); + } + + /** + * @param string $path + * @param int $mode + * + * @return RecursiveIteratorIterator + */ + protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST) + { + return new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), + $mode + ); + } + + /** + * @param string $path + * + * @return DirectoryIterator + */ + protected function getDirectoryIterator($path) + { + $iterator = new DirectoryIterator($path); + + return $iterator; + } + + /** + * @param SplFileInfo $file + * + * @return array + */ + protected function mapFileInfo(SplFileInfo $file) + { + $normalized = [ + 'type' => $file->getType(), + 'path' => $this->getFilePath($file), + ]; + + $normalized['timestamp'] = $file->getMTime(); + + if ($normalized['type'] === 'file') { + $normalized['size'] = $file->getSize(); + } + + return $normalized; + } + + /** + * @param SplFileInfo $file + * + * @throws UnreadableFileException + */ + protected function guardAgainstUnreadableFileInfo(SplFileInfo $file) + { + if ( ! $file->isReadable()) { + throw UnreadableFileException::forFileInfo($file); + } + } +} diff --git a/vendor/league/flysystem/src/Adapter/NullAdapter.php b/vendor/league/flysystem/src/Adapter/NullAdapter.php new file mode 100644 index 0000000..2527087 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/NullAdapter.php @@ -0,0 +1,144 @@ +get('visibility')) { + $result['visibility'] = $visibility; + } + + return $result; + } + + /** + * @inheritdoc + */ + public function update($path, $contents, Config $config) + { + return false; + } + + /** + * @inheritdoc + */ + public function read($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + return false; + } + + /** + * @inheritdoc + */ + public function delete($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + return []; + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + return false; + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + return compact('visibility'); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, Config $config) + { + return ['path' => $dirname, 'type' => 'dir']; + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + return false; + } +} diff --git a/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php b/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php new file mode 100644 index 0000000..fc0a747 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/Polyfill/NotSupportingVisibilityTrait.php @@ -0,0 +1,33 @@ +readStream($path); + + if ($response === false || ! is_resource($response['stream'])) { + return false; + } + + $result = $this->writeStream($newpath, $response['stream'], new Config()); + + if ($result !== false && is_resource($response['stream'])) { + fclose($response['stream']); + } + + return $result !== false; + } + + // Required abstract method + + /** + * @param string $path + * + * @return resource + */ + abstract public function readStream($path); + + /** + * @param string $path + * @param resource $resource + * @param Config $config + * + * @return resource + */ + abstract public function writeStream($path, $resource, Config $config); +} diff --git a/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php b/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php new file mode 100644 index 0000000..2b31c01 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/Polyfill/StreamedReadingTrait.php @@ -0,0 +1,44 @@ +read($path)) { + return false; + } + + $stream = fopen('php://temp', 'w+b'); + fwrite($stream, $data['contents']); + rewind($stream); + $data['stream'] = $stream; + unset($data['contents']); + + return $data; + } + + /** + * Reads a file. + * + * @param string $path + * + * @return array|false + * + * @see League\Flysystem\ReadInterface::read() + */ + abstract public function read($path); +} diff --git a/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php b/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php new file mode 100644 index 0000000..8042496 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/Polyfill/StreamedTrait.php @@ -0,0 +1,9 @@ +stream($path, $resource, $config, 'write'); + } + + /** + * Update a file using a stream. + * + * @param string $path + * @param resource $resource + * @param Config $config Config object or visibility setting + * + * @return mixed false of file metadata + */ + public function updateStream($path, $resource, Config $config) + { + return $this->stream($path, $resource, $config, 'update'); + } + + // Required abstract methods + abstract public function write($pash, $contents, Config $config); + abstract public function update($pash, $contents, Config $config); +} diff --git a/vendor/league/flysystem/src/Adapter/SynologyFtp.php b/vendor/league/flysystem/src/Adapter/SynologyFtp.php new file mode 100644 index 0000000..fe0d344 --- /dev/null +++ b/vendor/league/flysystem/src/Adapter/SynologyFtp.php @@ -0,0 +1,8 @@ +settings = $settings; + } + + /** + * Get a setting. + * + * @param string $key + * @param mixed $default + * + * @return mixed config setting or default when not found + */ + public function get($key, $default = null) + { + if ( ! array_key_exists($key, $this->settings)) { + return $this->getDefault($key, $default); + } + + return $this->settings[$key]; + } + + /** + * Check if an item exists by key. + * + * @param string $key + * + * @return bool + */ + public function has($key) + { + if (array_key_exists($key, $this->settings)) { + return true; + } + + return $this->fallback instanceof Config + ? $this->fallback->has($key) + : false; + } + + /** + * Try to retrieve a default setting from a config fallback. + * + * @param string $key + * @param mixed $default + * + * @return mixed config setting or default when not found + */ + protected function getDefault($key, $default) + { + if ( ! $this->fallback) { + return $default; + } + + return $this->fallback->get($key, $default); + } + + /** + * Set a setting. + * + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function set($key, $value) + { + $this->settings[$key] = $value; + + return $this; + } + + /** + * Set the fallback. + * + * @param Config $fallback + * + * @return $this + */ + public function setFallback(Config $fallback) + { + $this->fallback = $fallback; + + return $this; + } +} diff --git a/vendor/league/flysystem/src/ConfigAwareTrait.php b/vendor/league/flysystem/src/ConfigAwareTrait.php new file mode 100644 index 0000000..202d605 --- /dev/null +++ b/vendor/league/flysystem/src/ConfigAwareTrait.php @@ -0,0 +1,49 @@ +config = $config ? Util::ensureConfig($config) : new Config; + } + + /** + * Get the Config. + * + * @return Config config object + */ + public function getConfig() + { + return $this->config; + } + + /** + * Convert a config array to a Config object with the correct fallback. + * + * @param array $config + * + * @return Config + */ + protected function prepareConfig(array $config) + { + $config = new Config($config); + $config->setFallback($this->getConfig()); + + return $config; + } +} diff --git a/vendor/league/flysystem/src/Directory.php b/vendor/league/flysystem/src/Directory.php new file mode 100644 index 0000000..d4f90a8 --- /dev/null +++ b/vendor/league/flysystem/src/Directory.php @@ -0,0 +1,31 @@ +filesystem->deleteDir($this->path); + } + + /** + * List the directory contents. + * + * @param bool $recursive + * + * @return array|bool directory contents or false + */ + public function getContents($recursive = false) + { + return $this->filesystem->listContents($this->path, $recursive); + } +} diff --git a/vendor/league/flysystem/src/Exception.php b/vendor/league/flysystem/src/Exception.php new file mode 100644 index 0000000..d4a9907 --- /dev/null +++ b/vendor/league/flysystem/src/Exception.php @@ -0,0 +1,8 @@ +filesystem->has($this->path); + } + + /** + * Read the file. + * + * @return string|false file contents + */ + public function read() + { + return $this->filesystem->read($this->path); + } + + /** + * Read the file as a stream. + * + * @return resource|false file stream + */ + public function readStream() + { + return $this->filesystem->readStream($this->path); + } + + /** + * Write the new file. + * + * @param string $content + * + * @return bool success boolean + */ + public function write($content) + { + return $this->filesystem->write($this->path, $content); + } + + /** + * Write the new file using a stream. + * + * @param resource $resource + * + * @return bool success boolean + */ + public function writeStream($resource) + { + return $this->filesystem->writeStream($this->path, $resource); + } + + /** + * Update the file contents. + * + * @param string $content + * + * @return bool success boolean + */ + public function update($content) + { + return $this->filesystem->update($this->path, $content); + } + + /** + * Update the file contents with a stream. + * + * @param resource $resource + * + * @return bool success boolean + */ + public function updateStream($resource) + { + return $this->filesystem->updateStream($this->path, $resource); + } + + /** + * Create the file or update if exists. + * + * @param string $content + * + * @return bool success boolean + */ + public function put($content) + { + return $this->filesystem->put($this->path, $content); + } + + /** + * Create the file or update if exists using a stream. + * + * @param resource $resource + * + * @return bool success boolean + */ + public function putStream($resource) + { + return $this->filesystem->putStream($this->path, $resource); + } + + /** + * Rename the file. + * + * @param string $newpath + * + * @return bool success boolean + */ + public function rename($newpath) + { + if ($this->filesystem->rename($this->path, $newpath)) { + $this->path = $newpath; + + return true; + } + + return false; + } + + /** + * Copy the file. + * + * @param string $newpath + * + * @return File|false new file or false + */ + public function copy($newpath) + { + if ($this->filesystem->copy($this->path, $newpath)) { + return new File($this->filesystem, $newpath); + } + + return false; + } + + /** + * Get the file's timestamp. + * + * @return string|false The timestamp or false on failure. + */ + public function getTimestamp() + { + return $this->filesystem->getTimestamp($this->path); + } + + /** + * Get the file's mimetype. + * + * @return string|false The file mime-type or false on failure. + */ + public function getMimetype() + { + return $this->filesystem->getMimetype($this->path); + } + + /** + * Get the file's visibility. + * + * @return string|false The visibility (public|private) or false on failure. + */ + public function getVisibility() + { + return $this->filesystem->getVisibility($this->path); + } + + /** + * Get the file's metadata. + * + * @return array|false The file metadata or false on failure. + */ + public function getMetadata() + { + return $this->filesystem->getMetadata($this->path); + } + + /** + * Get the file size. + * + * @return int|false The file size or false on failure. + */ + public function getSize() + { + return $this->filesystem->getSize($this->path); + } + + /** + * Delete the file. + * + * @return bool success boolean + */ + public function delete() + { + return $this->filesystem->delete($this->path); + } +} diff --git a/vendor/league/flysystem/src/FileExistsException.php b/vendor/league/flysystem/src/FileExistsException.php new file mode 100644 index 0000000..c82e20c --- /dev/null +++ b/vendor/league/flysystem/src/FileExistsException.php @@ -0,0 +1,37 @@ +path = $path; + + parent::__construct('File already exists at path: ' . $this->getPath(), $code, $previous); + } + + /** + * Get the path which was found. + * + * @return string + */ + public function getPath() + { + return $this->path; + } +} diff --git a/vendor/league/flysystem/src/FileNotFoundException.php b/vendor/league/flysystem/src/FileNotFoundException.php new file mode 100644 index 0000000..989df69 --- /dev/null +++ b/vendor/league/flysystem/src/FileNotFoundException.php @@ -0,0 +1,37 @@ +path = $path; + + parent::__construct('File not found at path: ' . $this->getPath(), $code, $previous); + } + + /** + * Get the path which was not found. + * + * @return string + */ + public function getPath() + { + return $this->path; + } +} diff --git a/vendor/league/flysystem/src/Filesystem.php b/vendor/league/flysystem/src/Filesystem.php new file mode 100644 index 0000000..18b590e --- /dev/null +++ b/vendor/league/flysystem/src/Filesystem.php @@ -0,0 +1,408 @@ +adapter = $adapter; + $this->setConfig($config); + } + + /** + * Get the Adapter. + * + * @return AdapterInterface adapter + */ + public function getAdapter() + { + return $this->adapter; + } + + /** + * @inheritdoc + */ + public function has($path) + { + $path = Util::normalizePath($path); + + return strlen($path) === 0 ? false : (bool) $this->getAdapter()->has($path); + } + + /** + * @inheritdoc + */ + public function write($path, $contents, array $config = []) + { + $path = Util::normalizePath($path); + $this->assertAbsent($path); + $config = $this->prepareConfig($config); + + return (bool) $this->getAdapter()->write($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function writeStream($path, $resource, array $config = []) + { + if ( ! is_resource($resource)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); + } + + $path = Util::normalizePath($path); + $this->assertAbsent($path); + $config = $this->prepareConfig($config); + + Util::rewindStream($resource); + + return (bool) $this->getAdapter()->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function put($path, $contents, array $config = []) + { + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + + if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) { + return (bool) $this->getAdapter()->update($path, $contents, $config); + } + + return (bool) $this->getAdapter()->write($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function putStream($path, $resource, array $config = []) + { + if ( ! is_resource($resource)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); + } + + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + Util::rewindStream($resource); + + if ( ! $this->getAdapter() instanceof CanOverwriteFiles && $this->has($path)) { + return (bool) $this->getAdapter()->updateStream($path, $resource, $config); + } + + return (bool) $this->getAdapter()->writeStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function readAndDelete($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + $contents = $this->read($path); + + if ($contents === false) { + return false; + } + + $this->delete($path); + + return $contents; + } + + /** + * @inheritdoc + */ + public function update($path, $contents, array $config = []) + { + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + + $this->assertPresent($path); + + return (bool) $this->getAdapter()->update($path, $contents, $config); + } + + /** + * @inheritdoc + */ + public function updateStream($path, $resource, array $config = []) + { + if ( ! is_resource($resource)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.'); + } + + $path = Util::normalizePath($path); + $config = $this->prepareConfig($config); + $this->assertPresent($path); + Util::rewindStream($resource); + + return (bool) $this->getAdapter()->updateStream($path, $resource, $config); + } + + /** + * @inheritdoc + */ + public function read($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if ( ! ($object = $this->getAdapter()->read($path))) { + return false; + } + + return $object['contents']; + } + + /** + * @inheritdoc + */ + public function readStream($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if ( ! $object = $this->getAdapter()->readStream($path)) { + return false; + } + + return $object['stream']; + } + + /** + * @inheritdoc + */ + public function rename($path, $newpath) + { + $path = Util::normalizePath($path); + $newpath = Util::normalizePath($newpath); + $this->assertPresent($path); + $this->assertAbsent($newpath); + + return (bool) $this->getAdapter()->rename($path, $newpath); + } + + /** + * @inheritdoc + */ + public function copy($path, $newpath) + { + $path = Util::normalizePath($path); + $newpath = Util::normalizePath($newpath); + $this->assertPresent($path); + $this->assertAbsent($newpath); + + return $this->getAdapter()->copy($path, $newpath); + } + + /** + * @inheritdoc + */ + public function delete($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + return $this->getAdapter()->delete($path); + } + + /** + * @inheritdoc + */ + public function deleteDir($dirname) + { + $dirname = Util::normalizePath($dirname); + + if ($dirname === '') { + throw new RootViolationException('Root directories can not be deleted.'); + } + + return (bool) $this->getAdapter()->deleteDir($dirname); + } + + /** + * @inheritdoc + */ + public function createDir($dirname, array $config = []) + { + $dirname = Util::normalizePath($dirname); + $config = $this->prepareConfig($config); + + return (bool) $this->getAdapter()->createDir($dirname, $config); + } + + /** + * @inheritdoc + */ + public function listContents($directory = '', $recursive = false) + { + $directory = Util::normalizePath($directory); + $contents = $this->getAdapter()->listContents($directory, $recursive); + + return (new ContentListingFormatter($directory, $recursive, $this->config->get('case_sensitive', true))) + ->formatListing($contents); + } + + /** + * @inheritdoc + */ + public function getMimetype($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if (( ! $object = $this->getAdapter()->getMimetype($path)) || ! array_key_exists('mimetype', $object)) { + return false; + } + + return $object['mimetype']; + } + + /** + * @inheritdoc + */ + public function getTimestamp($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if (( ! $object = $this->getAdapter()->getTimestamp($path)) || ! array_key_exists('timestamp', $object)) { + return false; + } + + return $object['timestamp']; + } + + /** + * @inheritdoc + */ + public function getVisibility($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if (( ! $object = $this->getAdapter()->getVisibility($path)) || ! array_key_exists('visibility', $object)) { + return false; + } + + return $object['visibility']; + } + + /** + * @inheritdoc + */ + public function getSize($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + if (( ! $object = $this->getAdapter()->getSize($path)) || ! array_key_exists('size', $object)) { + return false; + } + + return (int) $object['size']; + } + + /** + * @inheritdoc + */ + public function setVisibility($path, $visibility) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + return (bool) $this->getAdapter()->setVisibility($path, $visibility); + } + + /** + * @inheritdoc + */ + public function getMetadata($path) + { + $path = Util::normalizePath($path); + $this->assertPresent($path); + + return $this->getAdapter()->getMetadata($path); + } + + /** + * @inheritdoc + */ + public function get($path, Handler $handler = null) + { + $path = Util::normalizePath($path); + + if ( ! $handler) { + $metadata = $this->getMetadata($path); + $handler = $metadata['type'] === 'file' ? new File($this, $path) : new Directory($this, $path); + } + + $handler->setPath($path); + $handler->setFilesystem($this); + + return $handler; + } + + /** + * Assert a file is present. + * + * @param string $path path to file + * + * @throws FileNotFoundException + * + * @return void + */ + public function assertPresent($path) + { + if ($this->config->get('disable_asserts', false) === false && ! $this->has($path)) { + throw new FileNotFoundException($path); + } + } + + /** + * Assert a file is absent. + * + * @param string $path path to file + * + * @throws FileExistsException + * + * @return void + */ + public function assertAbsent($path) + { + if ($this->config->get('disable_asserts', false) === false && $this->has($path)) { + throw new FileExistsException($path); + } + } +} diff --git a/vendor/league/flysystem/src/FilesystemInterface.php b/vendor/league/flysystem/src/FilesystemInterface.php new file mode 100644 index 0000000..09b811b --- /dev/null +++ b/vendor/league/flysystem/src/FilesystemInterface.php @@ -0,0 +1,284 @@ +path = $path; + $this->filesystem = $filesystem; + } + + /** + * Check whether the entree is a directory. + * + * @return bool + */ + public function isDir() + { + return $this->getType() === 'dir'; + } + + /** + * Check whether the entree is a file. + * + * @return bool + */ + public function isFile() + { + return $this->getType() === 'file'; + } + + /** + * Retrieve the entree type (file|dir). + * + * @return string file or dir + */ + public function getType() + { + $metadata = $this->filesystem->getMetadata($this->path); + + return $metadata['type']; + } + + /** + * Set the Filesystem object. + * + * @param FilesystemInterface $filesystem + * + * @return $this + */ + public function setFilesystem(FilesystemInterface $filesystem) + { + $this->filesystem = $filesystem; + + return $this; + } + + /** + * Retrieve the Filesystem object. + * + * @return FilesystemInterface + */ + public function getFilesystem() + { + return $this->filesystem; + } + + /** + * Set the entree path. + * + * @param string $path + * + * @return $this + */ + public function setPath($path) + { + $this->path = $path; + + return $this; + } + + /** + * Retrieve the entree path. + * + * @return string path + */ + public function getPath() + { + return $this->path; + } + + /** + * Plugins pass-through. + * + * @param string $method + * @param array $arguments + * + * @return mixed + */ + public function __call($method, array $arguments) + { + array_unshift($arguments, $this->path); + $callback = [$this->filesystem, $method]; + + try { + return call_user_func_array($callback, $arguments); + } catch (BadMethodCallException $e) { + throw new BadMethodCallException( + 'Call to undefined method ' + . get_called_class() + . '::' . $method + ); + } + } +} diff --git a/vendor/league/flysystem/src/MountManager.php b/vendor/league/flysystem/src/MountManager.php new file mode 100644 index 0000000..620f540 --- /dev/null +++ b/vendor/league/flysystem/src/MountManager.php @@ -0,0 +1,648 @@ + Filesystem,] + * + * @throws InvalidArgumentException + */ + public function __construct(array $filesystems = []) + { + $this->mountFilesystems($filesystems); + } + + /** + * Mount filesystems. + * + * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,] + * + * @throws InvalidArgumentException + * + * @return $this + */ + public function mountFilesystems(array $filesystems) + { + foreach ($filesystems as $prefix => $filesystem) { + $this->mountFilesystem($prefix, $filesystem); + } + + return $this; + } + + /** + * Mount filesystems. + * + * @param string $prefix + * @param FilesystemInterface $filesystem + * + * @throws InvalidArgumentException + * + * @return $this + */ + public function mountFilesystem($prefix, FilesystemInterface $filesystem) + { + if ( ! is_string($prefix)) { + throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.'); + } + + $this->filesystems[$prefix] = $filesystem; + + return $this; + } + + /** + * Get the filesystem with the corresponding prefix. + * + * @param string $prefix + * + * @throws FilesystemNotFoundException + * + * @return FilesystemInterface + */ + public function getFilesystem($prefix) + { + if ( ! isset($this->filesystems[$prefix])) { + throw new FilesystemNotFoundException('No filesystem mounted with prefix ' . $prefix); + } + + return $this->filesystems[$prefix]; + } + + /** + * Retrieve the prefix from an arguments array. + * + * @param array $arguments + * + * @throws InvalidArgumentException + * + * @return array [:prefix, :arguments] + */ + public function filterPrefix(array $arguments) + { + if (empty($arguments)) { + throw new InvalidArgumentException('At least one argument needed'); + } + + $path = array_shift($arguments); + + if ( ! is_string($path)) { + throw new InvalidArgumentException('First argument should be a string'); + } + + list($prefix, $path) = $this->getPrefixAndPath($path); + array_unshift($arguments, $path); + + return [$prefix, $arguments]; + } + + /** + * @param string $directory + * @param bool $recursive + * + * @throws InvalidArgumentException + * @throws FilesystemNotFoundException + * + * @return array + */ + public function listContents($directory = '', $recursive = false) + { + list($prefix, $directory) = $this->getPrefixAndPath($directory); + $filesystem = $this->getFilesystem($prefix); + $result = $filesystem->listContents($directory, $recursive); + + foreach ($result as &$file) { + $file['filesystem'] = $prefix; + } + + return $result; + } + + /** + * Call forwarder. + * + * @param string $method + * @param array $arguments + * + * @throws InvalidArgumentException + * @throws FilesystemNotFoundException + * + * @return mixed + */ + public function __call($method, $arguments) + { + list($prefix, $arguments) = $this->filterPrefix($arguments); + + return $this->invokePluginOnFilesystem($method, $arguments, $prefix); + } + + /** + * @param string $from + * @param string $to + * @param array $config + * + * @throws InvalidArgumentException + * @throws FilesystemNotFoundException + * @throws FileExistsException + * + * @return bool + */ + public function copy($from, $to, array $config = []) + { + list($prefixFrom, $from) = $this->getPrefixAndPath($from); + + $buffer = $this->getFilesystem($prefixFrom)->readStream($from); + + if ($buffer === false) { + return false; + } + + list($prefixTo, $to) = $this->getPrefixAndPath($to); + + $result = $this->getFilesystem($prefixTo)->writeStream($to, $buffer, $config); + + if (is_resource($buffer)) { + fclose($buffer); + } + + return $result; + } + + /** + * List with plugin adapter. + * + * @param array $keys + * @param string $directory + * @param bool $recursive + * + * @throws InvalidArgumentException + * @throws FilesystemNotFoundException + * + * @return array + */ + public function listWith(array $keys = [], $directory = '', $recursive = false) + { + list($prefix, $directory) = $this->getPrefixAndPath($directory); + $arguments = [$keys, $directory, $recursive]; + + return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix); + } + + /** + * Move a file. + * + * @param string $from + * @param string $to + * @param array $config + * + * @throws InvalidArgumentException + * @throws FilesystemNotFoundException + * + * @return bool + */ + public function move($from, $to, array $config = []) + { + list($prefixFrom, $pathFrom) = $this->getPrefixAndPath($from); + list($prefixTo, $pathTo) = $this->getPrefixAndPath($to); + + if ($prefixFrom === $prefixTo) { + $filesystem = $this->getFilesystem($prefixFrom); + $renamed = $filesystem->rename($pathFrom, $pathTo); + + if ($renamed && isset($config['visibility'])) { + return $filesystem->setVisibility($pathTo, $config['visibility']); + } + + return $renamed; + } + + $copied = $this->copy($from, $to, $config); + + if ($copied) { + return $this->delete($from); + } + + return false; + } + + /** + * Invoke a plugin on a filesystem mounted on a given prefix. + * + * @param string $method + * @param array $arguments + * @param string $prefix + * + * @throws FilesystemNotFoundException + * + * @return mixed + */ + public function invokePluginOnFilesystem($method, $arguments, $prefix) + { + $filesystem = $this->getFilesystem($prefix); + + try { + return $this->invokePlugin($method, $arguments, $filesystem); + } catch (PluginNotFoundException $e) { + // Let it pass, it's ok, don't panic. + } + + $callback = [$filesystem, $method]; + + return call_user_func_array($callback, $arguments); + } + + /** + * @param string $path + * + * @throws InvalidArgumentException + * + * @return string[] [:prefix, :path] + */ + protected function getPrefixAndPath($path) + { + if (strpos($path, '://') < 1) { + throw new InvalidArgumentException('No prefix detected in path: ' . $path); + } + + return explode('://', $path, 2); + } + + /** + * Check whether a file exists. + * + * @param string $path + * + * @return bool + */ + public function has($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->has($path); + } + + /** + * Read a file. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return string|false The file contents or false on failure. + */ + public function read($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->read($path); + } + + /** + * Retrieves a read-stream for a path. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return resource|false The path resource or false on failure. + */ + public function readStream($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->readStream($path); + } + + /** + * Get a file's metadata. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return array|false The file metadata or false on failure. + */ + public function getMetadata($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->getMetadata($path); + } + + /** + * Get a file's size. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return int|false The file size or false on failure. + */ + public function getSize($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->getSize($path); + } + + /** + * Get a file's mime-type. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return string|false The file mime-type or false on failure. + */ + public function getMimetype($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->getMimetype($path); + } + + /** + * Get a file's timestamp. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return string|false The timestamp or false on failure. + */ + public function getTimestamp($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->getTimestamp($path); + } + + /** + * Get a file's visibility. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return string|false The visibility (public|private) or false on failure. + */ + public function getVisibility($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->getVisibility($path); + } + + /** + * Write a new file. + * + * @param string $path The path of the new file. + * @param string $contents The file contents. + * @param array $config An optional configuration array. + * + * @throws FileExistsException + * + * @return bool True on success, false on failure. + */ + public function write($path, $contents, array $config = []) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->write($path, $contents, $config); + } + + /** + * Write a new file using a stream. + * + * @param string $path The path of the new file. + * @param resource $resource The file handle. + * @param array $config An optional configuration array. + * + * @throws InvalidArgumentException If $resource is not a file handle. + * @throws FileExistsException + * + * @return bool True on success, false on failure. + */ + public function writeStream($path, $resource, array $config = []) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->writeStream($path, $resource, $config); + } + + /** + * Update an existing file. + * + * @param string $path The path of the existing file. + * @param string $contents The file contents. + * @param array $config An optional configuration array. + * + * @throws FileNotFoundException + * + * @return bool True on success, false on failure. + */ + public function update($path, $contents, array $config = []) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->update($path, $contents, $config); + } + + /** + * Update an existing file using a stream. + * + * @param string $path The path of the existing file. + * @param resource $resource The file handle. + * @param array $config An optional configuration array. + * + * @throws InvalidArgumentException If $resource is not a file handle. + * @throws FileNotFoundException + * + * @return bool True on success, false on failure. + */ + public function updateStream($path, $resource, array $config = []) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->updateStream($path, $resource, $config); + } + + /** + * Rename a file. + * + * @param string $path Path to the existing file. + * @param string $newpath The new path of the file. + * + * @throws FileExistsException Thrown if $newpath exists. + * @throws FileNotFoundException Thrown if $path does not exist. + * + * @return bool True on success, false on failure. + */ + public function rename($path, $newpath) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->rename($path, $newpath); + } + + /** + * Delete a file. + * + * @param string $path + * + * @throws FileNotFoundException + * + * @return bool True on success, false on failure. + */ + public function delete($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->delete($path); + } + + /** + * Delete a directory. + * + * @param string $dirname + * + * @throws RootViolationException Thrown if $dirname is empty. + * + * @return bool True on success, false on failure. + */ + public function deleteDir($dirname) + { + list($prefix, $dirname) = $this->getPrefixAndPath($dirname); + + return $this->getFilesystem($prefix)->deleteDir($dirname); + } + + /** + * Create a directory. + * + * @param string $dirname The name of the new directory. + * @param array $config An optional configuration array. + * + * @return bool True on success, false on failure. + */ + public function createDir($dirname, array $config = []) + { + list($prefix, $dirname) = $this->getPrefixAndPath($dirname); + + return $this->getFilesystem($prefix)->createDir($dirname); + } + + /** + * Set the visibility for a file. + * + * @param string $path The path to the file. + * @param string $visibility One of 'public' or 'private'. + * + * @throws FileNotFoundException + * + * @return bool True on success, false on failure. + */ + public function setVisibility($path, $visibility) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->setVisibility($path, $visibility); + } + + /** + * Create a file or update if exists. + * + * @param string $path The path to the file. + * @param string $contents The file contents. + * @param array $config An optional configuration array. + * + * @return bool True on success, false on failure. + */ + public function put($path, $contents, array $config = []) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->put($path, $contents, $config); + } + + /** + * Create a file or update if exists. + * + * @param string $path The path to the file. + * @param resource $resource The file handle. + * @param array $config An optional configuration array. + * + * @throws InvalidArgumentException Thrown if $resource is not a resource. + * + * @return bool True on success, false on failure. + */ + public function putStream($path, $resource, array $config = []) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->putStream($path, $resource, $config); + } + + /** + * Read and delete a file. + * + * @param string $path The path to the file. + * + * @throws FileNotFoundException + * + * @return string|false The file contents, or false on failure. + */ + public function readAndDelete($path) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->readAndDelete($path); + } + + /** + * Get a file/directory handler. + * + * @deprecated + * + * @param string $path The path to the file. + * @param Handler $handler An optional existing handler to populate. + * + * @return Handler Either a file or directory handler. + */ + public function get($path, Handler $handler = null) + { + list($prefix, $path) = $this->getPrefixAndPath($path); + + return $this->getFilesystem($prefix)->get($path); + } +} diff --git a/vendor/league/flysystem/src/NotSupportedException.php b/vendor/league/flysystem/src/NotSupportedException.php new file mode 100644 index 0000000..08f47f7 --- /dev/null +++ b/vendor/league/flysystem/src/NotSupportedException.php @@ -0,0 +1,37 @@ +getPathname()); + } + + /** + * Create a new exception for a link. + * + * @param string $systemType + * + * @return static + */ + public static function forFtpSystemType($systemType) + { + $message = "The FTP system type '$systemType' is currently not supported."; + + return new static($message); + } +} diff --git a/vendor/league/flysystem/src/Plugin/AbstractPlugin.php b/vendor/league/flysystem/src/Plugin/AbstractPlugin.php new file mode 100644 index 0000000..0d56789 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/AbstractPlugin.php @@ -0,0 +1,24 @@ +filesystem = $filesystem; + } +} diff --git a/vendor/league/flysystem/src/Plugin/EmptyDir.php b/vendor/league/flysystem/src/Plugin/EmptyDir.php new file mode 100644 index 0000000..b5ae7f5 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/EmptyDir.php @@ -0,0 +1,34 @@ +filesystem->listContents($dirname, false); + + foreach ($listing as $item) { + if ($item['type'] === 'dir') { + $this->filesystem->deleteDir($item['path']); + } else { + $this->filesystem->delete($item['path']); + } + } + } +} diff --git a/vendor/league/flysystem/src/Plugin/ForcedCopy.php b/vendor/league/flysystem/src/Plugin/ForcedCopy.php new file mode 100644 index 0000000..a41e9f3 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/ForcedCopy.php @@ -0,0 +1,44 @@ +filesystem->delete($newpath); + } catch (FileNotFoundException $e) { + // The destination path does not exist. That's ok. + $deleted = true; + } + + if ($deleted) { + return $this->filesystem->copy($path, $newpath); + } + + return false; + } +} diff --git a/vendor/league/flysystem/src/Plugin/ForcedRename.php b/vendor/league/flysystem/src/Plugin/ForcedRename.php new file mode 100644 index 0000000..3f51cd6 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/ForcedRename.php @@ -0,0 +1,44 @@ +filesystem->delete($newpath); + } catch (FileNotFoundException $e) { + // The destination path does not exist. That's ok. + $deleted = true; + } + + if ($deleted) { + return $this->filesystem->rename($path, $newpath); + } + + return false; + } +} diff --git a/vendor/league/flysystem/src/Plugin/GetWithMetadata.php b/vendor/league/flysystem/src/Plugin/GetWithMetadata.php new file mode 100644 index 0000000..6fe4f05 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/GetWithMetadata.php @@ -0,0 +1,51 @@ +filesystem->getMetadata($path); + + if ( ! $object) { + return false; + } + + $keys = array_diff($metadata, array_keys($object)); + + foreach ($keys as $key) { + if ( ! method_exists($this->filesystem, $method = 'get' . ucfirst($key))) { + throw new InvalidArgumentException('Could not fetch metadata: ' . $key); + } + + $object[$key] = $this->filesystem->{$method}($path); + } + + return $object; + } +} diff --git a/vendor/league/flysystem/src/Plugin/ListFiles.php b/vendor/league/flysystem/src/Plugin/ListFiles.php new file mode 100644 index 0000000..9669fe7 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/ListFiles.php @@ -0,0 +1,35 @@ +filesystem->listContents($directory, $recursive); + + $filter = function ($object) { + return $object['type'] === 'file'; + }; + + return array_values(array_filter($contents, $filter)); + } +} diff --git a/vendor/league/flysystem/src/Plugin/ListPaths.php b/vendor/league/flysystem/src/Plugin/ListPaths.php new file mode 100644 index 0000000..514bdf0 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/ListPaths.php @@ -0,0 +1,36 @@ +filesystem->listContents($directory, $recursive); + + foreach ($contents as $object) { + $result[] = $object['path']; + } + + return $result; + } +} diff --git a/vendor/league/flysystem/src/Plugin/ListWith.php b/vendor/league/flysystem/src/Plugin/ListWith.php new file mode 100644 index 0000000..d90464e --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/ListWith.php @@ -0,0 +1,60 @@ +filesystem->listContents($directory, $recursive); + + foreach ($contents as $index => $object) { + if ($object['type'] === 'file') { + $missingKeys = array_diff($keys, array_keys($object)); + $contents[$index] = array_reduce($missingKeys, [$this, 'getMetadataByName'], $object); + } + } + + return $contents; + } + + /** + * Get a meta-data value by key name. + * + * @param array $object + * @param string $key + * + * @return array + */ + protected function getMetadataByName(array $object, $key) + { + $method = 'get' . ucfirst($key); + + if ( ! method_exists($this->filesystem, $method)) { + throw new \InvalidArgumentException('Could not get meta-data for key: ' . $key); + } + + $object[$key] = $this->filesystem->{$method}($object['path']); + + return $object; + } +} diff --git a/vendor/league/flysystem/src/Plugin/PluggableTrait.php b/vendor/league/flysystem/src/Plugin/PluggableTrait.php new file mode 100644 index 0000000..922edfe --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/PluggableTrait.php @@ -0,0 +1,97 @@ +plugins[$plugin->getMethod()] = $plugin; + + return $this; + } + + /** + * Find a specific plugin. + * + * @param string $method + * + * @throws PluginNotFoundException + * + * @return PluginInterface + */ + protected function findPlugin($method) + { + if ( ! isset($this->plugins[$method])) { + throw new PluginNotFoundException('Plugin not found for method: ' . $method); + } + + return $this->plugins[$method]; + } + + /** + * Invoke a plugin by method name. + * + * @param string $method + * @param array $arguments + * @param FilesystemInterface $filesystem + * + * @throws PluginNotFoundException + * + * @return mixed + */ + protected function invokePlugin($method, array $arguments, FilesystemInterface $filesystem) + { + $plugin = $this->findPlugin($method); + $plugin->setFilesystem($filesystem); + $callback = [$plugin, 'handle']; + + return call_user_func_array($callback, $arguments); + } + + /** + * Plugins pass-through. + * + * @param string $method + * @param array $arguments + * + * @throws BadMethodCallException + * + * @return mixed + */ + public function __call($method, array $arguments) + { + try { + return $this->invokePlugin($method, $arguments, $this); + } catch (PluginNotFoundException $e) { + throw new BadMethodCallException( + 'Call to undefined method ' + . get_class($this) + . '::' . $method + ); + } + } +} diff --git a/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php b/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php new file mode 100644 index 0000000..fd1d7e7 --- /dev/null +++ b/vendor/league/flysystem/src/Plugin/PluginNotFoundException.php @@ -0,0 +1,10 @@ +hash = spl_object_hash($this); + static::$safeStorage[$this->hash] = []; + } + + public function storeSafely($key, $value) + { + static::$safeStorage[$this->hash][$key] = $value; + } + + public function retrieveSafely($key) + { + if (array_key_exists($key, static::$safeStorage[$this->hash])) { + return static::$safeStorage[$this->hash][$key]; + } + } + + public function __destruct() + { + unset(static::$safeStorage[$this->hash]); + } +} diff --git a/vendor/league/flysystem/src/UnreadableFileException.php b/vendor/league/flysystem/src/UnreadableFileException.php new file mode 100644 index 0000000..e668033 --- /dev/null +++ b/vendor/league/flysystem/src/UnreadableFileException.php @@ -0,0 +1,18 @@ +getRealPath() + ) + ); + } +} diff --git a/vendor/league/flysystem/src/Util.php b/vendor/league/flysystem/src/Util.php new file mode 100644 index 0000000..2c77540 --- /dev/null +++ b/vendor/league/flysystem/src/Util.php @@ -0,0 +1,349 @@ + '']; + } + + /** + * Normalize a dirname return value. + * + * @param string $dirname + * + * @return string normalized dirname + */ + public static function normalizeDirname($dirname) + { + return $dirname === '.' ? '' : $dirname; + } + + /** + * Get a normalized dirname from a path. + * + * @param string $path + * + * @return string dirname + */ + public static function dirname($path) + { + return static::normalizeDirname(dirname($path)); + } + + /** + * Map result arrays. + * + * @param array $object + * @param array $map + * + * @return array mapped result + */ + public static function map(array $object, array $map) + { + $result = []; + + foreach ($map as $from => $to) { + if ( ! isset($object[$from])) { + continue; + } + + $result[$to] = $object[$from]; + } + + return $result; + } + + /** + * Normalize path. + * + * @param string $path + * + * @throws LogicException + * + * @return string + */ + public static function normalizePath($path) + { + return static::normalizeRelativePath($path); + } + + /** + * Normalize relative directories in a path. + * + * @param string $path + * + * @throws LogicException + * + * @return string + */ + public static function normalizeRelativePath($path) + { + $path = str_replace('\\', '/', $path); + $path = static::removeFunkyWhiteSpace($path); + + $parts = []; + + foreach (explode('/', $path) as $part) { + switch ($part) { + case '': + case '.': + break; + + case '..': + if (empty($parts)) { + throw new LogicException( + 'Path is outside of the defined root, path: [' . $path . ']' + ); + } + array_pop($parts); + break; + + default: + $parts[] = $part; + break; + } + } + + return implode('/', $parts); + } + + /** + * Removes unprintable characters and invalid unicode characters. + * + * @param string $path + * + * @return string $path + */ + protected static function removeFunkyWhiteSpace($path) + { + // We do this check in a loop, since removing invalid unicode characters + // can lead to new characters being created. + while (preg_match('#\p{C}+|^\./#u', $path)) { + $path = preg_replace('#\p{C}+|^\./#u', '', $path); + } + + return $path; + } + + /** + * Normalize prefix. + * + * @param string $prefix + * @param string $separator + * + * @return string normalized path + */ + public static function normalizePrefix($prefix, $separator) + { + return rtrim($prefix, $separator) . $separator; + } + + /** + * Get content size. + * + * @param string $contents + * + * @return int content size + */ + public static function contentSize($contents) + { + return defined('MB_OVERLOAD_STRING') ? mb_strlen($contents, '8bit') : strlen($contents); + } + + /** + * Guess MIME Type based on the path of the file and it's content. + * + * @param string $path + * @param string|resource $content + * + * @return string|null MIME Type or NULL if no extension detected + */ + public static function guessMimeType($path, $content) + { + $mimeType = MimeType::detectByContent($content); + + if ( ! (empty($mimeType) || in_array($mimeType, ['application/x-empty', 'text/plain', 'text/x-asm']))) { + return $mimeType; + } + + return MimeType::detectByFilename($path); + } + + /** + * Emulate directories. + * + * @param array $listing + * + * @return array listing with emulated directories + */ + public static function emulateDirectories(array $listing) + { + $directories = []; + $listedDirectories = []; + + foreach ($listing as $object) { + list($directories, $listedDirectories) = static::emulateObjectDirectories($object, $directories, $listedDirectories); + } + + $directories = array_diff(array_unique($directories), array_unique($listedDirectories)); + + foreach ($directories as $directory) { + $listing[] = static::pathinfo($directory) + ['type' => 'dir']; + } + + return $listing; + } + + /** + * Ensure a Config instance. + * + * @param null|array|Config $config + * + * @return Config config instance + * + * @throw LogicException + */ + public static function ensureConfig($config) + { + if ($config === null) { + return new Config(); + } + + if ($config instanceof Config) { + return $config; + } + + if (is_array($config)) { + return new Config($config); + } + + throw new LogicException('A config should either be an array or a Flysystem\Config object.'); + } + + /** + * Rewind a stream. + * + * @param resource $resource + */ + public static function rewindStream($resource) + { + if (ftell($resource) !== 0 && static::isSeekableStream($resource)) { + rewind($resource); + } + } + + public static function isSeekableStream($resource) + { + $metadata = stream_get_meta_data($resource); + + return $metadata['seekable']; + } + + /** + * Get the size of a stream. + * + * @param resource $resource + * + * @return int stream size + */ + public static function getStreamSize($resource) + { + $stat = fstat($resource); + + return $stat['size']; + } + + /** + * Emulate the directories of a single object. + * + * @param array $object + * @param array $directories + * @param array $listedDirectories + * + * @return array + */ + protected static function emulateObjectDirectories(array $object, array $directories, array $listedDirectories) + { + if ($object['type'] === 'dir') { + $listedDirectories[] = $object['path']; + } + + if (empty($object['dirname'])) { + return [$directories, $listedDirectories]; + } + + $parent = $object['dirname']; + + while ( ! empty($parent) && ! in_array($parent, $directories)) { + $directories[] = $parent; + $parent = static::dirname($parent); + } + + if (isset($object['type']) && $object['type'] === 'dir') { + $listedDirectories[] = $object['path']; + + return [$directories, $listedDirectories]; + } + + return [$directories, $listedDirectories]; + } + + /** + * Returns the trailing name component of the path. + * + * @param string $path + * + * @return string + */ + private static function basename($path) + { + $separators = DIRECTORY_SEPARATOR === '/' ? '/' : '\/'; + + $path = rtrim($path, $separators); + + $basename = preg_replace('#.*?([^' . preg_quote($separators, '#') . ']+$)#', '$1', $path); + + if (DIRECTORY_SEPARATOR === '/') { + return $basename; + } + // @codeCoverageIgnoreStart + // Extra Windows path munging. This is tested via AppVeyor, but code + // coverage is not reported. + + // Handle relative paths with drive letters. c:file.txt. + while (preg_match('#^[a-zA-Z]{1}:[^\\\/]#', $basename)) { + $basename = substr($basename, 2); + } + + // Remove colon for standalone drive letter names. + if (preg_match('#^[a-zA-Z]{1}:$#', $basename)) { + $basename = rtrim($basename, ':'); + } + + return $basename; + // @codeCoverageIgnoreEnd + } +} diff --git a/vendor/league/flysystem/src/Util/ContentListingFormatter.php b/vendor/league/flysystem/src/Util/ContentListingFormatter.php new file mode 100644 index 0000000..ae0d3b9 --- /dev/null +++ b/vendor/league/flysystem/src/Util/ContentListingFormatter.php @@ -0,0 +1,122 @@ +directory = rtrim($directory, '/'); + $this->recursive = $recursive; + $this->caseSensitive = $caseSensitive; + } + + /** + * Format contents listing. + * + * @param array $listing + * + * @return array + */ + public function formatListing(array $listing) + { + $listing = array_filter(array_map([$this, 'addPathInfo'], $listing), [$this, 'isEntryOutOfScope']); + + return $this->sortListing(array_values($listing)); + } + + private function addPathInfo(array $entry) + { + return $entry + Util::pathinfo($entry['path']); + } + + /** + * Determine if the entry is out of scope. + * + * @param array $entry + * + * @return bool + */ + private function isEntryOutOfScope(array $entry) + { + if (empty($entry['path']) && $entry['path'] !== '0') { + return false; + } + + if ($this->recursive) { + return $this->residesInDirectory($entry); + } + + return $this->isDirectChild($entry); + } + + /** + * Check if the entry resides within the parent directory. + * + * @param array $entry + * + * @return bool + */ + private function residesInDirectory(array $entry) + { + if ($this->directory === '') { + return true; + } + + return $this->caseSensitive + ? strpos($entry['path'], $this->directory . '/') === 0 + : stripos($entry['path'], $this->directory . '/') === 0; + } + + /** + * Check if the entry is a direct child of the directory. + * + * @param array $entry + * + * @return bool + */ + private function isDirectChild(array $entry) + { + return $this->caseSensitive + ? $entry['dirname'] === $this->directory + : strcasecmp($this->directory, $entry['dirname']) === 0; + } + + /** + * @param array $listing + * + * @return array + */ + private function sortListing(array $listing) + { + usort($listing, function ($a, $b) { + return strcasecmp($a['path'], $b['path']); + }); + + return $listing; + } +} diff --git a/vendor/league/flysystem/src/Util/MimeType.php b/vendor/league/flysystem/src/Util/MimeType.php new file mode 100644 index 0000000..a4bd5e2 --- /dev/null +++ b/vendor/league/flysystem/src/Util/MimeType.php @@ -0,0 +1,245 @@ + 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'csv' => 'text/csv', + 'bin' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'class' => 'application/octet-stream', + 'psd' => 'application/x-photoshop', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/pdf', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'xlt' => 'application/vnd.ms-excel', + 'xla' => 'application/vnd.ms-excel', + 'ppt' => 'application/powerpoint', + 'pot' => 'application/vnd.ms-powerpoint', + 'pps' => 'application/vnd.ms-powerpoint', + 'ppa' => 'application/vnd.ms-powerpoint', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'potm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'z' => 'application/x-compress', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'rdf' => 'application/rdf+xml', + 'zip' => 'application/x-zip', + 'rar' => 'application/x-rar', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => 'audio/x-wav', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'application/xml', + 'xsl' => 'application/xml', + 'dmn' => 'application/octet-stream', + 'bpmn' => 'application/octet-stream', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'docm' => 'application/vnd.ms-word.template.macroEnabled.12', + 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', + 'dot' => 'application/msword', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', + 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'word' => 'application/msword', + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => 'application/json', + 'pem' => 'application/x-x509-user-cert', + 'p10' => 'application/x-pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'crt' => 'application/x-x509-ca-cert', + 'crl' => 'application/pkix-crl', + 'der' => 'application/x-x509-ca-cert', + 'kdb' => 'application/octet-stream', + 'pgp' => 'application/pgp', + 'gpg' => 'application/gpg-keys', + 'sst' => 'application/octet-stream', + 'csr' => 'application/octet-stream', + 'rsa' => 'application/x-pkcs7', + 'cer' => 'application/pkix-cert', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gp', + 'mp4' => 'video/mp4', + 'm4a' => 'audio/x-m4a', + 'f4v' => 'video/mp4', + 'webm' => 'video/webm', + 'aac' => 'audio/x-acc', + 'm4u' => 'application/vnd.mpegurl', + 'm3u' => 'text/plain', + 'xspf' => 'application/xspf+xml', + 'vlc' => 'application/videolan', + 'wmv' => 'video/x-ms-wmv', + 'au' => 'audio/x-au', + 'ac3' => 'audio/ac3', + 'flac' => 'audio/x-flac', + 'ogg' => 'audio/ogg', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'ics' => 'text/calendar', + 'zsh' => 'text/x-scriptzsh', + '7zip' => 'application/x-7z-compressed', + 'cdr' => 'application/cdr', + 'wma' => 'audio/x-ms-wma', + 'jar' => 'application/java-archive', + 'tex' => 'application/x-tex', + 'latex' => 'application/x-latex', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + ]; + + /** + * Detects MIME Type based on given content. + * + * @param mixed $content + * + * @return string|null MIME Type or NULL if no mime type detected + */ + public static function detectByContent($content) + { + if ( ! class_exists('finfo') || ! is_string($content)) { + return null; + } + try { + $finfo = new finfo(FILEINFO_MIME_TYPE); + + return $finfo->buffer($content) ?: null; + // @codeCoverageIgnoreStart + } catch (ErrorException $e) { + // This is caused by an array to string conversion error. + } + } // @codeCoverageIgnoreEnd + + /** + * Detects MIME Type based on file extension. + * + * @param string $extension + * + * @return string|null MIME Type or NULL if no extension detected + */ + public static function detectByFileExtension($extension) + { + return isset(static::$extensionToMimeTypeMap[$extension]) + ? static::$extensionToMimeTypeMap[$extension] + : 'text/plain'; + } + + /** + * @param string $filename + * + * @return string|null MIME Type or NULL if no extension detected + */ + public static function detectByFilename($filename) + { + $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + + return empty($extension) ? 'text/plain' : static::detectByFileExtension($extension); + } + + /** + * @return array Map of file extension to MIME Type + */ + public static function getExtensionToMimeTypeMap() + { + return static::$extensionToMimeTypeMap; + } +} diff --git a/vendor/league/flysystem/src/Util/StreamHasher.php b/vendor/league/flysystem/src/Util/StreamHasher.php new file mode 100644 index 0000000..938ec5d --- /dev/null +++ b/vendor/league/flysystem/src/Util/StreamHasher.php @@ -0,0 +1,36 @@ +algo = $algo; + } + + /** + * @param resource $resource + * + * @return string + */ + public function hash($resource) + { + rewind($resource); + $context = hash_init($this->algo); + hash_update_stream($context, $resource); + fclose($resource); + + return hash_final($context); + } +} diff --git a/vendor/opis/closure/CHANGELOG.md b/vendor/opis/closure/CHANGELOG.md new file mode 100644 index 0000000..f3d663f --- /dev/null +++ b/vendor/opis/closure/CHANGELOG.md @@ -0,0 +1,207 @@ +CHANGELOG +--------- + +### v3.4.1, 2019.10.19 + +- Fixed a [bug](https://github.com/opis/closure/issues/40) that prevented serialization to work correctly. + +### v3.4.0, 2019.09.03 + +- Added `createClosure` static method in `Opis\Closure\SerializableClosure`. +This method creates a new closure from arbitrary code, emulating `create_function`, +but without using eval + +### v3.3.1, 2019.07.10 + +- Use `sha1` instead of `md5` for hashing file names in `Opis\Closure\ReflectionClosure` class + +### v3.3.0, 2019.05.31 + +- Fixed a bug that prevented signed closures to properly work when the serialized string +contains invalid UTF-8 chars. Starting with this version `json_encode` is no longer used +when signing a closure. Backward compatibility is maintained and all closures that were +previously signed using the old method will continue to work. + +### v3.2.0, 2019.05.05 + +- Since an unsigned closure can be unserialized when no security provider is set, +there is no reason to treat differently a signed closure in the same situation. +Therefore, the `Opis\Closure\SecurityException` exception is no longer thrown when +unserializing a signed closure, if no security provider is set. + +### v3.1.6, 2019.02.22 + +- Fixed a bug that occurred when trying to set properties of classes that were not defined in user-land. +Those properties are now ignored. + +### v3.1.5, 2019.01.14 + +- Improved parser + +### v3.1.4, 2019.01.14 + +- Added support for static methods that are named using PHP keywords or magic constants. +Ex: `A::new()`, `A::use()`, `A::if()`, `A::function()`, `A::__DIR__()`, etc. +- Used `@internal` to mark classes & methods that are for internal use only and +backward compatibility is not guaranteed. + +### v3.1.3, 2019.01.07 + +- Fixed a bug that prevented traits to be correctly resolved when used by an +anonymous class +- Fixed a bug that occurred when `$this` keyword was used inside an anonymous class + +### v3.1.2, 2018.12.16 + +* Fixed a bug regarding comma trail in group-use statements. See [issue 23](https://github.com/opis/closure/issues/23) + +### v3.1.1, 2018.10.02 + +* Fixed a bug where `parent` keyword was treated like a class-name and scope was not added to the +serialized closure +* Fixed a bug where return type was not properly handled for nested closures +* Support for anonymous classes was improved + +### v3.1.0, 2018.09.20 + +* Added `transformUseVariables` and `resolveUseVariables` to +`Opis\Closure\SerializableClosure` class. +* Added `removeSecurityProvider` static method to +`Opis\Closure\SerializableClosure` class. +* Fixed some security related issues where a user was able to unserialize an unsigned +closure, even when a security provider was in use. + +### v3.0.12, 2018.02.23 + +* Bugfix. See [issue 20](https://github.com/opis/closure/issues/20) + +### v3.0.11, 2018.01.22 + +* Bugfix. See [issue 18](https://github.com/opis/closure/issues/18) + +### v3.0.10, 2018.01.04 + +* Improved support for PHP 7.1 & 7.2 + +### v3.0.9, 2018.01.04 + +* Fixed a bug where the return type was not properly resolved. +See [issue 17](https://github.com/opis/closure/issues/17) +* Added more tests + +### v3.0.8, 2017.12.18 + +* Fixed a bug. See [issue 16](https://github.com/opis/closure/issues/16) + +### v3.0.7, 2017.10.31 + +* Bugfix: static properties are ignored now, since they are not serializable + +### v3.0.6, 2017.10.06 + +* Fixed a bug introduced by accident in 3.0.5 + +### v3.0.5, 2017.09.18 + +* Fixed a bug related to nested references + +### v3.0.4, 2017.09.18 + +* \[*internal*\] Refactored `SerializableClosure::mapPointers` method +* \[*internal*\] Added a new optional argument to `SerializableClosure::unwrapClosures` +* \[*internal*\] Removed `SerializableClosure::getClosurePointer` method +* Fixed various bugs + +### v3.0.3, 2017.09.06 + +* Fixed a bug related to nested object references +* \[*internal*\] `Opis\Closure\ClosureScope` now extends `SplObjectStorage` +* \[*internal*\] The `storage` property was removed from `Opis\Closure\ClosureScope` +* \[*internal*\] The `instances` and `objects` properties were removed from `Opis\Closure\ClosureContext` + +### v3.0.2, 2017.08.28 + +* Fixed a bug where `$this` object was not handled properly inside the +`SerializableClosre::serialize` method. + +### v3.0.1, 2017.04.13 + +* Fixed a bug in 'ignore_next' state + +### v3.0.0, 2017.04.07 + +* Dropped PHP 5.3 support +* Moved source files from `lib` to `src` folder +* Removed second parameter from `Opis\Closure\SerializableClosure::from` method and from constructor +* Removed `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` classes +* Refactored how signed closures were handled +* Added `wrapClosures` and `unwrapClosures` static methods to `Opis\Closure\SerializableClosure` class +* Added `Opis\Colosure\serialize` and `Opis\Closure\unserialize` functions +* Improved serialization. You can now serialize arbitrary objects and the library will automatically wrap all closures + +### v2.4.0, 2016.12.16 + +* The parser was refactored and improved +* Refactored `Opis\Closure\SerializableClosure::__invoke` method +* `Opis\Closure\{ISecurityProvider, SecurityProvider}` were added +* `Opis\Closure\{SecurityProviderInterface, DefaultSecurityProvider, SecureClosure}` were deprecated +and they will be removed in the next major version +* `setSecretKey` and `addSecurityProvider` static methods were added to `Opis\Closure\SerializableClosure` + +### v2.3.2, 2016.12.15 + +* Fixed a bug that prevented namespace resolution to be done properly + +### v2.3.1, 2016.12.13 + +* Hotfix. See [PR](https://github.com/opis/closure/pull/7) + +### v2.3.0, 2016.11.17 + +* Added `isBindingRequired` and `isScopeRequired` to the `Opis\Closure\ReflectionClosure` class +* Automatically detects when the scope and/or the bound object of a closure needs to be serialized. + +### v2.2.1, 2016.08.20 + +* Fixed a bug in `Opis\Closure\ReflectionClosure::fetchItems` + +### v2.2.0, 2016.07.26 + +* Fixed CS +* `Opis\Closure\ClosureContext`, `Opis\Closure\ClosureScope`, `Opis\Closure\SelfReference` + and `Opis\Closure\SecurityException` classes were moved into separate files +* Added support for PHP7 syntax +* Fixed some bugs in `Opis\Closure\ReflectionClosure` class +* Improved closure parser +* Added an analyzer for SuperClosure library + +### v2.1.0, 2015.09.30 + +* Added support for the missing `__METHOD__`, `__FUNCTION__` and `__TRAIT__` magic constants +* Added some security related classes and interfaces: `Opis\Closure\SecurityProviderInterface`, +`Opis\Closure\DefaultSecurityProvider`, `Opis\Closure\SecureClosure`, `Opis\Closure\SecurityException`. +* Fiexed a bug in `Opis\Closure\ReflectionClosure::getClasses` method +* Other minor bugfixes +* Added support for static closures +* Added public `isStatic` method to `Opis\Closure\ReflectionClosure` class + + +### v2.0.1, 2015.09.23 + +* Removed `branch-alias` property from `composer.json` +* Bugfix. See [issue #6](https://github.com/opis/closure/issues/6) + +### v2.0.0, 2015.07.31 + +* The closure parser was improved +* Class names are now automatically resolved +* Added support for the `#trackme` directive which allows tracking closure's residing source + +### v1.3.0, 2014.10.18 + +* Added autoload file +* Changed README file + +### Opis Closure 1.2.2 + +* Started changelog diff --git a/vendor/opis/closure/LICENSE b/vendor/opis/closure/LICENSE new file mode 100644 index 0000000..9c0a19b --- /dev/null +++ b/vendor/opis/closure/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018-2019 Zindex Software + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/opis/closure/NOTICE b/vendor/opis/closure/NOTICE new file mode 100644 index 0000000..ae5caa6 --- /dev/null +++ b/vendor/opis/closure/NOTICE @@ -0,0 +1,9 @@ +Opis Closure +Copyright 2018-2019 Zindex Software + +This product includes software developed at +Zindex Software (http://zindex.software). + +This software was originally developed by Marius Sarca and Sorin Sarca +(Copyright 2014-2018). The copyright info was changed with the permission +of the original authors. \ No newline at end of file diff --git a/vendor/opis/closure/README.md b/vendor/opis/closure/README.md new file mode 100644 index 0000000..75b319a --- /dev/null +++ b/vendor/opis/closure/README.md @@ -0,0 +1,98 @@ +Opis Closure +==================== +[![Build Status](https://travis-ci.org/opis/closure.png)](https://travis-ci.org/opis/closure) +[![Latest Stable Version](https://poser.pugx.org/opis/closure/v/stable.png)](https://packagist.org/packages/opis/closure) +[![Latest Unstable Version](https://poser.pugx.org/opis/closure/v/unstable.png)](https://packagist.org/packages/opis/closure) +[![License](https://poser.pugx.org/opis/closure/license.png)](https://packagist.org/packages/opis/closure) + +Serializable closures +--------------------- +**Opis Closure** is a library that aims to overcome PHP's limitations regarding closure +serialization by providing a wrapper that will make all closures serializable. + +**The library's key features:** + +- Serialize any closure +- Serialize arbitrary objects +- Doesn't use `eval` for closure serialization or unserialization +- Works with any PHP version that has support for closures +- Supports PHP 7 syntax +- Handles all variables referenced/imported in `use()` and automatically wraps all referenced/imported closures for +proper serialization +- Handles recursive closures +- Handles magic constants like `__FILE__`, `__DIR__`, `__LINE__`, `__NAMESPACE__`, `__CLASS__`, +`__TRAIT__`, `__METHOD__` and `__FUNCTION__`. +- Automatically resolves all class names, function names and constant names used inside the closure +- Track closure's residing source by using the `#trackme` directive +- Simple and very fast parser +- Any error or exception, that might occur when executing an unserialized closure, can be caught and treated properly +- You can serialize/unserialize any closure unlimited times, even those previously unserialized +(this is possible because `eval()` is not used for unserialization) +- Handles static closures +- Supports cryptographically signed closures +- Provides a reflector that can give you information about the serialized closure +- Provides an analyzer for *SuperClosure* library +- Automatically detects when the scope and/or the bound object of a closure needs to be serialized +in order for the closure to work after deserialization + +### Documentation + +The full documentation for this library can be found [here][documentation]. + +### License + +**Opis Closure** is licensed under the [MIT License (MIT)][license]. + +### Requirements + +* PHP ^5.4 || ^7.0 + +## Installation + +**Opis Closure** is available on [Packagist] and it can be installed from a +command line interface by using [Composer]. + +```bash +composer require opis/closure +``` + +Or you could directly reference it into your `composer.json` file as a dependency + +```json +{ + "require": { + "opis/closure": "^3.4" + } +} +``` + +### Migrating from 2.x + +If your project needs to support PHP 5.3 you can continue using the `2.x` version +of **Opis Closure**. Otherwise, assuming you are not using one of the removed/refactored classes or features(see +[CHANGELOG]), migrating to version `3.x` is simply a matter of updating your `composer.json` file. + +### Semantic versioning + +**Opis Closure** follows [semantic versioning][SemVer] specifications. + +### Arbitrary object serialization + +This feature was primarily introduced in order to support serializing an object bound +to a closure and available via `$this`. The implementation is far from being perfect +and it's really hard to make it work flawless. I will try to improve this, but I can +not guarantee anything. So my advice regarding the `Opis\Closure\serialize|unserialize` +functions is to use them with caution. + +### SuperClosure support + +**Opis Closure** is shipped with an analyzer(`Opis\Closure\Analyzer`) which +aims to provide *Opis Closure*'s parsing precision and speed to [SuperClosure]. + +[documentation]: https://www.opis.io/closure "Opis Closure" +[license]: http://opensource.org/licenses/MIT "MIT License" +[Packagist]: https://packagist.org/packages/opis/closure "Packagist" +[Composer]: https://getcomposer.org "Composer" +[SuperClosure]: https://github.com/jeremeamia/super_closure "SuperClosure" +[SemVer]: http://semver.org/ "Semantic versioning" +[CHANGELOG]: https://github.com/opis/closure/blob/master/CHANGELOG.md "Changelog" \ No newline at end of file diff --git a/vendor/opis/closure/autoload.php b/vendor/opis/closure/autoload.php new file mode 100644 index 0000000..a928014 --- /dev/null +++ b/vendor/opis/closure/autoload.php @@ -0,0 +1,39 @@ +getClosureScopeClass(); + + $data = [ + 'reflection' => $reflection, + 'code' => $reflection->getCode(), + 'hasThis' => $reflection->isBindingRequired(), + 'context' => $reflection->getUseVariables(), + 'hasRefs' => false, + 'binding' => $reflection->getClosureThis(), + 'scope' => $scope ? $scope->getName() : null, + 'isStatic' => $reflection->isStatic(), + ]; + + return $data; + } + + /** + * @param array $data + * @return mixed + */ + protected function determineCode(array &$data) + { + return null; + } + + /** + * @param array $data + * @return mixed + */ + protected function determineContext(array &$data) + { + return null; + } + +} diff --git a/vendor/opis/closure/src/ClosureContext.php b/vendor/opis/closure/src/ClosureContext.php new file mode 100644 index 0000000..d68cf98 --- /dev/null +++ b/vendor/opis/closure/src/ClosureContext.php @@ -0,0 +1,34 @@ +scope = new ClosureScope(); + $this->locks = 0; + } +} \ No newline at end of file diff --git a/vendor/opis/closure/src/ClosureScope.php b/vendor/opis/closure/src/ClosureScope.php new file mode 100644 index 0000000..71ad414 --- /dev/null +++ b/vendor/opis/closure/src/ClosureScope.php @@ -0,0 +1,25 @@ +content = "length = strlen($this->content); + return true; + } + + public function stream_read($count) + { + $value = substr($this->content, $this->pointer, $count); + $this->pointer += $count; + return $value; + } + + public function stream_eof() + { + return $this->pointer >= $this->length; + } + + public function stream_stat() + { + $stat = stat(__FILE__); + $stat[7] = $stat['size'] = $this->length; + return $stat; + } + + public function url_stat($path, $flags) + { + $stat = stat(__FILE__); + $stat[7] = $stat['size'] = $this->length; + return $stat; + } + + public function stream_seek($offset, $whence = SEEK_SET) + { + $crt = $this->pointer; + + switch ($whence) { + case SEEK_SET: + $this->pointer = $offset; + break; + case SEEK_CUR: + $this->pointer += $offset; + break; + case SEEK_END: + $this->pointer = $this->length + $offset; + break; + } + + if ($this->pointer < 0 || $this->pointer >= $this->length) { + $this->pointer = $crt; + return false; + } + + return true; + } + + public function stream_tell() + { + return $this->pointer; + } + + public static function register() + { + if (!static::$isRegistered) { + static::$isRegistered = stream_wrapper_register(static::STREAM_PROTO, __CLASS__); + } + } + +} diff --git a/vendor/opis/closure/src/ISecurityProvider.php b/vendor/opis/closure/src/ISecurityProvider.php new file mode 100644 index 0000000..d3b0a29 --- /dev/null +++ b/vendor/opis/closure/src/ISecurityProvider.php @@ -0,0 +1,25 @@ +code = $code; + parent::__construct($closure); + } + + /** + * @return bool + */ + public function isStatic() + { + if ($this->isStaticClosure === null) { + $this->isStaticClosure = strtolower(substr($this->getCode(), 0, 6)) === 'static'; + } + + return $this->isStaticClosure; + } + + /** + * @return string + */ + public function getCode() + { + if($this->code !== null){ + return $this->code; + } + + $fileName = $this->getFileName(); + $line = $this->getStartLine() - 1; + + $match = ClosureStream::STREAM_PROTO . '://'; + + if ($line === 1 && substr($fileName, 0, strlen($match)) === $match) { + return $this->code = substr($fileName, strlen($match)); + } + + $className = null; + + + if (null !== $className = $this->getClosureScopeClass()) { + $className = '\\' . trim($className->getName(), '\\'); + } + + + if($php7 = PHP_MAJOR_VERSION === 7){ + switch (PHP_MINOR_VERSION){ + case 0: + $php7_types = array('string', 'int', 'bool', 'float'); + break; + case 1: + $php7_types = array('string', 'int', 'bool', 'float', 'void'); + break; + case 2: + default: + $php7_types = array('string', 'int', 'bool', 'float', 'void', 'object'); + } + } + + $ns = $this->getNamespaceName(); + $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\' . $ns); + + $_file = var_export($fileName, true); + $_dir = var_export(dirname($fileName), true); + $_namespace = var_export($ns, true); + $_class = var_export(trim($className, '\\'), true); + $_function = $ns . ($ns == '' ? '' : '\\') . '{closure}'; + $_method = ($className == '' ? '' : trim($className, '\\') . '::') . $_function; + $_function = var_export($_function, true); + $_method = var_export($_method, true); + $_trait = null; + + $tokens = $this->getTokens(); + $state = $lastState = 'start'; + $inside_anonymous = false; + $anonymous_mark = 0; + $open = 0; + $code = ''; + $id_start = $id_start_ci = $id_name = $context = ''; + $classes = $functions = $constants = null; + $use = array(); + $lineAdd = 0; + $isUsingScope = false; + $isUsingThisObject = false; + + for($i = 0, $l = count($tokens); $i < $l; $i++) { + $token = $tokens[$i]; + switch ($state) { + case 'start': + if ($token[0] === T_FUNCTION || $token[0] === T_STATIC) { + $code .= $token[1]; + $state = $token[0] === T_FUNCTION ? 'function' : 'static'; + } + break; + case 'static': + if ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_FUNCTION) { + $code .= $token[1]; + if ($token[0] === T_FUNCTION) { + $state = 'function'; + } + } else { + $code = ''; + $state = 'start'; + } + break; + case 'function': + switch ($token[0]){ + case T_STRING: + $code = ''; + $state = 'named_function'; + break; + case '(': + $code .= '('; + $state = 'closure_args'; + break; + default: + $code .= is_array($token) ? $token[1] : $token; + } + break; + case 'named_function': + if($token[0] === T_FUNCTION || $token[0] === T_STATIC){ + $code = $token[1]; + $state = $token[0] === T_FUNCTION ? 'function' : 'static'; + } + break; + case 'closure_args': + switch ($token[0]){ + case T_NS_SEPARATOR: + case T_STRING: + $id_start = $token[1]; + $id_start_ci = strtolower($id_start); + $id_name = ''; + $context = 'args'; + $state = 'id_name'; + $lastState = 'closure_args'; + break; + case T_USE: + $code .= $token[1]; + $state = 'use'; + break; + case '=': + $code .= $token; + $lastState = 'closure_args'; + $state = 'ignore_next'; + break; + case ':': + $code .= ':'; + $state = 'return'; + break; + case '{': + $code .= '{'; + $state = 'closure'; + $open++; + break; + default: + $code .= is_array($token) ? $token[1] : $token; + } + break; + case 'use': + switch ($token[0]){ + case T_VARIABLE: + $use[] = substr($token[1], 1); + $code .= $token[1]; + break; + case '{': + $code .= '{'; + $state = 'closure'; + $open++; + break; + case ':': + $code .= ':'; + $state = 'return'; + break; + default: + $code .= is_array($token) ? $token[1] : $token; + break; + } + break; + case 'return': + switch ($token[0]){ + case T_WHITESPACE: + case T_COMMENT: + case T_DOC_COMMENT: + $code .= $token[1]; + break; + case T_NS_SEPARATOR: + case T_STRING: + $id_start = $token[1]; + $id_start_ci = strtolower($id_start); + $id_name = ''; + $context = 'return_type'; + $state = 'id_name'; + $lastState = 'return'; + break 2; + case '{': + $code .= '{'; + $state = 'closure'; + $open++; + break; + default: + $code .= is_array($token) ? $token[1] : $token; + break; + } + break; + case 'closure': + switch ($token[0]){ + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case T_STRING_VARNAME: + case '{': + $code .= '{'; + $open++; + break; + case '}': + $code .= '}'; + if(--$open === 0){ + break 3; + } elseif ($inside_anonymous) { + $inside_anonymous = !($open === $anonymous_mark); + } + break; + case T_LINE: + $code .= $token[2] - $line + $lineAdd; + break; + case T_FILE: + $code .= $_file; + break; + case T_DIR: + $code .= $_dir; + break; + case T_NS_C: + $code .= $_namespace; + break; + case T_CLASS_C: + $code .= $_class; + break; + case T_FUNC_C: + $code .= $_function; + break; + case T_METHOD_C: + $code .= $_method; + break; + case T_COMMENT: + if (substr($token[1], 0, 8) === '#trackme') { + $timestamp = time(); + $code .= '/**' . PHP_EOL; + $code .= '* Date : ' . date(DATE_W3C, $timestamp) . PHP_EOL; + $code .= '* Timestamp : ' . $timestamp . PHP_EOL; + $code .= '* Line : ' . ($line + 1) . PHP_EOL; + $code .= '* File : ' . $_file . PHP_EOL . '*/' . PHP_EOL; + $lineAdd += 5; + } else { + $code .= $token[1]; + } + break; + case T_VARIABLE: + if($token[1] == '$this' && !$inside_anonymous){ + $isUsingThisObject = true; + } + $code .= $token[1]; + break; + case T_STATIC: + $isUsingScope = true; + $code .= $token[1]; + break; + case T_NS_SEPARATOR: + case T_STRING: + $id_start = $token[1]; + $id_start_ci = strtolower($id_start); + $id_name = ''; + $context = 'root'; + $state = 'id_name'; + $lastState = 'closure'; + break 2; + case T_NEW: + $code .= $token[1]; + $context = 'new'; + $state = 'id_start'; + $lastState = 'closure'; + break 2; + case T_USE: + $code .= $token[1]; + $context = 'use'; + $state = 'id_start'; + $lastState = 'closure'; + break; + case T_INSTANCEOF: + $code .= $token[1]; + $context = 'instanceof'; + $state = 'id_start'; + $lastState = 'closure'; + break; + case T_OBJECT_OPERATOR: + case T_DOUBLE_COLON: + $code .= $token[1]; + $lastState = 'closure'; + $state = 'ignore_next'; + break; + case T_FUNCTION: + $code .= $token[1]; + $state = 'closure_args'; + break; + case T_TRAIT_C: + if ($_trait === null) { + $startLine = $this->getStartLine(); + $endLine = $this->getEndLine(); + $structures = $this->getStructures(); + + $_trait = ''; + + foreach ($structures as &$struct) { + if ($struct['type'] === 'trait' && + $struct['start'] <= $startLine && + $struct['end'] >= $endLine + ) { + $_trait = ($ns == '' ? '' : $ns . '\\') . $struct['name']; + break; + } + } + + $_trait = var_export($_trait, true); + } + + $code .= $_trait; + break; + default: + $code .= is_array($token) ? $token[1] : $token; + } + break; + case 'ignore_next': + switch ($token[0]){ + case T_WHITESPACE: + case T_COMMENT: + case T_DOC_COMMENT: + $code .= $token[1]; + break; + case T_CLASS: + case T_NEW: + case T_STATIC: + case T_VARIABLE: + case T_STRING: + case T_CLASS_C: + case T_FILE: + case T_DIR: + case T_METHOD_C: + case T_FUNC_C: + case T_FUNCTION: + case T_INSTANCEOF: + case T_LINE: + case T_NS_C: + case T_TRAIT_C: + case T_USE: + $code .= $token[1]; + $state = $lastState; + break; + default: + $state = $lastState; + $i--; + } + break; + case 'id_start': + switch ($token[0]){ + case T_WHITESPACE: + case T_COMMENT: + case T_DOC_COMMENT: + $code .= $token[1]; + break; + case T_NS_SEPARATOR: + case T_STRING: + case T_STATIC: + $id_start = $token[1]; + $id_start_ci = strtolower($id_start); + $id_name = ''; + $state = 'id_name'; + break 2; + case T_VARIABLE: + $code .= $token[1]; + $state = $lastState; + break; + case T_CLASS: + $code .= $token[1]; + $state = 'anonymous'; + break; + default: + $i--;//reprocess last + $state = 'id_name'; + } + break; + case 'id_name': + switch ($token[0]){ + case T_NS_SEPARATOR: + case T_STRING: + $id_name .= $token[1]; + break; + case T_WHITESPACE: + case T_COMMENT: + case T_DOC_COMMENT: + $id_name .= $token[1]; + break; + case '(': + if($context === 'new' || false !== strpos($id_name, '\\')){ + if($id_start !== '\\'){ + if ($classes === null) { + $classes = $this->getClasses(); + } + if (isset($classes[$id_start_ci])) { + $id_start = $classes[$id_start_ci]; + } + if($id_start[0] !== '\\'){ + $id_start = $nsf . '\\' . $id_start; + } + } + } else { + if($id_start !== '\\'){ + if($functions === null){ + $functions = $this->getFunctions(); + } + if(isset($functions[$id_start_ci])){ + $id_start = $functions[$id_start_ci]; + } + } + } + $code .= $id_start . $id_name . '('; + $state = $lastState; + break; + case T_VARIABLE: + case T_DOUBLE_COLON: + if($id_start !== '\\') { + if($id_start_ci === 'self' || $id_start_ci === 'static' || $id_start_ci === 'parent'){ + $isUsingScope = true; + } elseif (!($php7 && in_array($id_start_ci, $php7_types))){ + if ($classes === null) { + $classes = $this->getClasses(); + } + if (isset($classes[$id_start_ci])) { + $id_start = $classes[$id_start_ci]; + } + if($id_start[0] !== '\\'){ + $id_start = $nsf . '\\' . $id_start; + } + } + } + $code .= $id_start . $id_name . $token[1]; + $state = $token[0] === T_DOUBLE_COLON ? 'ignore_next' : $lastState; + break; + default: + if($id_start !== '\\'){ + if($context === 'use' || + $context === 'instanceof' || + $context === 'args' || + $context === 'return_type' || + $context === 'extends' + ){ + if($id_start_ci === 'self' || $id_start_ci === 'static' || $id_start_ci === 'parent'){ + $isUsingScope = true; + } elseif (!($php7 && in_array($id_start_ci, $php7_types))){ + if($classes === null){ + $classes = $this->getClasses(); + } + if(isset($classes[$id_start_ci])){ + $id_start = $classes[$id_start_ci]; + } + if($id_start[0] !== '\\'){ + $id_start = $nsf . '\\' . $id_start; + } + } + } else { + if($constants === null){ + $constants = $this->getConstants(); + } + if(isset($constants[$id_start])){ + $id_start = $constants[$id_start]; + } + } + } + $code .= $id_start . $id_name; + $state = $lastState; + $i--;//reprocess last token + } + break; + case 'anonymous': + switch ($token[0]) { + case T_NS_SEPARATOR: + case T_STRING: + $id_start = $token[1]; + $id_start_ci = strtolower($id_start); + $id_name = ''; + $state = 'id_name'; + $context = 'extends'; + $lastState = 'anonymous'; + break; + case '{': + $state = 'closure'; + if (!$inside_anonymous) { + $inside_anonymous = true; + $anonymous_mark = $open; + } + $i--; + break; + default: + $code .= is_array($token) ? $token[1] : $token; + } + break; + } + } + + $this->isBindingRequired = $isUsingThisObject; + $this->isScopeRequired = $isUsingScope; + $this->code = $code; + $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use)); + + return $this->code; + } + + /** + * @return array + */ + public function getUseVariables() + { + if($this->useVariables !== null){ + return $this->useVariables; + } + + $tokens = $this->getTokens(); + $use = array(); + $state = 'start'; + + foreach ($tokens as &$token) { + $is_array = is_array($token); + + switch ($state) { + case 'start': + if ($is_array && $token[0] === T_USE) { + $state = 'use'; + } + break; + case 'use': + if ($is_array) { + if ($token[0] === T_VARIABLE) { + $use[] = substr($token[1], 1); + } + } elseif ($token == ')') { + break 2; + } + break; + } + } + + $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use)); + + return $this->useVariables; + } + + /** + * return bool + */ + public function isBindingRequired() + { + if($this->isBindingRequired === null){ + $this->getCode(); + } + + return $this->isBindingRequired; + } + + /** + * return bool + */ + public function isScopeRequired() + { + if($this->isScopeRequired === null){ + $this->getCode(); + } + + return $this->isScopeRequired; + } + + /** + * @return string + */ + protected function getHashedFileName() + { + if ($this->hashedName === null) { + $this->hashedName = sha1($this->getFileName()); + } + + return $this->hashedName; + } + + /** + * @return array + */ + protected function getFileTokens() + { + $key = $this->getHashedFileName(); + + if (!isset(static::$files[$key])) { + static::$files[$key] = token_get_all(file_get_contents($this->getFileName())); + } + + return static::$files[$key]; + } + + /** + * @return array + */ + protected function getTokens() + { + if ($this->tokens === null) { + $tokens = $this->getFileTokens(); + $startLine = $this->getStartLine(); + $endLine = $this->getEndLine(); + $results = array(); + $start = false; + + foreach ($tokens as &$token) { + if (!is_array($token)) { + if ($start) { + $results[] = $token; + } + + continue; + } + + $line = $token[2]; + + if ($line <= $endLine) { + if ($line >= $startLine) { + $start = true; + $results[] = $token; + } + + continue; + } + + break; + } + + $this->tokens = $results; + } + + return $this->tokens; + } + + /** + * @return array + */ + protected function getClasses() + { + $key = $this->getHashedFileName(); + + if (!isset(static::$classes[$key])) { + $this->fetchItems(); + } + + return static::$classes[$key]; + } + + /** + * @return array + */ + protected function getFunctions() + { + $key = $this->getHashedFileName(); + + if (!isset(static::$functions[$key])) { + $this->fetchItems(); + } + + return static::$functions[$key]; + } + + /** + * @return array + */ + protected function getConstants() + { + $key = $this->getHashedFileName(); + + if (!isset(static::$constants[$key])) { + $this->fetchItems(); + } + + return static::$constants[$key]; + } + + /** + * @return array + */ + protected function getStructures() + { + $key = $this->getHashedFileName(); + + if (!isset(static::$structures[$key])) { + $this->fetchItems(); + } + + return static::$structures[$key]; + } + + protected function fetchItems() + { + $key = $this->getHashedFileName(); + + $classes = array(); + $functions = array(); + $constants = array(); + $structures = array(); + $tokens = $this->getFileTokens(); + + $open = 0; + $state = 'start'; + $lastState = ''; + $prefix = ''; + $name = ''; + $alias = ''; + $isFunc = $isConst = false; + + $startLine = $endLine = 0; + $structType = $structName = ''; + $structIgnore = false; + + foreach ($tokens as $token) { + + switch ($state) { + case 'start': + switch ($token[0]) { + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + $state = 'before_structure'; + $startLine = $token[2]; + $structType = $token[0] == T_CLASS + ? 'class' + : ($token[0] == T_INTERFACE ? 'interface' : 'trait'); + break; + case T_USE: + $state = 'use'; + $prefix = $name = $alias = ''; + $isFunc = $isConst = false; + break; + case T_FUNCTION: + $state = 'structure'; + $structIgnore = true; + break; + case T_NEW: + $state = 'new'; + break; + case T_OBJECT_OPERATOR: + case T_DOUBLE_COLON: + $state = 'invoke'; + break; + } + break; + case 'use': + switch ($token[0]) { + case T_FUNCTION: + $isFunc = true; + break; + case T_CONST: + $isConst = true; + break; + case T_NS_SEPARATOR: + $name .= $token[1]; + break; + case T_STRING: + $name .= $token[1]; + $alias = $token[1]; + break; + case T_AS: + $lastState = 'use'; + $state = 'alias'; + break; + case '{': + $prefix = $name; + $name = $alias = ''; + $state = 'use-group'; + break; + case ',': + case ';': + if ($name === '' || $name[0] !== '\\') { + $name = '\\' . $name; + } + + if ($alias !== '') { + if ($isFunc) { + $functions[strtolower($alias)] = $name; + } elseif ($isConst) { + $constants[$alias] = $name; + } else { + $classes[strtolower($alias)] = $name; + } + } + $name = $alias = ''; + $state = $token === ';' ? 'start' : 'use'; + break; + } + break; + case 'use-group': + switch ($token[0]) { + case T_NS_SEPARATOR: + $name .= $token[1]; + break; + case T_STRING: + $name .= $token[1]; + $alias = $token[1]; + break; + case T_AS: + $lastState = 'use-group'; + $state = 'alias'; + break; + case ',': + case '}': + + if ($prefix === '' || $prefix[0] !== '\\') { + $prefix = '\\' . $prefix; + } + + if ($alias !== '') { + if ($isFunc) { + $functions[strtolower($alias)] = $prefix . $name; + } elseif ($isConst) { + $constants[$alias] = $prefix . $name; + } else { + $classes[strtolower($alias)] = $prefix . $name; + } + } + $name = $alias = ''; + $state = $token === '}' ? 'use' : 'use-group'; + break; + } + break; + case 'alias': + if ($token[0] === T_STRING) { + $alias = $token[1]; + $state = $lastState; + } + break; + case 'new': + switch ($token[0]) { + case T_WHITESPACE: + case T_COMMENT: + case T_DOC_COMMENT: + break 2; + case T_CLASS: + $state = 'structure'; + $structIgnore = true; + break; + default: + $state = 'start'; + } + break; + case 'invoke': + switch ($token[0]) { + case T_WHITESPACE: + case T_COMMENT: + case T_DOC_COMMENT: + break 2; + default: + $state = 'start'; + } + break; + case 'before_structure': + if ($token[0] == T_STRING) { + $structName = $token[1]; + $state = 'structure'; + } + break; + case 'structure': + switch ($token[0]) { + case '{': + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case T_STRING_VARNAME: + $open++; + break; + case '}': + if (--$open == 0) { + if(!$structIgnore){ + $structures[] = array( + 'type' => $structType, + 'name' => $structName, + 'start' => $startLine, + 'end' => $endLine, + ); + } + $structIgnore = false; + $state = 'start'; + } + break; + default: + if (is_array($token)) { + $endLine = $token[2]; + } + } + break; + } + } + + static::$classes[$key] = $classes; + static::$functions[$key] = $functions; + static::$constants[$key] = $constants; + static::$structures[$key] = $structures; + } +} diff --git a/vendor/opis/closure/src/SecurityException.php b/vendor/opis/closure/src/SecurityException.php new file mode 100644 index 0000000..6a107ee --- /dev/null +++ b/vendor/opis/closure/src/SecurityException.php @@ -0,0 +1,18 @@ +secret = $secret; + } + + /** + * @inheritdoc + */ + public function sign($closure) + { + return array( + 'closure' => $closure, + 'hash' => base64_encode(hash_hmac('sha256', $closure, $this->secret, true)), + ); + } + + /** + * @inheritdoc + */ + public function verify(array $data) + { + return base64_encode(hash_hmac('sha256', $data['closure'], $this->secret, true)) === $data['hash']; + } +} \ No newline at end of file diff --git a/vendor/opis/closure/src/SelfReference.php b/vendor/opis/closure/src/SelfReference.php new file mode 100644 index 0000000..3c6ec80 --- /dev/null +++ b/vendor/opis/closure/src/SelfReference.php @@ -0,0 +1,31 @@ +hash = $hash; + } +} \ No newline at end of file diff --git a/vendor/opis/closure/src/SerializableClosure.php b/vendor/opis/closure/src/SerializableClosure.php new file mode 100644 index 0000000..c4991cf --- /dev/null +++ b/vendor/opis/closure/src/SerializableClosure.php @@ -0,0 +1,668 @@ +closure = $closure; + if (static::$context !== null) { + $this->scope = static::$context->scope; + $this->scope->toserialize++; + } + } + + /** + * Get the Closure object + * + * @return Closure The wrapped closure + */ + public function getClosure() + { + return $this->closure; + } + + /** + * Get the reflector for closure + * + * @return ReflectionClosure + */ + public function getReflector() + { + if ($this->reflector === null) { + $this->reflector = new ReflectionClosure($this->closure, $this->code); + $this->code = null; + } + + return $this->reflector; + } + + /** + * Implementation of magic method __invoke() + */ + public function __invoke() + { + return call_user_func_array($this->closure, func_get_args()); + } + + /** + * Implementation of Serializable::serialize() + * + * @return string The serialized closure + */ + public function serialize() + { + if ($this->scope === null) { + $this->scope = new ClosureScope(); + $this->scope->toserialize++; + } + + $this->scope->serializations++; + + $scope = $object = null; + $reflector = $this->getReflector(); + + if($reflector->isBindingRequired()){ + $object = $reflector->getClosureThis(); + static::wrapClosures($object, $this->scope); + if($scope = $reflector->getClosureScopeClass()){ + $scope = $scope->name; + } + } elseif($reflector->isScopeRequired()) { + if($scope = $reflector->getClosureScopeClass()){ + $scope = $scope->name; + } + } + + $this->reference = spl_object_hash($this->closure); + + $this->scope[$this->closure] = $this; + + $use = $this->transformUseVariables($reflector->getUseVariables()); + $code = $reflector->getCode(); + + $this->mapByReference($use); + + $ret = \serialize(array( + 'use' => $use, + 'function' => $code, + 'scope' => $scope, + 'this' => $object, + 'self' => $this->reference, + )); + + if (static::$securityProvider !== null) { + $data = static::$securityProvider->sign($ret); + $ret = '@' . $data['hash'] . '.' . $data['closure']; + } + + if (!--$this->scope->serializations && !--$this->scope->toserialize) { + $this->scope = null; + } + + return $ret; + } + + /** + * Transform the use variables before serialization. + * + * @param array $data The Closure's use variables + * @return array + */ + protected function transformUseVariables($data) + { + return $data; + } + + /** + * Implementation of Serializable::unserialize() + * + * @param string $data Serialized data + * @throws SecurityException + */ + public function unserialize($data) + { + ClosureStream::register(); + + if (static::$securityProvider !== null) { + if ($data[0] !== '@') { + throw new SecurityException("The serialized closure is not signed. ". + "Make sure you use a security provider for both serialization and unserialization."); + } + + if ($data[1] !== '{') { + $separator = strpos($data, '.'); + if ($separator === false) { + throw new SecurityException('Invalid signed closure'); + } + $hash = substr($data, 1, $separator - 1); + $closure = substr($data, $separator + 1); + + $data = ['hash' => $hash, 'closure' => $closure]; + + unset($hash, $closure); + } else { + $data = json_decode(substr($data, 1), true); + } + + if (!is_array($data) || !static::$securityProvider->verify($data)) { + throw new SecurityException("Your serialized closure might have been modified and it's unsafe to be unserialized. " . + "Make sure you use the same security provider, with the same settings, " . + "both for serialization and unserialization."); + } + + $data = $data['closure']; + } elseif ($data[0] === '@') { + if ($data[1] !== '{') { + $separator = strpos($data, '.'); + if ($separator === false) { + throw new SecurityException('Invalid signed closure'); + } + $hash = substr($data, 1, $separator - 1); + $closure = substr($data, $separator + 1); + + $data = ['hash' => $hash, 'closure' => $closure]; + + unset($hash, $closure); + } else { + $data = json_decode(substr($data, 1), true); + } + + if (!is_array($data) || !isset($data['closure']) || !isset($data['hash'])) { + throw new SecurityException('Invalid signed closure'); + } + + $data = $data['closure']; + } + + $this->code = \unserialize($data); + + // unset data + unset($data); + + $this->code['objects'] = array(); + + if ($this->code['use']) { + $this->scope = new ClosureScope(); + $this->code['use'] = $this->resolveUseVariables($this->code['use']); + $this->mapPointers($this->code['use']); + extract($this->code['use'], EXTR_OVERWRITE | EXTR_REFS); + $this->scope = null; + } + + $this->closure = include(ClosureStream::STREAM_PROTO . '://' . $this->code['function']); + + if($this->code['this'] === $this){ + $this->code['this'] = null; + } + + if ($this->code['scope'] !== null || $this->code['this'] !== null) { + $this->closure = $this->closure->bindTo($this->code['this'], $this->code['scope']); + } + + if(!empty($this->code['objects'])){ + foreach ($this->code['objects'] as $item){ + $item['property']->setValue($item['instance'], $item['object']->getClosure()); + } + } + + $this->code = $this->code['function']; + } + + /** + * Resolve the use variables after unserialization. + * + * @param array $data The Closure's transformed use variables + * @return array + */ + protected function resolveUseVariables($data) + { + return $data; + } + + /** + * Wraps a closure and sets the serialization context (if any) + * + * @param Closure $closure Closure to be wrapped + * + * @return self The wrapped closure + */ + public static function from(Closure $closure) + { + if (static::$context === null) { + $instance = new static($closure); + } elseif (isset(static::$context->scope[$closure])) { + $instance = static::$context->scope[$closure]; + } else { + $instance = new static($closure); + static::$context->scope[$closure] = $instance; + } + + return $instance; + } + + /** + * Increments the context lock counter or creates a new context if none exist + */ + public static function enterContext() + { + if (static::$context === null) { + static::$context = new ClosureContext(); + } + + static::$context->locks++; + } + + /** + * Decrements the context lock counter and destroy the context when it reaches to 0 + */ + public static function exitContext() + { + if (static::$context !== null && !--static::$context->locks) { + static::$context = null; + } + } + + /** + * @param string $secret + */ + public static function setSecretKey($secret) + { + if(static::$securityProvider === null){ + static::$securityProvider = new SecurityProvider($secret); + } + } + + /** + * @param ISecurityProvider $securityProvider + */ + public static function addSecurityProvider(ISecurityProvider $securityProvider) + { + static::$securityProvider = $securityProvider; + } + + /** + * Remove security provider + */ + public static function removeSecurityProvider() + { + static::$securityProvider = null; + } + + /** + * @return null|ISecurityProvider + */ + public static function getSecurityProvider() + { + return static::$securityProvider; + } + + /** + * Wrap closures + * + * @internal + * @param $data + * @param ClosureScope|SplObjectStorage|null $storage + */ + public static function wrapClosures(&$data, SplObjectStorage $storage = null) + { + if($storage === null){ + $storage = static::$context->scope; + } + + if($data instanceof Closure){ + $data = static::from($data); + } elseif (is_array($data)){ + if(isset($data[self::ARRAY_RECURSIVE_KEY])){ + return; + } + $data[self::ARRAY_RECURSIVE_KEY] = true; + foreach ($data as $key => &$value){ + if($key === self::ARRAY_RECURSIVE_KEY){ + continue; + } + static::wrapClosures($value, $storage); + } + unset($value); + unset($data[self::ARRAY_RECURSIVE_KEY]); + } elseif($data instanceof \stdClass){ + if(isset($storage[$data])){ + $data = $storage[$data]; + return; + } + $data = $storage[$data] = clone($data); + foreach ($data as &$value){ + static::wrapClosures($value, $storage); + } + unset($value); + } elseif (is_object($data) && ! $data instanceof static){ + if(isset($storage[$data])){ + $data = $storage[$data]; + return; + } + $instance = $data; + $reflection = new ReflectionObject($instance); + if(!$reflection->isUserDefined()){ + $storage[$instance] = $data; + return; + } + $storage[$instance] = $data = $reflection->newInstanceWithoutConstructor(); + + do{ + if(!$reflection->isUserDefined()){ + break; + } + foreach ($reflection->getProperties() as $property){ + if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ + continue; + } + $property->setAccessible(true); + $value = $property->getValue($instance); + if(is_array($value) || is_object($value)){ + static::wrapClosures($value, $storage); + } + $property->setValue($data, $value); + }; + } while($reflection = $reflection->getParentClass()); + } + } + + /** + * Unwrap closures + * + * @internal + * @param $data + * @param SplObjectStorage|null $storage + */ + public static function unwrapClosures(&$data, SplObjectStorage $storage = null) + { + if($storage === null){ + $storage = static::$context->scope; + } + + if($data instanceof static){ + $data = $data->getClosure(); + } elseif (is_array($data)){ + if(isset($data[self::ARRAY_RECURSIVE_KEY])){ + return; + } + $data[self::ARRAY_RECURSIVE_KEY] = true; + foreach ($data as $key => &$value){ + if($key === self::ARRAY_RECURSIVE_KEY){ + continue; + } + static::unwrapClosures($value, $storage); + } + unset($data[self::ARRAY_RECURSIVE_KEY]); + }elseif ($data instanceof \stdClass){ + if(isset($storage[$data])){ + return; + } + $storage[$data] = true; + foreach ($data as &$property){ + static::unwrapClosures($property, $storage); + } + } elseif (is_object($data) && !($data instanceof Closure)){ + if(isset($storage[$data])){ + return; + } + $storage[$data] = true; + $reflection = new ReflectionObject($data); + + do{ + if(!$reflection->isUserDefined()){ + break; + } + foreach ($reflection->getProperties() as $property){ + if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ + continue; + } + $property->setAccessible(true); + $value = $property->getValue($data); + if(is_array($value) || is_object($value)){ + static::unwrapClosures($value, $storage); + $property->setValue($data, $value); + } + }; + } while($reflection = $reflection->getParentClass()); + } + } + + /** + * Creates a new closure from arbitrary code, + * emulating create_function, but without using eval + * + * @param string$args + * @param string $code + * @return Closure + */ + public static function createClosure($args, $code) + { + ClosureStream::register(); + return include(ClosureStream::STREAM_PROTO . '://function(' . $args. '){' . $code . '};'); + } + + /** + * Internal method used to map closure pointers + * @internal + * @param $data + */ + protected function mapPointers(&$data) + { + $scope = $this->scope; + + if ($data instanceof static) { + $data = &$data->closure; + } elseif (is_array($data)) { + if(isset($data[self::ARRAY_RECURSIVE_KEY])){ + return; + } + $data[self::ARRAY_RECURSIVE_KEY] = true; + foreach ($data as $key => &$value){ + if($key === self::ARRAY_RECURSIVE_KEY){ + continue; + } elseif ($value instanceof static) { + $data[$key] = &$value->closure; + } elseif ($value instanceof SelfReference && $value->hash === $this->code['self']){ + $data[$key] = &$this->closure; + } else { + $this->mapPointers($value); + } + } + unset($value); + unset($data[self::ARRAY_RECURSIVE_KEY]); + } elseif ($data instanceof \stdClass) { + if(isset($scope[$data])){ + return; + } + $scope[$data] = true; + foreach ($data as $key => &$value){ + if ($value instanceof SelfReference && $value->hash === $this->code['self']){ + $data->{$key} = &$this->closure; + } elseif(is_array($value) || is_object($value)) { + $this->mapPointers($value); + } + } + unset($value); + } elseif (is_object($data) && !($data instanceof Closure)){ + if(isset($scope[$data])){ + return; + } + $scope[$data] = true; + $reflection = new ReflectionObject($data); + do{ + if(!$reflection->isUserDefined()){ + break; + } + foreach ($reflection->getProperties() as $property){ + if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ + continue; + } + $property->setAccessible(true); + $item = $property->getValue($data); + if ($item instanceof SerializableClosure || ($item instanceof SelfReference && $item->hash === $this->code['self'])) { + $this->code['objects'][] = array( + 'instance' => $data, + 'property' => $property, + 'object' => $item instanceof SelfReference ? $this : $item, + ); + } elseif (is_array($item) || is_object($item)) { + $this->mapPointers($item); + $property->setValue($data, $item); + } + } + } while($reflection = $reflection->getParentClass()); + } + } + + /** + * Internal method used to map closures by reference + * + * @internal + * @param mixed &$data + */ + protected function mapByReference(&$data) + { + if ($data instanceof Closure) { + if($data === $this->closure){ + $data = new SelfReference($this->reference); + return; + } + + if (isset($this->scope[$data])) { + $data = $this->scope[$data]; + return; + } + + $instance = new static($data); + + if (static::$context !== null) { + static::$context->scope->toserialize--; + } else { + $instance->scope = $this->scope; + } + + $data = $this->scope[$data] = $instance; + } elseif (is_array($data)) { + if(isset($data[self::ARRAY_RECURSIVE_KEY])){ + return; + } + $data[self::ARRAY_RECURSIVE_KEY] = true; + foreach ($data as $key => &$value){ + if($key === self::ARRAY_RECURSIVE_KEY){ + continue; + } + $this->mapByReference($value); + } + unset($value); + unset($data[self::ARRAY_RECURSIVE_KEY]); + } elseif ($data instanceof \stdClass) { + if(isset($this->scope[$data])){ + $data = $this->scope[$data]; + return; + } + $instance = $data; + $this->scope[$instance] = $data = clone($data); + + foreach ($data as &$value){ + $this->mapByReference($value); + } + unset($value); + } elseif (is_object($data) && !$data instanceof SerializableClosure){ + if(isset($this->scope[$data])){ + $data = $this->scope[$data]; + return; + } + + $instance = $data; + $reflection = new ReflectionObject($data); + if(!$reflection->isUserDefined()){ + $this->scope[$instance] = $data; + return; + } + $this->scope[$instance] = $data = $reflection->newInstanceWithoutConstructor(); + + do{ + if(!$reflection->isUserDefined()){ + break; + } + foreach ($reflection->getProperties() as $property){ + if($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()){ + continue; + } + $property->setAccessible(true); + $value = $property->getValue($instance); + if(is_array($value) || is_object($value)){ + $this->mapByReference($value); + } + $property->setValue($data, $value); + } + } while($reflection = $reflection->getParentClass()); + } + } + +} diff --git a/vendor/phpmailer/phpmailer/COMMITMENT b/vendor/phpmailer/phpmailer/COMMITMENT new file mode 100644 index 0000000..a687e0d --- /dev/null +++ b/vendor/phpmailer/phpmailer/COMMITMENT @@ -0,0 +1,46 @@ +GPL Cooperation Commitment +Version 1.0 + +Before filing or continuing to prosecute any legal proceeding or claim +(other than a Defensive Action) arising from termination of a Covered +License, we commit to extend to the person or entity ('you') accused +of violating the Covered License the following provisions regarding +cure and reinstatement, taken from GPL version 3. As used here, the +term 'this License' refers to the specific Covered License being +enforced. + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly + and finally terminates your license, and (b) permanently, if the + copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you + have received notice of violation of this License (for any work) + from that copyright holder, and you cure the violation prior to 30 + days after your receipt of the notice. + +We intend this Commitment to be irrevocable, and binding and +enforceable against us and assignees of or successors to our +copyrights. + +Definitions + +'Covered License' means the GNU General Public License, version 2 +(GPLv2), the GNU Lesser General Public License, version 2.1 +(LGPLv2.1), or the GNU Library General Public License, version 2 +(LGPLv2), all as published by the Free Software Foundation. + +'Defensive Action' means a legal proceeding or claim that We bring +against you in response to a prior proceeding or claim initiated by +you or your affiliate. + +'We' means each contributor to this repository as of the date of +inclusion of this file, including subsidiaries of a corporate +contributor. + +This work is available under a Creative Commons Attribution-ShareAlike +4.0 International license (https://creativecommons.org/licenses/by-sa/4.0/). diff --git a/vendor/phpmailer/phpmailer/LICENSE b/vendor/phpmailer/phpmailer/LICENSE new file mode 100644 index 0000000..f166cc5 --- /dev/null +++ b/vendor/phpmailer/phpmailer/LICENSE @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! \ No newline at end of file diff --git a/vendor/phpmailer/phpmailer/README.md b/vendor/phpmailer/phpmailer/README.md new file mode 100644 index 0000000..c287e30 --- /dev/null +++ b/vendor/phpmailer/phpmailer/README.md @@ -0,0 +1,221 @@ +![PHPMailer](https://raw.github.com/PHPMailer/PHPMailer/master/examples/images/phpmailer.png) + +# PHPMailer - A full-featured email creation and transfer class for PHP + +Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](https://travis-ci.org/PHPMailer/PHPMailer) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/badges/quality-score.png?s=3758e21d279becdf847a557a56a3ed16dfec9d5d)](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/) +[![Code Coverage](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/badges/coverage.png?s=3fe6ca5fe8cd2cdf96285756e42932f7ca256962)](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/) + +[![Latest Stable Version](https://poser.pugx.org/phpmailer/phpmailer/v/stable.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer) [![Latest Unstable Version](https://poser.pugx.org/phpmailer/phpmailer/v/unstable.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](http://phpmailer.github.io/PHPMailer/) + +## Class Features +- Probably the world's most popular code for sending email from PHP! +- Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more +- Integrated SMTP support - send without a local mail server +- Send emails with multiple To, CC, BCC and Reply-to addresses +- Multipart/alternative emails for mail clients that do not read HTML email +- Add attachments, including inline +- Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings +- SMTP authentication with LOGIN, PLAIN, CRAM-MD5, and XOAUTH2 mechanisms over SSL and SMTP+STARTTLS transports +- Validates email addresses automatically +- Protect against header injection attacks +- Error messages in over 50 languages! +- DKIM and S/MIME signing support +- Compatible with PHP 5.5 and later +- Namespaced to prevent name clashes +- Much more! + +## Why you might need it +Many PHP developers need to send email from their code. The only PHP function that supports this is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments. + +Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules – the vast majority of code that you'll find online that uses the `mail()` function directly is just plain wrong! +*Please* don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/), [Zend/Mail](https://zendframework.github.io/zend-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail) etc. + +The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD, and macOS platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server. + +## License +This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read LICENSE for information on the software availability and distribution. + +## Installation & loading +PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file: + +```json +"phpmailer/phpmailer": "~6.1" +``` + +or run + +```sh +composer require phpmailer/phpmailer +``` + +Note that the `vendor` folder and the `vendor/autoload.php` script are generated by Composer; they are not part of PHPMailer. + +If you want to use the Gmail XOAUTH2 authentication class, you will also need to add a dependency on the `league/oauth2-client` package in your `composer.json`. + +Alternatively, if you're not using Composer, copy the contents of the PHPMailer folder into one of the `include_path` directories specified in your PHP configuration and load each class file manually: + +```php +SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output + $mail->isSMTP(); // Send using SMTP + $mail->Host = 'smtp1.example.com'; // Set the SMTP server to send through + $mail->SMTPAuth = true; // Enable SMTP authentication + $mail->Username = 'user@example.com'; // SMTP username + $mail->Password = 'secret'; // SMTP password + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged + $mail->Port = 587; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above + + //Recipients + $mail->setFrom('from@example.com', 'Mailer'); + $mail->addAddress('joe@example.net', 'Joe User'); // Add a recipient + $mail->addAddress('ellen@example.com'); // Name is optional + $mail->addReplyTo('info@example.com', 'Information'); + $mail->addCC('cc@example.com'); + $mail->addBCC('bcc@example.com'); + + // Attachments + $mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments + $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name + + // Content + $mail->isHTML(true); // Set email format to HTML + $mail->Subject = 'Here is the subject'; + $mail->Body = 'This is the HTML message body in bold!'; + $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; + + $mail->send(); + echo 'Message has been sent'; +} catch (Exception $e) { + echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"; +} +``` + +You'll find plenty more to play with in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder. + +If you are re-using the instance (e.g. when sending to a mailing list), you may need to clear the recipient list to avoid sending duplicate messages. See [the mailing list example](https://github.com/PHPMailer/PHPMailer/blob/master/examples/mailing_list.phps) for further guidance. + +That's it. You should now be ready to use PHPMailer! + +## Localization +PHPMailer defaults to English, but in the [language](https://github.com/PHPMailer/PHPMailer/tree/master/language/) folder you'll find many translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this: + +```php +// To load the French version +$mail->setLanguage('fr', '/optional/path/to/language/directory/'); +``` + +We welcome corrections and new languages - if you're looking for corrections to do, run the [PHPMailerLangTest.php](https://github.com/PHPMailer/PHPMailer/tree/master/test/PHPMailerLangTest.php) script in the tests folder and it will show any missing translations. + +## Documentation +Start reading at the [GitHub wiki](https://github.com/PHPMailer/PHPMailer/wiki). If you're having trouble, this should be the first place you look as it's the most frequently updated. + +Examples of how to use PHPMailer for common scenarios can be found in the [examples](https://github.com/PHPMailer/PHPMailer/tree/master/examples) folder. If you're looking for a good starting point, we recommend you start with [the Gmail example](https://github.com/PHPMailer/PHPMailer/tree/master/examples/gmail.phps). + +Note that in order to reduce PHPMailer's deployed code footprint, the examples are no longer included if you load PHPMailer via Composer or via [GitHub's zip file download](https://github.com/PHPMailer/PHPMailer/archive/master.zip), so you'll need to either clone the git repository or use the above links to get to the examples directly. + +Complete generated API documentation is [available online](http://phpmailer.github.io/PHPMailer/). + +You can generate complete API-level documentation by running `phpdoc` in the top-level folder, and documentation will appear in the `docs` folder, though you'll need to have [PHPDocumentor](http://www.phpdoc.org) installed. You may find [the unit tests](https://github.com/PHPMailer/PHPMailer/blob/master/test/PHPMailerTest.php) a good source of how to do various operations such as encryption. + +If the documentation doesn't cover what you need, search the [many questions on Stack Overflow](http://stackoverflow.com/questions/tagged/phpmailer), and before you ask a question about "SMTP Error: Could not connect to SMTP host.", [read the troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting). + +## Tests +There is a PHPUnit test script in the [test](https://github.com/PHPMailer/PHPMailer/tree/master/test/) folder. PHPMailer uses PHPUnit 4.8 - we would use 5.x but we need to run on PHP 5.5. + +Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](https://travis-ci.org/PHPMailer/PHPMailer) + +If this isn't passing, is there something you can do to help? + +## Security +Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately. + +PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity. + +PHPMailer versions prior to 5.2.20 (released December 28th 2016) are vulnerable to [CVE-2016-10045](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10045) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html), and patched by Paul Buonopane (@Zenexer). + +PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a critical remote code execution vulnerability, responsibly reported by [Dawid Golunski](http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html). + +See [SECURITY](https://github.com/PHPMailer/PHPMailer/tree/master/SECURITY.md) for more detail on security issues. + +## Contributing +Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues). + +We're particularly interested in fixing edge-cases, expanding test coverage and updating translations. + +If you found a mistake in the docs, or want to add something, go ahead and amend the wiki - anyone can edit it. + +If you have git clones from prior to the move to the PHPMailer GitHub organisation, you'll need to update any remote URLs referencing the old GitHub location with a command like this from within your clone: + +```sh +git remote set-url upstream https://github.com/PHPMailer/PHPMailer.git +``` + +Please *don't* use the SourceForge or Google Code projects any more; they are obsolete and no longer maintained. + +## Sponsorship +Development time and resources for PHPMailer are provided by [Smartmessages.net](https://info.smartmessages.net/), a powerful email marketing system. + +Smartmessages email marketing + +Other contributions are gladly received, whether in beer 🍺, T-shirts 👕, Amazon wishlist raids, or cold, hard cash 💰. If you'd like to donate to say "thank you" to maintainers or contributors, please contact them through individual profile pages via [the contributors page](https://github.com/PHPMailer/PHPMailer/graphs/contributors). + +## Changelog +See [changelog](changelog.md). + +## History +- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/). +- Marcus Bointon (coolbru on SF) and Andy Prevost (codeworxtech) took over the project in 2004. +- Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski. +- Marcus created his fork on [GitHub](https://github.com/Synchro/PHPMailer) in 2008. +- Jim and Marcus decide to join forces and use GitHub as the canonical and official repo for PHPMailer in 2013. +- PHPMailer moves to the [PHPMailer organisation](https://github.com/PHPMailer) on GitHub in 2013. + +### What's changed since moving from SourceForge? +- Official successor to the SourceForge and Google Code projects. +- Test suite. +- Continuous integration with Travis-CI. +- Composer support. +- Public development. +- Additional languages and language strings. +- CRAM-MD5 authentication support. +- Preserves full repo history of authors, commits and branches from the original SourceForge project. diff --git a/vendor/phpmailer/phpmailer/SECURITY.md b/vendor/phpmailer/phpmailer/SECURITY.md new file mode 100644 index 0000000..5e917cd --- /dev/null +++ b/vendor/phpmailer/phpmailer/SECURITY.md @@ -0,0 +1,28 @@ +# Security notices relating to PHPMailer + +Please disclose any vulnerabilities found responsibly - report any security problems found to the maintainers privately. + +PHPMailer versions prior to 6.0.6 and 5.2.27 are vulnerable to an object injection attack by passing `phar://` paths into `addAttachment()` and other functions that may receive unfiltered local paths, possibly leading to RCE. Recorded as [CVE-2018-19296](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-19296). See [this article](https://knasmueller.net/5-answers-about-php-phar-exploitation) for more info on this type of vulnerability. Mitigated by blocking the use of paths containing URL-protocol style prefixes such as `phar://`. Reported by Sehun Oh of cyberone.kr. + +PHPMailer versions prior to 5.2.24 (released July 26th 2017) have an XSS vulnerability in one of the code examples, [CVE-2017-11503](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-11503). The `code_generator.phps` example did not filter user input prior to output. This file is distributed with a `.phps` extension, so it it not normally executable unless it is explicitly renamed, and the file is not included when PHPMailer is loaded through composer, so it is safe by default. There was also an undisclosed potential XSS vulnerability in the default exception handler (unused by default). Patches for both issues kindly provided by Patrick Monnerat of the Fedora Project. + +PHPMailer versions prior to 5.2.22 (released January 9th 2017) have a local file disclosure vulnerability, [CVE-2017-5223](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-5223). If content passed into `msgHTML()` is sourced from unfiltered user input, relative paths can map to absolute local file paths and added as attachments. Also note that `addAttachment` (just like `file_get_contents`, `passthru`, `unlink`, etc) should not be passed user-sourced params either! Reported by Yongxiang Li of Asiasecurity. + +PHPMailer versions prior to 5.2.20 (released December 28th 2016) are vulnerable to [CVE-2016-10045](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10045) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html), and patched by Paul Buonopane (@Zenexer). + +PHPMailer versions prior to 5.2.18 (released December 2016) are vulnerable to [CVE-2016-10033](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-10033) a remote code execution vulnerability, responsibly reported by [Dawid Golunski](http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html). + +PHPMailer versions prior to 5.2.14 (released November 2015) are vulnerable to [CVE-2015-8476](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-8476) an SMTP CRLF injection bug permitting arbitrary message sending. + +PHPMailer versions prior to 5.2.10 (released May 2015) are vulnerable to [CVE-2008-5619](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2008-5619), a remote code execution vulnerability in the bundled html2text library. This file was removed in 5.2.10, so if you are using a version prior to that and make use of the html2text function, it's vitally important that you upgrade and remove this file. + +PHPMailer versions prior to 2.0.7 and 2.2.1 are vulnerable to [CVE-2012-0796](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-0796), an email header injection attack. + +Joomla 1.6.0 uses PHPMailer in an unsafe way, allowing it to reveal local file paths, reported in [CVE-2011-3747](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-3747). + +PHPMailer didn't sanitise the `$lang_path` parameter in `SetLanguage`. This wasn't a problem in itself, but some apps (PHPClassifieds, ATutor) also failed to sanitise user-provided parameters passed to it, permitting semi-arbitrary local file inclusion, reported in [CVE-2010-4914](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2010-4914), [CVE-2007-2021](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2007-2021) and [CVE-2006-5734](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2006-5734). + +PHPMailer 1.7.2 and earlier contained a possible DDoS vulnerability reported in [CVE-2005-1807](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-1807). + +PHPMailer 1.7 and earlier (June 2003) have a possible vulnerability in the `SendmailSend` method where shell commands may not be sanitised. Reported in [CVE-2007-3215](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2007-3215). + diff --git a/vendor/phpmailer/phpmailer/VERSION b/vendor/phpmailer/phpmailer/VERSION new file mode 100644 index 0000000..f8c5c2c --- /dev/null +++ b/vendor/phpmailer/phpmailer/VERSION @@ -0,0 +1 @@ +6.1.5 \ No newline at end of file diff --git a/vendor/phpmailer/phpmailer/composer.json b/vendor/phpmailer/phpmailer/composer.json new file mode 100644 index 0000000..fd0695c --- /dev/null +++ b/vendor/phpmailer/phpmailer/composer.json @@ -0,0 +1,51 @@ +{ + "name": "phpmailer/phpmailer", + "type": "library", + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "require": { + "php": ">=5.5.0", + "ext-ctype": "*", + "ext-filter": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.2", + "phpunit/phpunit": "^4.8 || ^5.7", + "doctrine/annotations": "^1.2" + }, + "suggest": { + "psr/log": "For optional PSR-3 debug logging", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "PHPMailer\\Test\\": "test/" + } + }, + "license": "LGPL-2.1-only" +} diff --git a/vendor/phpmailer/phpmailer/get_oauth_token.php b/vendor/phpmailer/phpmailer/get_oauth_token.php new file mode 100644 index 0000000..1237b57 --- /dev/null +++ b/vendor/phpmailer/phpmailer/get_oauth_token.php @@ -0,0 +1,144 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2017 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ +/** + * Get an OAuth2 token from an OAuth2 provider. + * * Install this script on your server so that it's accessible + * as [https/http]:////get_oauth_token.php + * e.g.: http://localhost/phpmailer/get_oauth_token.php + * * Ensure dependencies are installed with 'composer install' + * * Set up an app in your Google/Yahoo/Microsoft account + * * Set the script address as the app's redirect URL + * If no refresh token is obtained when running this file, + * revoke access to your app and run the script again. + */ + +namespace PHPMailer\PHPMailer; + +/** + * Aliases for League Provider Classes + * Make sure you have added these to your composer.json and run `composer install` + * Plenty to choose from here: + * @see http://oauth2-client.thephpleague.com/providers/thirdparty/ + */ +// @see https://github.com/thephpleague/oauth2-google +use League\OAuth2\Client\Provider\Google; +// @see https://packagist.org/packages/hayageek/oauth2-yahoo +use Hayageek\OAuth2\Client\Provider\Yahoo; +// @see https://github.com/stevenmaguire/oauth2-microsoft +use Stevenmaguire\OAuth2\Client\Provider\Microsoft; + +if (!isset($_GET['code']) && !isset($_GET['provider'])) { +?> + +Select Provider:
+Google
+Yahoo
+Microsoft/Outlook/Hotmail/Live/Office365
+ + + $clientId, + 'clientSecret' => $clientSecret, + 'redirectUri' => $redirectUri, + 'accessType' => 'offline' +]; + +$options = []; +$provider = null; + +switch ($providerName) { + case 'Google': + $provider = new Google($params); + $options = [ + 'scope' => [ + 'https://mail.google.com/' + ] + ]; + break; + case 'Yahoo': + $provider = new Yahoo($params); + break; + case 'Microsoft': + $provider = new Microsoft($params); + $options = [ + 'scope' => [ + 'wl.imap', + 'wl.offline_access' + ] + ]; + break; +} + +if (null === $provider) { + exit('Provider missing'); +} + +if (!isset($_GET['code'])) { + // If we don't have an authorization code then get one + $authUrl = $provider->getAuthorizationUrl($options); + $_SESSION['oauth2state'] = $provider->getState(); + header('Location: ' . $authUrl); + exit; +// Check given state against previously stored one to mitigate CSRF attack +} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { + unset($_SESSION['oauth2state']); + unset($_SESSION['provider']); + exit('Invalid state'); +} else { + unset($_SESSION['provider']); + // Try to get an access token (using the authorization code grant) + $token = $provider->getAccessToken( + 'authorization_code', + [ + 'code' => $_GET['code'] + ] + ); + // Use this to interact with an API on the users behalf + // Use this to get a new access token if the old one expires + echo 'Refresh Token: ', $token->getRefreshToken(); +} diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php new file mode 100644 index 0000000..3c42d78 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-af.php @@ -0,0 +1,25 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP -ի սխալ: չհաջողվեց ստուգել իսկությունը.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP -ի սխալ: չհաջողվեց կապ հաստատել SMTP սերվերի հետ.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP -ի սխալ: տվյալները ընդունված չեն.'; +$PHPMAILER_LANG['empty_message'] = 'Հաղորդագրությունը դատարկ է'; +$PHPMAILER_LANG['encoding'] = 'Կոդավորման անհայտ տեսակ: '; +$PHPMAILER_LANG['execute'] = 'Չհաջողվեց իրականացնել հրամանը: '; +$PHPMAILER_LANG['file_access'] = 'Ֆայլը հասանելի չէ: '; +$PHPMAILER_LANG['file_open'] = 'Ֆայլի սխալ: ֆայլը չհաջողվեց բացել: '; +$PHPMAILER_LANG['from_failed'] = 'Ուղարկողի հետևյալ հասցեն սխալ է: '; +$PHPMAILER_LANG['instantiate'] = 'Հնարավոր չէ կանչել mail ֆունկցիան.'; +$PHPMAILER_LANG['invalid_address'] = 'Հասցեն սխալ է: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' փոստային սերվերի հետ չի աշխատում.'; +$PHPMAILER_LANG['provide_address'] = 'Անհրաժեշտ է տրամադրել գոնե մեկ ստացողի e-mail հասցե.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP -ի սխալ: չի հաջողվել ուղարկել հետևյալ ստացողների հասցեներին: '; +$PHPMAILER_LANG['signing'] = 'Ստորագրման սխալ: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP -ի connect() ֆունկցիան չի հաջողվել'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP սերվերի սխալ: '; +$PHPMAILER_LANG['variable_set'] = 'Չի հաջողվում ստեղծել կամ վերափոխել փոփոխականը: '; +$PHPMAILER_LANG['extension_missing'] = 'Հավելվածը բացակայում է: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ar.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ar.php new file mode 100644 index 0000000..865d0b7 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ar.php @@ -0,0 +1,27 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'خطأ SMTP : لا يمكن تأكيد الهوية.'; +$PHPMAILER_LANG['connect_host'] = 'خطأ SMTP: لا يمكن الاتصال بالخادم SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'خطأ SMTP: لم يتم قبول المعلومات .'; +$PHPMAILER_LANG['empty_message'] = 'نص الرسالة فارغ'; +$PHPMAILER_LANG['encoding'] = 'ترميز غير معروف: '; +$PHPMAILER_LANG['execute'] = 'لا يمكن تنفيذ : '; +$PHPMAILER_LANG['file_access'] = 'لا يمكن الوصول للملف: '; +$PHPMAILER_LANG['file_open'] = 'خطأ في الملف: لا يمكن فتحه: '; +$PHPMAILER_LANG['from_failed'] = 'خطأ على مستوى عنوان المرسل : '; +$PHPMAILER_LANG['instantiate'] = 'لا يمكن توفير خدمة البريد.'; +$PHPMAILER_LANG['invalid_address'] = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' برنامج الإرسال غير مدعوم.'; +$PHPMAILER_LANG['provide_address'] = 'يجب توفير عنوان البريد الإلكتروني لمستلم واحد على الأقل.'; +$PHPMAILER_LANG['recipients_failed'] = 'خطأ SMTP: الأخطاء التالية ' . + 'فشل في الارسال لكل من : '; +$PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() غير ممكن.'; +$PHPMAILER_LANG['smtp_error'] = 'خطأ على مستوى الخادم SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'لا يمكن تعيين أو إعادة تعيين متغير: '; +$PHPMAILER_LANG['extension_missing'] = 'الإضافة غير موجودة: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-az.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-az.php new file mode 100644 index 0000000..3749d83 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-az.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Greška: Neuspjela prijava.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Greška: Nije moguće spojiti se sa SMTP serverom.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Greška: Podatci nisu prihvaćeni.'; +$PHPMAILER_LANG['empty_message'] = 'Sadržaj poruke je prazan.'; +$PHPMAILER_LANG['encoding'] = 'Nepoznata kriptografija: '; +$PHPMAILER_LANG['execute'] = 'Nije moguće izvršiti naredbu: '; +$PHPMAILER_LANG['file_access'] = 'Nije moguće pristupiti datoteci: '; +$PHPMAILER_LANG['file_open'] = 'Nije moguće otvoriti datoteku: '; +$PHPMAILER_LANG['from_failed'] = 'SMTP Greška: Slanje sa navedenih e-mail adresa nije uspjelo: '; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Greška: Slanje na navedene e-mail adrese nije uspjelo: '; +$PHPMAILER_LANG['instantiate'] = 'Ne mogu pokrenuti mail funkcionalnost.'; +$PHPMAILER_LANG['invalid_address'] = 'E-mail nije poslan. Neispravna e-mail adresa: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nije podržan.'; +$PHPMAILER_LANG['provide_address'] = 'Definišite barem jednu adresu primaoca.'; +$PHPMAILER_LANG['signing'] = 'Greška prilikom prijave: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Spajanje na SMTP server nije uspjelo.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP greška: '; +$PHPMAILER_LANG['variable_set'] = 'Nije moguće postaviti varijablu ili je vratiti nazad: '; +$PHPMAILER_LANG['extension_missing'] = 'Nedostaje ekstenzija: '; \ No newline at end of file diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-be.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-be.php new file mode 100644 index 0000000..e2f98f0 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-be.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Памылка SMTP: памылка ідэнтыфікацыі.'; +$PHPMAILER_LANG['connect_host'] = 'Памылка SMTP: нельга ўстанавіць сувязь з SMTP-серверам.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Памылка SMTP: звесткі непрынятыя.'; +$PHPMAILER_LANG['empty_message'] = 'Пустое паведамленне.'; +$PHPMAILER_LANG['encoding'] = 'Невядомая кадыроўка тэксту: '; +$PHPMAILER_LANG['execute'] = 'Нельга выканаць каманду: '; +$PHPMAILER_LANG['file_access'] = 'Няма доступу да файла: '; +$PHPMAILER_LANG['file_open'] = 'Нельга адкрыць файл: '; +$PHPMAILER_LANG['from_failed'] = 'Няправільны адрас адпраўніка: '; +$PHPMAILER_LANG['instantiate'] = 'Нельга прымяніць функцыю mail().'; +$PHPMAILER_LANG['invalid_address'] = 'Нельга даслаць паведамленне, няправільны email атрымальніка: '; +$PHPMAILER_LANG['provide_address'] = 'Запоўніце, калі ласка, правільны email атрымальніка.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' - паштовы сервер не падтрымліваецца.'; +$PHPMAILER_LANG['recipients_failed'] = 'Памылка SMTP: няправільныя атрымальнікі: '; +$PHPMAILER_LANG['signing'] = 'Памылка подпісу паведамлення: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Памылка сувязі з SMTP-серверам.'; +$PHPMAILER_LANG['smtp_error'] = 'Памылка SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Нельга ўстанавіць або перамяніць значэнне пераменнай: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-bg.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-bg.php new file mode 100644 index 0000000..b22941f --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-bg.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP грешка: Не може да се удостовери пред сървъра.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP грешка: Не може да се свърже с SMTP хоста.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP грешка: данните не са приети.'; +$PHPMAILER_LANG['empty_message'] = 'Съдържанието на съобщението е празно'; +$PHPMAILER_LANG['encoding'] = 'Неизвестно кодиране: '; +$PHPMAILER_LANG['execute'] = 'Не може да се изпълни: '; +$PHPMAILER_LANG['file_access'] = 'Няма достъп до файл: '; +$PHPMAILER_LANG['file_open'] = 'Файлова грешка: Не може да се отвори файл: '; +$PHPMAILER_LANG['from_failed'] = 'Следните адреси за подател са невалидни: '; +$PHPMAILER_LANG['instantiate'] = 'Не може да се инстанцира функцията mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Невалиден адрес: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' - пощенски сървър не се поддържа.'; +$PHPMAILER_LANG['provide_address'] = 'Трябва да предоставите поне един email адрес за получател.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP грешка: Следните адреси за Получател са невалидни: '; +$PHPMAILER_LANG['signing'] = 'Грешка при подписване: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP провален connect().'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP сървърна грешка: '; +$PHPMAILER_LANG['variable_set'] = 'Не може да се установи или възстанови променлива: '; +$PHPMAILER_LANG['extension_missing'] = 'Липсва разширение: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ca.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ca.php new file mode 100644 index 0000000..4117596 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ca.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Error SMTP: No s’ha pogut autenticar.'; +$PHPMAILER_LANG['connect_host'] = 'Error SMTP: No es pot connectar al servidor SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Dades no acceptades.'; +$PHPMAILER_LANG['empty_message'] = 'El cos del missatge està buit.'; +$PHPMAILER_LANG['encoding'] = 'Codificació desconeguda: '; +$PHPMAILER_LANG['execute'] = 'No es pot executar: '; +$PHPMAILER_LANG['file_access'] = 'No es pot accedir a l’arxiu: '; +$PHPMAILER_LANG['file_open'] = 'Error d’Arxiu: No es pot obrir l’arxiu: '; +$PHPMAILER_LANG['from_failed'] = 'La(s) següent(s) adreces de remitent han fallat: '; +$PHPMAILER_LANG['instantiate'] = 'No s’ha pogut crear una instància de la funció Mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Adreça d’email invalida: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no està suportat'; +$PHPMAILER_LANG['provide_address'] = 'S’ha de proveir almenys una adreça d’email com a destinatari.'; +$PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Els següents destinataris han fallat: '; +$PHPMAILER_LANG['signing'] = 'Error al signar: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Ha fallat el SMTP Connect().'; +$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'No s’ha pogut establir o restablir la variable: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ch.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ch.php new file mode 100644 index 0000000..4fda6b8 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ch.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:身份验证失败。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 错误: 不能连接SMTP主机。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误: 数据不可接受。'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = '未知编码:'; +$PHPMAILER_LANG['execute'] = '不能执行: '; +$PHPMAILER_LANG['file_access'] = '不能访问文件:'; +$PHPMAILER_LANG['file_open'] = '文件错误:不能打开文件:'; +$PHPMAILER_LANG['from_failed'] = '下面的发送地址邮件发送失败了: '; +$PHPMAILER_LANG['instantiate'] = '不能实现mail方法。'; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' 您所选择的发送邮件的方法并不支持。'; +$PHPMAILER_LANG['provide_address'] = '您必须提供至少一个 收信人的email地址。'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误: 下面的 收件人失败了: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-cs.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-cs.php new file mode 100644 index 0000000..1160cf0 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-cs.php @@ -0,0 +1,25 @@ + + * Rewrite and extension of the work by Mikael Stokkebro + * + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Login mislykkedes.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Forbindelse til SMTP serveren kunne ikke oprettes.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data blev ikke accepteret.'; +$PHPMAILER_LANG['empty_message'] = 'Meddelelsen er uden indhold'; +$PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: '; +$PHPMAILER_LANG['execute'] = 'Kunne ikke afvikle: '; +$PHPMAILER_LANG['file_access'] = 'Kunne ikke tilgå filen: '; +$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: '; +$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: '; +$PHPMAILER_LANG['instantiate'] = 'Email funktionen kunne ikke initialiseres.'; +$PHPMAILER_LANG['invalid_address'] = 'Udgyldig adresse: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.'; +$PHPMAILER_LANG['provide_address'] = 'Indtast mindst en modtagers email adresse.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: '; +$PHPMAILER_LANG['signing'] = 'Signeringsfejl: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: '; +$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: '; +$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php new file mode 100644 index 0000000..aa987a9 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php @@ -0,0 +1,25 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.'; +$PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.'; +$PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío.'; +$PHPMAILER_LANG['encoding'] = 'Codificación desconocida: '; +$PHPMAILER_LANG['execute'] = 'Imposible ejecutar: '; +$PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: '; +$PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: '; +$PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: '; +$PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.'; +$PHPMAILER_LANG['provide_address'] = 'Debe proporcionar al menos una dirección de email de destino.'; +$PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinos fallaron: '; +$PHPMAILER_LANG['signing'] = 'Error al firmar: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.'; +$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: '; +$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-et.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-et.php new file mode 100644 index 0000000..7e06da1 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-et.php @@ -0,0 +1,27 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Viga: Autoriseerimise viga.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Viga: Ei õnnestunud luua ühendust SMTP serveriga.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Viga: Vigased andmed.'; +$PHPMAILER_LANG['empty_message'] = 'Tühi kirja sisu'; +$PHPMAILER_LANG["encoding"] = 'Tundmatu kodeering: '; +$PHPMAILER_LANG['execute'] = 'Tegevus ebaõnnestus: '; +$PHPMAILER_LANG['file_access'] = 'Pole piisavalt õiguseid järgneva faili avamiseks: '; +$PHPMAILER_LANG['file_open'] = 'Faili Viga: Faili avamine ebaõnnestus: '; +$PHPMAILER_LANG['from_failed'] = 'Järgnev saatja e-posti aadress on vigane: '; +$PHPMAILER_LANG['instantiate'] = 'mail funktiooni käivitamine ebaõnnestus.'; +$PHPMAILER_LANG['invalid_address'] = 'Saatmine peatatud, e-posti address vigane: '; +$PHPMAILER_LANG['provide_address'] = 'Te peate määrama vähemalt ühe saaja e-posti aadressi.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' maileri tugi puudub.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Viga: Järgnevate saajate e-posti aadressid on vigased: '; +$PHPMAILER_LANG["signing"] = 'Viga allkirjastamisel: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() ebaõnnestus.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP serveri viga: '; +$PHPMAILER_LANG['variable_set'] = 'Ei õnnestunud määrata või lähtestada muutujat: '; +$PHPMAILER_LANG['extension_missing'] = 'Nõutud laiendus on puudu: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-fa.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-fa.php new file mode 100644 index 0000000..8aa0ad2 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-fa.php @@ -0,0 +1,27 @@ + + * @author Mohammad Hossein Mojtahedi + */ + +$PHPMAILER_LANG['authenticate'] = 'خطای SMTP: احراز هویت با شکست مواجه شد.'; +$PHPMAILER_LANG['connect_host'] = 'خطای SMTP: اتصال به سرور SMTP برقرار نشد.'; +$PHPMAILER_LANG['data_not_accepted'] = 'خطای SMTP: داده‌ها نا‌درست هستند.'; +$PHPMAILER_LANG['empty_message'] = 'بخش متن پیام خالی است.'; +$PHPMAILER_LANG['encoding'] = 'کد‌گذاری نا‌شناخته: '; +$PHPMAILER_LANG['execute'] = 'امکان اجرا وجود ندارد: '; +$PHPMAILER_LANG['file_access'] = 'امکان دسترسی به فایل وجود ندارد: '; +$PHPMAILER_LANG['file_open'] = 'خطای File: امکان بازکردن فایل وجود ندارد: '; +$PHPMAILER_LANG['from_failed'] = 'آدرس فرستنده اشتباه است: '; +$PHPMAILER_LANG['instantiate'] = 'امکان معرفی تابع ایمیل وجود ندارد.'; +$PHPMAILER_LANG['invalid_address'] = 'آدرس ایمیل معتبر نیست: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer پشتیبانی نمی‌شود.'; +$PHPMAILER_LANG['provide_address'] = 'باید حداقل یک آدرس گیرنده وارد کنید.'; +$PHPMAILER_LANG['recipients_failed'] = 'خطای SMTP: ارسال به آدرس گیرنده با خطا مواجه شد: '; +$PHPMAILER_LANG['signing'] = 'خطا در امضا: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'خطا در اتصال به SMTP.'; +$PHPMAILER_LANG['smtp_error'] = 'خطا در SMTP Server: '; +$PHPMAILER_LANG['variable_set'] = 'امکان ارسال یا ارسال مجدد متغیر‌ها وجود ندارد: '; +$PHPMAILER_LANG['extension_missing'] = 'افزونه موجود نیست: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-fi.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-fi.php new file mode 100644 index 0000000..ec4e752 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-fi.php @@ -0,0 +1,27 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP feilur: Kundi ikki góðkenna.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP feilur: Kundi ikki knýta samband við SMTP vert.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP feilur: Data ikki góðkent.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Ókend encoding: '; +$PHPMAILER_LANG['execute'] = 'Kundi ikki útføra: '; +$PHPMAILER_LANG['file_access'] = 'Kundi ikki tilganga fílu: '; +$PHPMAILER_LANG['file_open'] = 'Fílu feilur: Kundi ikki opna fílu: '; +$PHPMAILER_LANG['from_failed'] = 'fylgjandi Frá/From adressa miseydnaðist: '; +$PHPMAILER_LANG['instantiate'] = 'Kuni ikki instantiera mail funktión.'; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporterað.'; +$PHPMAILER_LANG['provide_address'] = 'Tú skal uppgeva minst móttakara-emailadressu(r).'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Feilur: Fylgjandi móttakarar miseydnaðust: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php new file mode 100644 index 0000000..af68c92 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php @@ -0,0 +1,29 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Erro SMTP: Non puido ser autentificado.'; +$PHPMAILER_LANG['connect_host'] = 'Erro SMTP: Non puido conectar co servidor SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Erro SMTP: Datos non aceptados.'; +$PHPMAILER_LANG['empty_message'] = 'Corpo da mensaxe vacía'; +$PHPMAILER_LANG['encoding'] = 'Codificación descoñecida: '; +$PHPMAILER_LANG['execute'] = 'Non puido ser executado: '; +$PHPMAILER_LANG['file_access'] = 'Nob puido acceder ó arquivo: '; +$PHPMAILER_LANG['file_open'] = 'Erro de Arquivo: No puido abrir o arquivo: '; +$PHPMAILER_LANG['from_failed'] = 'A(s) seguinte(s) dirección(s) de remitente(s) deron erro: '; +$PHPMAILER_LANG['instantiate'] = 'Non puido crear unha instancia da función Mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Non puido envia-lo correo: dirección de email inválida: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer non está soportado.'; +$PHPMAILER_LANG['provide_address'] = 'Debe engadir polo menos unha dirección de email coma destino.'; +$PHPMAILER_LANG['recipients_failed'] = 'Erro SMTP: Os seguintes destinos fallaron: '; +$PHPMAILER_LANG['signing'] = 'Erro ó firmar: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fallou.'; +$PHPMAILER_LANG['smtp_error'] = 'Erro do servidor SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Non puidemos axustar ou reaxustar a variábel: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-he.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-he.php new file mode 100644 index 0000000..70eb717 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-he.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'שגיאת SMTP: פעולת האימות נכשלה.'; +$PHPMAILER_LANG['connect_host'] = 'שגיאת SMTP: לא הצלחתי להתחבר לשרת SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'שגיאת SMTP: מידע לא התקבל.'; +$PHPMAILER_LANG['empty_message'] = 'גוף ההודעה ריק'; +$PHPMAILER_LANG['invalid_address'] = 'כתובת שגויה: '; +$PHPMAILER_LANG['encoding'] = 'קידוד לא מוכר: '; +$PHPMAILER_LANG['execute'] = 'לא הצלחתי להפעיל את: '; +$PHPMAILER_LANG['file_access'] = 'לא ניתן לגשת לקובץ: '; +$PHPMAILER_LANG['file_open'] = 'שגיאת קובץ: לא ניתן לגשת לקובץ: '; +$PHPMAILER_LANG['from_failed'] = 'כתובות הנמענים הבאות נכשלו: '; +$PHPMAILER_LANG['instantiate'] = 'לא הצלחתי להפעיל את פונקציית המייל.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' אינה נתמכת.'; +$PHPMAILER_LANG['provide_address'] = 'חובה לספק לפחות כתובת אחת של מקבל המייל.'; +$PHPMAILER_LANG['recipients_failed'] = 'שגיאת SMTP: הנמענים הבאים נכשלו: '; +$PHPMAILER_LANG['signing'] = 'שגיאת חתימה: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +$PHPMAILER_LANG['smtp_error'] = 'שגיאת שרת SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'לא ניתן לקבוע או לשנות את המשתנה: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-hi.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hi.php new file mode 100644 index 0000000..607a5ee --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hi.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP त्रुटि: प्रामाणिकता की जांच नहीं हो सका। '; +$PHPMAILER_LANG['connect_host'] = 'SMTP त्रुटि: SMTP सर्वर से कनेक्ट नहीं हो सका। '; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP त्रुटि: डेटा स्वीकार नहीं किया जाता है। '; +$PHPMAILER_LANG['empty_message'] = 'संदेश खाली है। '; +$PHPMAILER_LANG['encoding'] = 'अज्ञात एन्कोडिंग प्रकार। '; +$PHPMAILER_LANG['execute'] = 'आदेश को निष्पादित करने में विफल। '; +$PHPMAILER_LANG['file_access'] = 'फ़ाइल उपलब्ध नहीं है। '; +$PHPMAILER_LANG['file_open'] = 'फ़ाइल त्रुटि: फाइल को खोला नहीं जा सका। '; +$PHPMAILER_LANG['from_failed'] = 'प्रेषक का पता गलत है। '; +$PHPMAILER_LANG['instantiate'] = 'मेल फ़ंक्शन कॉल नहीं कर सकता है।'; +$PHPMAILER_LANG['invalid_address'] = 'पता गलत है। '; +$PHPMAILER_LANG['mailer_not_supported'] = 'मेल सर्वर के साथ काम नहीं करता है। '; +$PHPMAILER_LANG['provide_address'] = 'आपको कम से कम एक प्राप्तकर्ता का ई-मेल पता प्रदान करना होगा।'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP त्रुटि: निम्न प्राप्तकर्ताओं को पते भेजने में विफल। '; +$PHPMAILER_LANG['signing'] = 'साइनअप त्रुटि:। '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP का connect () फ़ंक्शन विफल हुआ। '; +$PHPMAILER_LANG['smtp_error'] = 'SMTP सर्वर त्रुटि। '; +$PHPMAILER_LANG['variable_set'] = 'चर को बना या संशोधित नहीं किया जा सकता। '; +$PHPMAILER_LANG['extension_missing'] = 'एक्सटेन्षन गायब है: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php new file mode 100644 index 0000000..3822920 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Greška: Neuspjela autentikacija.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Greška: Ne mogu se spojiti na SMTP poslužitelj.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Greška: Podatci nisu prihvaćeni.'; +$PHPMAILER_LANG['empty_message'] = 'Sadržaj poruke je prazan.'; +$PHPMAILER_LANG['encoding'] = 'Nepoznati encoding: '; +$PHPMAILER_LANG['execute'] = 'Nije moguće izvršiti naredbu: '; +$PHPMAILER_LANG['file_access'] = 'Nije moguće pristupiti datoteci: '; +$PHPMAILER_LANG['file_open'] = 'Nije moguće otvoriti datoteku: '; +$PHPMAILER_LANG['from_failed'] = 'SMTP Greška: Slanje s navedenih e-mail adresa nije uspjelo: '; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Greška: Slanje na navedenih e-mail adresa nije uspjelo: '; +$PHPMAILER_LANG['instantiate'] = 'Ne mogu pokrenuti mail funkcionalnost.'; +$PHPMAILER_LANG['invalid_address'] = 'E-mail nije poslan. Neispravna e-mail adresa: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nije podržan.'; +$PHPMAILER_LANG['provide_address'] = 'Definirajte barem jednu adresu primatelja.'; +$PHPMAILER_LANG['signing'] = 'Greška prilikom prijave: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Spajanje na SMTP poslužitelj nije uspjelo.'; +$PHPMAILER_LANG['smtp_error'] = 'Greška SMTP poslužitelja: '; +$PHPMAILER_LANG['variable_set'] = 'Ne mogu postaviti varijablu niti ju vratiti nazad: '; +$PHPMAILER_LANG['extension_missing'] = 'Nedostaje proširenje: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-hu.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hu.php new file mode 100644 index 0000000..196cddc --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-hu.php @@ -0,0 +1,26 @@ + + * @author @januridp + */ + +$PHPMAILER_LANG['authenticate'] = 'Kesalahan SMTP: Tidak dapat mengotentikasi.'; +$PHPMAILER_LANG['connect_host'] = 'Kesalahan SMTP: Tidak dapat terhubung ke host SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Kesalahan SMTP: Data tidak diterima.'; +$PHPMAILER_LANG['empty_message'] = 'Isi pesan kosong'; +$PHPMAILER_LANG['encoding'] = 'Pengkodean karakter tidak dikenali: '; +$PHPMAILER_LANG['execute'] = 'Tidak dapat menjalankan proses : '; +$PHPMAILER_LANG['file_access'] = 'Tidak dapat mengakses berkas : '; +$PHPMAILER_LANG['file_open'] = 'Kesalahan File: Berkas tidak dapat dibuka : '; +$PHPMAILER_LANG['from_failed'] = 'Alamat pengirim berikut mengakibatkan kesalahan : '; +$PHPMAILER_LANG['instantiate'] = 'Tidak dapat menginisialisasi fungsi surel'; +$PHPMAILER_LANG['invalid_address'] = 'Gagal terkirim, alamat surel tidak benar : '; +$PHPMAILER_LANG['provide_address'] = 'Harus disediakan minimal satu alamat tujuan'; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer tidak didukung'; +$PHPMAILER_LANG['recipients_failed'] = 'Kesalahan SMTP: Alamat tujuan berikut menghasilkan kesalahan : '; +$PHPMAILER_LANG['signing'] = 'Kesalahan dalam tanda tangan : '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() gagal.'; +$PHPMAILER_LANG['smtp_error'] = 'Kesalahan pada pelayan SMTP : '; +$PHPMAILER_LANG['variable_set'] = 'Tidak dapat mengatur atau mengatur ulang variable : '; +$PHPMAILER_LANG['extension_missing'] = 'Ekstensi hilang: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php new file mode 100644 index 0000000..e67b6f7 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php @@ -0,0 +1,27 @@ + + * @author Stefano Sabatini + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Error: Impossibile autenticarsi.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: Impossibile connettersi all\'host SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Dati non accettati dal server.'; +$PHPMAILER_LANG['empty_message'] = 'Il corpo del messaggio è vuoto'; +$PHPMAILER_LANG['encoding'] = 'Codifica dei caratteri sconosciuta: '; +$PHPMAILER_LANG['execute'] = 'Impossibile eseguire l\'operazione: '; +$PHPMAILER_LANG['file_access'] = 'Impossibile accedere al file: '; +$PHPMAILER_LANG['file_open'] = 'File Error: Impossibile aprire il file: '; +$PHPMAILER_LANG['from_failed'] = 'I seguenti indirizzi mittenti hanno generato errore: '; +$PHPMAILER_LANG['instantiate'] = 'Impossibile istanziare la funzione mail'; +$PHPMAILER_LANG['invalid_address'] = 'Impossibile inviare, l\'indirizzo email non è valido: '; +$PHPMAILER_LANG['provide_address'] = 'Deve essere fornito almeno un indirizzo ricevente'; +$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: I seguenti indirizzi destinatari hanno generato un errore: '; +$PHPMAILER_LANG['signing'] = 'Errore nella firma: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fallita.'; +$PHPMAILER_LANG['smtp_error'] = 'Errore del server SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Impossibile impostare o resettare la variabile: '; +$PHPMAILER_LANG['extension_missing'] = 'Estensione mancante: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php new file mode 100644 index 0000000..2d77872 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php @@ -0,0 +1,27 @@ + + * @author Yoshi Sakai + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。'; +$PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = '不明なエンコーディング: '; +$PHPMAILER_LANG['execute'] = '実行できませんでした: '; +$PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: '; +$PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: '; +$PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: '; +$PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。'; +//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; +$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。'; +$PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: '; +//$PHPMAILER_LANG['signing'] = 'Signing Error: '; +//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; +//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ka.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ka.php new file mode 100644 index 0000000..dd1af8a --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ka.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP შეცდომა: ავტორიზაცია შეუძლებელია.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP შეცდომა: SMTP სერვერთან დაკავშირება შეუძლებელია.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP შეცდომა: მონაცემები არ იქნა მიღებული.'; +$PHPMAILER_LANG['encoding'] = 'კოდირების უცნობი ტიპი: '; +$PHPMAILER_LANG['execute'] = 'შეუძლებელია შემდეგი ბრძანების შესრულება: '; +$PHPMAILER_LANG['file_access'] = 'შეუძლებელია წვდომა ფაილთან: '; +$PHPMAILER_LANG['file_open'] = 'ფაილური სისტემის შეცდომა: არ იხსნება ფაილი: '; +$PHPMAILER_LANG['from_failed'] = 'გამგზავნის არასწორი მისამართი: '; +$PHPMAILER_LANG['instantiate'] = 'mail ფუნქციის გაშვება ვერ ხერხდება.'; +$PHPMAILER_LANG['provide_address'] = 'გთხოვთ მიუთითოთ ერთი ადრესატის e-mail მისამართი მაინც.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' - საფოსტო სერვერის მხარდაჭერა არ არის.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP შეცდომა: შემდეგ მისამართებზე გაგზავნა ვერ მოხერხდა: '; +$PHPMAILER_LANG['empty_message'] = 'შეტყობინება ცარიელია'; +$PHPMAILER_LANG['invalid_address'] = 'არ გაიგზავნა, e-mail მისამართის არასწორი ფორმატი: '; +$PHPMAILER_LANG['signing'] = 'ხელმოწერის შეცდომა: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'შეცდომა SMTP სერვერთან დაკავშირებისას'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP სერვერის შეცდომა: '; +$PHPMAILER_LANG['variable_set'] = 'შეუძლებელია შემდეგი ცვლადის შექმნა ან შეცვლა: '; +$PHPMAILER_LANG['extension_missing'] = 'ბიბლიოთეკა არ არსებობს: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ko.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ko.php new file mode 100644 index 0000000..9599fa6 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ko.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 오류: 인증할 수 없습니다.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 오류: SMTP 호스트에 접속할 수 없습니다.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 오류: 데이터가 받아들여지지 않았습니다.'; +$PHPMAILER_LANG['empty_message'] = '메세지 내용이 없습니다'; +$PHPMAILER_LANG['encoding'] = '알 수 없는 인코딩: '; +$PHPMAILER_LANG['execute'] = '실행 불가: '; +$PHPMAILER_LANG['file_access'] = '파일 접근 불가: '; +$PHPMAILER_LANG['file_open'] = '파일 오류: 파일을 열 수 없습니다: '; +$PHPMAILER_LANG['from_failed'] = '다음 From 주소에서 오류가 발생했습니다: '; +$PHPMAILER_LANG['instantiate'] = 'mail 함수를 인스턴스화할 수 없습니다'; +$PHPMAILER_LANG['invalid_address'] = '잘못된 주소: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' 메일러는 지원되지 않습니다.'; +$PHPMAILER_LANG['provide_address'] = '적어도 한 개 이상의 수신자 메일 주소를 제공해야 합니다.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 오류: 다음 수신자에서 오류가 발생했습니다: '; +$PHPMAILER_LANG['signing'] = '서명 오류: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP 연결을 실패하였습니다.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP 서버 오류: '; +$PHPMAILER_LANG['variable_set'] = '변수 설정 및 초기화 불가: '; +$PHPMAILER_LANG['extension_missing'] = '확장자 없음: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-lt.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-lt.php new file mode 100644 index 0000000..1253a4f --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-lt.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP klaida: autentifikacija nepavyko.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP klaida: nepavyksta prisijungti prie SMTP stoties.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP klaida: duomenys nepriimti.'; +$PHPMAILER_LANG['empty_message'] = 'Laiško turinys tuščias'; +$PHPMAILER_LANG['encoding'] = 'Neatpažinta koduotė: '; +$PHPMAILER_LANG['execute'] = 'Nepavyko įvykdyti komandos: '; +$PHPMAILER_LANG['file_access'] = 'Byla nepasiekiama: '; +$PHPMAILER_LANG['file_open'] = 'Bylos klaida: Nepavyksta atidaryti: '; +$PHPMAILER_LANG['from_failed'] = 'Neteisingas siuntėjo adresas: '; +$PHPMAILER_LANG['instantiate'] = 'Nepavyko paleisti mail funkcijos.'; +$PHPMAILER_LANG['invalid_address'] = 'Neteisingas adresas: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' pašto stotis nepalaikoma.'; +$PHPMAILER_LANG['provide_address'] = 'Nurodykite bent vieną gavėjo adresą.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP klaida: nepavyko išsiųsti šiems gavėjams: '; +$PHPMAILER_LANG['signing'] = 'Prisijungimo klaida: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP susijungimo klaida'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP stoties klaida: '; +$PHPMAILER_LANG['variable_set'] = 'Nepavyko priskirti reikšmės kintamajam: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-lv.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-lv.php new file mode 100644 index 0000000..39bf9a1 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-lv.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP kļūda: Autorizācija neizdevās.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Kļūda: Nevar izveidot savienojumu ar SMTP serveri.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Kļūda: Nepieņem informāciju.'; +$PHPMAILER_LANG['empty_message'] = 'Ziņojuma teksts ir tukšs'; +$PHPMAILER_LANG['encoding'] = 'Neatpazīts kodējums: '; +$PHPMAILER_LANG['execute'] = 'Neizdevās izpildīt komandu: '; +$PHPMAILER_LANG['file_access'] = 'Fails nav pieejams: '; +$PHPMAILER_LANG['file_open'] = 'Faila kļūda: Nevar atvērt failu: '; +$PHPMAILER_LANG['from_failed'] = 'Nepareiza sūtītāja adrese: '; +$PHPMAILER_LANG['instantiate'] = 'Nevar palaist sūtīšanas funkciju.'; +$PHPMAILER_LANG['invalid_address'] = 'Nepareiza adrese: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' sūtītājs netiek atbalstīts.'; +$PHPMAILER_LANG['provide_address'] = 'Lūdzu, norādiet vismaz vienu adresātu.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP kļūda: neizdevās nosūtīt šādiem saņēmējiem: '; +$PHPMAILER_LANG['signing'] = 'Autorizācijas kļūda: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP savienojuma kļūda'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP servera kļūda: '; +$PHPMAILER_LANG['variable_set'] = 'Nevar piešķirt mainīgā vērtību: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-mg.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-mg.php new file mode 100644 index 0000000..f4c7563 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-mg.php @@ -0,0 +1,25 @@ + + */ +$PHPMAILER_LANG['authenticate'] = 'Hadisoana SMTP: Tsy nahomby ny fanamarinana.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: Tsy afaka mampifandray amin\'ny mpampiantrano SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP diso: tsy voarakitra ny angona.'; +$PHPMAILER_LANG['empty_message'] = 'Tsy misy ny votoaty mailaka.'; +$PHPMAILER_LANG['encoding'] = 'Tsy fantatra encoding: '; +$PHPMAILER_LANG['execute'] = 'Tsy afaka manatanteraka ity baiko manaraka ity: '; +$PHPMAILER_LANG['file_access'] = 'Tsy nahomby ny fidirana amin\'ity rakitra ity: '; +$PHPMAILER_LANG['file_open'] = 'Hadisoana diso: Tsy afaka nanokatra ity file manaraka ity: '; +$PHPMAILER_LANG['from_failed'] = 'Ny adiresy iraka manaraka dia diso: '; +$PHPMAILER_LANG['instantiate'] = 'Tsy afaka nanomboka ny hetsika mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Tsy mety ny adiresy: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer tsy manohana.'; +$PHPMAILER_LANG['provide_address'] = 'Alefaso azafady iray adiresy iray farafahakeliny.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: Tsy mety ireo mpanaraka ireto: '; +$PHPMAILER_LANG['signing'] = 'Error nandritra ny sonia:'; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Tsy nahomby ny fifandraisana tamin\'ny server SMTP.'; +$PHPMAILER_LANG['smtp_error'] = 'Fahadisoana tamin\'ny server SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Tsy azo atao ny mametraka na mamerina ny variable: '; +$PHPMAILER_LANG['extension_missing'] = 'Tsy hita ny ampahany: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php new file mode 100644 index 0000000..f12a6ad --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Ralat SMTP: Tidak dapat pengesahan.'; +$PHPMAILER_LANG['connect_host'] = 'Ralat SMTP: Tidak dapat menghubungi hos pelayan SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Ralat SMTP: Data tidak diterima oleh pelayan.'; +$PHPMAILER_LANG['empty_message'] = 'Tiada isi untuk mesej'; +$PHPMAILER_LANG['encoding'] = 'Pengekodan tidak diketahui: '; +$PHPMAILER_LANG['execute'] = 'Tidak dapat melaksanakan: '; +$PHPMAILER_LANG['file_access'] = 'Tidak dapat mengakses fail: '; +$PHPMAILER_LANG['file_open'] = 'Ralat Fail: Tidak dapat membuka fail: '; +$PHPMAILER_LANG['from_failed'] = 'Berikut merupakan ralat dari alamat e-mel: '; +$PHPMAILER_LANG['instantiate'] = 'Tidak dapat memberi contoh fungsi e-mel.'; +$PHPMAILER_LANG['invalid_address'] = 'Alamat emel tidak sah: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' jenis penghantar emel tidak disokong.'; +$PHPMAILER_LANG['provide_address'] = 'Anda perlu menyediakan sekurang-kurangnya satu alamat e-mel penerima.'; +$PHPMAILER_LANG['recipients_failed'] = 'Ralat SMTP: Penerima e-mel berikut telah gagal: '; +$PHPMAILER_LANG['signing'] = 'Ralat pada tanda tangan: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() telah gagal.'; +$PHPMAILER_LANG['smtp_error'] = 'Ralat pada pelayan SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Tidak boleh menetapkan atau menetapkan semula pembolehubah: '; +$PHPMAILER_LANG['extension_missing'] = 'Sambungan hilang: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-nb.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-nb.php new file mode 100644 index 0000000..97403e7 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-nb.php @@ -0,0 +1,25 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP-fout: authenticatie mislukt.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP-fout: kon niet verbinden met SMTP-host.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-fout: data niet geaccepteerd.'; +$PHPMAILER_LANG['empty_message'] = 'Berichttekst is leeg'; +$PHPMAILER_LANG['encoding'] = 'Onbekende codering: '; +$PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: '; +$PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: '; +$PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: '; +$PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: '; +$PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.'; +$PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres: '; +$PHPMAILER_LANG['invalid_hostentry'] = 'Ongeldige hostentry: '; +$PHPMAILER_LANG['invalid_host'] = 'Ongeldige host: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.'; +$PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: '; +$PHPMAILER_LANG['signing'] = 'Signeerfout: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Verbinding mislukt.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfout: '; +$PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of resetten: '; +$PHPMAILER_LANG['extension_missing'] = 'Extensie afwezig: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-pl.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-pl.php new file mode 100644 index 0000000..3da0dee --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-pl.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.'; +$PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Erro do SMTP: Os dados foram rejeitados.'; +$PHPMAILER_LANG['empty_message'] = 'A mensagem no e-mail está vazia.'; +$PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: '; +$PHPMAILER_LANG['execute'] = 'Não foi possível executar: '; +$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder o ficheiro: '; +$PHPMAILER_LANG['file_open'] = 'Abertura do ficheiro: Não foi possível abrir o ficheiro: '; +$PHPMAILER_LANG['from_failed'] = 'Ocorreram falhas nos endereços dos seguintes remententes: '; +$PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.'; +$PHPMAILER_LANG['provide_address'] = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.'; +$PHPMAILER_LANG['recipients_failed'] = 'Erro do SMTP: O endereço do seguinte destinatário falhou: '; +$PHPMAILER_LANG['signing'] = 'Erro ao assinar: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.'; +$PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: '; +$PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt_br.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt_br.php new file mode 100644 index 0000000..62d692d --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-pt_br.php @@ -0,0 +1,29 @@ + + * @author Lucas Guimarães + * @author Phelipe Alves + * @author Fabio Beneditto + */ + +$PHPMAILER_LANG['authenticate'] = 'Erro de SMTP: Não foi possível autenticar.'; +$PHPMAILER_LANG['connect_host'] = 'Erro de SMTP: Não foi possível conectar ao servidor SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Erro de SMTP: Dados rejeitados.'; +$PHPMAILER_LANG['empty_message'] = 'Mensagem vazia'; +$PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: '; +$PHPMAILER_LANG['execute'] = 'Não foi possível executar: '; +$PHPMAILER_LANG['file_access'] = 'Não foi possível acessar o arquivo: '; +$PHPMAILER_LANG['file_open'] = 'Erro de Arquivo: Não foi possível abrir o arquivo: '; +$PHPMAILER_LANG['from_failed'] = 'Os seguintes remetentes falharam: '; +$PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.'; +$PHPMAILER_LANG['invalid_address'] = 'Endereço de e-mail inválido: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.'; +$PHPMAILER_LANG['provide_address'] = 'Você deve informar pelo menos um destinatário.'; +$PHPMAILER_LANG['recipients_failed'] = 'Erro de SMTP: Os seguintes destinatários falharam: '; +$PHPMAILER_LANG['signing'] = 'Erro de Assinatura: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.'; +$PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: '; +$PHPMAILER_LANG['extension_missing'] = 'Extensão não existe: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ro.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ro.php new file mode 100644 index 0000000..fa100ea --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ro.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Eroare SMTP: Autentificarea a eșuat.'; +$PHPMAILER_LANG['connect_host'] = 'Eroare SMTP: Conectarea la serverul SMTP a eșuat.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Eroare SMTP: Datele nu au fost acceptate.'; +$PHPMAILER_LANG['empty_message'] = 'Mesajul este gol.'; +$PHPMAILER_LANG['encoding'] = 'Encodare necunoscută: '; +$PHPMAILER_LANG['execute'] = 'Nu se poate executa următoarea comandă: '; +$PHPMAILER_LANG['file_access'] = 'Nu se poate accesa următorul fișier: '; +$PHPMAILER_LANG['file_open'] = 'Eroare fișier: Nu se poate deschide următorul fișier: '; +$PHPMAILER_LANG['from_failed'] = 'Următoarele adrese From au dat eroare: '; +$PHPMAILER_LANG['instantiate'] = 'Funcția mail nu a putut fi inițializată.'; +$PHPMAILER_LANG['invalid_address'] = 'Adresa de email nu este validă: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.'; +$PHPMAILER_LANG['provide_address'] = 'Trebuie să adăugați cel puțin o adresă de email.'; +$PHPMAILER_LANG['recipients_failed'] = 'Eroare SMTP: Următoarele adrese de email au eșuat: '; +$PHPMAILER_LANG['signing'] = 'A aparut o problemă la semnarea emailului. '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Conectarea la serverul SMTP a eșuat.'; +$PHPMAILER_LANG['smtp_error'] = 'Eroare server SMTP: '; +$PHPMAILER_LANG['variable_set'] = 'Nu se poate seta/reseta variabila. '; +$PHPMAILER_LANG['extension_missing'] = 'Lipsește extensia: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php new file mode 100644 index 0000000..720e9a1 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php @@ -0,0 +1,27 @@ + + * @author Foster Snowhill + */ + +$PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.'; +$PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к SMTP-серверу.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.'; +$PHPMAILER_LANG['encoding'] = 'Неизвестная кодировка: '; +$PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: '; +$PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: '; +$PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удаётся открыть файл: '; +$PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: '; +$PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail().'; +$PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один email-адрес получателя.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.'; +$PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: не удалась отправка таким адресатам: '; +$PHPMAILER_LANG['empty_message'] = 'Пустое сообщение'; +$PHPMAILER_LANG['invalid_address'] = 'Не отправлено из-за неправильного формата email-адреса: '; +$PHPMAILER_LANG['signing'] = 'Ошибка подписи: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Ошибка соединения с SMTP-сервером'; +$PHPMAILER_LANG['smtp_error'] = 'Ошибка SMTP-сервера: '; +$PHPMAILER_LANG['variable_set'] = 'Невозможно установить или сбросить переменную: '; +$PHPMAILER_LANG['extension_missing'] = 'Расширение отсутствует: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sk.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sk.php new file mode 100644 index 0000000..69cfb0f --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sk.php @@ -0,0 +1,27 @@ + + * @author Peter Orlický + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Error: Chyba autentifikácie.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: Nebolo možné nadviazať spojenie so SMTP serverom.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Dáta neboli prijaté'; +$PHPMAILER_LANG['empty_message'] = 'Prázdne telo správy.'; +$PHPMAILER_LANG['encoding'] = 'Neznáme kódovanie: '; +$PHPMAILER_LANG['execute'] = 'Nedá sa vykonať: '; +$PHPMAILER_LANG['file_access'] = 'Súbor nebol nájdený: '; +$PHPMAILER_LANG['file_open'] = 'File Error: Súbor sa otvoriť pre čítanie: '; +$PHPMAILER_LANG['from_failed'] = 'Následujúca adresa From je nesprávna: '; +$PHPMAILER_LANG['instantiate'] = 'Nedá sa vytvoriť inštancia emailovej funkcie.'; +$PHPMAILER_LANG['invalid_address'] = 'Neodoslané, emailová adresa je nesprávna: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' emailový klient nieje podporovaný.'; +$PHPMAILER_LANG['provide_address'] = 'Musíte zadať aspoň jednu emailovú adresu príjemcu.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: Adresy príjemcov niesu správne '; +$PHPMAILER_LANG['signing'] = 'Chyba prihlasovania: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zlyhalo.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP chyba serveru: '; +$PHPMAILER_LANG['variable_set'] = 'Nemožno nastaviť alebo resetovať premennú: '; +$PHPMAILER_LANG['extension_missing'] = 'Chýba rozšírenie: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sl.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sl.php new file mode 100644 index 0000000..1e3cb7f --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sl.php @@ -0,0 +1,27 @@ + + * @author Filip Š + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP napaka: Avtentikacija ni uspela.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP napaka: Vzpostavljanje povezave s SMTP gostiteljem ni uspelo.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP napaka: Strežnik zavrača podatke.'; +$PHPMAILER_LANG['empty_message'] = 'E-poštno sporočilo nima vsebine.'; +$PHPMAILER_LANG['encoding'] = 'Nepoznan tip kodiranja: '; +$PHPMAILER_LANG['execute'] = 'Operacija ni uspela: '; +$PHPMAILER_LANG['file_access'] = 'Nimam dostopa do datoteke: '; +$PHPMAILER_LANG['file_open'] = 'Ne morem odpreti datoteke: '; +$PHPMAILER_LANG['from_failed'] = 'Neveljaven e-naslov pošiljatelja: '; +$PHPMAILER_LANG['instantiate'] = 'Ne morem inicializirati mail funkcije.'; +$PHPMAILER_LANG['invalid_address'] = 'E-poštno sporočilo ni bilo poslano. E-naslov je neveljaven: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer ni podprt.'; +$PHPMAILER_LANG['provide_address'] = 'Prosim vnesite vsaj enega naslovnika.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP napaka: Sledeči naslovniki so neveljavni: '; +$PHPMAILER_LANG['signing'] = 'Napaka pri podpisovanju: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Ne morem vzpostaviti povezave s SMTP strežnikom.'; +$PHPMAILER_LANG['smtp_error'] = 'Napaka SMTP strežnika: '; +$PHPMAILER_LANG['variable_set'] = 'Ne morem nastaviti oz. ponastaviti spremenljivke: '; +$PHPMAILER_LANG['extension_missing'] = 'Manjkajoča razširitev: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php new file mode 100644 index 0000000..34c1e18 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php @@ -0,0 +1,27 @@ + + * @author Miloš Milanović + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP грешка: аутентификација није успела.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP грешка: повезивање са SMTP сервером није успело.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP грешка: подаци нису прихваћени.'; +$PHPMAILER_LANG['empty_message'] = 'Садржај поруке је празан.'; +$PHPMAILER_LANG['encoding'] = 'Непознато кодирање: '; +$PHPMAILER_LANG['execute'] = 'Није могуће извршити наредбу: '; +$PHPMAILER_LANG['file_access'] = 'Није могуће приступити датотеци: '; +$PHPMAILER_LANG['file_open'] = 'Није могуће отворити датотеку: '; +$PHPMAILER_LANG['from_failed'] = 'SMTP грешка: слање са следећих адреса није успело: '; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP грешка: слање на следеће адресе није успело: '; +$PHPMAILER_LANG['instantiate'] = 'Није могуће покренути mail функцију.'; +$PHPMAILER_LANG['invalid_address'] = 'Порука није послата. Неисправна адреса: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' мејлер није подржан.'; +$PHPMAILER_LANG['provide_address'] = 'Дефинишите бар једну адресу примаоца.'; +$PHPMAILER_LANG['signing'] = 'Грешка приликом пријаве: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Повезивање са SMTP сервером није успело.'; +$PHPMAILER_LANG['smtp_error'] = 'Грешка SMTP сервера: '; +$PHPMAILER_LANG['variable_set'] = 'Није могуће задати нити ресетовати променљиву: '; +$PHPMAILER_LANG['extension_missing'] = 'Недостаје проширење: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php new file mode 100644 index 0000000..4408e63 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP fel: Kunde inte autentisera.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP fel: Kunde inte ansluta till SMTP-server.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP fel: Data accepterades inte.'; +//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; +$PHPMAILER_LANG['encoding'] = 'Okänt encode-format: '; +$PHPMAILER_LANG['execute'] = 'Kunde inte köra: '; +$PHPMAILER_LANG['file_access'] = 'Ingen åtkomst till fil: '; +$PHPMAILER_LANG['file_open'] = 'Fil fel: Kunde inte öppna fil: '; +$PHPMAILER_LANG['from_failed'] = 'Följande avsändaradress är felaktig: '; +$PHPMAILER_LANG['instantiate'] = 'Kunde inte initiera e-postfunktion.'; +$PHPMAILER_LANG['invalid_address'] = 'Felaktig adress: '; +$PHPMAILER_LANG['provide_address'] = 'Du måste ange minst en mottagares e-postadress.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP fel: Följande mottagare är felaktig: '; +$PHPMAILER_LANG['signing'] = 'Signerings fel: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() misslyckades.'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP server fel: '; +$PHPMAILER_LANG['variable_set'] = 'Kunde inte definiera eller återställa variabel: '; +$PHPMAILER_LANG['extension_missing'] = 'Tillägg ej tillgängligt: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-tl.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-tl.php new file mode 100644 index 0000000..ed51d4c --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-tl.php @@ -0,0 +1,27 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP Error: Hindi mapatotohanan.'; +$PHPMAILER_LANG['connect_host'] = 'SMTP Error: Hindi makakonekta sa SMTP host.'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Ang datos ay hindi maaaring matatanggap.'; +$PHPMAILER_LANG['empty_message'] = 'Walang laman ang mensahe'; +$PHPMAILER_LANG['encoding'] = 'Hindi alam ang encoding: '; +$PHPMAILER_LANG['execute'] = 'Hindi maisasagawa: '; +$PHPMAILER_LANG['file_access'] = 'Hindi ma-access ang file: '; +$PHPMAILER_LANG['file_open'] = 'Hindi mabuksan ang file: '; +$PHPMAILER_LANG['from_failed'] = 'Ang sumusunod na address ay nabigo: '; +$PHPMAILER_LANG['instantiate'] = 'Hindi maaaring magbigay ng institusyon ang mail'; +$PHPMAILER_LANG['invalid_address'] = 'Hindi wasto ang address na naibigay: '; +$PHPMAILER_LANG['mailer_not_supported'] = 'Ang mailer ay hindi suportado'; +$PHPMAILER_LANG['provide_address'] = 'Kailangan mong magbigay ng kahit isang email address na tatanggap'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: Ang mga sumusunod na tatanggap ay nabigo: '; +$PHPMAILER_LANG['signing'] = 'Hindi ma-sign'; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Ang SMTP connect() ay nabigo'; +$PHPMAILER_LANG['smtp_error'] = 'Ang server ng SMTP ay nabigo'; +$PHPMAILER_LANG['variable_set'] = 'Hindi matatakda ang mga variables: '; +$PHPMAILER_LANG['extension_missing'] = 'Nawawala ang extension'; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php new file mode 100644 index 0000000..cfe8eaa --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php @@ -0,0 +1,30 @@ + + * @fixed by Boris Yurchenko + */ + +$PHPMAILER_LANG['authenticate'] = 'Помилка SMTP: помилка авторизації.'; +$PHPMAILER_LANG['connect_host'] = 'Помилка SMTP: не вдається під\'єднатися до SMTP-серверу.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Помилка SMTP: дані не прийнято.'; +$PHPMAILER_LANG['encoding'] = 'Невідоме кодування: '; +$PHPMAILER_LANG['execute'] = 'Неможливо виконати команду: '; +$PHPMAILER_LANG['file_access'] = 'Немає доступу до файлу: '; +$PHPMAILER_LANG['file_open'] = 'Помилка файлової системи: не вдається відкрити файл: '; +$PHPMAILER_LANG['from_failed'] = 'Невірна адреса відправника: '; +$PHPMAILER_LANG['instantiate'] = 'Неможливо запустити функцію mail().'; +$PHPMAILER_LANG['provide_address'] = 'Будь-ласка, введіть хоча б одну email-адресу отримувача.'; +$PHPMAILER_LANG['mailer_not_supported'] = ' - поштовий сервер не підтримується.'; +$PHPMAILER_LANG['recipients_failed'] = 'Помилка SMTP: не вдалося відправлення для таких отримувачів: '; +$PHPMAILER_LANG['empty_message'] = 'Пусте повідомлення'; +$PHPMAILER_LANG['invalid_address'] = 'Не відправлено через невірний формат email-адреси: '; +$PHPMAILER_LANG['signing'] = 'Помилка підпису: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Помилка з\'єднання з SMTP-сервером'; +$PHPMAILER_LANG['smtp_error'] = 'Помилка SMTP-сервера: '; +$PHPMAILER_LANG['variable_set'] = 'Неможливо встановити або скинути змінну: '; +$PHPMAILER_LANG['extension_missing'] = 'Розширення відсутнє: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-vi.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-vi.php new file mode 100644 index 0000000..c60dade --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-vi.php @@ -0,0 +1,26 @@ + + */ + +$PHPMAILER_LANG['authenticate'] = 'Lỗi SMTP: Không thể xác thực.'; +$PHPMAILER_LANG['connect_host'] = 'Lỗi SMTP: Không thể kết nối máy chủ SMTP.'; +$PHPMAILER_LANG['data_not_accepted'] = 'Lỗi SMTP: Dữ liệu không được chấp nhận.'; +$PHPMAILER_LANG['empty_message'] = 'Không có nội dung'; +$PHPMAILER_LANG['encoding'] = 'Mã hóa không xác định: '; +$PHPMAILER_LANG['execute'] = 'Không thực hiện được: '; +$PHPMAILER_LANG['file_access'] = 'Không thể truy cập tệp tin '; +$PHPMAILER_LANG['file_open'] = 'Lỗi Tập tin: Không thể mở tệp tin: '; +$PHPMAILER_LANG['from_failed'] = 'Lỗi địa chỉ gửi đi: '; +$PHPMAILER_LANG['instantiate'] = 'Không dùng được các hàm gửi thư.'; +$PHPMAILER_LANG['invalid_address'] = 'Đại chỉ emai không đúng: '; +$PHPMAILER_LANG['mailer_not_supported'] = ' trình gửi thư không được hỗ trợ.'; +$PHPMAILER_LANG['provide_address'] = 'Bạn phải cung cấp ít nhất một địa chỉ người nhận.'; +$PHPMAILER_LANG['recipients_failed'] = 'Lỗi SMTP: lỗi địa chỉ người nhận: '; +$PHPMAILER_LANG['signing'] = 'Lỗi đăng nhập: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'Lỗi kết nối với SMTP'; +$PHPMAILER_LANG['smtp_error'] = 'Lỗi máy chủ smtp '; +$PHPMAILER_LANG['variable_set'] = 'Không thể thiết lập hoặc thiết lập lại biến: '; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh.php new file mode 100644 index 0000000..3e9e358 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh.php @@ -0,0 +1,28 @@ + + * @author Peter Dave Hello <@PeterDaveHello/> + * @author Jason Chiang + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登入失敗。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連線到 SMTP 主機。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:無法接受的資料。'; +$PHPMAILER_LANG['empty_message'] = '郵件內容為空'; +$PHPMAILER_LANG['encoding'] = '未知編碼: '; +$PHPMAILER_LANG['execute'] = '無法執行:'; +$PHPMAILER_LANG['file_access'] = '無法存取檔案:'; +$PHPMAILER_LANG['file_open'] = '檔案錯誤:無法開啟檔案:'; +$PHPMAILER_LANG['from_failed'] = '發送地址錯誤:'; +$PHPMAILER_LANG['instantiate'] = '未知函數呼叫。'; +$PHPMAILER_LANG['invalid_address'] = '因為電子郵件地址無效,無法傳送: '; +$PHPMAILER_LANG['mailer_not_supported'] = '不支援的發信客戶端。'; +$PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:以下收件人地址錯誤:'; +$PHPMAILER_LANG['signing'] = '電子簽章錯誤: '; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP 連線失敗'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP 伺服器錯誤: '; +$PHPMAILER_LANG['variable_set'] = '無法設定或重設變數: '; +$PHPMAILER_LANG['extension_missing'] = '遺失模組 Extension: '; diff --git a/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh_cn.php b/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh_cn.php new file mode 100644 index 0000000..3753780 --- /dev/null +++ b/vendor/phpmailer/phpmailer/language/phpmailer.lang-zh_cn.php @@ -0,0 +1,28 @@ + + * @author young + * @author Teddysun + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。'; +$PHPMAILER_LANG['empty_message'] = '邮件正文为空。'; +$PHPMAILER_LANG['encoding'] = '未知编码:'; +$PHPMAILER_LANG['execute'] = '无法执行:'; +$PHPMAILER_LANG['file_access'] = '无法访问文件:'; +$PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; +$PHPMAILER_LANG['from_failed'] = '发送地址错误:'; +$PHPMAILER_LANG['instantiate'] = '未知函数调用。'; +$PHPMAILER_LANG['invalid_address'] = '发送失败,电子邮箱地址是无效的:'; +$PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; +$PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; +$PHPMAILER_LANG['signing'] = '登录失败:'; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP服务器连接失败。'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP服务器出错:'; +$PHPMAILER_LANG['variable_set'] = '无法设置或重置变量:'; +$PHPMAILER_LANG['extension_missing'] = '丢失模块 Extension:'; diff --git a/vendor/phpmailer/phpmailer/src/Exception.php b/vendor/phpmailer/phpmailer/src/Exception.php new file mode 100644 index 0000000..b1e552f --- /dev/null +++ b/vendor/phpmailer/phpmailer/src/Exception.php @@ -0,0 +1,39 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2017 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +namespace PHPMailer\PHPMailer; + +/** + * PHPMailer exception handler. + * + * @author Marcus Bointon + */ +class Exception extends \Exception +{ + /** + * Prettify error message output. + * + * @return string + */ + public function errorMessage() + { + return '' . htmlspecialchars($this->getMessage()) . "
\n"; + } +} diff --git a/vendor/phpmailer/phpmailer/src/OAuth.php b/vendor/phpmailer/phpmailer/src/OAuth.php new file mode 100644 index 0000000..0271963 --- /dev/null +++ b/vendor/phpmailer/phpmailer/src/OAuth.php @@ -0,0 +1,138 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2015 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +namespace PHPMailer\PHPMailer; + +use League\OAuth2\Client\Grant\RefreshToken; +use League\OAuth2\Client\Provider\AbstractProvider; +use League\OAuth2\Client\Token\AccessToken; + +/** + * OAuth - OAuth2 authentication wrapper class. + * Uses the oauth2-client package from the League of Extraordinary Packages. + * + * @see http://oauth2-client.thephpleague.com + * + * @author Marcus Bointon (Synchro/coolbru) + */ +class OAuth +{ + /** + * An instance of the League OAuth Client Provider. + * + * @var AbstractProvider + */ + protected $provider; + + /** + * The current OAuth access token. + * + * @var AccessToken + */ + protected $oauthToken; + + /** + * The user's email address, usually used as the login ID + * and also the from address when sending email. + * + * @var string + */ + protected $oauthUserEmail = ''; + + /** + * The client secret, generated in the app definition of the service you're connecting to. + * + * @var string + */ + protected $oauthClientSecret = ''; + + /** + * The client ID, generated in the app definition of the service you're connecting to. + * + * @var string + */ + protected $oauthClientId = ''; + + /** + * The refresh token, used to obtain new AccessTokens. + * + * @var string + */ + protected $oauthRefreshToken = ''; + + /** + * OAuth constructor. + * + * @param array $options Associative array containing + * `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements + */ + public function __construct($options) + { + $this->provider = $options['provider']; + $this->oauthUserEmail = $options['userName']; + $this->oauthClientSecret = $options['clientSecret']; + $this->oauthClientId = $options['clientId']; + $this->oauthRefreshToken = $options['refreshToken']; + } + + /** + * Get a new RefreshToken. + * + * @return RefreshToken + */ + protected function getGrant() + { + return new RefreshToken(); + } + + /** + * Get a new AccessToken. + * + * @return AccessToken + */ + protected function getToken() + { + return $this->provider->getAccessToken( + $this->getGrant(), + ['refresh_token' => $this->oauthRefreshToken] + ); + } + + /** + * Generate a base64-encoded OAuth token. + * + * @return string + */ + public function getOauth64() + { + // Get a new token if it's not available or has expired + if (null === $this->oauthToken || $this->oauthToken->hasExpired()) { + $this->oauthToken = $this->getToken(); + } + + return base64_encode( + 'user=' . + $this->oauthUserEmail . + "\001auth=Bearer " . + $this->oauthToken . + "\001\001" + ); + } +} diff --git a/vendor/phpmailer/phpmailer/src/PHPMailer.php b/vendor/phpmailer/phpmailer/src/PHPMailer.php new file mode 100644 index 0000000..fddad40 --- /dev/null +++ b/vendor/phpmailer/phpmailer/src/PHPMailer.php @@ -0,0 +1,4820 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2019 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +namespace PHPMailer\PHPMailer; + +/** + * PHPMailer - PHP email creation and transport class. + * + * @author Marcus Bointon (Synchro/coolbru) + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + */ +class PHPMailer +{ + const CHARSET_ASCII = 'us-ascii'; + const CHARSET_ISO88591 = 'iso-8859-1'; + const CHARSET_UTF8 = 'utf-8'; + + const CONTENT_TYPE_PLAINTEXT = 'text/plain'; + const CONTENT_TYPE_TEXT_CALENDAR = 'text/calendar'; + const CONTENT_TYPE_TEXT_HTML = 'text/html'; + const CONTENT_TYPE_MULTIPART_ALTERNATIVE = 'multipart/alternative'; + const CONTENT_TYPE_MULTIPART_MIXED = 'multipart/mixed'; + const CONTENT_TYPE_MULTIPART_RELATED = 'multipart/related'; + + const ENCODING_7BIT = '7bit'; + const ENCODING_8BIT = '8bit'; + const ENCODING_BASE64 = 'base64'; + const ENCODING_BINARY = 'binary'; + const ENCODING_QUOTED_PRINTABLE = 'quoted-printable'; + + const ENCRYPTION_STARTTLS = 'tls'; + const ENCRYPTION_SMTPS = 'ssl'; + + const ICAL_METHOD_REQUEST = 'REQUEST'; + const ICAL_METHOD_PUBLISH = 'PUBLISH'; + const ICAL_METHOD_REPLY = 'REPLY'; + const ICAL_METHOD_ADD = 'ADD'; + const ICAL_METHOD_CANCEL = 'CANCEL'; + const ICAL_METHOD_REFRESH = 'REFRESH'; + const ICAL_METHOD_COUNTER = 'COUNTER'; + const ICAL_METHOD_DECLINECOUNTER = 'DECLINECOUNTER'; + + /** + * Email priority. + * Options: null (default), 1 = High, 3 = Normal, 5 = low. + * When null, the header is not set at all. + * + * @var int|null + */ + public $Priority; + + /** + * The character set of the message. + * + * @var string + */ + public $CharSet = self::CHARSET_ISO88591; + + /** + * The MIME Content-type of the message. + * + * @var string + */ + public $ContentType = self::CONTENT_TYPE_PLAINTEXT; + + /** + * The message encoding. + * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable". + * + * @var string + */ + public $Encoding = self::ENCODING_8BIT; + + /** + * Holds the most recent mailer error message. + * + * @var string + */ + public $ErrorInfo = ''; + + /** + * The From email address for the message. + * + * @var string + */ + public $From = 'root@localhost'; + + /** + * The From name of the message. + * + * @var string + */ + public $FromName = 'Root User'; + + /** + * The envelope sender of the message. + * This will usually be turned into a Return-Path header by the receiver, + * and is the address that bounces will be sent to. + * If not empty, will be passed via `-f` to sendmail or as the 'MAIL FROM' value over SMTP. + * + * @var string + */ + public $Sender = ''; + + /** + * The Subject of the message. + * + * @var string + */ + public $Subject = ''; + + /** + * An HTML or plain text message body. + * If HTML then call isHTML(true). + * + * @var string + */ + public $Body = ''; + + /** + * The plain-text message body. + * This body can be read by mail clients that do not have HTML email + * capability such as mutt & Eudora. + * Clients that can read HTML will view the normal Body. + * + * @var string + */ + public $AltBody = ''; + + /** + * An iCal message part body. + * Only supported in simple alt or alt_inline message types + * To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator. + * + * @see http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ + * @see http://kigkonsult.se/iCalcreator/ + * + * @var string + */ + public $Ical = ''; + + /** + * Value-array of "method" in Contenttype header "text/calendar" + * + * @var string[] + */ + protected static $IcalMethods = [ + self::ICAL_METHOD_REQUEST, + self::ICAL_METHOD_PUBLISH, + self::ICAL_METHOD_REPLY, + self::ICAL_METHOD_ADD, + self::ICAL_METHOD_CANCEL, + self::ICAL_METHOD_REFRESH, + self::ICAL_METHOD_COUNTER, + self::ICAL_METHOD_DECLINECOUNTER, + ]; + + /** + * The complete compiled MIME message body. + * + * @var string + */ + protected $MIMEBody = ''; + + /** + * The complete compiled MIME message headers. + * + * @var string + */ + protected $MIMEHeader = ''; + + /** + * Extra headers that createHeader() doesn't fold in. + * + * @var string + */ + protected $mailHeader = ''; + + /** + * Word-wrap the message body to this number of chars. + * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance. + * + * @see static::STD_LINE_LENGTH + * + * @var int + */ + public $WordWrap = 0; + + /** + * Which method to use to send mail. + * Options: "mail", "sendmail", or "smtp". + * + * @var string + */ + public $Mailer = 'mail'; + + /** + * The path to the sendmail program. + * + * @var string + */ + public $Sendmail = '/usr/sbin/sendmail'; + + /** + * Whether mail() uses a fully sendmail-compatible MTA. + * One which supports sendmail's "-oi -f" options. + * + * @var bool + */ + public $UseSendmailOptions = true; + + /** + * The email address that a reading confirmation should be sent to, also known as read receipt. + * + * @var string + */ + public $ConfirmReadingTo = ''; + + /** + * The hostname to use in the Message-ID header and as default HELO string. + * If empty, PHPMailer attempts to find one with, in order, + * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value + * 'localhost.localdomain'. + * + * @see PHPMailer::$Helo + * + * @var string + */ + public $Hostname = ''; + + /** + * An ID to be used in the Message-ID header. + * If empty, a unique id will be generated. + * You can set your own, but it must be in the format "", + * as defined in RFC5322 section 3.6.4 or it will be ignored. + * + * @see https://tools.ietf.org/html/rfc5322#section-3.6.4 + * + * @var string + */ + public $MessageID = ''; + + /** + * The message Date to be used in the Date header. + * If empty, the current date will be added. + * + * @var string + */ + public $MessageDate = ''; + + /** + * SMTP hosts. + * Either a single hostname or multiple semicolon-delimited hostnames. + * You can also specify a different port + * for each host by using this format: [hostname:port] + * (e.g. "smtp1.example.com:25;smtp2.example.com"). + * You can also specify encryption type, for example: + * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465"). + * Hosts will be tried in order. + * + * @var string + */ + public $Host = 'localhost'; + + /** + * The default SMTP server port. + * + * @var int + */ + public $Port = 25; + + /** + * The SMTP HELO/EHLO name used for the SMTP connection. + * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find + * one with the same method described above for $Hostname. + * + * @see PHPMailer::$Hostname + * + * @var string + */ + public $Helo = ''; + + /** + * What kind of encryption to use on the SMTP connection. + * Options: '', static::ENCRYPTION_STARTTLS, or static::ENCRYPTION_SMTPS. + * + * @var string + */ + public $SMTPSecure = ''; + + /** + * Whether to enable TLS encryption automatically if a server supports it, + * even if `SMTPSecure` is not set to 'tls'. + * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid. + * + * @var bool + */ + public $SMTPAutoTLS = true; + + /** + * Whether to use SMTP authentication. + * Uses the Username and Password properties. + * + * @see PHPMailer::$Username + * @see PHPMailer::$Password + * + * @var bool + */ + public $SMTPAuth = false; + + /** + * Options array passed to stream_context_create when connecting via SMTP. + * + * @var array + */ + public $SMTPOptions = []; + + /** + * SMTP username. + * + * @var string + */ + public $Username = ''; + + /** + * SMTP password. + * + * @var string + */ + public $Password = ''; + + /** + * SMTP auth type. + * Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2, attempted in that order if not specified. + * + * @var string + */ + public $AuthType = ''; + + /** + * An instance of the PHPMailer OAuth class. + * + * @var OAuth + */ + protected $oauth; + + /** + * The SMTP server timeout in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2. + * + * @var int + */ + public $Timeout = 300; + + /** + * Comma separated list of DSN notifications + * 'NEVER' under no circumstances a DSN must be returned to the sender. + * If you use NEVER all other notifications will be ignored. + * 'SUCCESS' will notify you when your mail has arrived at its destination. + * 'FAILURE' will arrive if an error occurred during delivery. + * 'DELAY' will notify you if there is an unusual delay in delivery, but the actual + * delivery's outcome (success or failure) is not yet decided. + * + * @see https://tools.ietf.org/html/rfc3461 See section 4.1 for more information about NOTIFY + */ + public $dsn = ''; + + /** + * SMTP class debug output mode. + * Debug output level. + * Options: + * * SMTP::DEBUG_OFF: No output + * * SMTP::DEBUG_CLIENT: Client messages + * * SMTP::DEBUG_SERVER: Client and server messages + * * SMTP::DEBUG_CONNECTION: As SERVER plus connection status + * * SMTP::DEBUG_LOWLEVEL: Noisy, low-level data output, rarely needed + * + * @see SMTP::$do_debug + * + * @var int + */ + public $SMTPDebug = 0; + + /** + * How to handle debug output. + * Options: + * * `echo` Output plain-text as-is, appropriate for CLI + * * `html` Output escaped, line breaks converted to `
`, appropriate for browser output + * * `error_log` Output to error log as configured in php.ini + * By default PHPMailer will use `echo` if run from a `cli` or `cli-server` SAPI, `html` otherwise. + * Alternatively, you can provide a callable expecting two params: a message string and the debug level: + * + * ```php + * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; + * ``` + * + * Alternatively, you can pass in an instance of a PSR-3 compatible logger, though only `debug` + * level output is used: + * + * ```php + * $mail->Debugoutput = new myPsr3Logger; + * ``` + * + * @see SMTP::$Debugoutput + * + * @var string|callable|\Psr\Log\LoggerInterface + */ + public $Debugoutput = 'echo'; + + /** + * Whether to keep SMTP connection open after each message. + * If this is set to true then to close the connection + * requires an explicit call to smtpClose(). + * + * @var bool + */ + public $SMTPKeepAlive = false; + + /** + * Whether to split multiple to addresses into multiple messages + * or send them all in one message. + * Only supported in `mail` and `sendmail` transports, not in SMTP. + * + * @var bool + */ + public $SingleTo = false; + + /** + * Storage for addresses when SingleTo is enabled. + * + * @var array + */ + protected $SingleToArray = []; + + /** + * Whether to generate VERP addresses on send. + * Only applicable when sending via SMTP. + * + * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path + * @see http://www.postfix.org/VERP_README.html Postfix VERP info + * + * @var bool + */ + public $do_verp = false; + + /** + * Whether to allow sending messages with an empty body. + * + * @var bool + */ + public $AllowEmpty = false; + + /** + * DKIM selector. + * + * @var string + */ + public $DKIM_selector = ''; + + /** + * DKIM Identity. + * Usually the email address used as the source of the email. + * + * @var string + */ + public $DKIM_identity = ''; + + /** + * DKIM passphrase. + * Used if your key is encrypted. + * + * @var string + */ + public $DKIM_passphrase = ''; + + /** + * DKIM signing domain name. + * + * @example 'example.com' + * + * @var string + */ + public $DKIM_domain = ''; + + /** + * DKIM Copy header field values for diagnostic use. + * + * @var bool + */ + public $DKIM_copyHeaderFields = true; + + /** + * DKIM Extra signing headers. + * + * @example ['List-Unsubscribe', 'List-Help'] + * + * @var array + */ + public $DKIM_extraHeaders = []; + + /** + * DKIM private key file path. + * + * @var string + */ + public $DKIM_private = ''; + + /** + * DKIM private key string. + * + * If set, takes precedence over `$DKIM_private`. + * + * @var string + */ + public $DKIM_private_string = ''; + + /** + * Callback Action function name. + * + * The function that handles the result of the send email action. + * It is called out by send() for each email sent. + * + * Value can be any php callable: http://www.php.net/is_callable + * + * Parameters: + * bool $result result of the send action + * array $to email addresses of the recipients + * array $cc cc email addresses + * array $bcc bcc email addresses + * string $subject the subject + * string $body the email body + * string $from email address of sender + * string $extra extra information of possible use + * "smtp_transaction_id' => last smtp transaction id + * + * @var string + */ + public $action_function = ''; + + /** + * What to put in the X-Mailer header. + * Options: An empty string for PHPMailer default, whitespace/null for none, or a string to use. + * + * @var string|null + */ + public $XMailer = ''; + + /** + * Which validator to use by default when validating email addresses. + * May be a callable to inject your own validator, but there are several built-in validators. + * The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option. + * + * @see PHPMailer::validateAddress() + * + * @var string|callable + */ + public static $validator = 'php'; + + /** + * An instance of the SMTP sender class. + * + * @var SMTP + */ + protected $smtp; + + /** + * The array of 'to' names and addresses. + * + * @var array + */ + protected $to = []; + + /** + * The array of 'cc' names and addresses. + * + * @var array + */ + protected $cc = []; + + /** + * The array of 'bcc' names and addresses. + * + * @var array + */ + protected $bcc = []; + + /** + * The array of reply-to names and addresses. + * + * @var array + */ + protected $ReplyTo = []; + + /** + * An array of all kinds of addresses. + * Includes all of $to, $cc, $bcc. + * + * @see PHPMailer::$to + * @see PHPMailer::$cc + * @see PHPMailer::$bcc + * + * @var array + */ + protected $all_recipients = []; + + /** + * An array of names and addresses queued for validation. + * In send(), valid and non duplicate entries are moved to $all_recipients + * and one of $to, $cc, or $bcc. + * This array is used only for addresses with IDN. + * + * @see PHPMailer::$to + * @see PHPMailer::$cc + * @see PHPMailer::$bcc + * @see PHPMailer::$all_recipients + * + * @var array + */ + protected $RecipientsQueue = []; + + /** + * An array of reply-to names and addresses queued for validation. + * In send(), valid and non duplicate entries are moved to $ReplyTo. + * This array is used only for addresses with IDN. + * + * @see PHPMailer::$ReplyTo + * + * @var array + */ + protected $ReplyToQueue = []; + + /** + * The array of attachments. + * + * @var array + */ + protected $attachment = []; + + /** + * The array of custom headers. + * + * @var array + */ + protected $CustomHeader = []; + + /** + * The most recent Message-ID (including angular brackets). + * + * @var string + */ + protected $lastMessageID = ''; + + /** + * The message's MIME type. + * + * @var string + */ + protected $message_type = ''; + + /** + * The array of MIME boundary strings. + * + * @var array + */ + protected $boundary = []; + + /** + * The array of available languages. + * + * @var array + */ + protected $language = []; + + /** + * The number of errors encountered. + * + * @var int + */ + protected $error_count = 0; + + /** + * The S/MIME certificate file path. + * + * @var string + */ + protected $sign_cert_file = ''; + + /** + * The S/MIME key file path. + * + * @var string + */ + protected $sign_key_file = ''; + + /** + * The optional S/MIME extra certificates ("CA Chain") file path. + * + * @var string + */ + protected $sign_extracerts_file = ''; + + /** + * The S/MIME password for the key. + * Used only if the key is encrypted. + * + * @var string + */ + protected $sign_key_pass = ''; + + /** + * Whether to throw exceptions for errors. + * + * @var bool + */ + protected $exceptions = false; + + /** + * Unique ID used for message ID and boundaries. + * + * @var string + */ + protected $uniqueid = ''; + + /** + * The PHPMailer Version number. + * + * @var string + */ + const VERSION = '6.1.5'; + + /** + * Error severity: message only, continue processing. + * + * @var int + */ + const STOP_MESSAGE = 0; + + /** + * Error severity: message, likely ok to continue processing. + * + * @var int + */ + const STOP_CONTINUE = 1; + + /** + * Error severity: message, plus full stop, critical error reached. + * + * @var int + */ + const STOP_CRITICAL = 2; + + /** + * The SMTP standard CRLF line break. + * If you want to change line break format, change static::$LE, not this. + */ + const CRLF = "\r\n"; + + /** + * "Folding White Space" a white space string used for line folding. + */ + const FWS = ' '; + + /** + * SMTP RFC standard line ending; Carriage Return, Line Feed. + * + * @var string + */ + protected static $LE = self::CRLF; + + /** + * The maximum line length supported by mail(). + * + * Background: mail() will sometimes corrupt messages + * with headers headers longer than 65 chars, see #818. + * + * @var int + */ + const MAIL_MAX_LINE_LENGTH = 63; + + /** + * The maximum line length allowed by RFC 2822 section 2.1.1. + * + * @var int + */ + const MAX_LINE_LENGTH = 998; + + /** + * The lower maximum line length allowed by RFC 2822 section 2.1.1. + * This length does NOT include the line break + * 76 means that lines will be 77 or 78 chars depending on whether + * the line break format is LF or CRLF; both are valid. + * + * @var int + */ + const STD_LINE_LENGTH = 76; + + /** + * Constructor. + * + * @param bool $exceptions Should we throw external exceptions? + */ + public function __construct($exceptions = null) + { + if (null !== $exceptions) { + $this->exceptions = (bool) $exceptions; + } + //Pick an appropriate debug output format automatically + $this->Debugoutput = (strpos(PHP_SAPI, 'cli') !== false ? 'echo' : 'html'); + } + + /** + * Destructor. + */ + public function __destruct() + { + //Close any open SMTP connection nicely + $this->smtpClose(); + } + + /** + * Call mail() in a safe_mode-aware fashion. + * Also, unless sendmail_path points to sendmail (or something that + * claims to be sendmail), don't pass params (not a perfect fix, + * but it will do). + * + * @param string $to To + * @param string $subject Subject + * @param string $body Message Body + * @param string $header Additional Header(s) + * @param string|null $params Params + * + * @return bool + */ + private function mailPassthru($to, $subject, $body, $header, $params) + { + //Check overloading of mail function to avoid double-encoding + if (ini_get('mbstring.func_overload') & 1) { + $subject = $this->secureHeader($subject); + } else { + $subject = $this->encodeHeader($this->secureHeader($subject)); + } + //Calling mail() with null params breaks + if (!$this->UseSendmailOptions || null === $params) { + $result = @mail($to, $subject, $body, $header); + } else { + $result = @mail($to, $subject, $body, $header, $params); + } + + return $result; + } + + /** + * Output debugging info via user-defined method. + * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug). + * + * @see PHPMailer::$Debugoutput + * @see PHPMailer::$SMTPDebug + * + * @param string $str + */ + protected function edebug($str) + { + if ($this->SMTPDebug <= 0) { + return; + } + //Is this a PSR-3 logger? + if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { + $this->Debugoutput->debug($str); + + return; + } + //Avoid clash with built-in function names + if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) { + call_user_func($this->Debugoutput, $str, $this->SMTPDebug); + + return; + } + switch ($this->Debugoutput) { + case 'error_log': + //Don't output, just log + error_log($str); + break; + case 'html': + //Cleans up output a bit for a better looking, HTML-safe output + echo htmlentities( + preg_replace('/[\r\n]+/', '', $str), + ENT_QUOTES, + 'UTF-8' + ), "
\n"; + break; + case 'echo': + default: + //Normalize line breaks + $str = preg_replace('/\r\n|\r/m', "\n", $str); + echo gmdate('Y-m-d H:i:s'), + "\t", + //Trim trailing space + trim( + //Indent for readability, except for trailing break + str_replace( + "\n", + "\n \t ", + trim($str) + ) + ), + "\n"; + } + } + + /** + * Sets message type to HTML or plain. + * + * @param bool $isHtml True for HTML mode + */ + public function isHTML($isHtml = true) + { + if ($isHtml) { + $this->ContentType = static::CONTENT_TYPE_TEXT_HTML; + } else { + $this->ContentType = static::CONTENT_TYPE_PLAINTEXT; + } + } + + /** + * Send messages using SMTP. + */ + public function isSMTP() + { + $this->Mailer = 'smtp'; + } + + /** + * Send messages using PHP's mail() function. + */ + public function isMail() + { + $this->Mailer = 'mail'; + } + + /** + * Send messages using $Sendmail. + */ + public function isSendmail() + { + $ini_sendmail_path = ini_get('sendmail_path'); + + if (false === stripos($ini_sendmail_path, 'sendmail')) { + $this->Sendmail = '/usr/sbin/sendmail'; + } else { + $this->Sendmail = $ini_sendmail_path; + } + $this->Mailer = 'sendmail'; + } + + /** + * Send messages using qmail. + */ + public function isQmail() + { + $ini_sendmail_path = ini_get('sendmail_path'); + + if (false === stripos($ini_sendmail_path, 'qmail')) { + $this->Sendmail = '/var/qmail/bin/qmail-inject'; + } else { + $this->Sendmail = $ini_sendmail_path; + } + $this->Mailer = 'qmail'; + } + + /** + * Add a "To" address. + * + * @param string $address The email address to send to + * @param string $name + * + * @throws Exception + * + * @return bool true on success, false if address already used or invalid in some way + */ + public function addAddress($address, $name = '') + { + return $this->addOrEnqueueAnAddress('to', $address, $name); + } + + /** + * Add a "CC" address. + * + * @param string $address The email address to send to + * @param string $name + * + * @throws Exception + * + * @return bool true on success, false if address already used or invalid in some way + */ + public function addCC($address, $name = '') + { + return $this->addOrEnqueueAnAddress('cc', $address, $name); + } + + /** + * Add a "BCC" address. + * + * @param string $address The email address to send to + * @param string $name + * + * @throws Exception + * + * @return bool true on success, false if address already used or invalid in some way + */ + public function addBCC($address, $name = '') + { + return $this->addOrEnqueueAnAddress('bcc', $address, $name); + } + + /** + * Add a "Reply-To" address. + * + * @param string $address The email address to reply to + * @param string $name + * + * @throws Exception + * + * @return bool true on success, false if address already used or invalid in some way + */ + public function addReplyTo($address, $name = '') + { + return $this->addOrEnqueueAnAddress('Reply-To', $address, $name); + } + + /** + * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer + * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still + * be modified after calling this function), addition of such addresses is delayed until send(). + * Addresses that have been added already return false, but do not throw exceptions. + * + * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' + * @param string $address The email address to send, resp. to reply to + * @param string $name + * + * @throws Exception + * + * @return bool true on success, false if address already used or invalid in some way + */ + protected function addOrEnqueueAnAddress($kind, $address, $name) + { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + $pos = strrpos($address, '@'); + if (false === $pos) { + // At-sign is missing. + $error_message = sprintf( + '%s (%s): %s', + $this->lang('invalid_address'), + $kind, + $address + ); + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new Exception($error_message); + } + + return false; + } + $params = [$kind, $address, $name]; + // Enqueue addresses with IDN until we know the PHPMailer::$CharSet. + if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) { + if ('Reply-To' !== $kind) { + if (!array_key_exists($address, $this->RecipientsQueue)) { + $this->RecipientsQueue[$address] = $params; + + return true; + } + } elseif (!array_key_exists($address, $this->ReplyToQueue)) { + $this->ReplyToQueue[$address] = $params; + + return true; + } + + return false; + } + + // Immediately add standard addresses without IDN. + return call_user_func_array([$this, 'addAnAddress'], $params); + } + + /** + * Add an address to one of the recipient arrays or to the ReplyTo array. + * Addresses that have been added already return false, but do not throw exceptions. + * + * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' + * @param string $address The email address to send, resp. to reply to + * @param string $name + * + * @throws Exception + * + * @return bool true on success, false if address already used or invalid in some way + */ + protected function addAnAddress($kind, $address, $name = '') + { + if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) { + $error_message = sprintf( + '%s: %s', + $this->lang('Invalid recipient kind'), + $kind + ); + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new Exception($error_message); + } + + return false; + } + if (!static::validateAddress($address)) { + $error_message = sprintf( + '%s (%s): %s', + $this->lang('invalid_address'), + $kind, + $address + ); + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new Exception($error_message); + } + + return false; + } + if ('Reply-To' !== $kind) { + if (!array_key_exists(strtolower($address), $this->all_recipients)) { + $this->{$kind}[] = [$address, $name]; + $this->all_recipients[strtolower($address)] = true; + + return true; + } + } elseif (!array_key_exists(strtolower($address), $this->ReplyTo)) { + $this->ReplyTo[strtolower($address)] = [$address, $name]; + + return true; + } + + return false; + } + + /** + * Parse and validate a string containing one or more RFC822-style comma-separated email addresses + * of the form "display name
" into an array of name/address pairs. + * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available. + * Note that quotes in the name part are removed. + * + * @see http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation + * + * @param string $addrstr The address list string + * @param bool $useimap Whether to use the IMAP extension to parse the list + * + * @return array + */ + public static function parseAddresses($addrstr, $useimap = true) + { + $addresses = []; + if ($useimap && function_exists('imap_rfc822_parse_adrlist')) { + //Use this built-in parser if it's available + $list = imap_rfc822_parse_adrlist($addrstr, ''); + foreach ($list as $address) { + if (('.SYNTAX-ERROR.' !== $address->host) && static::validateAddress( + $address->mailbox . '@' . $address->host + )) { + $addresses[] = [ + 'name' => (property_exists($address, 'personal') ? $address->personal : ''), + 'address' => $address->mailbox . '@' . $address->host, + ]; + } + } + } else { + //Use this simpler parser + $list = explode(',', $addrstr); + foreach ($list as $address) { + $address = trim($address); + //Is there a separate name part? + if (strpos($address, '<') === false) { + //No separate name, just use the whole thing + if (static::validateAddress($address)) { + $addresses[] = [ + 'name' => '', + 'address' => $address, + ]; + } + } else { + list($name, $email) = explode('<', $address); + $email = trim(str_replace('>', '', $email)); + if (static::validateAddress($email)) { + $addresses[] = [ + 'name' => trim(str_replace(['"', "'"], '', $name)), + 'address' => $email, + ]; + } + } + } + } + + return $addresses; + } + + /** + * Set the From and FromName properties. + * + * @param string $address + * @param string $name + * @param bool $auto Whether to also set the Sender address, defaults to true + * + * @throws Exception + * + * @return bool + */ + public function setFrom($address, $name = '', $auto = true) + { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + // Don't validate now addresses with IDN. Will be done in send(). + $pos = strrpos($address, '@'); + if ((false === $pos) + || ((!$this->has8bitChars(substr($address, ++$pos)) || !static::idnSupported()) + && !static::validateAddress($address)) + ) { + $error_message = sprintf( + '%s (From): %s', + $this->lang('invalid_address'), + $address + ); + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new Exception($error_message); + } + + return false; + } + $this->From = $address; + $this->FromName = $name; + if ($auto && empty($this->Sender)) { + $this->Sender = $address; + } + + return true; + } + + /** + * Return the Message-ID header of the last email. + * Technically this is the value from the last time the headers were created, + * but it's also the message ID of the last sent message except in + * pathological cases. + * + * @return string + */ + public function getLastMessageID() + { + return $this->lastMessageID; + } + + /** + * Check that a string looks like an email address. + * Validation patterns supported: + * * `auto` Pick best pattern automatically; + * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0; + * * `pcre` Use old PCRE implementation; + * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; + * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. + * * `noregex` Don't use a regex: super fast, really dumb. + * Alternatively you may pass in a callable to inject your own validator, for example: + * + * ```php + * PHPMailer::validateAddress('user@example.com', function($address) { + * return (strpos($address, '@') !== false); + * }); + * ``` + * + * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator. + * + * @param string $address The email address to check + * @param string|callable $patternselect Which pattern to use + * + * @return bool + */ + public static function validateAddress($address, $patternselect = null) + { + if (null === $patternselect) { + $patternselect = static::$validator; + } + if (is_callable($patternselect)) { + return $patternselect($address); + } + //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 + if (strpos($address, "\n") !== false || strpos($address, "\r") !== false) { + return false; + } + switch ($patternselect) { + case 'pcre': //Kept for BC + case 'pcre8': + /* + * A more complex and more permissive version of the RFC5322 regex on which FILTER_VALIDATE_EMAIL + * is based. + * In addition to the addresses allowed by filter_var, also permits: + * * dotless domains: `a@b` + * * comments: `1234 @ local(blah) .machine .example` + * * quoted elements: `'"test blah"@example.org'` + * * numeric TLDs: `a@b.123` + * * unbracketed IPv4 literals: `a@192.168.0.1` + * * IPv6 literals: 'first.last@[IPv6:a1::]' + * Not all of these will necessarily work for sending! + * + * @see http://squiloople.com/2009/12/20/email-address-validation/ + * @copyright 2009-2010 Michael Rushton + * Feel free to use and redistribute this code. But please keep this copyright notice. + */ + return (bool) preg_match( + '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . + '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' . + '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' . + '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' . + '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' . + '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' . + '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' . + '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' . + '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', + $address + ); + case 'html5': + /* + * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements. + * + * @see http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email) + */ + return (bool) preg_match( + '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' . + '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', + $address + ); + case 'php': + default: + return filter_var($address, FILTER_VALIDATE_EMAIL) !== false; + } + } + + /** + * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the + * `intl` and `mbstring` PHP extensions. + * + * @return bool `true` if required functions for IDN support are present + */ + public static function idnSupported() + { + return function_exists('idn_to_ascii') && function_exists('mb_convert_encoding'); + } + + /** + * Converts IDN in given email address to its ASCII form, also known as punycode, if possible. + * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet. + * This function silently returns unmodified address if: + * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form) + * - Conversion to punycode is impossible (e.g. required PHP functions are not available) + * or fails for any reason (e.g. domain contains characters not allowed in an IDN). + * + * @see PHPMailer::$CharSet + * + * @param string $address The email address to convert + * + * @return string The encoded address in ASCII form + */ + public function punyencodeAddress($address) + { + // Verify we have required functions, CharSet, and at-sign. + $pos = strrpos($address, '@'); + if (!empty($this->CharSet) && + false !== $pos && + static::idnSupported() + ) { + $domain = substr($address, ++$pos); + // Verify CharSet string is a valid one, and domain properly encoded in this CharSet. + if ($this->has8bitChars($domain) && @mb_check_encoding($domain, $this->CharSet)) { + $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet); + //Ignore IDE complaints about this line - method signature changed in PHP 5.4 + $errorcode = 0; + if (defined('INTL_IDNA_VARIANT_UTS46')) { + $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_UTS46); + } elseif (defined('INTL_IDNA_VARIANT_2003')) { + $punycode = idn_to_ascii($domain, $errorcode, INTL_IDNA_VARIANT_2003); + } else { + $punycode = idn_to_ascii($domain, $errorcode); + } + if (false !== $punycode) { + return substr($address, 0, $pos) . $punycode; + } + } + } + + return $address; + } + + /** + * Create a message and send it. + * Uses the sending method specified by $Mailer. + * + * @throws Exception + * + * @return bool false on error - See the ErrorInfo property for details of the error + */ + public function send() + { + try { + if (!$this->preSend()) { + return false; + } + + return $this->postSend(); + } catch (Exception $exc) { + $this->mailHeader = ''; + $this->setError($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + + return false; + } + } + + /** + * Prepare a message for sending. + * + * @throws Exception + * + * @return bool + */ + public function preSend() + { + if ('smtp' === $this->Mailer + || ('mail' === $this->Mailer && stripos(PHP_OS, 'WIN') === 0) + ) { + //SMTP mandates RFC-compliant line endings + //and it's also used with mail() on Windows + static::setLE(self::CRLF); + } else { + //Maintain backward compatibility with legacy Linux command line mailers + static::setLE(PHP_EOL); + } + //Check for buggy PHP versions that add a header with an incorrect line break + if ('mail' === $this->Mailer + && ((PHP_VERSION_ID >= 70000 && PHP_VERSION_ID < 70017) + || (PHP_VERSION_ID >= 70100 && PHP_VERSION_ID < 70103)) + && ini_get('mail.add_x_header') === '1' + && stripos(PHP_OS, 'WIN') === 0 + ) { + trigger_error( + 'Your version of PHP is affected by a bug that may result in corrupted messages.' . + ' To fix it, switch to sending using SMTP, disable the mail.add_x_header option in' . + ' your php.ini, switch to MacOS or Linux, or upgrade your PHP to version 7.0.17+ or 7.1.3+.', + E_USER_WARNING + ); + } + + try { + $this->error_count = 0; // Reset errors + $this->mailHeader = ''; + + // Dequeue recipient and Reply-To addresses with IDN + foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) { + $params[1] = $this->punyencodeAddress($params[1]); + call_user_func_array([$this, 'addAnAddress'], $params); + } + if (count($this->to) + count($this->cc) + count($this->bcc) < 1) { + throw new Exception($this->lang('provide_address'), self::STOP_CRITICAL); + } + + // Validate From, Sender, and ConfirmReadingTo addresses + foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) { + $this->$address_kind = trim($this->$address_kind); + if (empty($this->$address_kind)) { + continue; + } + $this->$address_kind = $this->punyencodeAddress($this->$address_kind); + if (!static::validateAddress($this->$address_kind)) { + $error_message = sprintf( + '%s (%s): %s', + $this->lang('invalid_address'), + $address_kind, + $this->$address_kind + ); + $this->setError($error_message); + $this->edebug($error_message); + if ($this->exceptions) { + throw new Exception($error_message); + } + + return false; + } + } + + // Set whether the message is multipart/alternative + if ($this->alternativeExists()) { + $this->ContentType = static::CONTENT_TYPE_MULTIPART_ALTERNATIVE; + } + + $this->setMessageType(); + // Refuse to send an empty message unless we are specifically allowing it + if (!$this->AllowEmpty && empty($this->Body)) { + throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL); + } + + //Trim subject consistently + $this->Subject = trim($this->Subject); + // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding) + $this->MIMEHeader = ''; + $this->MIMEBody = $this->createBody(); + // createBody may have added some headers, so retain them + $tempheaders = $this->MIMEHeader; + $this->MIMEHeader = $this->createHeader(); + $this->MIMEHeader .= $tempheaders; + + // To capture the complete message when using mail(), create + // an extra header list which createHeader() doesn't fold in + if ('mail' === $this->Mailer) { + if (count($this->to) > 0) { + $this->mailHeader .= $this->addrAppend('To', $this->to); + } else { + $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;'); + } + $this->mailHeader .= $this->headerLine( + 'Subject', + $this->encodeHeader($this->secureHeader($this->Subject)) + ); + } + + // Sign with DKIM if enabled + if (!empty($this->DKIM_domain) + && !empty($this->DKIM_selector) + && (!empty($this->DKIM_private_string) + || (!empty($this->DKIM_private) + && static::isPermittedPath($this->DKIM_private) + && file_exists($this->DKIM_private) + ) + ) + ) { + $header_dkim = $this->DKIM_Add( + $this->MIMEHeader . $this->mailHeader, + $this->encodeHeader($this->secureHeader($this->Subject)), + $this->MIMEBody + ); + $this->MIMEHeader = static::stripTrailingWSP($this->MIMEHeader) . static::$LE . + static::normalizeBreaks($header_dkim) . static::$LE; + } + + return true; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + + return false; + } + } + + /** + * Actually send a message via the selected mechanism. + * + * @throws Exception + * + * @return bool + */ + public function postSend() + { + try { + // Choose the mailer and send through it + switch ($this->Mailer) { + case 'sendmail': + case 'qmail': + return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody); + case 'smtp': + return $this->smtpSend($this->MIMEHeader, $this->MIMEBody); + case 'mail': + return $this->mailSend($this->MIMEHeader, $this->MIMEBody); + default: + $sendMethod = $this->Mailer . 'Send'; + if (method_exists($this, $sendMethod)) { + return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody); + } + + return $this->mailSend($this->MIMEHeader, $this->MIMEBody); + } + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + } + + return false; + } + + /** + * Send mail using the $Sendmail program. + * + * @see PHPMailer::$Sendmail + * + * @param string $header The message headers + * @param string $body The message body + * + * @throws Exception + * + * @return bool + */ + protected function sendmailSend($header, $body) + { + $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; + + // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. + if (!empty($this->Sender) && self::isShellSafe($this->Sender)) { + if ('qmail' === $this->Mailer) { + $sendmailFmt = '%s -f%s'; + } else { + $sendmailFmt = '%s -oi -f%s -t'; + } + } elseif ('qmail' === $this->Mailer) { + $sendmailFmt = '%s'; + } else { + $sendmailFmt = '%s -oi -t'; + } + + $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender); + + if ($this->SingleTo) { + foreach ($this->SingleToArray as $toAddr) { + $mail = @popen($sendmail, 'w'); + if (!$mail) { + throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fwrite($mail, 'To: ' . $toAddr . "\n"); + fwrite($mail, $header); + fwrite($mail, $body); + $result = pclose($mail); + $this->doCallback( + ($result === 0), + [$toAddr], + $this->cc, + $this->bcc, + $this->Subject, + $body, + $this->From, + [] + ); + if (0 !== $result) { + throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + } else { + $mail = @popen($sendmail, 'w'); + if (!$mail) { + throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fwrite($mail, $header); + fwrite($mail, $body); + $result = pclose($mail); + $this->doCallback( + ($result === 0), + $this->to, + $this->cc, + $this->bcc, + $this->Subject, + $body, + $this->From, + [] + ); + if (0 !== $result) { + throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + + return true; + } + + /** + * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters. + * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows. + * + * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report + * + * @param string $string The string to be validated + * + * @return bool + */ + protected static function isShellSafe($string) + { + // Future-proof + if (escapeshellcmd($string) !== $string + || !in_array(escapeshellarg($string), ["'$string'", "\"$string\""]) + ) { + return false; + } + + $length = strlen($string); + + for ($i = 0; $i < $length; ++$i) { + $c = $string[$i]; + + // All other characters have a special meaning in at least one common shell, including = and +. + // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here. + // Note that this does permit non-Latin alphanumeric characters based on the current locale. + if (!ctype_alnum($c) && strpos('@_-.', $c) === false) { + return false; + } + } + + return true; + } + + /** + * Check whether a file path is of a permitted type. + * Used to reject URLs and phar files from functions that access local file paths, + * such as addAttachment. + * + * @param string $path A relative or absolute path to a file + * + * @return bool + */ + protected static function isPermittedPath($path) + { + return !preg_match('#^[a-z]+://#i', $path); + } + + /** + * Send mail using the PHP mail() function. + * + * @see http://www.php.net/manual/en/book.mail.php + * + * @param string $header The message headers + * @param string $body The message body + * + * @throws Exception + * + * @return bool + */ + protected function mailSend($header, $body) + { + $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; + + $toArr = []; + foreach ($this->to as $toaddr) { + $toArr[] = $this->addrFormat($toaddr); + } + $to = implode(', ', $toArr); + + $params = null; + //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver + //A space after `-f` is optional, but there is a long history of its presence + //causing problems, so we don't use one + //Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html + //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html + //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html + //Example problem: https://www.drupal.org/node/1057954 + // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. + if (!empty($this->Sender) && static::validateAddress($this->Sender) && self::isShellSafe($this->Sender)) { + $params = sprintf('-f%s', $this->Sender); + } + if (!empty($this->Sender) && static::validateAddress($this->Sender)) { + $old_from = ini_get('sendmail_from'); + ini_set('sendmail_from', $this->Sender); + } + $result = false; + if ($this->SingleTo && count($toArr) > 1) { + foreach ($toArr as $toAddr) { + $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); + $this->doCallback($result, [$toAddr], $this->cc, $this->bcc, $this->Subject, $body, $this->From, []); + } + } else { + $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params); + $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From, []); + } + if (isset($old_from)) { + ini_set('sendmail_from', $old_from); + } + if (!$result) { + throw new Exception($this->lang('instantiate'), self::STOP_CRITICAL); + } + + return true; + } + + /** + * Get an instance to use for SMTP operations. + * Override this function to load your own SMTP implementation, + * or set one with setSMTPInstance. + * + * @return SMTP + */ + public function getSMTPInstance() + { + if (!is_object($this->smtp)) { + $this->smtp = new SMTP(); + } + + return $this->smtp; + } + + /** + * Provide an instance to use for SMTP operations. + * + * @return SMTP + */ + public function setSMTPInstance(SMTP $smtp) + { + $this->smtp = $smtp; + + return $this->smtp; + } + + /** + * Send mail via SMTP. + * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. + * + * @see PHPMailer::setSMTPInstance() to use a different class. + * + * @uses \PHPMailer\PHPMailer\SMTP + * + * @param string $header The message headers + * @param string $body The message body + * + * @throws Exception + * + * @return bool + */ + protected function smtpSend($header, $body) + { + $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; + $bad_rcpt = []; + if (!$this->smtpConnect($this->SMTPOptions)) { + throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); + } + //Sender already validated in preSend() + if ('' === $this->Sender) { + $smtp_from = $this->From; + } else { + $smtp_from = $this->Sender; + } + if (!$this->smtp->mail($smtp_from)) { + $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); + throw new Exception($this->ErrorInfo, self::STOP_CRITICAL); + } + + $callbacks = []; + // Attempt to send to all recipients + foreach ([$this->to, $this->cc, $this->bcc] as $togroup) { + foreach ($togroup as $to) { + if (!$this->smtp->recipient($to[0], $this->dsn)) { + $error = $this->smtp->getError(); + $bad_rcpt[] = ['to' => $to[0], 'error' => $error['detail']]; + $isSent = false; + } else { + $isSent = true; + } + + $callbacks[] = ['issent'=>$isSent, 'to'=>$to[0]]; + } + } + + // Only send the DATA command if we have viable recipients + if ((count($this->all_recipients) > count($bad_rcpt)) && !$this->smtp->data($header . $body)) { + throw new Exception($this->lang('data_not_accepted'), self::STOP_CRITICAL); + } + + $smtp_transaction_id = $this->smtp->getLastTransactionID(); + + if ($this->SMTPKeepAlive) { + $this->smtp->reset(); + } else { + $this->smtp->quit(); + $this->smtp->close(); + } + + foreach ($callbacks as $cb) { + $this->doCallback( + $cb['issent'], + [$cb['to']], + [], + [], + $this->Subject, + $body, + $this->From, + ['smtp_transaction_id' => $smtp_transaction_id] + ); + } + + //Create error message for any bad addresses + if (count($bad_rcpt) > 0) { + $errstr = ''; + foreach ($bad_rcpt as $bad) { + $errstr .= $bad['to'] . ': ' . $bad['error']; + } + throw new Exception($this->lang('recipients_failed') . $errstr, self::STOP_CONTINUE); + } + + return true; + } + + /** + * Initiate a connection to an SMTP server. + * Returns false if the operation failed. + * + * @param array $options An array of options compatible with stream_context_create() + * + * @throws Exception + * + * @uses \PHPMailer\PHPMailer\SMTP + * + * @return bool + */ + public function smtpConnect($options = null) + { + if (null === $this->smtp) { + $this->smtp = $this->getSMTPInstance(); + } + + //If no options are provided, use whatever is set in the instance + if (null === $options) { + $options = $this->SMTPOptions; + } + + // Already connected? + if ($this->smtp->connected()) { + return true; + } + + $this->smtp->setTimeout($this->Timeout); + $this->smtp->setDebugLevel($this->SMTPDebug); + $this->smtp->setDebugOutput($this->Debugoutput); + $this->smtp->setVerp($this->do_verp); + $hosts = explode(';', $this->Host); + $lastexception = null; + + foreach ($hosts as $hostentry) { + $hostinfo = []; + if (!preg_match( + '/^(?:(ssl|tls):\/\/)?(.+?)(?::(\d+))?$/', + trim($hostentry), + $hostinfo + )) { + $this->edebug($this->lang('invalid_hostentry') . ' ' . trim($hostentry)); + // Not a valid host entry + continue; + } + // $hostinfo[1]: optional ssl or tls prefix + // $hostinfo[2]: the hostname + // $hostinfo[3]: optional port number + // The host string prefix can temporarily override the current setting for SMTPSecure + // If it's not specified, the default value is used + + //Check the host name is a valid name or IP address before trying to use it + if (!static::isValidHost($hostinfo[2])) { + $this->edebug($this->lang('invalid_host') . ' ' . $hostinfo[2]); + continue; + } + $prefix = ''; + $secure = $this->SMTPSecure; + $tls = (static::ENCRYPTION_STARTTLS === $this->SMTPSecure); + if ('ssl' === $hostinfo[1] || ('' === $hostinfo[1] && static::ENCRYPTION_SMTPS === $this->SMTPSecure)) { + $prefix = 'ssl://'; + $tls = false; // Can't have SSL and TLS at the same time + $secure = static::ENCRYPTION_SMTPS; + } elseif ('tls' === $hostinfo[1]) { + $tls = true; + // tls doesn't use a prefix + $secure = static::ENCRYPTION_STARTTLS; + } + //Do we need the OpenSSL extension? + $sslext = defined('OPENSSL_ALGO_SHA256'); + if (static::ENCRYPTION_STARTTLS === $secure || static::ENCRYPTION_SMTPS === $secure) { + //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled + if (!$sslext) { + throw new Exception($this->lang('extension_missing') . 'openssl', self::STOP_CRITICAL); + } + } + $host = $hostinfo[2]; + $port = $this->Port; + if (array_key_exists(3, $hostinfo) && is_numeric($hostinfo[3]) && $hostinfo[3] > 0 && $hostinfo[3] < 65536) { + $port = (int) $hostinfo[3]; + } + if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { + try { + if ($this->Helo) { + $hello = $this->Helo; + } else { + $hello = $this->serverHostname(); + } + $this->smtp->hello($hello); + //Automatically enable TLS encryption if: + // * it's not disabled + // * we have openssl extension + // * we are not already using SSL + // * the server offers STARTTLS + if ($this->SMTPAutoTLS && $sslext && 'ssl' !== $secure && $this->smtp->getServerExt('STARTTLS')) { + $tls = true; + } + if ($tls) { + if (!$this->smtp->startTLS()) { + throw new Exception($this->lang('connect_host')); + } + // We must resend EHLO after TLS negotiation + $this->smtp->hello($hello); + } + if ($this->SMTPAuth && !$this->smtp->authenticate( + $this->Username, + $this->Password, + $this->AuthType, + $this->oauth + )) { + throw new Exception($this->lang('authenticate')); + } + + return true; + } catch (Exception $exc) { + $lastexception = $exc; + $this->edebug($exc->getMessage()); + // We must have connected, but then failed TLS or Auth, so close connection nicely + $this->smtp->quit(); + } + } + } + // If we get here, all connection attempts have failed, so close connection hard + $this->smtp->close(); + // As we've caught all exceptions, just report whatever the last one was + if ($this->exceptions && null !== $lastexception) { + throw $lastexception; + } + + return false; + } + + /** + * Close the active SMTP session if one exists. + */ + public function smtpClose() + { + if ((null !== $this->smtp) && $this->smtp->connected()) { + $this->smtp->quit(); + $this->smtp->close(); + } + } + + /** + * Set the language for error messages. + * Returns false if it cannot load the language file. + * The default language is English. + * + * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr") + * @param string $lang_path Path to the language file directory, with trailing separator (slash) + * + * @return bool + */ + public function setLanguage($langcode = 'en', $lang_path = '') + { + // Backwards compatibility for renamed language codes + $renamed_langcodes = [ + 'br' => 'pt_br', + 'cz' => 'cs', + 'dk' => 'da', + 'no' => 'nb', + 'se' => 'sv', + 'rs' => 'sr', + 'tg' => 'tl', + ]; + + if (isset($renamed_langcodes[$langcode])) { + $langcode = $renamed_langcodes[$langcode]; + } + + // Define full set of translatable strings in English + $PHPMAILER_LANG = [ + 'authenticate' => 'SMTP Error: Could not authenticate.', + 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', + 'data_not_accepted' => 'SMTP Error: data not accepted.', + 'empty_message' => 'Message body empty', + 'encoding' => 'Unknown encoding: ', + 'execute' => 'Could not execute: ', + 'file_access' => 'Could not access file: ', + 'file_open' => 'File Error: Could not open file: ', + 'from_failed' => 'The following From address failed: ', + 'instantiate' => 'Could not instantiate mail function.', + 'invalid_address' => 'Invalid address: ', + 'invalid_hostentry' => 'Invalid hostentry: ', + 'invalid_host' => 'Invalid host: ', + 'mailer_not_supported' => ' mailer is not supported.', + 'provide_address' => 'You must provide at least one recipient email address.', + 'recipients_failed' => 'SMTP Error: The following recipients failed: ', + 'signing' => 'Signing Error: ', + 'smtp_connect_failed' => 'SMTP connect() failed.', + 'smtp_error' => 'SMTP server error: ', + 'variable_set' => 'Cannot set or reset variable: ', + 'extension_missing' => 'Extension missing: ', + ]; + if (empty($lang_path)) { + // Calculate an absolute path so it can work if CWD is not here + $lang_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR; + } + //Validate $langcode + if (!preg_match('/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) { + $langcode = 'en'; + } + $foundlang = true; + $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php'; + // There is no English translation file + if ('en' !== $langcode) { + // Make sure language file path is readable + if (!static::isPermittedPath($lang_file) || !file_exists($lang_file)) { + $foundlang = false; + } else { + // Overwrite language-specific strings. + // This way we'll never have missing translation keys. + $foundlang = include $lang_file; + } + } + $this->language = $PHPMAILER_LANG; + + return (bool) $foundlang; // Returns false if language not found + } + + /** + * Get the array of strings for the current language. + * + * @return array + */ + public function getTranslations() + { + return $this->language; + } + + /** + * Create recipient headers. + * + * @param string $type + * @param array $addr An array of recipients, + * where each recipient is a 2-element indexed array with element 0 containing an address + * and element 1 containing a name, like: + * [['joe@example.com', 'Joe User'], ['zoe@example.com', 'Zoe User']] + * + * @return string + */ + public function addrAppend($type, $addr) + { + $addresses = []; + foreach ($addr as $address) { + $addresses[] = $this->addrFormat($address); + } + + return $type . ': ' . implode(', ', $addresses) . static::$LE; + } + + /** + * Format an address for use in a message header. + * + * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name like + * ['joe@example.com', 'Joe User'] + * + * @return string + */ + public function addrFormat($addr) + { + if (empty($addr[1])) { // No name provided + return $this->secureHeader($addr[0]); + } + + return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . + ' <' . $this->secureHeader($addr[0]) . '>'; + } + + /** + * Word-wrap message. + * For use with mailers that do not automatically perform wrapping + * and for quoted-printable encoded messages. + * Original written by philippe. + * + * @param string $message The message to wrap + * @param int $length The line length to wrap to + * @param bool $qp_mode Whether to run in Quoted-Printable mode + * + * @return string + */ + public function wrapText($message, $length, $qp_mode = false) + { + if ($qp_mode) { + $soft_break = sprintf(' =%s', static::$LE); + } else { + $soft_break = static::$LE; + } + // If utf-8 encoding is used, we will need to make sure we don't + // split multibyte characters when we wrap + $is_utf8 = static::CHARSET_UTF8 === strtolower($this->CharSet); + $lelen = strlen(static::$LE); + $crlflen = strlen(static::$LE); + + $message = static::normalizeBreaks($message); + //Remove a trailing line break + if (substr($message, -$lelen) === static::$LE) { + $message = substr($message, 0, -$lelen); + } + + //Split message into lines + $lines = explode(static::$LE, $message); + //Message will be rebuilt in here + $message = ''; + foreach ($lines as $line) { + $words = explode(' ', $line); + $buf = ''; + $firstword = true; + foreach ($words as $word) { + if ($qp_mode && (strlen($word) > $length)) { + $space_left = $length - strlen($buf) - $crlflen; + if (!$firstword) { + if ($space_left > 20) { + $len = $space_left; + if ($is_utf8) { + $len = $this->utf8CharBoundary($word, $len); + } elseif ('=' === substr($word, $len - 1, 1)) { + --$len; + } elseif ('=' === substr($word, $len - 2, 1)) { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = substr($word, $len); + $buf .= ' ' . $part; + $message .= $buf . sprintf('=%s', static::$LE); + } else { + $message .= $buf . $soft_break; + } + $buf = ''; + } + while ($word !== '') { + if ($length <= 0) { + break; + } + $len = $length; + if ($is_utf8) { + $len = $this->utf8CharBoundary($word, $len); + } elseif ('=' === substr($word, $len - 1, 1)) { + --$len; + } elseif ('=' === substr($word, $len - 2, 1)) { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = (string) substr($word, $len); + + if ($word !== '') { + $message .= $part . sprintf('=%s', static::$LE); + } else { + $buf = $part; + } + } + } else { + $buf_o = $buf; + if (!$firstword) { + $buf .= ' '; + } + $buf .= $word; + + if ('' !== $buf_o && strlen($buf) > $length) { + $message .= $buf_o . $soft_break; + $buf = $word; + } + } + $firstword = false; + } + $message .= $buf . static::$LE; + } + + return $message; + } + + /** + * Find the last character boundary prior to $maxLength in a utf-8 + * quoted-printable encoded string. + * Original written by Colin Brown. + * + * @param string $encodedText utf-8 QP text + * @param int $maxLength Find the last character boundary prior to this length + * + * @return int + */ + public function utf8CharBoundary($encodedText, $maxLength) + { + $foundSplitPos = false; + $lookBack = 3; + while (!$foundSplitPos) { + $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); + $encodedCharPos = strpos($lastChunk, '='); + if (false !== $encodedCharPos) { + // Found start of encoded character byte within $lookBack block. + // Check the encoded byte value (the 2 chars after the '=') + $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); + $dec = hexdec($hex); + if ($dec < 128) { + // Single byte character. + // If the encoded char was found at pos 0, it will fit + // otherwise reduce maxLength to start of the encoded char + if ($encodedCharPos > 0) { + $maxLength -= $lookBack - $encodedCharPos; + } + $foundSplitPos = true; + } elseif ($dec >= 192) { + // First byte of a multi byte character + // Reduce maxLength to split at start of character + $maxLength -= $lookBack - $encodedCharPos; + $foundSplitPos = true; + } elseif ($dec < 192) { + // Middle byte of a multi byte character, look further back + $lookBack += 3; + } + } else { + // No encoded character found + $foundSplitPos = true; + } + } + + return $maxLength; + } + + /** + * Apply word wrapping to the message body. + * Wraps the message body to the number of chars set in the WordWrap property. + * You should only do this to plain-text bodies as wrapping HTML tags may break them. + * This is called automatically by createBody(), so you don't need to call it yourself. + */ + public function setWordWrap() + { + if ($this->WordWrap < 1) { + return; + } + + switch ($this->message_type) { + case 'alt': + case 'alt_inline': + case 'alt_attach': + case 'alt_inline_attach': + $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap); + break; + default: + $this->Body = $this->wrapText($this->Body, $this->WordWrap); + break; + } + } + + /** + * Assemble message headers. + * + * @return string The assembled headers + */ + public function createHeader() + { + $result = ''; + + $result .= $this->headerLine('Date', '' === $this->MessageDate ? self::rfcDate() : $this->MessageDate); + + // To be created automatically by mail() + if ($this->SingleTo) { + if ('mail' !== $this->Mailer) { + foreach ($this->to as $toaddr) { + $this->SingleToArray[] = $this->addrFormat($toaddr); + } + } + } elseif (count($this->to) > 0) { + if ('mail' !== $this->Mailer) { + $result .= $this->addrAppend('To', $this->to); + } + } elseif (count($this->cc) === 0) { + $result .= $this->headerLine('To', 'undisclosed-recipients:;'); + } + + $result .= $this->addrAppend('From', [[trim($this->From), $this->FromName]]); + + // sendmail and mail() extract Cc from the header before sending + if (count($this->cc) > 0) { + $result .= $this->addrAppend('Cc', $this->cc); + } + + // sendmail and mail() extract Bcc from the header before sending + if (( + 'sendmail' === $this->Mailer || 'qmail' === $this->Mailer || 'mail' === $this->Mailer + ) + && count($this->bcc) > 0 + ) { + $result .= $this->addrAppend('Bcc', $this->bcc); + } + + if (count($this->ReplyTo) > 0) { + $result .= $this->addrAppend('Reply-To', $this->ReplyTo); + } + + // mail() sets the subject itself + if ('mail' !== $this->Mailer) { + $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); + } + + // Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 + // https://tools.ietf.org/html/rfc5322#section-3.6.4 + if ('' !== $this->MessageID && preg_match('/^<.*@.*>$/', $this->MessageID)) { + $this->lastMessageID = $this->MessageID; + } else { + $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname()); + } + $result .= $this->headerLine('Message-ID', $this->lastMessageID); + if (null !== $this->Priority) { + $result .= $this->headerLine('X-Priority', $this->Priority); + } + if ('' === $this->XMailer) { + $result .= $this->headerLine( + 'X-Mailer', + 'PHPMailer ' . self::VERSION . ' (https://github.com/PHPMailer/PHPMailer)' + ); + } else { + $myXmailer = trim($this->XMailer); + if ($myXmailer) { + $result .= $this->headerLine('X-Mailer', $myXmailer); + } + } + + if ('' !== $this->ConfirmReadingTo) { + $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>'); + } + + // Add custom headers + foreach ($this->CustomHeader as $header) { + $result .= $this->headerLine( + trim($header[0]), + $this->encodeHeader(trim($header[1])) + ); + } + if (!$this->sign_key_file) { + $result .= $this->headerLine('MIME-Version', '1.0'); + $result .= $this->getMailMIME(); + } + + return $result; + } + + /** + * Get the message MIME type headers. + * + * @return string + */ + public function getMailMIME() + { + $result = ''; + $ismultipart = true; + switch ($this->message_type) { + case 'inline': + $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';'); + $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"'); + break; + case 'attach': + case 'inline_attach': + case 'alt_attach': + case 'alt_inline_attach': + $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_MIXED . ';'); + $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"'); + break; + case 'alt': + case 'alt_inline': + $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';'); + $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"'); + break; + default: + // Catches case 'plain': and case '': + $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet); + $ismultipart = false; + break; + } + // RFC1341 part 5 says 7bit is assumed if not specified + if (static::ENCODING_7BIT !== $this->Encoding) { + // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE + if ($ismultipart) { + if (static::ENCODING_8BIT === $this->Encoding) { + $result .= $this->headerLine('Content-Transfer-Encoding', static::ENCODING_8BIT); + } + // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible + } else { + $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding); + } + } + + if ('mail' !== $this->Mailer) { +// $result .= static::$LE; + } + + return $result; + } + + /** + * Returns the whole MIME message. + * Includes complete headers and body. + * Only valid post preSend(). + * + * @see PHPMailer::preSend() + * + * @return string + */ + public function getSentMIMEMessage() + { + return static::stripTrailingWSP($this->MIMEHeader . $this->mailHeader) . + static::$LE . static::$LE . $this->MIMEBody; + } + + /** + * Create a unique ID to use for boundaries. + * + * @return string + */ + protected function generateId() + { + $len = 32; //32 bytes = 256 bits + $bytes = ''; + if (function_exists('random_bytes')) { + try { + $bytes = random_bytes($len); + } catch (\Exception $e) { + //Do nothing + } + } elseif (function_exists('openssl_random_pseudo_bytes')) { + /** @noinspection CryptographicallySecureRandomnessInspection */ + $bytes = openssl_random_pseudo_bytes($len); + } + if ($bytes === '') { + //We failed to produce a proper random string, so make do. + //Use a hash to force the length to the same as the other methods + $bytes = hash('sha256', uniqid((string) mt_rand(), true), true); + } + + //We don't care about messing up base64 format here, just want a random string + return str_replace(['=', '+', '/'], '', base64_encode(hash('sha256', $bytes, true))); + } + + /** + * Assemble the message body. + * Returns an empty string on failure. + * + * @throws Exception + * + * @return string The assembled message body + */ + public function createBody() + { + $body = ''; + //Create unique IDs and preset boundaries + $this->uniqueid = $this->generateId(); + $this->boundary[1] = 'b1_' . $this->uniqueid; + $this->boundary[2] = 'b2_' . $this->uniqueid; + $this->boundary[3] = 'b3_' . $this->uniqueid; + + if ($this->sign_key_file) { + $body .= $this->getMailMIME() . static::$LE; + } + + $this->setWordWrap(); + + $bodyEncoding = $this->Encoding; + $bodyCharSet = $this->CharSet; + //Can we do a 7-bit downgrade? + if (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) { + $bodyEncoding = static::ENCODING_7BIT; + //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit + $bodyCharSet = static::CHARSET_ASCII; + } + //If lines are too long, and we're not already using an encoding that will shorten them, + //change to quoted-printable transfer encoding for the body part only + if (static::ENCODING_BASE64 !== $this->Encoding && static::hasLineLongerThanMax($this->Body)) { + $bodyEncoding = static::ENCODING_QUOTED_PRINTABLE; + } + + $altBodyEncoding = $this->Encoding; + $altBodyCharSet = $this->CharSet; + //Can we do a 7-bit downgrade? + if (static::ENCODING_8BIT === $altBodyEncoding && !$this->has8bitChars($this->AltBody)) { + $altBodyEncoding = static::ENCODING_7BIT; + //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit + $altBodyCharSet = static::CHARSET_ASCII; + } + //If lines are too long, and we're not already using an encoding that will shorten them, + //change to quoted-printable transfer encoding for the alt body part only + if (static::ENCODING_BASE64 !== $altBodyEncoding && static::hasLineLongerThanMax($this->AltBody)) { + $altBodyEncoding = static::ENCODING_QUOTED_PRINTABLE; + } + //Use this as a preamble in all multipart message types + $mimepre = 'This is a multi-part message in MIME format.' . static::$LE . static::$LE; + switch ($this->message_type) { + case 'inline': + $body .= $mimepre; + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= static::$LE; + $body .= $this->attachAll('inline', $this->boundary[1]); + break; + case 'attach': + $body .= $mimepre; + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= static::$LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'inline_attach': + $body .= $mimepre; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';'); + $body .= $this->textLine(' boundary="' . $this->boundary[2] . '";'); + $body .= $this->textLine(' type="' . static::CONTENT_TYPE_TEXT_HTML . '"'); + $body .= static::$LE; + $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= static::$LE; + $body .= $this->attachAll('inline', $this->boundary[2]); + $body .= static::$LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'alt': + $body .= $mimepre; + $body .= $this->getBoundary( + $this->boundary[1], + $altBodyCharSet, + static::CONTENT_TYPE_PLAINTEXT, + $altBodyEncoding + ); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= static::$LE; + $body .= $this->getBoundary( + $this->boundary[1], + $bodyCharSet, + static::CONTENT_TYPE_TEXT_HTML, + $bodyEncoding + ); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= static::$LE; + if (!empty($this->Ical)) { + $method = static::ICAL_METHOD_REQUEST; + foreach (static::$IcalMethods as $imethod) { + if (stripos($this->Ical, 'METHOD:' . $imethod) !== false) { + $method = $imethod; + break; + } + } + $body .= $this->getBoundary( + $this->boundary[1], + '', + static::CONTENT_TYPE_TEXT_CALENDAR . '; method=' . $method, + '' + ); + $body .= $this->encodeString($this->Ical, $this->Encoding); + $body .= static::$LE; + } + $body .= $this->endBoundary($this->boundary[1]); + break; + case 'alt_inline': + $body .= $mimepre; + $body .= $this->getBoundary( + $this->boundary[1], + $altBodyCharSet, + static::CONTENT_TYPE_PLAINTEXT, + $altBodyEncoding + ); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= static::$LE; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';'); + $body .= $this->textLine(' boundary="' . $this->boundary[2] . '";'); + $body .= $this->textLine(' type="' . static::CONTENT_TYPE_TEXT_HTML . '"'); + $body .= static::$LE; + $body .= $this->getBoundary( + $this->boundary[2], + $bodyCharSet, + static::CONTENT_TYPE_TEXT_HTML, + $bodyEncoding + ); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= static::$LE; + $body .= $this->attachAll('inline', $this->boundary[2]); + $body .= static::$LE; + $body .= $this->endBoundary($this->boundary[1]); + break; + case 'alt_attach': + $body .= $mimepre; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';'); + $body .= $this->textLine(' boundary="' . $this->boundary[2] . '"'); + $body .= static::$LE; + $body .= $this->getBoundary( + $this->boundary[2], + $altBodyCharSet, + static::CONTENT_TYPE_PLAINTEXT, + $altBodyEncoding + ); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= static::$LE; + $body .= $this->getBoundary( + $this->boundary[2], + $bodyCharSet, + static::CONTENT_TYPE_TEXT_HTML, + $bodyEncoding + ); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= static::$LE; + if (!empty($this->Ical)) { + $method = static::ICAL_METHOD_REQUEST; + foreach (static::$IcalMethods as $imethod) { + if (stripos($this->Ical, 'METHOD:' . $imethod) !== false) { + $method = $imethod; + break; + } + } + $body .= $this->getBoundary( + $this->boundary[2], + '', + static::CONTENT_TYPE_TEXT_CALENDAR . '; method=' . $method, + '' + ); + $body .= $this->encodeString($this->Ical, $this->Encoding); + } + $body .= $this->endBoundary($this->boundary[2]); + $body .= static::$LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'alt_inline_attach': + $body .= $mimepre; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';'); + $body .= $this->textLine(' boundary="' . $this->boundary[2] . '"'); + $body .= static::$LE; + $body .= $this->getBoundary( + $this->boundary[2], + $altBodyCharSet, + static::CONTENT_TYPE_PLAINTEXT, + $altBodyEncoding + ); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= static::$LE; + $body .= $this->textLine('--' . $this->boundary[2]); + $body .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';'); + $body .= $this->textLine(' boundary="' . $this->boundary[3] . '";'); + $body .= $this->textLine(' type="' . static::CONTENT_TYPE_TEXT_HTML . '"'); + $body .= static::$LE; + $body .= $this->getBoundary( + $this->boundary[3], + $bodyCharSet, + static::CONTENT_TYPE_TEXT_HTML, + $bodyEncoding + ); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= static::$LE; + $body .= $this->attachAll('inline', $this->boundary[3]); + $body .= static::$LE; + $body .= $this->endBoundary($this->boundary[2]); + $body .= static::$LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + default: + // Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types + //Reset the `Encoding` property in case we changed it for line length reasons + $this->Encoding = $bodyEncoding; + $body .= $this->encodeString($this->Body, $this->Encoding); + break; + } + + if ($this->isError()) { + $body = ''; + if ($this->exceptions) { + throw new Exception($this->lang('empty_message'), self::STOP_CRITICAL); + } + } elseif ($this->sign_key_file) { + try { + if (!defined('PKCS7_TEXT')) { + throw new Exception($this->lang('extension_missing') . 'openssl'); + } + + $file = tempnam(sys_get_temp_dir(), 'srcsign'); + $signed = tempnam(sys_get_temp_dir(), 'mailsign'); + file_put_contents($file, $body); + + //Workaround for PHP bug https://bugs.php.net/bug.php?id=69197 + if (empty($this->sign_extracerts_file)) { + $sign = @openssl_pkcs7_sign( + $file, + $signed, + 'file://' . realpath($this->sign_cert_file), + ['file://' . realpath($this->sign_key_file), $this->sign_key_pass], + [] + ); + } else { + $sign = @openssl_pkcs7_sign( + $file, + $signed, + 'file://' . realpath($this->sign_cert_file), + ['file://' . realpath($this->sign_key_file), $this->sign_key_pass], + [], + PKCS7_DETACHED, + $this->sign_extracerts_file + ); + } + + @unlink($file); + if ($sign) { + $body = file_get_contents($signed); + @unlink($signed); + //The message returned by openssl contains both headers and body, so need to split them up + $parts = explode("\n\n", $body, 2); + $this->MIMEHeader .= $parts[0] . static::$LE . static::$LE; + $body = $parts[1]; + } else { + @unlink($signed); + throw new Exception($this->lang('signing') . openssl_error_string()); + } + } catch (Exception $exc) { + $body = ''; + if ($this->exceptions) { + throw $exc; + } + } + } + + return $body; + } + + /** + * Return the start of a message boundary. + * + * @param string $boundary + * @param string $charSet + * @param string $contentType + * @param string $encoding + * + * @return string + */ + protected function getBoundary($boundary, $charSet, $contentType, $encoding) + { + $result = ''; + if ('' === $charSet) { + $charSet = $this->CharSet; + } + if ('' === $contentType) { + $contentType = $this->ContentType; + } + if ('' === $encoding) { + $encoding = $this->Encoding; + } + $result .= $this->textLine('--' . $boundary); + $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet); + $result .= static::$LE; + // RFC1341 part 5 says 7bit is assumed if not specified + if (static::ENCODING_7BIT !== $encoding) { + $result .= $this->headerLine('Content-Transfer-Encoding', $encoding); + } + $result .= static::$LE; + + return $result; + } + + /** + * Return the end of a message boundary. + * + * @param string $boundary + * + * @return string + */ + protected function endBoundary($boundary) + { + return static::$LE . '--' . $boundary . '--' . static::$LE; + } + + /** + * Set the message type. + * PHPMailer only supports some preset message types, not arbitrary MIME structures. + */ + protected function setMessageType() + { + $type = []; + if ($this->alternativeExists()) { + $type[] = 'alt'; + } + if ($this->inlineImageExists()) { + $type[] = 'inline'; + } + if ($this->attachmentExists()) { + $type[] = 'attach'; + } + $this->message_type = implode('_', $type); + if ('' === $this->message_type) { + //The 'plain' message_type refers to the message having a single body element, not that it is plain-text + $this->message_type = 'plain'; + } + } + + /** + * Format a header line. + * + * @param string $name + * @param string|int $value + * + * @return string + */ + public function headerLine($name, $value) + { + return $name . ': ' . $value . static::$LE; + } + + /** + * Return a formatted mail line. + * + * @param string $value + * + * @return string + */ + public function textLine($value) + { + return $value . static::$LE; + } + + /** + * Add an attachment from a path on the filesystem. + * Never use a user-supplied path to a file! + * Returns false if the file could not be found or read. + * Explicitly *does not* support passing URLs; PHPMailer is not an HTTP client. + * If you need to do that, fetch the resource yourself and pass it in via a local file or string. + * + * @param string $path Path to the attachment + * @param string $name Overrides the attachment name + * @param string $encoding File encoding (see $Encoding) + * @param string $type File extension (MIME) type + * @param string $disposition Disposition to use + * + * @throws Exception + * + * @return bool + */ + public function addAttachment( + $path, + $name = '', + $encoding = self::ENCODING_BASE64, + $type = '', + $disposition = 'attachment' + ) { + try { + if (!static::isPermittedPath($path) || !@is_file($path) || !is_readable($path)) { + throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE); + } + + // If a MIME type is not specified, try to work it out from the file name + if ('' === $type) { + $type = static::filenameToType($path); + } + + $filename = (string) static::mb_pathinfo($path, PATHINFO_BASENAME); + if ('' === $name) { + $name = $filename; + } + + if (!$this->validateEncoding($encoding)) { + throw new Exception($this->lang('encoding') . $encoding); + } + + $this->attachment[] = [ + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => $disposition, + 7 => $name, + ]; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + + return false; + } + + return true; + } + + /** + * Return the array of attachments. + * + * @return array + */ + public function getAttachments() + { + return $this->attachment; + } + + /** + * Attach all file, string, and binary attachments to the message. + * Returns an empty string on failure. + * + * @param string $disposition_type + * @param string $boundary + * + * @throws Exception + * + * @return string + */ + protected function attachAll($disposition_type, $boundary) + { + // Return text of body + $mime = []; + $cidUniq = []; + $incl = []; + + // Add all attachments + foreach ($this->attachment as $attachment) { + // Check if it is a valid disposition_filter + if ($attachment[6] === $disposition_type) { + // Check for string attachment + $string = ''; + $path = ''; + $bString = $attachment[5]; + if ($bString) { + $string = $attachment[0]; + } else { + $path = $attachment[0]; + } + + $inclhash = hash('sha256', serialize($attachment)); + if (in_array($inclhash, $incl, true)) { + continue; + } + $incl[] = $inclhash; + $name = $attachment[2]; + $encoding = $attachment[3]; + $type = $attachment[4]; + $disposition = $attachment[6]; + $cid = $attachment[7]; + if ('inline' === $disposition && array_key_exists($cid, $cidUniq)) { + continue; + } + $cidUniq[$cid] = true; + + $mime[] = sprintf('--%s%s', $boundary, static::$LE); + //Only include a filename property if we have one + if (!empty($name)) { + $mime[] = sprintf( + 'Content-Type: %s; name="%s"%s', + $type, + $this->encodeHeader($this->secureHeader($name)), + static::$LE + ); + } else { + $mime[] = sprintf( + 'Content-Type: %s%s', + $type, + static::$LE + ); + } + // RFC1341 part 5 says 7bit is assumed if not specified + if (static::ENCODING_7BIT !== $encoding) { + $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, static::$LE); + } + + //Only set Content-IDs on inline attachments + if ((string) $cid !== '' && $disposition === 'inline') { + $mime[] = 'Content-ID: <' . $this->encodeHeader($this->secureHeader($cid)) . '>' . static::$LE; + } + + // If a filename contains any of these chars, it should be quoted, + // but not otherwise: RFC2183 & RFC2045 5.1 + // Fixes a warning in IETF's msglint MIME checker + // Allow for bypassing the Content-Disposition header totally + if (!empty($disposition)) { + $encoded_name = $this->encodeHeader($this->secureHeader($name)); + if (preg_match('/[ ()<>@,;:"\/\[\]?=]/', $encoded_name)) { + $mime[] = sprintf( + 'Content-Disposition: %s; filename="%s"%s', + $disposition, + $encoded_name, + static::$LE . static::$LE + ); + } elseif (!empty($encoded_name)) { + $mime[] = sprintf( + 'Content-Disposition: %s; filename=%s%s', + $disposition, + $encoded_name, + static::$LE . static::$LE + ); + } else { + $mime[] = sprintf( + 'Content-Disposition: %s%s', + $disposition, + static::$LE . static::$LE + ); + } + } else { + $mime[] = static::$LE; + } + + // Encode as string attachment + if ($bString) { + $mime[] = $this->encodeString($string, $encoding); + } else { + $mime[] = $this->encodeFile($path, $encoding); + } + if ($this->isError()) { + return ''; + } + $mime[] = static::$LE; + } + } + + $mime[] = sprintf('--%s--%s', $boundary, static::$LE); + + return implode('', $mime); + } + + /** + * Encode a file attachment in requested format. + * Returns an empty string on failure. + * + * @param string $path The full path to the file + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * + * @return string + */ + protected function encodeFile($path, $encoding = self::ENCODING_BASE64) + { + try { + if (!static::isPermittedPath($path) || !file_exists($path) || !is_readable($path)) { + throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE); + } + $file_buffer = file_get_contents($path); + if (false === $file_buffer) { + throw new Exception($this->lang('file_open') . $path, self::STOP_CONTINUE); + } + $file_buffer = $this->encodeString($file_buffer, $encoding); + + return $file_buffer; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + return ''; + } + } + + /** + * Encode a string in requested format. + * Returns an empty string on failure. + * + * @param string $str The text to encode + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * + * @throws Exception + * + * @return string + */ + public function encodeString($str, $encoding = self::ENCODING_BASE64) + { + $encoded = ''; + switch (strtolower($encoding)) { + case static::ENCODING_BASE64: + $encoded = chunk_split( + base64_encode($str), + static::STD_LINE_LENGTH, + static::$LE + ); + break; + case static::ENCODING_7BIT: + case static::ENCODING_8BIT: + $encoded = static::normalizeBreaks($str); + // Make sure it ends with a line break + if (substr($encoded, -(strlen(static::$LE))) !== static::$LE) { + $encoded .= static::$LE; + } + break; + case static::ENCODING_BINARY: + $encoded = $str; + break; + case static::ENCODING_QUOTED_PRINTABLE: + $encoded = $this->encodeQP($str); + break; + default: + $this->setError($this->lang('encoding') . $encoding); + if ($this->exceptions) { + throw new Exception($this->lang('encoding') . $encoding); + } + break; + } + + return $encoded; + } + + /** + * Encode a header value (not including its label) optimally. + * Picks shortest of Q, B, or none. Result includes folding if needed. + * See RFC822 definitions for phrase, comment and text positions. + * + * @param string $str The header value to encode + * @param string $position What context the string will be used in + * + * @return string + */ + public function encodeHeader($str, $position = 'text') + { + $matchcount = 0; + switch (strtolower($position)) { + case 'phrase': + if (!preg_match('/[\200-\377]/', $str)) { + // Can't use addslashes as we don't know the value of magic_quotes_sybase + $encoded = addcslashes($str, "\0..\37\177\\\""); + if (($str === $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { + return $encoded; + } + + return "\"$encoded\""; + } + $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); + break; + /* @noinspection PhpMissingBreakStatementInspection */ + case 'comment': + $matchcount = preg_match_all('/[()"]/', $str, $matches); + //fallthrough + case 'text': + default: + $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); + break; + } + + if ($this->has8bitChars($str)) { + $charset = $this->CharSet; + } else { + $charset = static::CHARSET_ASCII; + } + + // Q/B encoding adds 8 chars and the charset ("` =??[QB]??=`"). + $overhead = 8 + strlen($charset); + + if ('mail' === $this->Mailer) { + $maxlen = static::MAIL_MAX_LINE_LENGTH - $overhead; + } else { + $maxlen = static::MAX_LINE_LENGTH - $overhead; + } + + // Select the encoding that produces the shortest output and/or prevents corruption. + if ($matchcount > strlen($str) / 3) { + // More than 1/3 of the content needs encoding, use B-encode. + $encoding = 'B'; + } elseif ($matchcount > 0) { + // Less than 1/3 of the content needs encoding, use Q-encode. + $encoding = 'Q'; + } elseif (strlen($str) > $maxlen) { + // No encoding needed, but value exceeds max line length, use Q-encode to prevent corruption. + $encoding = 'Q'; + } else { + // No reformatting needed + $encoding = false; + } + + switch ($encoding) { + case 'B': + if ($this->hasMultiBytes($str)) { + // Use a custom function which correctly encodes and wraps long + // multibyte strings without breaking lines within a character + $encoded = $this->base64EncodeWrapMB($str, "\n"); + } else { + $encoded = base64_encode($str); + $maxlen -= $maxlen % 4; + $encoded = trim(chunk_split($encoded, $maxlen, "\n")); + } + $encoded = preg_replace('/^(.*)$/m', ' =?' . $charset . "?$encoding?\\1?=", $encoded); + break; + case 'Q': + $encoded = $this->encodeQ($str, $position); + $encoded = $this->wrapText($encoded, $maxlen, true); + $encoded = str_replace('=' . static::$LE, "\n", trim($encoded)); + $encoded = preg_replace('/^(.*)$/m', ' =?' . $charset . "?$encoding?\\1?=", $encoded); + break; + default: + return $str; + } + + return trim(static::normalizeBreaks($encoded)); + } + + /** + * Check if a string contains multi-byte characters. + * + * @param string $str multi-byte text to wrap encode + * + * @return bool + */ + public function hasMultiBytes($str) + { + if (function_exists('mb_strlen')) { + return strlen($str) > mb_strlen($str, $this->CharSet); + } + + // Assume no multibytes (we can't handle without mbstring functions anyway) + return false; + } + + /** + * Does a string contain any 8-bit chars (in any charset)? + * + * @param string $text + * + * @return bool + */ + public function has8bitChars($text) + { + return (bool) preg_match('/[\x80-\xFF]/', $text); + } + + /** + * Encode and wrap long multibyte strings for mail headers + * without breaking lines within a character. + * Adapted from a function by paravoid. + * + * @see http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 + * + * @param string $str multi-byte text to wrap encode + * @param string $linebreak string to use as linefeed/end-of-line + * + * @return string + */ + public function base64EncodeWrapMB($str, $linebreak = null) + { + $start = '=?' . $this->CharSet . '?B?'; + $end = '?='; + $encoded = ''; + if (null === $linebreak) { + $linebreak = static::$LE; + } + + $mb_length = mb_strlen($str, $this->CharSet); + // Each line must have length <= 75, including $start and $end + $length = 75 - strlen($start) - strlen($end); + // Average multi-byte ratio + $ratio = $mb_length / strlen($str); + // Base64 has a 4:3 ratio + $avgLength = floor($length * $ratio * .75); + + $offset = 0; + for ($i = 0; $i < $mb_length; $i += $offset) { + $lookBack = 0; + do { + $offset = $avgLength - $lookBack; + $chunk = mb_substr($str, $i, $offset, $this->CharSet); + $chunk = base64_encode($chunk); + ++$lookBack; + } while (strlen($chunk) > $length); + $encoded .= $chunk . $linebreak; + } + + // Chomp the last linefeed + return substr($encoded, 0, -strlen($linebreak)); + } + + /** + * Encode a string in quoted-printable format. + * According to RFC2045 section 6.7. + * + * @param string $string The text to encode + * + * @return string + */ + public function encodeQP($string) + { + return static::normalizeBreaks(quoted_printable_encode($string)); + } + + /** + * Encode a string using Q encoding. + * + * @see http://tools.ietf.org/html/rfc2047#section-4.2 + * + * @param string $str the text to encode + * @param string $position Where the text is going to be used, see the RFC for what that means + * + * @return string + */ + public function encodeQ($str, $position = 'text') + { + // There should not be any EOL in the string + $pattern = ''; + $encoded = str_replace(["\r", "\n"], '', $str); + switch (strtolower($position)) { + case 'phrase': + // RFC 2047 section 5.3 + $pattern = '^A-Za-z0-9!*+\/ -'; + break; + /* + * RFC 2047 section 5.2. + * Build $pattern without including delimiters and [] + */ + /* @noinspection PhpMissingBreakStatementInspection */ + case 'comment': + $pattern = '\(\)"'; + /* Intentional fall through */ + case 'text': + default: + // RFC 2047 section 5.1 + // Replace every high ascii, control, =, ? and _ characters + $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern; + break; + } + $matches = []; + if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) { + // If the string contains an '=', make sure it's the first thing we replace + // so as to avoid double-encoding + $eqkey = array_search('=', $matches[0], true); + if (false !== $eqkey) { + unset($matches[0][$eqkey]); + array_unshift($matches[0], '='); + } + foreach (array_unique($matches[0]) as $char) { + $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded); + } + } + // Replace spaces with _ (more readable than =20) + // RFC 2047 section 4.2(2) + return str_replace(' ', '_', $encoded); + } + + /** + * Add a string or binary attachment (non-filesystem). + * This method can be used to attach ascii or binary data, + * such as a BLOB record from a database. + * + * @param string $string String attachment data + * @param string $filename Name of the attachment + * @param string $encoding File encoding (see $Encoding) + * @param string $type File extension (MIME) type + * @param string $disposition Disposition to use + * + * @throws Exception + * + * @return bool True on successfully adding an attachment + */ + public function addStringAttachment( + $string, + $filename, + $encoding = self::ENCODING_BASE64, + $type = '', + $disposition = 'attachment' + ) { + try { + // If a MIME type is not specified, try to work it out from the file name + if ('' === $type) { + $type = static::filenameToType($filename); + } + + if (!$this->validateEncoding($encoding)) { + throw new Exception($this->lang('encoding') . $encoding); + } + + // Append to $attachment array + $this->attachment[] = [ + 0 => $string, + 1 => $filename, + 2 => static::mb_pathinfo($filename, PATHINFO_BASENAME), + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => $disposition, + 7 => 0, + ]; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + + return false; + } + + return true; + } + + /** + * Add an embedded (inline) attachment from a file. + * This can include images, sounds, and just about any other document type. + * These differ from 'regular' attachments in that they are intended to be + * displayed inline with the message, not just attached for download. + * This is used in HTML messages that embed the images + * the HTML refers to using the $cid value. + * Never use a user-supplied path to a file! + * + * @param string $path Path to the attachment + * @param string $cid Content ID of the attachment; Use this to reference + * the content when using an embedded image in HTML + * @param string $name Overrides the attachment name + * @param string $encoding File encoding (see $Encoding) + * @param string $type File MIME type + * @param string $disposition Disposition to use + * + * @throws Exception + * + * @return bool True on successfully adding an attachment + */ + public function addEmbeddedImage( + $path, + $cid, + $name = '', + $encoding = self::ENCODING_BASE64, + $type = '', + $disposition = 'inline' + ) { + try { + if (!static::isPermittedPath($path) || !@is_file($path) || !is_readable($path)) { + throw new Exception($this->lang('file_access') . $path, self::STOP_CONTINUE); + } + + // If a MIME type is not specified, try to work it out from the file name + if ('' === $type) { + $type = static::filenameToType($path); + } + + if (!$this->validateEncoding($encoding)) { + throw new Exception($this->lang('encoding') . $encoding); + } + + $filename = (string) static::mb_pathinfo($path, PATHINFO_BASENAME); + if ('' === $name) { + $name = $filename; + } + + // Append to $attachment array + $this->attachment[] = [ + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => $disposition, + 7 => $cid, + ]; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + + return false; + } + + return true; + } + + /** + * Add an embedded stringified attachment. + * This can include images, sounds, and just about any other document type. + * If your filename doesn't contain an extension, be sure to set the $type to an appropriate MIME type. + * + * @param string $string The attachment binary data + * @param string $cid Content ID of the attachment; Use this to reference + * the content when using an embedded image in HTML + * @param string $name A filename for the attachment. If this contains an extension, + * PHPMailer will attempt to set a MIME type for the attachment. + * For example 'file.jpg' would get an 'image/jpeg' MIME type. + * @param string $encoding File encoding (see $Encoding), defaults to 'base64' + * @param string $type MIME type - will be used in preference to any automatically derived type + * @param string $disposition Disposition to use + * + * @throws Exception + * + * @return bool True on successfully adding an attachment + */ + public function addStringEmbeddedImage( + $string, + $cid, + $name = '', + $encoding = self::ENCODING_BASE64, + $type = '', + $disposition = 'inline' + ) { + try { + // If a MIME type is not specified, try to work it out from the name + if ('' === $type && !empty($name)) { + $type = static::filenameToType($name); + } + + if (!$this->validateEncoding($encoding)) { + throw new Exception($this->lang('encoding') . $encoding); + } + + // Append to $attachment array + $this->attachment[] = [ + 0 => $string, + 1 => $name, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => $disposition, + 7 => $cid, + ]; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + + return false; + } + + return true; + } + + /** + * Validate encodings. + * + * @param string $encoding + * + * @return bool + */ + protected function validateEncoding($encoding) + { + return in_array( + $encoding, + [ + self::ENCODING_7BIT, + self::ENCODING_QUOTED_PRINTABLE, + self::ENCODING_BASE64, + self::ENCODING_8BIT, + self::ENCODING_BINARY, + ], + true + ); + } + + /** + * Check if an embedded attachment is present with this cid. + * + * @param string $cid + * + * @return bool + */ + protected function cidExists($cid) + { + foreach ($this->attachment as $attachment) { + if ('inline' === $attachment[6] && $cid === $attachment[7]) { + return true; + } + } + + return false; + } + + /** + * Check if an inline attachment is present. + * + * @return bool + */ + public function inlineImageExists() + { + foreach ($this->attachment as $attachment) { + if ('inline' === $attachment[6]) { + return true; + } + } + + return false; + } + + /** + * Check if an attachment (non-inline) is present. + * + * @return bool + */ + public function attachmentExists() + { + foreach ($this->attachment as $attachment) { + if ('attachment' === $attachment[6]) { + return true; + } + } + + return false; + } + + /** + * Check if this message has an alternative body set. + * + * @return bool + */ + public function alternativeExists() + { + return !empty($this->AltBody); + } + + /** + * Clear queued addresses of given kind. + * + * @param string $kind 'to', 'cc', or 'bcc' + */ + public function clearQueuedAddresses($kind) + { + $this->RecipientsQueue = array_filter( + $this->RecipientsQueue, + static function ($params) use ($kind) { + return $params[0] !== $kind; + } + ); + } + + /** + * Clear all To recipients. + */ + public function clearAddresses() + { + foreach ($this->to as $to) { + unset($this->all_recipients[strtolower($to[0])]); + } + $this->to = []; + $this->clearQueuedAddresses('to'); + } + + /** + * Clear all CC recipients. + */ + public function clearCCs() + { + foreach ($this->cc as $cc) { + unset($this->all_recipients[strtolower($cc[0])]); + } + $this->cc = []; + $this->clearQueuedAddresses('cc'); + } + + /** + * Clear all BCC recipients. + */ + public function clearBCCs() + { + foreach ($this->bcc as $bcc) { + unset($this->all_recipients[strtolower($bcc[0])]); + } + $this->bcc = []; + $this->clearQueuedAddresses('bcc'); + } + + /** + * Clear all ReplyTo recipients. + */ + public function clearReplyTos() + { + $this->ReplyTo = []; + $this->ReplyToQueue = []; + } + + /** + * Clear all recipient types. + */ + public function clearAllRecipients() + { + $this->to = []; + $this->cc = []; + $this->bcc = []; + $this->all_recipients = []; + $this->RecipientsQueue = []; + } + + /** + * Clear all filesystem, string, and binary attachments. + */ + public function clearAttachments() + { + $this->attachment = []; + } + + /** + * Clear all custom headers. + */ + public function clearCustomHeaders() + { + $this->CustomHeader = []; + } + + /** + * Add an error message to the error container. + * + * @param string $msg + */ + protected function setError($msg) + { + ++$this->error_count; + if ('smtp' === $this->Mailer && null !== $this->smtp) { + $lasterror = $this->smtp->getError(); + if (!empty($lasterror['error'])) { + $msg .= $this->lang('smtp_error') . $lasterror['error']; + if (!empty($lasterror['detail'])) { + $msg .= ' Detail: ' . $lasterror['detail']; + } + if (!empty($lasterror['smtp_code'])) { + $msg .= ' SMTP code: ' . $lasterror['smtp_code']; + } + if (!empty($lasterror['smtp_code_ex'])) { + $msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex']; + } + } + } + $this->ErrorInfo = $msg; + } + + /** + * Return an RFC 822 formatted date. + * + * @return string + */ + public static function rfcDate() + { + // Set the time zone to whatever the default is to avoid 500 errors + // Will default to UTC if it's not set properly in php.ini + date_default_timezone_set(@date_default_timezone_get()); + + return date('D, j M Y H:i:s O'); + } + + /** + * Get the server hostname. + * Returns 'localhost.localdomain' if unknown. + * + * @return string + */ + protected function serverHostname() + { + $result = ''; + if (!empty($this->Hostname)) { + $result = $this->Hostname; + } elseif (isset($_SERVER) && array_key_exists('SERVER_NAME', $_SERVER)) { + $result = $_SERVER['SERVER_NAME']; + } elseif (function_exists('gethostname') && gethostname() !== false) { + $result = gethostname(); + } elseif (php_uname('n') !== false) { + $result = php_uname('n'); + } + if (!static::isValidHost($result)) { + return 'localhost.localdomain'; + } + + return $result; + } + + /** + * Validate whether a string contains a valid value to use as a hostname or IP address. + * IPv6 addresses must include [], e.g. `[::1]`, not just `::1`. + * + * @param string $host The host name or IP address to check + * + * @return bool + */ + public static function isValidHost($host) + { + //Simple syntax limits + if (empty($host) + || !is_string($host) + || strlen($host) > 256 + || !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+])$/', $host) + ) { + return false; + } + //Looks like a bracketed IPv6 address + if (strlen($host) > 2 && substr($host, 0, 1) === '[' && substr($host, -1, 1) === ']') { + return filter_var(substr($host, 1, -1), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false; + } + //If removing all the dots results in a numeric string, it must be an IPv4 address. + //Need to check this first because otherwise things like `999.0.0.0` are considered valid host names + if (is_numeric(str_replace('.', '', $host))) { + //Is it a valid IPv4 address? + return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false; + } + if (filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false) { + //Is it a syntactically valid hostname? + return true; + } + + return false; + } + + /** + * Get an error message in the current language. + * + * @param string $key + * + * @return string + */ + protected function lang($key) + { + if (count($this->language) < 1) { + $this->setLanguage(); // set the default language + } + + if (array_key_exists($key, $this->language)) { + if ('smtp_connect_failed' === $key) { + //Include a link to troubleshooting docs on SMTP connection failure + //this is by far the biggest cause of support questions + //but it's usually not PHPMailer's fault. + return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting'; + } + + return $this->language[$key]; + } + + //Return the key as a fallback + return $key; + } + + /** + * Check if an error occurred. + * + * @return bool True if an error did occur + */ + public function isError() + { + return $this->error_count > 0; + } + + /** + * Add a custom header. + * $name value can be overloaded to contain + * both header name and value (name:value). + * + * @param string $name Custom header name + * @param string|null $value Header value + * + * @throws Exception + */ + public function addCustomHeader($name, $value = null) + { + if (null === $value && strpos($name, ':') !== false) { + // Value passed in as name:value + list($name, $value) = explode(':', $name, 2); + } + $name = trim($name); + $value = trim($value); + //Ensure name is not empty, and that neither name nor value contain line breaks + if (empty($name) || strpbrk($name . $value, "\r\n") !== false) { + if ($this->exceptions) { + throw new Exception('Invalid header name or value'); + } + + return false; + } + $this->CustomHeader[] = [$name, $value]; + + return true; + } + + /** + * Returns all custom headers. + * + * @return array + */ + public function getCustomHeaders() + { + return $this->CustomHeader; + } + + /** + * Create a message body from an HTML string. + * Automatically inlines images and creates a plain-text version by converting the HTML, + * overwriting any existing values in Body and AltBody. + * Do not source $message content from user input! + * $basedir is prepended when handling relative URLs, e.g. and must not be empty + * will look for an image file in $basedir/images/a.png and convert it to inline. + * If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email) + * Converts data-uri images into embedded attachments. + * If you don't want to apply these transformations to your HTML, just set Body and AltBody directly. + * + * @param string $message HTML message string + * @param string $basedir Absolute path to a base directory to prepend to relative paths to images + * @param bool|callable $advanced Whether to use the internal HTML to text converter + * or your own custom converter @return string $message The transformed message Body + * + * @throws Exception + * + * @see PHPMailer::html2text() + */ + public function msgHTML($message, $basedir = '', $advanced = false) + { + preg_match_all('/(? 1 && '/' !== substr($basedir, -1)) { + // Ensure $basedir has a trailing / + $basedir .= '/'; + } + foreach ($images[2] as $imgindex => $url) { + // Convert data URIs into embedded images + //e.g. "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" + $match = []; + if (preg_match('#^data:(image/(?:jpe?g|gif|png));?(base64)?,(.+)#', $url, $match)) { + if (count($match) === 4 && static::ENCODING_BASE64 === $match[2]) { + $data = base64_decode($match[3]); + } elseif ('' === $match[2]) { + $data = rawurldecode($match[3]); + } else { + //Not recognised so leave it alone + continue; + } + //Hash the decoded data, not the URL, so that the same data-URI image used in multiple places + //will only be embedded once, even if it used a different encoding + $cid = substr(hash('sha256', $data), 0, 32) . '@phpmailer.0'; // RFC2392 S 2 + + if (!$this->cidExists($cid)) { + $this->addStringEmbeddedImage( + $data, + $cid, + 'embed' . $imgindex, + static::ENCODING_BASE64, + $match[1] + ); + } + $message = str_replace( + $images[0][$imgindex], + $images[1][$imgindex] . '="cid:' . $cid . '"', + $message + ); + continue; + } + if (// Only process relative URLs if a basedir is provided (i.e. no absolute local paths) + !empty($basedir) + // Ignore URLs containing parent dir traversal (..) + && (strpos($url, '..') === false) + // Do not change urls that are already inline images + && 0 !== strpos($url, 'cid:') + // Do not change absolute URLs, including anonymous protocol + && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url) + ) { + $filename = static::mb_pathinfo($url, PATHINFO_BASENAME); + $directory = dirname($url); + if ('.' === $directory) { + $directory = ''; + } + // RFC2392 S 2 + $cid = substr(hash('sha256', $url), 0, 32) . '@phpmailer.0'; + if (strlen($basedir) > 1 && '/' !== substr($basedir, -1)) { + $basedir .= '/'; + } + if (strlen($directory) > 1 && '/' !== substr($directory, -1)) { + $directory .= '/'; + } + if ($this->addEmbeddedImage( + $basedir . $directory . $filename, + $cid, + $filename, + static::ENCODING_BASE64, + static::_mime_types((string) static::mb_pathinfo($filename, PATHINFO_EXTENSION)) + ) + ) { + $message = preg_replace( + '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', + $images[1][$imgindex] . '="cid:' . $cid . '"', + $message + ); + } + } + } + } + $this->isHTML(); + // Convert all message body line breaks to LE, makes quoted-printable encoding work much better + $this->Body = static::normalizeBreaks($message); + $this->AltBody = static::normalizeBreaks($this->html2text($message, $advanced)); + if (!$this->alternativeExists()) { + $this->AltBody = 'This is an HTML-only message. To view it, activate HTML in your email application.' + . static::$LE; + } + + return $this->Body; + } + + /** + * Convert an HTML string into plain text. + * This is used by msgHTML(). + * Note - older versions of this function used a bundled advanced converter + * which was removed for license reasons in #232. + * Example usage: + * + * ```php + * // Use default conversion + * $plain = $mail->html2text($html); + * // Use your own custom converter + * $plain = $mail->html2text($html, function($html) { + * $converter = new MyHtml2text($html); + * return $converter->get_text(); + * }); + * ``` + * + * @param string $html The HTML text to convert + * @param bool|callable $advanced Any boolean value to use the internal converter, + * or provide your own callable for custom conversion + * + * @return string + */ + public function html2text($html, $advanced = false) + { + if (is_callable($advanced)) { + return $advanced($html); + } + + return html_entity_decode( + trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))), + ENT_QUOTES, + $this->CharSet + ); + } + + /** + * Get the MIME type for a file extension. + * + * @param string $ext File extension + * + * @return string MIME type of file + */ + public static function _mime_types($ext = '') + { + $mimes = [ + 'xl' => 'application/excel', + 'js' => 'application/javascript', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'bin' => 'application/macbinary', + 'doc' => 'application/msword', + 'word' => 'application/msword', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'class' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'psd' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'so' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'php3' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'zip' => 'application/zip', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'm4a' => 'audio/mp4', + 'mpga' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'wav' => 'audio/x-wav', + 'mka' => 'audio/x-matroska', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'png' => 'image/png', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'webp' => 'image/webp', + 'heif' => 'image/heif', + 'heifs' => 'image/heif-sequence', + 'heic' => 'image/heic', + 'heics' => 'image/heic-sequence', + 'eml' => 'message/rfc822', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'log' => 'text/plain', + 'text' => 'text/plain', + 'txt' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'vcf' => 'text/vcard', + 'vcard' => 'text/vcard', + 'ics' => 'text/calendar', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'wmv' => 'video/x-ms-wmv', + 'mpeg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mp4' => 'video/mp4', + 'm4v' => 'video/mp4', + 'mov' => 'video/quicktime', + 'qt' => 'video/quicktime', + 'rv' => 'video/vnd.rn-realvideo', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'webm' => 'video/webm', + 'mkv' => 'video/x-matroska', + ]; + $ext = strtolower($ext); + if (array_key_exists($ext, $mimes)) { + return $mimes[$ext]; + } + + return 'application/octet-stream'; + } + + /** + * Map a file name to a MIME type. + * Defaults to 'application/octet-stream', i.e.. arbitrary binary data. + * + * @param string $filename A file name or full path, does not need to exist as a file + * + * @return string + */ + public static function filenameToType($filename) + { + // In case the path is a URL, strip any query string before getting extension + $qpos = strpos($filename, '?'); + if (false !== $qpos) { + $filename = substr($filename, 0, $qpos); + } + $ext = static::mb_pathinfo($filename, PATHINFO_EXTENSION); + + return static::_mime_types($ext); + } + + /** + * Multi-byte-safe pathinfo replacement. + * Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe. + * + * @see http://www.php.net/manual/en/function.pathinfo.php#107461 + * + * @param string $path A filename or path, does not need to exist as a file + * @param int|string $options Either a PATHINFO_* constant, + * or a string name to return only the specified piece + * + * @return string|array + */ + public static function mb_pathinfo($path, $options = null) + { + $ret = ['dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '']; + $pathinfo = []; + if (preg_match('#^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^.\\\\/]+?)|))[\\\\/.]*$#m', $path, $pathinfo)) { + if (array_key_exists(1, $pathinfo)) { + $ret['dirname'] = $pathinfo[1]; + } + if (array_key_exists(2, $pathinfo)) { + $ret['basename'] = $pathinfo[2]; + } + if (array_key_exists(5, $pathinfo)) { + $ret['extension'] = $pathinfo[5]; + } + if (array_key_exists(3, $pathinfo)) { + $ret['filename'] = $pathinfo[3]; + } + } + switch ($options) { + case PATHINFO_DIRNAME: + case 'dirname': + return $ret['dirname']; + case PATHINFO_BASENAME: + case 'basename': + return $ret['basename']; + case PATHINFO_EXTENSION: + case 'extension': + return $ret['extension']; + case PATHINFO_FILENAME: + case 'filename': + return $ret['filename']; + default: + return $ret; + } + } + + /** + * Set or reset instance properties. + * You should avoid this function - it's more verbose, less efficient, more error-prone and + * harder to debug than setting properties directly. + * Usage Example: + * `$mail->set('SMTPSecure', static::ENCRYPTION_STARTTLS);` + * is the same as: + * `$mail->SMTPSecure = static::ENCRYPTION_STARTTLS;`. + * + * @param string $name The property name to set + * @param mixed $value The value to set the property to + * + * @return bool + */ + public function set($name, $value = '') + { + if (property_exists($this, $name)) { + $this->$name = $value; + + return true; + } + $this->setError($this->lang('variable_set') . $name); + + return false; + } + + /** + * Strip newlines to prevent header injection. + * + * @param string $str + * + * @return string + */ + public function secureHeader($str) + { + return trim(str_replace(["\r", "\n"], '', $str)); + } + + /** + * Normalize line breaks in a string. + * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format. + * Defaults to CRLF (for message bodies) and preserves consecutive breaks. + * + * @param string $text + * @param string $breaktype What kind of line break to use; defaults to static::$LE + * + * @return string + */ + public static function normalizeBreaks($text, $breaktype = null) + { + if (null === $breaktype) { + $breaktype = static::$LE; + } + // Normalise to \n + $text = str_replace([self::CRLF, "\r"], "\n", $text); + // Now convert LE as needed + if ("\n" !== $breaktype) { + $text = str_replace("\n", $breaktype, $text); + } + + return $text; + } + + /** + * Remove trailing breaks from a string. + * + * @param string $text + * + * @return string The text to remove breaks from + */ + public static function stripTrailingWSP($text) + { + return rtrim($text, " \r\n\t"); + } + + /** + * Return the current line break format string. + * + * @return string + */ + public static function getLE() + { + return static::$LE; + } + + /** + * Set the line break format string, e.g. "\r\n". + * + * @param string $le + */ + protected static function setLE($le) + { + static::$LE = $le; + } + + /** + * Set the public and private key files and password for S/MIME signing. + * + * @param string $cert_filename + * @param string $key_filename + * @param string $key_pass Password for private key + * @param string $extracerts_filename Optional path to chain certificate + */ + public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '') + { + $this->sign_cert_file = $cert_filename; + $this->sign_key_file = $key_filename; + $this->sign_key_pass = $key_pass; + $this->sign_extracerts_file = $extracerts_filename; + } + + /** + * Quoted-Printable-encode a DKIM header. + * + * @param string $txt + * + * @return string + */ + public function DKIM_QP($txt) + { + $line = ''; + $len = strlen($txt); + for ($i = 0; $i < $len; ++$i) { + $ord = ord($txt[$i]); + if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord === 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) { + $line .= $txt[$i]; + } else { + $line .= '=' . sprintf('%02X', $ord); + } + } + + return $line; + } + + /** + * Generate a DKIM signature. + * + * @param string $signHeader + * + * @throws Exception + * + * @return string The DKIM signature value + */ + public function DKIM_Sign($signHeader) + { + if (!defined('PKCS7_TEXT')) { + if ($this->exceptions) { + throw new Exception($this->lang('extension_missing') . 'openssl'); + } + + return ''; + } + $privKeyStr = !empty($this->DKIM_private_string) ? + $this->DKIM_private_string : + file_get_contents($this->DKIM_private); + if ('' !== $this->DKIM_passphrase) { + $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); + } else { + $privKey = openssl_pkey_get_private($privKeyStr); + } + if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) { + openssl_pkey_free($privKey); + + return base64_encode($signature); + } + openssl_pkey_free($privKey); + + return ''; + } + + /** + * Generate a DKIM canonicalization header. + * Uses the 'relaxed' algorithm from RFC6376 section 3.4.2. + * Canonicalized headers should *always* use CRLF, regardless of mailer setting. + * + * @see https://tools.ietf.org/html/rfc6376#section-3.4.2 + * + * @param string $signHeader Header + * + * @return string + */ + public function DKIM_HeaderC($signHeader) + { + //Normalize breaks to CRLF (regardless of the mailer) + $signHeader = static::normalizeBreaks($signHeader, self::CRLF); + //Unfold header lines + //Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]` + //@see https://tools.ietf.org/html/rfc5322#section-2.2 + //That means this may break if you do something daft like put vertical tabs in your headers. + $signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader); + //Break headers out into an array + $lines = explode(self::CRLF, $signHeader); + foreach ($lines as $key => $line) { + //If the header is missing a :, skip it as it's invalid + //This is likely to happen because the explode() above will also split + //on the trailing LE, leaving an empty line + if (strpos($line, ':') === false) { + continue; + } + list($heading, $value) = explode(':', $line, 2); + //Lower-case header name + $heading = strtolower($heading); + //Collapse white space within the value, also convert WSP to space + $value = preg_replace('/[ \t]+/', ' ', $value); + //RFC6376 is slightly unclear here - it says to delete space at the *end* of each value + //But then says to delete space before and after the colon. + //Net result is the same as trimming both ends of the value. + //By elimination, the same applies to the field name + $lines[$key] = trim($heading, " \t") . ':' . trim($value, " \t"); + } + + return implode(self::CRLF, $lines); + } + + /** + * Generate a DKIM canonicalization body. + * Uses the 'simple' algorithm from RFC6376 section 3.4.3. + * Canonicalized bodies should *always* use CRLF, regardless of mailer setting. + * + * @see https://tools.ietf.org/html/rfc6376#section-3.4.3 + * + * @param string $body Message Body + * + * @return string + */ + public function DKIM_BodyC($body) + { + if (empty($body)) { + return self::CRLF; + } + // Normalize line endings to CRLF + $body = static::normalizeBreaks($body, self::CRLF); + + //Reduce multiple trailing line breaks to a single one + return static::stripTrailingWSP($body) . self::CRLF; + } + + /** + * Create the DKIM header and body in a new message header. + * + * @param string $headers_line Header lines + * @param string $subject Subject + * @param string $body Body + * + * @throws Exception + * + * @return string + */ + public function DKIM_Add($headers_line, $subject, $body) + { + $DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms + $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization methods of header & body + $DKIMquery = 'dns/txt'; // Query method + $DKIMtime = time(); + //Always sign these headers without being asked + //Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1 + $autoSignHeaders = [ + 'from', + 'to', + 'cc', + 'date', + 'subject', + 'reply-to', + 'message-id', + 'content-type', + 'mime-version', + 'x-mailer', + ]; + if (stripos($headers_line, 'Subject') === false) { + $headers_line .= 'Subject: ' . $subject . static::$LE; + } + $headerLines = explode(static::$LE, $headers_line); + $currentHeaderLabel = ''; + $currentHeaderValue = ''; + $parsedHeaders = []; + $headerLineIndex = 0; + $headerLineCount = count($headerLines); + foreach ($headerLines as $headerLine) { + $matches = []; + if (preg_match('/^([^ \t]*?)(?::[ \t]*)(.*)$/', $headerLine, $matches)) { + if ($currentHeaderLabel !== '') { + //We were previously in another header; This is the start of a new header, so save the previous one + $parsedHeaders[] = ['label' => $currentHeaderLabel, 'value' => $currentHeaderValue]; + } + $currentHeaderLabel = $matches[1]; + $currentHeaderValue = $matches[2]; + } elseif (preg_match('/^[ \t]+(.*)$/', $headerLine, $matches)) { + //This is a folded continuation of the current header, so unfold it + $currentHeaderValue .= ' ' . $matches[1]; + } + ++$headerLineIndex; + if ($headerLineIndex >= $headerLineCount) { + //This was the last line, so finish off this header + $parsedHeaders[] = ['label' => $currentHeaderLabel, 'value' => $currentHeaderValue]; + } + } + $copiedHeaders = []; + $headersToSignKeys = []; + $headersToSign = []; + foreach ($parsedHeaders as $header) { + //Is this header one that must be included in the DKIM signature? + if (in_array(strtolower($header['label']), $autoSignHeaders, true)) { + $headersToSignKeys[] = $header['label']; + $headersToSign[] = $header['label'] . ': ' . $header['value']; + if ($this->DKIM_copyHeaderFields) { + $copiedHeaders[] = $header['label'] . ':' . //Note no space after this, as per RFC + str_replace('|', '=7C', $this->DKIM_QP($header['value'])); + } + continue; + } + //Is this an extra custom header we've been asked to sign? + if (in_array($header['label'], $this->DKIM_extraHeaders, true)) { + //Find its value in custom headers + foreach ($this->CustomHeader as $customHeader) { + if ($customHeader[0] === $header['label']) { + $headersToSignKeys[] = $header['label']; + $headersToSign[] = $header['label'] . ': ' . $header['value']; + if ($this->DKIM_copyHeaderFields) { + $copiedHeaders[] = $header['label'] . ':' . //Note no space after this, as per RFC + str_replace('|', '=7C', $this->DKIM_QP($header['value'])); + } + //Skip straight to the next header + continue 2; + } + } + } + } + $copiedHeaderFields = ''; + if ($this->DKIM_copyHeaderFields && count($copiedHeaders) > 0) { + //Assemble a DKIM 'z' tag + $copiedHeaderFields = ' z='; + $first = true; + foreach ($copiedHeaders as $copiedHeader) { + if (!$first) { + $copiedHeaderFields .= static::$LE . ' |'; + } + //Fold long values + if (strlen($copiedHeader) > self::STD_LINE_LENGTH - 3) { + $copiedHeaderFields .= substr( + chunk_split($copiedHeader, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS), + 0, + -strlen(static::$LE . self::FWS) + ); + } else { + $copiedHeaderFields .= $copiedHeader; + } + $first = false; + } + $copiedHeaderFields .= ';' . static::$LE; + } + $headerKeys = ' h=' . implode(':', $headersToSignKeys) . ';' . static::$LE; + $headerValues = implode(static::$LE, $headersToSign); + $body = $this->DKIM_BodyC($body); + $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body + $ident = ''; + if ('' !== $this->DKIM_identity) { + $ident = ' i=' . $this->DKIM_identity . ';' . static::$LE; + } + //The DKIM-Signature header is included in the signature *except for* the value of the `b` tag + //which is appended after calculating the signature + //https://tools.ietf.org/html/rfc6376#section-3.5 + $dkimSignatureHeader = 'DKIM-Signature: v=1;' . + ' d=' . $this->DKIM_domain . ';' . + ' s=' . $this->DKIM_selector . ';' . static::$LE . + ' a=' . $DKIMsignatureType . ';' . + ' q=' . $DKIMquery . ';' . + ' t=' . $DKIMtime . ';' . + ' c=' . $DKIMcanonicalization . ';' . static::$LE . + $headerKeys . + $ident . + $copiedHeaderFields . + ' bh=' . $DKIMb64 . ';' . static::$LE . + ' b='; + //Canonicalize the set of headers + $canonicalizedHeaders = $this->DKIM_HeaderC( + $headerValues . static::$LE . $dkimSignatureHeader + ); + $signature = $this->DKIM_Sign($canonicalizedHeaders); + $signature = trim(chunk_split($signature, self::STD_LINE_LENGTH - 3, static::$LE . self::FWS)); + + return static::normalizeBreaks($dkimSignatureHeader . $signature); + } + + /** + * Detect if a string contains a line longer than the maximum line length + * allowed by RFC 2822 section 2.1.1. + * + * @param string $str + * + * @return bool + */ + public static function hasLineLongerThanMax($str) + { + return (bool) preg_match('/^(.{' . (self::MAX_LINE_LENGTH + strlen(static::$LE)) . ',})/m', $str); + } + + /** + * Allows for public read access to 'to' property. + * Before the send() call, queued addresses (i.e. with IDN) are not yet included. + * + * @return array + */ + public function getToAddresses() + { + return $this->to; + } + + /** + * Allows for public read access to 'cc' property. + * Before the send() call, queued addresses (i.e. with IDN) are not yet included. + * + * @return array + */ + public function getCcAddresses() + { + return $this->cc; + } + + /** + * Allows for public read access to 'bcc' property. + * Before the send() call, queued addresses (i.e. with IDN) are not yet included. + * + * @return array + */ + public function getBccAddresses() + { + return $this->bcc; + } + + /** + * Allows for public read access to 'ReplyTo' property. + * Before the send() call, queued addresses (i.e. with IDN) are not yet included. + * + * @return array + */ + public function getReplyToAddresses() + { + return $this->ReplyTo; + } + + /** + * Allows for public read access to 'all_recipients' property. + * Before the send() call, queued addresses (i.e. with IDN) are not yet included. + * + * @return array + */ + public function getAllRecipientAddresses() + { + return $this->all_recipients; + } + + /** + * Perform a callback. + * + * @param bool $isSent + * @param array $to + * @param array $cc + * @param array $bcc + * @param string $subject + * @param string $body + * @param string $from + * @param array $extra + */ + protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from, $extra) + { + if (!empty($this->action_function) && is_callable($this->action_function)) { + call_user_func($this->action_function, $isSent, $to, $cc, $bcc, $subject, $body, $from, $extra); + } + } + + /** + * Get the OAuth instance. + * + * @return OAuth + */ + public function getOAuth() + { + return $this->oauth; + } + + /** + * Set an OAuth instance. + */ + public function setOAuth(OAuth $oauth) + { + $this->oauth = $oauth; + } +} diff --git a/vendor/phpmailer/phpmailer/src/POP3.php b/vendor/phpmailer/phpmailer/src/POP3.php new file mode 100644 index 0000000..cd6fc2f --- /dev/null +++ b/vendor/phpmailer/phpmailer/src/POP3.php @@ -0,0 +1,421 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2019 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +namespace PHPMailer\PHPMailer; + +/** + * PHPMailer POP-Before-SMTP Authentication Class. + * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication. + * 1) This class does not support APOP authentication. + * 2) Opening and closing lots of POP3 connections can be quite slow. If you need + * to send a batch of emails then just perform the authentication once at the start, + * and then loop through your mail sending script. Providing this process doesn't + * take longer than the verification period lasts on your POP3 server, you should be fine. + * 3) This is really ancient technology; you should only need to use it to talk to very old systems. + * 4) This POP3 class is deliberately lightweight and incomplete, implementing just + * enough to do authentication. + * If you want a more complete class there are other POP3 classes for PHP available. + * + * @author Richard Davey (original author) + * @author Marcus Bointon (Synchro/coolbru) + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + */ +class POP3 +{ + /** + * The POP3 PHPMailer Version number. + * + * @var string + */ + const VERSION = '6.1.5'; + + /** + * Default POP3 port number. + * + * @var int + */ + const DEFAULT_PORT = 110; + + /** + * Default timeout in seconds. + * + * @var int + */ + const DEFAULT_TIMEOUT = 30; + + /** + * Debug display level. + * Options: 0 = no, 1+ = yes. + * + * @var int + */ + public $do_debug = 0; + + /** + * POP3 mail server hostname. + * + * @var string + */ + public $host; + + /** + * POP3 port number. + * + * @var int + */ + public $port; + + /** + * POP3 Timeout Value in seconds. + * + * @var int + */ + public $tval; + + /** + * POP3 username. + * + * @var string + */ + public $username; + + /** + * POP3 password. + * + * @var string + */ + public $password; + + /** + * Resource handle for the POP3 connection socket. + * + * @var resource + */ + protected $pop_conn; + + /** + * Are we connected? + * + * @var bool + */ + protected $connected = false; + + /** + * Error container. + * + * @var array + */ + protected $errors = []; + + /** + * Line break constant. + */ + const LE = "\r\n"; + + /** + * Simple static wrapper for all-in-one POP before SMTP. + * + * @param string $host The hostname to connect to + * @param int|bool $port The port number to connect to + * @param int|bool $timeout The timeout value + * @param string $username + * @param string $password + * @param int $debug_level + * + * @return bool + */ + public static function popBeforeSmtp( + $host, + $port = false, + $timeout = false, + $username = '', + $password = '', + $debug_level = 0 + ) { + $pop = new self(); + + return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level); + } + + /** + * Authenticate with a POP3 server. + * A connect, login, disconnect sequence + * appropriate for POP-before SMTP authorisation. + * + * @param string $host The hostname to connect to + * @param int|bool $port The port number to connect to + * @param int|bool $timeout The timeout value + * @param string $username + * @param string $password + * @param int $debug_level + * + * @return bool + */ + public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0) + { + $this->host = $host; + // If no port value provided, use default + if (false === $port) { + $this->port = static::DEFAULT_PORT; + } else { + $this->port = (int) $port; + } + // If no timeout value provided, use default + if (false === $timeout) { + $this->tval = static::DEFAULT_TIMEOUT; + } else { + $this->tval = (int) $timeout; + } + $this->do_debug = $debug_level; + $this->username = $username; + $this->password = $password; + // Reset the error log + $this->errors = []; + // connect + $result = $this->connect($this->host, $this->port, $this->tval); + if ($result) { + $login_result = $this->login($this->username, $this->password); + if ($login_result) { + $this->disconnect(); + + return true; + } + } + // We need to disconnect regardless of whether the login succeeded + $this->disconnect(); + + return false; + } + + /** + * Connect to a POP3 server. + * + * @param string $host + * @param int|bool $port + * @param int $tval + * + * @return bool + */ + public function connect($host, $port = false, $tval = 30) + { + // Are we already connected? + if ($this->connected) { + return true; + } + + //On Windows this will raise a PHP Warning error if the hostname doesn't exist. + //Rather than suppress it with @fsockopen, capture it cleanly instead + set_error_handler([$this, 'catchWarning']); + + if (false === $port) { + $port = static::DEFAULT_PORT; + } + + // connect to the POP3 server + $errno = 0; + $errstr = ''; + $this->pop_conn = fsockopen( + $host, // POP3 Host + $port, // Port # + $errno, // Error Number + $errstr, // Error Message + $tval + ); // Timeout (seconds) + // Restore the error handler + restore_error_handler(); + + // Did we connect? + if (false === $this->pop_conn) { + // It would appear not... + $this->setError( + "Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr" + ); + + return false; + } + + // Increase the stream time-out + stream_set_timeout($this->pop_conn, $tval, 0); + + // Get the POP3 server response + $pop3_response = $this->getResponse(); + // Check for the +OK + if ($this->checkResponse($pop3_response)) { + // The connection is established and the POP3 server is talking + $this->connected = true; + + return true; + } + + return false; + } + + /** + * Log in to the POP3 server. + * Does not support APOP (RFC 2828, 4949). + * + * @param string $username + * @param string $password + * + * @return bool + */ + public function login($username = '', $password = '') + { + if (!$this->connected) { + $this->setError('Not connected to POP3 server'); + } + if (empty($username)) { + $username = $this->username; + } + if (empty($password)) { + $password = $this->password; + } + + // Send the Username + $this->sendString("USER $username" . static::LE); + $pop3_response = $this->getResponse(); + if ($this->checkResponse($pop3_response)) { + // Send the Password + $this->sendString("PASS $password" . static::LE); + $pop3_response = $this->getResponse(); + if ($this->checkResponse($pop3_response)) { + return true; + } + } + + return false; + } + + /** + * Disconnect from the POP3 server. + */ + public function disconnect() + { + $this->sendString('QUIT'); + //The QUIT command may cause the daemon to exit, which will kill our connection + //So ignore errors here + try { + @fclose($this->pop_conn); + } catch (Exception $e) { + //Do nothing + } + } + + /** + * Get a response from the POP3 server. + * + * @param int $size The maximum number of bytes to retrieve + * + * @return string + */ + protected function getResponse($size = 128) + { + $response = fgets($this->pop_conn, $size); + if ($this->do_debug >= 1) { + echo 'Server -> Client: ', $response; + } + + return $response; + } + + /** + * Send raw data to the POP3 server. + * + * @param string $string + * + * @return int + */ + protected function sendString($string) + { + if ($this->pop_conn) { + if ($this->do_debug >= 2) { //Show client messages when debug >= 2 + echo 'Client -> Server: ', $string; + } + + return fwrite($this->pop_conn, $string, strlen($string)); + } + + return 0; + } + + /** + * Checks the POP3 server response. + * Looks for for +OK or -ERR. + * + * @param string $string + * + * @return bool + */ + protected function checkResponse($string) + { + if (strpos($string, '+OK') !== 0) { + $this->setError("Server reported an error: $string"); + + return false; + } + + return true; + } + + /** + * Add an error to the internal error store. + * Also display debug output if it's enabled. + * + * @param string $error + */ + protected function setError($error) + { + $this->errors[] = $error; + if ($this->do_debug >= 1) { + echo '
';
+            foreach ($this->errors as $e) {
+                print_r($e);
+            }
+            echo '
'; + } + } + + /** + * Get an array of error messages, if any. + * + * @return array + */ + public function getErrors() + { + return $this->errors; + } + + /** + * POP3 connection error handler. + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + */ + protected function catchWarning($errno, $errstr, $errfile, $errline) + { + $this->setError( + 'Connecting to the POP3 server raised a PHP warning:' . + "errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline" + ); + } +} diff --git a/vendor/phpmailer/phpmailer/src/SMTP.php b/vendor/phpmailer/phpmailer/src/SMTP.php new file mode 100644 index 0000000..1e38ba7 --- /dev/null +++ b/vendor/phpmailer/phpmailer/src/SMTP.php @@ -0,0 +1,1371 @@ + + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2019 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +namespace PHPMailer\PHPMailer; + +/** + * PHPMailer RFC821 SMTP email transport class. + * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. + * + * @author Chris Ryan + * @author Marcus Bointon + */ +class SMTP +{ + /** + * The PHPMailer SMTP version number. + * + * @var string + */ + const VERSION = '6.1.5'; + + /** + * SMTP line break constant. + * + * @var string + */ + const LE = "\r\n"; + + /** + * The SMTP port to use if one is not specified. + * + * @var int + */ + const DEFAULT_PORT = 25; + + /** + * The maximum line length allowed by RFC 5321 section 4.5.3.1.6, + * *excluding* a trailing CRLF break. + * + * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.6 + * + * @var int + */ + const MAX_LINE_LENGTH = 998; + + /** + * The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5, + * *including* a trailing CRLF line break. + * + * @see https://tools.ietf.org/html/rfc5321#section-4.5.3.1.5 + * + * @var int + */ + const MAX_REPLY_LENGTH = 512; + + /** + * Debug level for no output. + * + * @var int + */ + const DEBUG_OFF = 0; + + /** + * Debug level to show client -> server messages. + * + * @var int + */ + const DEBUG_CLIENT = 1; + + /** + * Debug level to show client -> server and server -> client messages. + * + * @var int + */ + const DEBUG_SERVER = 2; + + /** + * Debug level to show connection status, client -> server and server -> client messages. + * + * @var int + */ + const DEBUG_CONNECTION = 3; + + /** + * Debug level to show all messages. + * + * @var int + */ + const DEBUG_LOWLEVEL = 4; + + /** + * Debug output level. + * Options: + * * self::DEBUG_OFF (`0`) No debug output, default + * * self::DEBUG_CLIENT (`1`) Client commands + * * self::DEBUG_SERVER (`2`) Client commands and server responses + * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status + * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages. + * + * @var int + */ + public $do_debug = self::DEBUG_OFF; + + /** + * How to handle debug output. + * Options: + * * `echo` Output plain-text as-is, appropriate for CLI + * * `html` Output escaped, line breaks converted to `
`, appropriate for browser output + * * `error_log` Output to error log as configured in php.ini + * Alternatively, you can provide a callable expecting two params: a message string and the debug level: + * + * ```php + * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; + * ``` + * + * Alternatively, you can pass in an instance of a PSR-3 compatible logger, though only `debug` + * level output is used: + * + * ```php + * $mail->Debugoutput = new myPsr3Logger; + * ``` + * + * @var string|callable|\Psr\Log\LoggerInterface + */ + public $Debugoutput = 'echo'; + + /** + * Whether to use VERP. + * + * @see http://en.wikipedia.org/wiki/Variable_envelope_return_path + * @see http://www.postfix.org/VERP_README.html Info on VERP + * + * @var bool + */ + public $do_verp = false; + + /** + * The timeout value for connection, in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2. + * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. + * + * @see http://tools.ietf.org/html/rfc2821#section-4.5.3.2 + * + * @var int + */ + public $Timeout = 300; + + /** + * How long to wait for commands to complete, in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2. + * + * @var int + */ + public $Timelimit = 300; + + /** + * Patterns to extract an SMTP transaction id from reply to a DATA command. + * The first capture group in each regex will be used as the ID. + * MS ESMTP returns the message ID, which may not be correct for internal tracking. + * + * @var string[] + */ + protected $smtp_transaction_id_patterns = [ + 'exim' => '/[\d]{3} OK id=(.*)/', + 'sendmail' => '/[\d]{3} 2.0.0 (.*) Message/', + 'postfix' => '/[\d]{3} 2.0.0 Ok: queued as (.*)/', + 'Microsoft_ESMTP' => '/[0-9]{3} 2.[\d].0 (.*)@(?:.*) Queued mail for delivery/', + 'Amazon_SES' => '/[\d]{3} Ok (.*)/', + 'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', + 'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/', + ]; + + /** + * The last transaction ID issued in response to a DATA command, + * if one was detected. + * + * @var string|bool|null + */ + protected $last_smtp_transaction_id; + + /** + * The socket for the server connection. + * + * @var ?resource + */ + protected $smtp_conn; + + /** + * Error information, if any, for the last SMTP command. + * + * @var array + */ + protected $error = [ + 'error' => '', + 'detail' => '', + 'smtp_code' => '', + 'smtp_code_ex' => '', + ]; + + /** + * The reply the server sent to us for HELO. + * If null, no HELO string has yet been received. + * + * @var string|null + */ + protected $helo_rply; + + /** + * The set of SMTP extensions sent in reply to EHLO command. + * Indexes of the array are extension names. + * Value at index 'HELO' or 'EHLO' (according to command that was sent) + * represents the server name. In case of HELO it is the only element of the array. + * Other values can be boolean TRUE or an array containing extension options. + * If null, no HELO/EHLO string has yet been received. + * + * @var array|null + */ + protected $server_caps; + + /** + * The most recent reply received from the server. + * + * @var string + */ + protected $last_reply = ''; + + /** + * Output debugging info via a user-selected method. + * + * @param string $str Debug string to output + * @param int $level The debug level of this message; see DEBUG_* constants + * + * @see SMTP::$Debugoutput + * @see SMTP::$do_debug + */ + protected function edebug($str, $level = 0) + { + if ($level > $this->do_debug) { + return; + } + //Is this a PSR-3 logger? + if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { + $this->Debugoutput->debug($str); + + return; + } + //Avoid clash with built-in function names + if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) { + call_user_func($this->Debugoutput, $str, $level); + + return; + } + switch ($this->Debugoutput) { + case 'error_log': + //Don't output, just log + error_log($str); + break; + case 'html': + //Cleans up output a bit for a better looking, HTML-safe output + echo gmdate('Y-m-d H:i:s'), ' ', htmlentities( + preg_replace('/[\r\n]+/', '', $str), + ENT_QUOTES, + 'UTF-8' + ), "
\n"; + break; + case 'echo': + default: + //Normalize line breaks + $str = preg_replace('/\r\n|\r/m', "\n", $str); + echo gmdate('Y-m-d H:i:s'), + "\t", + //Trim trailing space + trim( + //Indent for readability, except for trailing break + str_replace( + "\n", + "\n \t ", + trim($str) + ) + ), + "\n"; + } + } + + /** + * Connect to an SMTP server. + * + * @param string $host SMTP server IP or host name + * @param int $port The port number to connect to + * @param int $timeout How long to wait for the connection to open + * @param array $options An array of options for stream_context_create() + * + * @return bool + */ + public function connect($host, $port = null, $timeout = 30, $options = []) + { + static $streamok; + //This is enabled by default since 5.0.0 but some providers disable it + //Check this once and cache the result + if (null === $streamok) { + $streamok = function_exists('stream_socket_client'); + } + // Clear errors to avoid confusion + $this->setError(''); + // Make sure we are __not__ connected + if ($this->connected()) { + // Already connected, generate error + $this->setError('Already connected to a server'); + + return false; + } + if (empty($port)) { + $port = self::DEFAULT_PORT; + } + // Connect to the SMTP server + $this->edebug( + "Connection: opening to $host:$port, timeout=$timeout, options=" . + (count($options) > 0 ? var_export($options, true) : 'array()'), + self::DEBUG_CONNECTION + ); + $errno = 0; + $errstr = ''; + if ($streamok) { + $socket_context = stream_context_create($options); + set_error_handler([$this, 'errorHandler']); + $this->smtp_conn = stream_socket_client( + $host . ':' . $port, + $errno, + $errstr, + $timeout, + STREAM_CLIENT_CONNECT, + $socket_context + ); + restore_error_handler(); + } else { + //Fall back to fsockopen which should work in more places, but is missing some features + $this->edebug( + 'Connection: stream_socket_client not available, falling back to fsockopen', + self::DEBUG_CONNECTION + ); + set_error_handler([$this, 'errorHandler']); + $this->smtp_conn = fsockopen( + $host, + $port, + $errno, + $errstr, + $timeout + ); + restore_error_handler(); + } + // Verify we connected properly + if (!is_resource($this->smtp_conn)) { + $this->setError( + 'Failed to connect to server', + '', + (string) $errno, + $errstr + ); + $this->edebug( + 'SMTP ERROR: ' . $this->error['error'] + . ": $errstr ($errno)", + self::DEBUG_CLIENT + ); + + return false; + } + $this->edebug('Connection: opened', self::DEBUG_CONNECTION); + // SMTP server can take longer to respond, give longer timeout for first read + // Windows does not have support for this timeout function + if (strpos(PHP_OS, 'WIN') !== 0) { + $max = (int) ini_get('max_execution_time'); + // Don't bother if unlimited + if (0 !== $max && $timeout > $max) { + @set_time_limit($timeout); + } + stream_set_timeout($this->smtp_conn, $timeout, 0); + } + // Get any announcement + $announce = $this->get_lines(); + $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER); + + return true; + } + + /** + * Initiate a TLS (encrypted) session. + * + * @return bool + */ + public function startTLS() + { + if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) { + return false; + } + + //Allow the best TLS version(s) we can + $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT; + + //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT + //so add them back in manually if we can + if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) { + $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; + } + + // Begin encrypted connection + set_error_handler([$this, 'errorHandler']); + $crypto_ok = stream_socket_enable_crypto( + $this->smtp_conn, + true, + $crypto_method + ); + restore_error_handler(); + + return (bool) $crypto_ok; + } + + /** + * Perform SMTP authentication. + * Must be run after hello(). + * + * @see hello() + * + * @param string $username The user name + * @param string $password The password + * @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2) + * @param OAuth $OAuth An optional OAuth instance for XOAUTH2 authentication + * + * @return bool True if successfully authenticated + */ + public function authenticate( + $username, + $password, + $authtype = null, + $OAuth = null + ) { + if (!$this->server_caps) { + $this->setError('Authentication is not allowed before HELO/EHLO'); + + return false; + } + + if (array_key_exists('EHLO', $this->server_caps)) { + // SMTP extensions are available; try to find a proper authentication method + if (!array_key_exists('AUTH', $this->server_caps)) { + $this->setError('Authentication is not allowed at this stage'); + // 'at this stage' means that auth may be allowed after the stage changes + // e.g. after STARTTLS + + return false; + } + + $this->edebug('Auth method requested: ' . ($authtype ?: 'UNSPECIFIED'), self::DEBUG_LOWLEVEL); + $this->edebug( + 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']), + self::DEBUG_LOWLEVEL + ); + + //If we have requested a specific auth type, check the server supports it before trying others + if (null !== $authtype && !in_array($authtype, $this->server_caps['AUTH'], true)) { + $this->edebug('Requested auth method not available: ' . $authtype, self::DEBUG_LOWLEVEL); + $authtype = null; + } + + if (empty($authtype)) { + //If no auth mechanism is specified, attempt to use these, in this order + //Try CRAM-MD5 first as it's more secure than the others + foreach (['CRAM-MD5', 'LOGIN', 'PLAIN', 'XOAUTH2'] as $method) { + if (in_array($method, $this->server_caps['AUTH'], true)) { + $authtype = $method; + break; + } + } + if (empty($authtype)) { + $this->setError('No supported authentication methods found'); + + return false; + } + $this->edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL); + } + + if (!in_array($authtype, $this->server_caps['AUTH'], true)) { + $this->setError("The requested authentication method \"$authtype\" is not supported by the server"); + + return false; + } + } elseif (empty($authtype)) { + $authtype = 'LOGIN'; + } + switch ($authtype) { + case 'PLAIN': + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { + return false; + } + // Send encoded username and password + if (!$this->sendCommand( + 'User & Password', + base64_encode("\0" . $username . "\0" . $password), + 235 + ) + ) { + return false; + } + break; + case 'LOGIN': + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { + return false; + } + if (!$this->sendCommand('Username', base64_encode($username), 334)) { + return false; + } + if (!$this->sendCommand('Password', base64_encode($password), 235)) { + return false; + } + break; + case 'CRAM-MD5': + // Start authentication + if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { + return false; + } + // Get the challenge + $challenge = base64_decode(substr($this->last_reply, 4)); + + // Build the response + $response = $username . ' ' . $this->hmac($challenge, $password); + + // send encoded credentials + return $this->sendCommand('Username', base64_encode($response), 235); + case 'XOAUTH2': + //The OAuth instance must be set up prior to requesting auth. + if (null === $OAuth) { + return false; + } + $oauth = $OAuth->getOauth64(); + + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { + return false; + } + break; + default: + $this->setError("Authentication method \"$authtype\" is not supported"); + + return false; + } + + return true; + } + + /** + * Calculate an MD5 HMAC hash. + * Works like hash_hmac('md5', $data, $key) + * in case that function is not available. + * + * @param string $data The data to hash + * @param string $key The key to hash with + * + * @return string + */ + protected function hmac($data, $key) + { + if (function_exists('hash_hmac')) { + return hash_hmac('md5', $data, $key); + } + + // The following borrowed from + // http://php.net/manual/en/function.mhash.php#27225 + + // RFC 2104 HMAC implementation for php. + // Creates an md5 HMAC. + // Eliminates the need to install mhash to compute a HMAC + // by Lance Rushing + + $bytelen = 64; // byte length for md5 + if (strlen($key) > $bytelen) { + $key = pack('H*', md5($key)); + } + $key = str_pad($key, $bytelen, chr(0x00)); + $ipad = str_pad('', $bytelen, chr(0x36)); + $opad = str_pad('', $bytelen, chr(0x5c)); + $k_ipad = $key ^ $ipad; + $k_opad = $key ^ $opad; + + return md5($k_opad . pack('H*', md5($k_ipad . $data))); + } + + /** + * Check connection state. + * + * @return bool True if connected + */ + public function connected() + { + if (is_resource($this->smtp_conn)) { + $sock_status = stream_get_meta_data($this->smtp_conn); + if ($sock_status['eof']) { + // The socket is valid but we are not connected + $this->edebug( + 'SMTP NOTICE: EOF caught while checking if connected', + self::DEBUG_CLIENT + ); + $this->close(); + + return false; + } + + return true; // everything looks good + } + + return false; + } + + /** + * Close the socket and clean up the state of the class. + * Don't use this function without first trying to use QUIT. + * + * @see quit() + */ + public function close() + { + $this->setError(''); + $this->server_caps = null; + $this->helo_rply = null; + if (is_resource($this->smtp_conn)) { + // close the connection and cleanup + fclose($this->smtp_conn); + $this->smtp_conn = null; //Makes for cleaner serialization + $this->edebug('Connection: closed', self::DEBUG_CONNECTION); + } + } + + /** + * Send an SMTP DATA command. + * Issues a data command and sends the msg_data to the server, + * finializing the mail transaction. $msg_data is the message + * that is to be send with the headers. Each header needs to be + * on a single line followed by a with the message headers + * and the message body being separated by an additional . + * Implements RFC 821: DATA . + * + * @param string $msg_data Message data to send + * + * @return bool + */ + public function data($msg_data) + { + //This will use the standard timelimit + if (!$this->sendCommand('DATA', 'DATA', 354)) { + return false; + } + + /* The server is ready to accept data! + * According to rfc821 we should not send more than 1000 characters on a single line (including the LE) + * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into + * smaller lines to fit within the limit. + * We will also look for lines that start with a '.' and prepend an additional '.'. + * NOTE: this does not count towards line-length limit. + */ + + // Normalize line breaks before exploding + $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); + + /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field + * of the first line (':' separated) does not contain a space then it _should_ be a header and we will + * process all lines before a blank line as headers. + */ + + $field = substr($lines[0], 0, strpos($lines[0], ':')); + $in_headers = false; + if (!empty($field) && strpos($field, ' ') === false) { + $in_headers = true; + } + + foreach ($lines as $line) { + $lines_out = []; + if ($in_headers && $line === '') { + $in_headers = false; + } + //Break this line up into several smaller lines if it's too long + //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len), + while (isset($line[self::MAX_LINE_LENGTH])) { + //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on + //so as to avoid breaking in the middle of a word + $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' '); + //Deliberately matches both false and 0 + if (!$pos) { + //No nice break found, add a hard break + $pos = self::MAX_LINE_LENGTH - 1; + $lines_out[] = substr($line, 0, $pos); + $line = substr($line, $pos); + } else { + //Break at the found point + $lines_out[] = substr($line, 0, $pos); + //Move along by the amount we dealt with + $line = substr($line, $pos + 1); + } + //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1 + if ($in_headers) { + $line = "\t" . $line; + } + } + $lines_out[] = $line; + + //Send the lines to the server + foreach ($lines_out as $line_out) { + //RFC2821 section 4.5.2 + if (!empty($line_out) && $line_out[0] === '.') { + $line_out = '.' . $line_out; + } + $this->client_send($line_out . static::LE, 'DATA'); + } + } + + //Message data has been sent, complete the command + //Increase timelimit for end of DATA command + $savetimelimit = $this->Timelimit; + $this->Timelimit *= 2; + $result = $this->sendCommand('DATA END', '.', 250); + $this->recordLastTransactionID(); + //Restore timelimit + $this->Timelimit = $savetimelimit; + + return $result; + } + + /** + * Send an SMTP HELO or EHLO command. + * Used to identify the sending server to the receiving server. + * This makes sure that client and server are in a known state. + * Implements RFC 821: HELO + * and RFC 2821 EHLO. + * + * @param string $host The host name or IP to connect to + * + * @return bool + */ + public function hello($host = '') + { + //Try extended hello first (RFC 2821) + return $this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host); + } + + /** + * Send an SMTP HELO or EHLO command. + * Low-level implementation used by hello(). + * + * @param string $hello The HELO string + * @param string $host The hostname to say we are + * + * @return bool + * + * @see hello() + */ + protected function sendHello($hello, $host) + { + $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250); + $this->helo_rply = $this->last_reply; + if ($noerror) { + $this->parseHelloFields($hello); + } else { + $this->server_caps = null; + } + + return $noerror; + } + + /** + * Parse a reply to HELO/EHLO command to discover server extensions. + * In case of HELO, the only parameter that can be discovered is a server name. + * + * @param string $type `HELO` or `EHLO` + */ + protected function parseHelloFields($type) + { + $this->server_caps = []; + $lines = explode("\n", $this->helo_rply); + + foreach ($lines as $n => $s) { + //First 4 chars contain response code followed by - or space + $s = trim(substr($s, 4)); + if (empty($s)) { + continue; + } + $fields = explode(' ', $s); + if (!empty($fields)) { + if (!$n) { + $name = $type; + $fields = $fields[0]; + } else { + $name = array_shift($fields); + switch ($name) { + case 'SIZE': + $fields = ($fields ? $fields[0] : 0); + break; + case 'AUTH': + if (!is_array($fields)) { + $fields = []; + } + break; + default: + $fields = true; + } + } + $this->server_caps[$name] = $fields; + } + } + } + + /** + * Send an SMTP MAIL command. + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more recipient + * commands may be called followed by a data command. + * Implements RFC 821: MAIL FROM: . + * + * @param string $from Source address of this message + * + * @return bool + */ + public function mail($from) + { + $useVerp = ($this->do_verp ? ' XVERP' : ''); + + return $this->sendCommand( + 'MAIL FROM', + 'MAIL FROM:<' . $from . '>' . $useVerp, + 250 + ); + } + + /** + * Send an SMTP QUIT command. + * Closes the socket if there is no error or the $close_on_error argument is true. + * Implements from RFC 821: QUIT . + * + * @param bool $close_on_error Should the connection close if an error occurs? + * + * @return bool + */ + public function quit($close_on_error = true) + { + $noerror = $this->sendCommand('QUIT', 'QUIT', 221); + $err = $this->error; //Save any error + if ($noerror || $close_on_error) { + $this->close(); + $this->error = $err; //Restore any error from the quit command + } + + return $noerror; + } + + /** + * Send an SMTP RCPT command. + * Sets the TO argument to $toaddr. + * Returns true if the recipient was accepted false if it was rejected. + * Implements from RFC 821: RCPT TO: . + * + * @param string $address The address the message is being sent to + * @param string $dsn Comma separated list of DSN notifications. NEVER, SUCCESS, FAILURE + * or DELAY. If you specify NEVER all other notifications are ignored. + * + * @return bool + */ + public function recipient($address, $dsn = '') + { + if (empty($dsn)) { + $rcpt = 'RCPT TO:<' . $address . '>'; + } else { + $dsn = strtoupper($dsn); + $notify = []; + + if (strpos($dsn, 'NEVER') !== false) { + $notify[] = 'NEVER'; + } else { + foreach (['SUCCESS', 'FAILURE', 'DELAY'] as $value) { + if (strpos($dsn, $value) !== false) { + $notify[] = $value; + } + } + } + + $rcpt = 'RCPT TO:<' . $address . '> NOTIFY=' . implode(',', $notify); + } + + return $this->sendCommand( + 'RCPT TO', + $rcpt, + [250, 251] + ); + } + + /** + * Send an SMTP RSET command. + * Abort any transaction that is currently in progress. + * Implements RFC 821: RSET . + * + * @return bool True on success + */ + public function reset() + { + return $this->sendCommand('RSET', 'RSET', 250); + } + + /** + * Send a command to an SMTP server and check its return code. + * + * @param string $command The command name - not sent to the server + * @param string $commandstring The actual command to send + * @param int|array $expect One or more expected integer success codes + * + * @return bool True on success + */ + protected function sendCommand($command, $commandstring, $expect) + { + if (!$this->connected()) { + $this->setError("Called $command without being connected"); + + return false; + } + //Reject line breaks in all commands + if ((strpos($commandstring, "\n") !== false) || (strpos($commandstring, "\r") !== false)) { + $this->setError("Command '$command' contained line breaks"); + + return false; + } + $this->client_send($commandstring . static::LE, $command); + + $this->last_reply = $this->get_lines(); + // Fetch SMTP code and possible error code explanation + $matches = []; + if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) { + $code = (int) $matches[1]; + $code_ex = (count($matches) > 2 ? $matches[2] : null); + // Cut off error code from each response line + $detail = preg_replace( + "/{$code}[ -]" . + ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m', + '', + $this->last_reply + ); + } else { + // Fall back to simple parsing if regex fails + $code = (int) substr($this->last_reply, 0, 3); + $code_ex = null; + $detail = substr($this->last_reply, 4); + } + + $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); + + if (!in_array($code, (array) $expect, true)) { + $this->setError( + "$command command failed", + $detail, + $code, + $code_ex + ); + $this->edebug( + 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, + self::DEBUG_CLIENT + ); + + return false; + } + + $this->setError(''); + + return true; + } + + /** + * Send an SMTP SAML command. + * Starts a mail transaction from the email address specified in $from. + * Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more recipient + * commands may be called followed by a data command. This command + * will send the message to the users terminal if they are logged + * in and send them an email. + * Implements RFC 821: SAML FROM: . + * + * @param string $from The address the message is from + * + * @return bool + */ + public function sendAndMail($from) + { + return $this->sendCommand('SAML', "SAML FROM:$from", 250); + } + + /** + * Send an SMTP VRFY command. + * + * @param string $name The name to verify + * + * @return bool + */ + public function verify($name) + { + return $this->sendCommand('VRFY', "VRFY $name", [250, 251]); + } + + /** + * Send an SMTP NOOP command. + * Used to keep keep-alives alive, doesn't actually do anything. + * + * @return bool + */ + public function noop() + { + return $this->sendCommand('NOOP', 'NOOP', 250); + } + + /** + * Send an SMTP TURN command. + * This is an optional command for SMTP that this class does not support. + * This method is here to make the RFC821 Definition complete for this class + * and _may_ be implemented in future. + * Implements from RFC 821: TURN . + * + * @return bool + */ + public function turn() + { + $this->setError('The SMTP TURN command is not implemented'); + $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT); + + return false; + } + + /** + * Send raw data to the server. + * + * @param string $data The data to send + * @param string $command Optionally, the command this is part of, used only for controlling debug output + * + * @return int|bool The number of bytes sent to the server or false on error + */ + public function client_send($data, $command = '') + { + //If SMTP transcripts are left enabled, or debug output is posted online + //it can leak credentials, so hide credentials in all but lowest level + if (self::DEBUG_LOWLEVEL > $this->do_debug && + in_array($command, ['User & Password', 'Username', 'Password'], true)) { + $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT); + } else { + $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT); + } + set_error_handler([$this, 'errorHandler']); + $result = fwrite($this->smtp_conn, $data); + restore_error_handler(); + + return $result; + } + + /** + * Get the latest error. + * + * @return array + */ + public function getError() + { + return $this->error; + } + + /** + * Get SMTP extensions available on the server. + * + * @return array|null + */ + public function getServerExtList() + { + return $this->server_caps; + } + + /** + * Get metadata about the SMTP server from its HELO/EHLO response. + * The method works in three ways, dependent on argument value and current state: + * 1. HELO/EHLO has not been sent - returns null and populates $this->error. + * 2. HELO has been sent - + * $name == 'HELO': returns server name + * $name == 'EHLO': returns boolean false + * $name == any other string: returns null and populates $this->error + * 3. EHLO has been sent - + * $name == 'HELO'|'EHLO': returns the server name + * $name == any other string: if extension $name exists, returns True + * or its options (e.g. AUTH mechanisms supported). Otherwise returns False. + * + * @param string $name Name of SMTP extension or 'HELO'|'EHLO' + * + * @return string|bool|null + */ + public function getServerExt($name) + { + if (!$this->server_caps) { + $this->setError('No HELO/EHLO was sent'); + + return; + } + + if (!array_key_exists($name, $this->server_caps)) { + if ('HELO' === $name) { + return $this->server_caps['EHLO']; + } + if ('EHLO' === $name || array_key_exists('EHLO', $this->server_caps)) { + return false; + } + $this->setError('HELO handshake was used; No information about server extensions available'); + + return; + } + + return $this->server_caps[$name]; + } + + /** + * Get the last reply from the server. + * + * @return string + */ + public function getLastReply() + { + return $this->last_reply; + } + + /** + * Read the SMTP server's response. + * Either before eof or socket timeout occurs on the operation. + * With SMTP we can tell if we have more lines to read if the + * 4th character is '-' symbol. If it is a space then we don't + * need to read anything else. + * + * @return string + */ + protected function get_lines() + { + // If the connection is bad, give up straight away + if (!is_resource($this->smtp_conn)) { + return ''; + } + $data = ''; + $endtime = 0; + stream_set_timeout($this->smtp_conn, $this->Timeout); + if ($this->Timelimit > 0) { + $endtime = time() + $this->Timelimit; + } + $selR = [$this->smtp_conn]; + $selW = null; + while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { + //Must pass vars in here as params are by reference + if (!stream_select($selR, $selW, $selW, $this->Timelimit)) { + $this->edebug( + 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', + self::DEBUG_LOWLEVEL + ); + break; + } + //Deliberate noise suppression - errors are handled afterwards + $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH); + $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL); + $data .= $str; + // If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled), + // or 4th character is a space or a line break char, we are done reading, break the loop. + // String array access is a significant micro-optimisation over strlen + if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") { + break; + } + // Timed-out? Log and break + $info = stream_get_meta_data($this->smtp_conn); + if ($info['timed_out']) { + $this->edebug( + 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', + self::DEBUG_LOWLEVEL + ); + break; + } + // Now check if reads took too long + if ($endtime && time() > $endtime) { + $this->edebug( + 'SMTP -> get_lines(): timelimit reached (' . + $this->Timelimit . ' sec)', + self::DEBUG_LOWLEVEL + ); + break; + } + } + + return $data; + } + + /** + * Enable or disable VERP address generation. + * + * @param bool $enabled + */ + public function setVerp($enabled = false) + { + $this->do_verp = $enabled; + } + + /** + * Get VERP address generation mode. + * + * @return bool + */ + public function getVerp() + { + return $this->do_verp; + } + + /** + * Set error messages and codes. + * + * @param string $message The error message + * @param string $detail Further detail on the error + * @param string $smtp_code An associated SMTP error code + * @param string $smtp_code_ex Extended SMTP code + */ + protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '') + { + $this->error = [ + 'error' => $message, + 'detail' => $detail, + 'smtp_code' => $smtp_code, + 'smtp_code_ex' => $smtp_code_ex, + ]; + } + + /** + * Set debug output method. + * + * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it + */ + public function setDebugOutput($method = 'echo') + { + $this->Debugoutput = $method; + } + + /** + * Get debug output method. + * + * @return string + */ + public function getDebugOutput() + { + return $this->Debugoutput; + } + + /** + * Set debug output level. + * + * @param int $level + */ + public function setDebugLevel($level = 0) + { + $this->do_debug = $level; + } + + /** + * Get debug output level. + * + * @return int + */ + public function getDebugLevel() + { + return $this->do_debug; + } + + /** + * Set SMTP timeout. + * + * @param int $timeout The timeout duration in seconds + */ + public function setTimeout($timeout = 0) + { + $this->Timeout = $timeout; + } + + /** + * Get SMTP timeout. + * + * @return int + */ + public function getTimeout() + { + return $this->Timeout; + } + + /** + * Reports an error number and string. + * + * @param int $errno The error number returned by PHP + * @param string $errmsg The error message returned by PHP + * @param string $errfile The file the error occurred in + * @param int $errline The line number the error occurred on + */ + protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0) + { + $notice = 'Connection failed.'; + $this->setError( + $notice, + $errmsg, + (string) $errno + ); + $this->edebug( + "$notice Error #$errno: $errmsg [$errfile line $errline]", + self::DEBUG_CONNECTION + ); + } + + /** + * Extract and return the ID of the last SMTP transaction based on + * a list of patterns provided in SMTP::$smtp_transaction_id_patterns. + * Relies on the host providing the ID in response to a DATA command. + * If no reply has been received yet, it will return null. + * If no pattern was matched, it will return false. + * + * @return bool|string|null + */ + protected function recordLastTransactionID() + { + $reply = $this->getLastReply(); + + if (empty($reply)) { + $this->last_smtp_transaction_id = null; + } else { + $this->last_smtp_transaction_id = false; + foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) { + $matches = []; + if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) { + $this->last_smtp_transaction_id = trim($matches[1]); + break; + } + } + } + + return $this->last_smtp_transaction_id; + } + + /** + * Get the queue/transaction ID of the last SMTP transaction + * If no reply has been received yet, it will return null. + * If no pattern was matched, it will return false. + * + * @return bool|string|null + * + * @see recordLastTransactionID() + */ + public function getLastTransactionID() + { + return $this->last_smtp_transaction_id; + } +} diff --git a/vendor/psr/cache/CHANGELOG.md b/vendor/psr/cache/CHANGELOG.md new file mode 100644 index 0000000..58ddab0 --- /dev/null +++ b/vendor/psr/cache/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 1.0.1 - 2016-08-06 + +### Fixed + +- Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr +- Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr +- Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell +- For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell + +## 1.0.0 - 2015-12-11 + +Initial stable release; reflects accepted PSR-6 specification diff --git a/vendor/psr/cache/LICENSE.txt b/vendor/psr/cache/LICENSE.txt new file mode 100644 index 0000000..b1c2c97 --- /dev/null +++ b/vendor/psr/cache/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2015 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/psr/cache/README.md b/vendor/psr/cache/README.md new file mode 100644 index 0000000..c8706ce --- /dev/null +++ b/vendor/psr/cache/README.md @@ -0,0 +1,9 @@ +PSR Cache +========= + +This repository holds all interfaces defined by +[PSR-6](http://www.php-fig.org/psr/psr-6/). + +Note that this is not a Cache implementation of its own. It is merely an +interface that describes a Cache implementation. See the specification for more +details. diff --git a/vendor/psr/cache/composer.json b/vendor/psr/cache/composer.json new file mode 100644 index 0000000..e828fec --- /dev/null +++ b/vendor/psr/cache/composer.json @@ -0,0 +1,25 @@ +{ + "name": "psr/cache", + "description": "Common interface for caching libraries", + "keywords": ["psr", "psr-6", "cache"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/psr/cache/src/CacheException.php b/vendor/psr/cache/src/CacheException.php new file mode 100644 index 0000000..e27f22f --- /dev/null +++ b/vendor/psr/cache/src/CacheException.php @@ -0,0 +1,10 @@ +=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php new file mode 100644 index 0000000..d35c6b4 --- /dev/null +++ b/vendor/psr/container/src/ContainerExceptionInterface.php @@ -0,0 +1,13 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 0000000..67f852d --- /dev/null +++ b/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 0000000..5ea7243 --- /dev/null +++ b/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,123 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 0000000..d8cd682 --- /dev/null +++ b/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,28 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php new file mode 100644 index 0000000..4b861c3 --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php @@ -0,0 +1,144 @@ + ". + * + * Example ->error('Foo') would yield "error Foo". + * + * @return string[] + */ + abstract public function getLogs(); + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException \Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + } + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextCanContainAnything() + { + $closed = fopen('php://memory', 'r'); + fclose($closed); + + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest), + 'object' => new \DateTime, + 'resource' => fopen('php://memory', 'r'), + 'closed' => $closed, + ); + + $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!' + ); + $this->assertEquals($expected, $this->getLogs()); + } +} + +class DummyTest +{ + public function __toString() + { + } +} diff --git a/vendor/psr/log/Psr/Log/Test/TestLogger.php b/vendor/psr/log/Psr/Log/Test/TestLogger.php new file mode 100644 index 0000000..0cdffe4 --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/TestLogger.php @@ -0,0 +1,146 @@ + $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + } +} diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md new file mode 100644 index 0000000..5571a25 --- /dev/null +++ b/vendor/psr/log/README.md @@ -0,0 +1,52 @@ +PSR Log +======= + +This repository holds all interfaces/classes/traits related to +[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Note that this is not a logger of its own. It is merely an interface that +describes a logger. See the specification for more details. + +Installation +------------ + +```bash +composer require psr/log +``` + +Usage +----- + +If you need a logger, you can use the interface like this: + +```php +logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json new file mode 100644 index 0000000..87934d7 --- /dev/null +++ b/vendor/psr/log/composer.json @@ -0,0 +1,26 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/psr/simple-cache/.editorconfig b/vendor/psr/simple-cache/.editorconfig new file mode 100644 index 0000000..48542cb --- /dev/null +++ b/vendor/psr/simple-cache/.editorconfig @@ -0,0 +1,12 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/vendor/psr/simple-cache/LICENSE.md b/vendor/psr/simple-cache/LICENSE.md new file mode 100644 index 0000000..e49a7c8 --- /dev/null +++ b/vendor/psr/simple-cache/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2016 PHP Framework Interoperability Group + +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. diff --git a/vendor/psr/simple-cache/README.md b/vendor/psr/simple-cache/README.md new file mode 100644 index 0000000..43641d1 --- /dev/null +++ b/vendor/psr/simple-cache/README.md @@ -0,0 +1,8 @@ +PHP FIG Simple Cache PSR +======================== + +This repository holds all interfaces related to PSR-16. + +Note that this is not a cache implementation of its own. It is merely an interface that describes a cache implementation. See [the specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md) for more details. + +You can find implementations of the specification by looking for packages providing the [psr/simple-cache-implementation](https://packagist.org/providers/psr/simple-cache-implementation) virtual package. diff --git a/vendor/psr/simple-cache/composer.json b/vendor/psr/simple-cache/composer.json new file mode 100644 index 0000000..2978fa5 --- /dev/null +++ b/vendor/psr/simple-cache/composer.json @@ -0,0 +1,25 @@ +{ + "name": "psr/simple-cache", + "description": "Common interfaces for simple caching", + "keywords": ["psr", "psr-16", "cache", "simple-cache", "caching"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/psr/simple-cache/src/CacheException.php b/vendor/psr/simple-cache/src/CacheException.php new file mode 100644 index 0000000..eba5381 --- /dev/null +++ b/vendor/psr/simple-cache/src/CacheException.php @@ -0,0 +1,10 @@ + value pairs. Cache keys that do not exist or are stale will have $default as value. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if $keys is neither an array nor a Traversable, + * or if any of the $keys are not a legal value. + */ + public function getMultiple($keys, $default = null); + + /** + * Persists a set of key => value pairs in the cache, with an optional TTL. + * + * @param iterable $values A list of key => value pairs for a multiple-set operation. + * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * the driver supports TTL then the library may set a default value + * for it or let the driver take care of that. + * + * @return bool True on success and false on failure. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if $values is neither an array nor a Traversable, + * or if any of the $values are not a legal value. + */ + public function setMultiple($values, $ttl = null); + + /** + * Deletes multiple cache items in a single operation. + * + * @param iterable $keys A list of string-based keys to be deleted. + * + * @return bool True if the items were successfully removed. False if there was an error. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if $keys is neither an array nor a Traversable, + * or if any of the $keys are not a legal value. + */ + public function deleteMultiple($keys); + + /** + * Determines whether an item is present in the cache. + * + * NOTE: It is recommended that has() is only to be used for cache warming type purposes + * and not to be used within your live applications operations for get/set, as this method + * is subject to a race condition where your has() will return true and immediately after, + * another script can remove it making the state of your app out of date. + * + * @param string $key The cache item key. + * + * @return bool + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if the $key string is not a legal value. + */ + public function has($key); +} diff --git a/vendor/psr/simple-cache/src/InvalidArgumentException.php b/vendor/psr/simple-cache/src/InvalidArgumentException.php new file mode 100644 index 0000000..6a9524a --- /dev/null +++ b/vendor/psr/simple-cache/src/InvalidArgumentException.php @@ -0,0 +1,13 @@ + 'think\\captcha\\CaptchaService', + 1 => 'think\\app\\Service', + 2 => 'think\\trace\\Service', +); \ No newline at end of file diff --git a/vendor/symfony/polyfill-mbstring/LICENSE b/vendor/symfony/polyfill-mbstring/LICENSE new file mode 100644 index 0000000..4cd8bdd --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php new file mode 100644 index 0000000..1fc4fee --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -0,0 +1,829 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Mbstring; + +/** + * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. + * + * Implemented: + * - mb_chr - Returns a specific character from its Unicode code point + * - mb_convert_encoding - Convert character encoding + * - mb_convert_variables - Convert character code in variable(s) + * - mb_decode_mimeheader - Decode string in MIME header field + * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED + * - mb_decode_numericentity - Decode HTML numeric string reference to character + * - mb_encode_numericentity - Encode character to HTML numeric string reference + * - mb_convert_case - Perform case folding on a string + * - mb_detect_encoding - Detect character encoding + * - mb_get_info - Get internal settings of mbstring + * - mb_http_input - Detect HTTP input character encoding + * - mb_http_output - Set/Get HTTP output character encoding + * - mb_internal_encoding - Set/Get internal character encoding + * - mb_list_encodings - Returns an array of all supported encodings + * - mb_ord - Returns the Unicode code point of a character + * - mb_output_handler - Callback function converts character encoding in output buffer + * - mb_scrub - Replaces ill-formed byte sequences with substitute characters + * - mb_strlen - Get string length + * - mb_strpos - Find position of first occurrence of string in a string + * - mb_strrpos - Find position of last occurrence of a string in a string + * - mb_str_split - Convert a string to an array + * - mb_strtolower - Make a string lowercase + * - mb_strtoupper - Make a string uppercase + * - mb_substitute_character - Set/Get substitution character + * - mb_substr - Get part of string + * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive + * - mb_stristr - Finds first occurrence of a string within another, case insensitive + * - mb_strrchr - Finds the last occurrence of a character in a string within another + * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive + * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive + * - mb_strstr - Finds first occurrence of a string within another + * - mb_strwidth - Return width of string + * - mb_substr_count - Count the number of substring occurrences + * + * Not implemented: + * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) + * - mb_ereg_* - Regular expression with multibyte support + * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable + * - mb_preferred_mime_name - Get MIME charset string + * - mb_regex_encoding - Returns current encoding for multibyte regex as string + * - mb_regex_set_options - Set/Get the default options for mbregex functions + * - mb_send_mail - Send encoded mail + * - mb_split - Split multibyte string using regular expression + * - mb_strcut - Get part of string + * - mb_strimwidth - Get truncated string with specified width + * + * @author Nicolas Grekas + * + * @internal + */ +final class Mbstring +{ + const MB_CASE_FOLD = PHP_INT_MAX; + + private static $encodingList = array('ASCII', 'UTF-8'); + private static $language = 'neutral'; + private static $internalEncoding = 'UTF-8'; + private static $caseFold = array( + array('µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"), + array('μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'), + ); + + public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) + { + if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) { + $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); + } else { + $fromEncoding = self::getEncoding($fromEncoding); + } + + $toEncoding = self::getEncoding($toEncoding); + + if ('BASE64' === $fromEncoding) { + $s = base64_decode($s); + $fromEncoding = $toEncoding; + } + + if ('BASE64' === $toEncoding) { + return base64_encode($s); + } + + if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) { + if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) { + $fromEncoding = 'Windows-1252'; + } + if ('UTF-8' !== $fromEncoding) { + $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); + } + + return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s); + } + + if ('HTML-ENTITIES' === $fromEncoding) { + $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8'); + $fromEncoding = 'UTF-8'; + } + + return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); + } + + public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) + { + $vars = array(&$a, &$b, &$c, &$d, &$e, &$f); + + $ok = true; + array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) { + if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) { + $ok = false; + } + }); + + return $ok ? $fromEncoding : false; + } + + public static function mb_decode_mimeheader($s) + { + return iconv_mime_decode($s, 2, self::$internalEncoding); + } + + public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) + { + trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING); + } + + public static function mb_decode_numericentity($s, $convmap, $encoding = null) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { + trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING); + + return null; + } + + if (!\is_array($convmap) || !$convmap) { + return false; + } + + if (null !== $encoding && !\is_scalar($encoding)) { + trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING); + + return ''; // Instead of null (cf. mb_encode_numericentity). + } + + $s = (string) $s; + if ('' === $s) { + return ''; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $s)) { + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + $cnt = floor(\count($convmap) / 4) * 4; + + for ($i = 0; $i < $cnt; $i += 4) { + // collector_decode_htmlnumericentity ignores $convmap[$i + 3] + $convmap[$i] += $convmap[$i + 2]; + $convmap[$i + 1] += $convmap[$i + 2]; + } + + $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) { + $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1]; + for ($i = 0; $i < $cnt; $i += 4) { + if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) { + return Mbstring::mb_chr($c - $convmap[$i + 2]); + } + } + + return $m[0]; + }, $s); + + if (null === $encoding) { + return $s; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $s); + } + + public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { + trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING); + + return null; + } + + if (!\is_array($convmap) || !$convmap) { + return false; + } + + if (null !== $encoding && !\is_scalar($encoding)) { + trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING); + + return null; // Instead of '' (cf. mb_decode_numericentity). + } + + if (null !== $is_hex && !\is_scalar($is_hex)) { + trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', E_USER_WARNING); + + return null; + } + + $s = (string) $s; + if ('' === $s) { + return ''; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $s)) { + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4); + + $cnt = floor(\count($convmap) / 4) * 4; + $i = 0; + $len = \strlen($s); + $result = ''; + + while ($i < $len) { + $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; + $uchr = substr($s, $i, $ulen); + $i += $ulen; + $c = self::mb_ord($uchr); + + for ($j = 0; $j < $cnt; $j += 4) { + if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) { + $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3]; + $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';'; + continue 2; + } + } + $result .= $uchr; + } + + if (null === $encoding) { + return $result; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $result); + } + + public static function mb_convert_case($s, $mode, $encoding = null) + { + $s = (string) $s; + if ('' === $s) { + return ''; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $s)) { + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + if (MB_CASE_TITLE == $mode) { + static $titleRegexp = null; + if (null === $titleRegexp) { + $titleRegexp = self::getData('titleCaseRegexp'); + } + $s = preg_replace_callback($titleRegexp, array(__CLASS__, 'title_case'), $s); + } else { + if (MB_CASE_UPPER == $mode) { + static $upper = null; + if (null === $upper) { + $upper = self::getData('upperCase'); + } + $map = $upper; + } else { + if (self::MB_CASE_FOLD === $mode) { + $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s); + } + + static $lower = null; + if (null === $lower) { + $lower = self::getData('lowerCase'); + } + $map = $lower; + } + + static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4); + + $i = 0; + $len = \strlen($s); + + while ($i < $len) { + $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; + $uchr = substr($s, $i, $ulen); + $i += $ulen; + + if (isset($map[$uchr])) { + $uchr = $map[$uchr]; + $nlen = \strlen($uchr); + + if ($nlen == $ulen) { + $nlen = $i; + do { + $s[--$nlen] = $uchr[--$ulen]; + } while ($ulen); + } else { + $s = substr_replace($s, $uchr, $i - $ulen, $ulen); + $len += $nlen - $ulen; + $i += $nlen - $ulen; + } + } + } + } + + if (null === $encoding) { + return $s; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $s); + } + + public static function mb_internal_encoding($encoding = null) + { + if (null === $encoding) { + return self::$internalEncoding; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) { + self::$internalEncoding = $encoding; + + return true; + } + + return false; + } + + public static function mb_language($lang = null) + { + if (null === $lang) { + return self::$language; + } + + switch ($lang = strtolower($lang)) { + case 'uni': + case 'neutral': + self::$language = $lang; + + return true; + } + + return false; + } + + public static function mb_list_encodings() + { + return array('UTF-8'); + } + + public static function mb_encoding_aliases($encoding) + { + switch (strtoupper($encoding)) { + case 'UTF8': + case 'UTF-8': + return array('utf8'); + } + + return false; + } + + public static function mb_check_encoding($var = null, $encoding = null) + { + if (null === $encoding) { + if (null === $var) { + return false; + } + $encoding = self::$internalEncoding; + } + + return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var); + } + + public static function mb_detect_encoding($str, $encodingList = null, $strict = false) + { + if (null === $encodingList) { + $encodingList = self::$encodingList; + } else { + if (!\is_array($encodingList)) { + $encodingList = array_map('trim', explode(',', $encodingList)); + } + $encodingList = array_map('strtoupper', $encodingList); + } + + foreach ($encodingList as $enc) { + switch ($enc) { + case 'ASCII': + if (!preg_match('/[\x80-\xFF]/', $str)) { + return $enc; + } + break; + + case 'UTF8': + case 'UTF-8': + if (preg_match('//u', $str)) { + return 'UTF-8'; + } + break; + + default: + if (0 === strncmp($enc, 'ISO-8859-', 9)) { + return $enc; + } + } + } + + return false; + } + + public static function mb_detect_order($encodingList = null) + { + if (null === $encodingList) { + return self::$encodingList; + } + + if (!\is_array($encodingList)) { + $encodingList = array_map('trim', explode(',', $encodingList)); + } + $encodingList = array_map('strtoupper', $encodingList); + + foreach ($encodingList as $enc) { + switch ($enc) { + default: + if (strncmp($enc, 'ISO-8859-', 9)) { + return false; + } + // no break + case 'ASCII': + case 'UTF8': + case 'UTF-8': + } + } + + self::$encodingList = $encodingList; + + return true; + } + + public static function mb_strlen($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strlen($s); + } + + return @iconv_strlen($s, $encoding); + } + + public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strpos($haystack, $needle, $offset); + } + + $needle = (string) $needle; + if ('' === $needle) { + trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING); + + return false; + } + + return iconv_strpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strrpos($haystack, $needle, $offset); + } + + if ($offset != (int) $offset) { + $offset = 0; + } elseif ($offset = (int) $offset) { + if ($offset < 0) { + $haystack = self::mb_substr($haystack, 0, $offset, $encoding); + $offset = 0; + } else { + $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding); + } + } + + $pos = iconv_strrpos($haystack, $needle, $encoding); + + return false !== $pos ? $offset + $pos : false; + } + + public static function mb_str_split($string, $split_length = 1, $encoding = null) + { + if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) { + trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', E_USER_WARNING); + + return null; + } + + if ($split_length < 1) { + trigger_error('The length of each segment must be greater than zero', E_USER_WARNING); + + return false; + } + + if (null === $encoding) { + $encoding = mb_internal_encoding(); + } + + $result = array(); + $length = mb_strlen($string, $encoding); + + for ($i = 0; $i < $length; $i += $split_length) { + $result[] = mb_substr($string, $i, $split_length, $encoding); + } + + return $result; + } + + public static function mb_strtolower($s, $encoding = null) + { + return self::mb_convert_case($s, MB_CASE_LOWER, $encoding); + } + + public static function mb_strtoupper($s, $encoding = null) + { + return self::mb_convert_case($s, MB_CASE_UPPER, $encoding); + } + + public static function mb_substitute_character($c = null) + { + if (0 === strcasecmp($c, 'none')) { + return true; + } + + return null !== $c ? false : 'none'; + } + + public static function mb_substr($s, $start, $length = null, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return (string) substr($s, $start, null === $length ? 2147483647 : $length); + } + + if ($start < 0) { + $start = iconv_strlen($s, $encoding) + $start; + if ($start < 0) { + $start = 0; + } + } + + if (null === $length) { + $length = 2147483647; + } elseif ($length < 0) { + $length = iconv_strlen($s, $encoding) + $length - $start; + if ($length < 0) { + return ''; + } + } + + return (string) iconv_substr($s, $start, $length, $encoding); + } + + public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) + { + $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding); + $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); + + return self::mb_strpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_stristr($haystack, $needle, $part = false, $encoding = null) + { + $pos = self::mb_stripos($haystack, $needle, 0, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strrchr($haystack, $needle, $part); + } + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = iconv_strrpos($haystack, $needle, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null) + { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = self::mb_strripos($haystack, $needle, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) + { + $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding); + $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding); + + return self::mb_strrpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_strstr($haystack, $needle, $part = false, $encoding = null) + { + $pos = strpos($haystack, $needle); + if (false === $pos) { + return false; + } + if ($part) { + return substr($haystack, 0, $pos); + } + + return substr($haystack, $pos); + } + + public static function mb_get_info($type = 'all') + { + $info = array( + 'internal_encoding' => self::$internalEncoding, + 'http_output' => 'pass', + 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)', + 'func_overload' => 0, + 'func_overload_list' => 'no overload', + 'mail_charset' => 'UTF-8', + 'mail_header_encoding' => 'BASE64', + 'mail_body_encoding' => 'BASE64', + 'illegal_chars' => 0, + 'encoding_translation' => 'Off', + 'language' => self::$language, + 'detect_order' => self::$encodingList, + 'substitute_character' => 'none', + 'strict_detection' => 'Off', + ); + + if ('all' === $type) { + return $info; + } + if (isset($info[$type])) { + return $info[$type]; + } + + return false; + } + + public static function mb_http_input($type = '') + { + return false; + } + + public static function mb_http_output($encoding = null) + { + return null !== $encoding ? 'pass' === $encoding : 'pass'; + } + + public static function mb_strwidth($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + + if ('UTF-8' !== $encoding) { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); + + return ($wide << 1) + iconv_strlen($s, 'UTF-8'); + } + + public static function mb_substr_count($haystack, $needle, $encoding = null) + { + return substr_count($haystack, $needle); + } + + public static function mb_output_handler($contents, $status) + { + return $contents; + } + + public static function mb_chr($code, $encoding = null) + { + if (0x80 > $code %= 0x200000) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); + } elseif (0x10000 > $code) { + $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } else { + $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } + + if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { + $s = mb_convert_encoding($s, $encoding, 'UTF-8'); + } + + return $s; + } + + public static function mb_ord($s, $encoding = null) + { + if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { + $s = mb_convert_encoding($s, 'UTF-8', $encoding); + } + + if (1 === \strlen($s)) { + return \ord($s); + } + + $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; + if (0xF0 <= $code) { + return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; + } + if (0xE0 <= $code) { + return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; + } + if (0xC0 <= $code) { + return (($code - 0xC0) << 6) + $s[2] - 0x80; + } + + return $code; + } + + private static function getSubpart($pos, $part, $haystack, $encoding) + { + if (false === $pos) { + return false; + } + if ($part) { + return self::mb_substr($haystack, 0, $pos, $encoding); + } + + return self::mb_substr($haystack, $pos, null, $encoding); + } + + private static function html_encoding_callback(array $m) + { + $i = 1; + $entities = ''; + $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8')); + + while (isset($m[$i])) { + if (0x80 > $m[$i]) { + $entities .= \chr($m[$i++]); + continue; + } + if (0xF0 <= $m[$i]) { + $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; + } elseif (0xE0 <= $m[$i]) { + $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; + } else { + $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80; + } + + $entities .= '&#'.$c.';'; + } + + return $entities; + } + + private static function title_case(array $s) + { + return self::mb_convert_case($s[1], MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], MB_CASE_LOWER, 'UTF-8'); + } + + private static function getData($file) + { + if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { + return require $file; + } + + return false; + } + + private static function getEncoding($encoding) + { + if (null === $encoding) { + return self::$internalEncoding; + } + + $encoding = strtoupper($encoding); + + if ('8BIT' === $encoding || 'BINARY' === $encoding) { + return 'CP850'; + } + if ('UTF8' === $encoding) { + return 'UTF-8'; + } + + return $encoding; + } +} diff --git a/vendor/symfony/polyfill-mbstring/README.md b/vendor/symfony/polyfill-mbstring/README.md new file mode 100644 index 0000000..342e828 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/README.md @@ -0,0 +1,13 @@ +Symfony Polyfill / Mbstring +=========================== + +This component provides a partial, native PHP implementation for the +[Mbstring](http://php.net/mbstring) extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php new file mode 100644 index 0000000..e6fbfa6 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php @@ -0,0 +1,1096 @@ + 'a', + 'B' => 'b', + 'C' => 'c', + 'D' => 'd', + 'E' => 'e', + 'F' => 'f', + 'G' => 'g', + 'H' => 'h', + 'I' => 'i', + 'J' => 'j', + 'K' => 'k', + 'L' => 'l', + 'M' => 'm', + 'N' => 'n', + 'O' => 'o', + 'P' => 'p', + 'Q' => 'q', + 'R' => 'r', + 'S' => 's', + 'T' => 't', + 'U' => 'u', + 'V' => 'v', + 'W' => 'w', + 'X' => 'x', + 'Y' => 'y', + 'Z' => 'z', + 'À' => 'à', + 'Á' => 'á', + 'Â' => 'â', + 'Ã' => 'ã', + 'Ä' => 'ä', + 'Å' => 'å', + 'Æ' => 'æ', + 'Ç' => 'ç', + 'È' => 'è', + 'É' => 'é', + 'Ê' => 'ê', + 'Ë' => 'ë', + 'Ì' => 'ì', + 'Í' => 'í', + 'Î' => 'î', + 'Ï' => 'ï', + 'Ð' => 'ð', + 'Ñ' => 'ñ', + 'Ò' => 'ò', + 'Ó' => 'ó', + 'Ô' => 'ô', + 'Õ' => 'õ', + 'Ö' => 'ö', + 'Ø' => 'ø', + 'Ù' => 'ù', + 'Ú' => 'ú', + 'Û' => 'û', + 'Ü' => 'ü', + 'Ý' => 'ý', + 'Þ' => 'þ', + 'Ā' => 'ā', + 'Ă' => 'ă', + 'Ą' => 'ą', + 'Ć' => 'ć', + 'Ĉ' => 'ĉ', + 'Ċ' => 'ċ', + 'Č' => 'č', + 'Ď' => 'ď', + 'Đ' => 'đ', + 'Ē' => 'ē', + 'Ĕ' => 'ĕ', + 'Ė' => 'ė', + 'Ę' => 'ę', + 'Ě' => 'ě', + 'Ĝ' => 'ĝ', + 'Ğ' => 'ğ', + 'Ġ' => 'ġ', + 'Ģ' => 'ģ', + 'Ĥ' => 'ĥ', + 'Ħ' => 'ħ', + 'Ĩ' => 'ĩ', + 'Ī' => 'ī', + 'Ĭ' => 'ĭ', + 'Į' => 'į', + 'İ' => 'i', + 'IJ' => 'ij', + 'Ĵ' => 'ĵ', + 'Ķ' => 'ķ', + 'Ĺ' => 'ĺ', + 'Ļ' => 'ļ', + 'Ľ' => 'ľ', + 'Ŀ' => 'ŀ', + 'Ł' => 'ł', + 'Ń' => 'ń', + 'Ņ' => 'ņ', + 'Ň' => 'ň', + 'Ŋ' => 'ŋ', + 'Ō' => 'ō', + 'Ŏ' => 'ŏ', + 'Ő' => 'ő', + 'Œ' => 'œ', + 'Ŕ' => 'ŕ', + 'Ŗ' => 'ŗ', + 'Ř' => 'ř', + 'Ś' => 'ś', + 'Ŝ' => 'ŝ', + 'Ş' => 'ş', + 'Š' => 'š', + 'Ţ' => 'ţ', + 'Ť' => 'ť', + 'Ŧ' => 'ŧ', + 'Ũ' => 'ũ', + 'Ū' => 'ū', + 'Ŭ' => 'ŭ', + 'Ů' => 'ů', + 'Ű' => 'ű', + 'Ų' => 'ų', + 'Ŵ' => 'ŵ', + 'Ŷ' => 'ŷ', + 'Ÿ' => 'ÿ', + 'Ź' => 'ź', + 'Ż' => 'ż', + 'Ž' => 'ž', + 'Ɓ' => 'ɓ', + 'Ƃ' => 'ƃ', + 'Ƅ' => 'ƅ', + 'Ɔ' => 'ɔ', + 'Ƈ' => 'ƈ', + 'Ɖ' => 'ɖ', + 'Ɗ' => 'ɗ', + 'Ƌ' => 'ƌ', + 'Ǝ' => 'ǝ', + 'Ə' => 'ə', + 'Ɛ' => 'ɛ', + 'Ƒ' => 'ƒ', + 'Ɠ' => 'ɠ', + 'Ɣ' => 'ɣ', + 'Ɩ' => 'ɩ', + 'Ɨ' => 'ɨ', + 'Ƙ' => 'ƙ', + 'Ɯ' => 'ɯ', + 'Ɲ' => 'ɲ', + 'Ɵ' => 'ɵ', + 'Ơ' => 'ơ', + 'Ƣ' => 'ƣ', + 'Ƥ' => 'ƥ', + 'Ʀ' => 'ʀ', + 'Ƨ' => 'ƨ', + 'Ʃ' => 'ʃ', + 'Ƭ' => 'ƭ', + 'Ʈ' => 'ʈ', + 'Ư' => 'ư', + 'Ʊ' => 'ʊ', + 'Ʋ' => 'ʋ', + 'Ƴ' => 'ƴ', + 'Ƶ' => 'ƶ', + 'Ʒ' => 'ʒ', + 'Ƹ' => 'ƹ', + 'Ƽ' => 'ƽ', + 'DŽ' => 'dž', + 'Dž' => 'dž', + 'LJ' => 'lj', + 'Lj' => 'lj', + 'NJ' => 'nj', + 'Nj' => 'nj', + 'Ǎ' => 'ǎ', + 'Ǐ' => 'ǐ', + 'Ǒ' => 'ǒ', + 'Ǔ' => 'ǔ', + 'Ǖ' => 'ǖ', + 'Ǘ' => 'ǘ', + 'Ǚ' => 'ǚ', + 'Ǜ' => 'ǜ', + 'Ǟ' => 'ǟ', + 'Ǡ' => 'ǡ', + 'Ǣ' => 'ǣ', + 'Ǥ' => 'ǥ', + 'Ǧ' => 'ǧ', + 'Ǩ' => 'ǩ', + 'Ǫ' => 'ǫ', + 'Ǭ' => 'ǭ', + 'Ǯ' => 'ǯ', + 'DZ' => 'dz', + 'Dz' => 'dz', + 'Ǵ' => 'ǵ', + 'Ƕ' => 'ƕ', + 'Ƿ' => 'ƿ', + 'Ǹ' => 'ǹ', + 'Ǻ' => 'ǻ', + 'Ǽ' => 'ǽ', + 'Ǿ' => 'ǿ', + 'Ȁ' => 'ȁ', + 'Ȃ' => 'ȃ', + 'Ȅ' => 'ȅ', + 'Ȇ' => 'ȇ', + 'Ȉ' => 'ȉ', + 'Ȋ' => 'ȋ', + 'Ȍ' => 'ȍ', + 'Ȏ' => 'ȏ', + 'Ȑ' => 'ȑ', + 'Ȓ' => 'ȓ', + 'Ȕ' => 'ȕ', + 'Ȗ' => 'ȗ', + 'Ș' => 'ș', + 'Ț' => 'ț', + 'Ȝ' => 'ȝ', + 'Ȟ' => 'ȟ', + 'Ƞ' => 'ƞ', + 'Ȣ' => 'ȣ', + 'Ȥ' => 'ȥ', + 'Ȧ' => 'ȧ', + 'Ȩ' => 'ȩ', + 'Ȫ' => 'ȫ', + 'Ȭ' => 'ȭ', + 'Ȯ' => 'ȯ', + 'Ȱ' => 'ȱ', + 'Ȳ' => 'ȳ', + 'Ⱥ' => 'ⱥ', + 'Ȼ' => 'ȼ', + 'Ƚ' => 'ƚ', + 'Ⱦ' => 'ⱦ', + 'Ɂ' => 'ɂ', + 'Ƀ' => 'ƀ', + 'Ʉ' => 'ʉ', + 'Ʌ' => 'ʌ', + 'Ɇ' => 'ɇ', + 'Ɉ' => 'ɉ', + 'Ɋ' => 'ɋ', + 'Ɍ' => 'ɍ', + 'Ɏ' => 'ɏ', + 'Ͱ' => 'ͱ', + 'Ͳ' => 'ͳ', + 'Ͷ' => 'ͷ', + 'Ϳ' => 'ϳ', + 'Ά' => 'ά', + 'Έ' => 'έ', + 'Ή' => 'ή', + 'Ί' => 'ί', + 'Ό' => 'ό', + 'Ύ' => 'ύ', + 'Ώ' => 'ώ', + 'Α' => 'α', + 'Β' => 'β', + 'Γ' => 'γ', + 'Δ' => 'δ', + 'Ε' => 'ε', + 'Ζ' => 'ζ', + 'Η' => 'η', + 'Θ' => 'θ', + 'Ι' => 'ι', + 'Κ' => 'κ', + 'Λ' => 'λ', + 'Μ' => 'μ', + 'Ν' => 'ν', + 'Ξ' => 'ξ', + 'Ο' => 'ο', + 'Π' => 'π', + 'Ρ' => 'ρ', + 'Σ' => 'σ', + 'Τ' => 'τ', + 'Υ' => 'υ', + 'Φ' => 'φ', + 'Χ' => 'χ', + 'Ψ' => 'ψ', + 'Ω' => 'ω', + 'Ϊ' => 'ϊ', + 'Ϋ' => 'ϋ', + 'Ϗ' => 'ϗ', + 'Ϙ' => 'ϙ', + 'Ϛ' => 'ϛ', + 'Ϝ' => 'ϝ', + 'Ϟ' => 'ϟ', + 'Ϡ' => 'ϡ', + 'Ϣ' => 'ϣ', + 'Ϥ' => 'ϥ', + 'Ϧ' => 'ϧ', + 'Ϩ' => 'ϩ', + 'Ϫ' => 'ϫ', + 'Ϭ' => 'ϭ', + 'Ϯ' => 'ϯ', + 'ϴ' => 'θ', + 'Ϸ' => 'ϸ', + 'Ϲ' => 'ϲ', + 'Ϻ' => 'ϻ', + 'Ͻ' => 'ͻ', + 'Ͼ' => 'ͼ', + 'Ͽ' => 'ͽ', + 'Ѐ' => 'ѐ', + 'Ё' => 'ё', + 'Ђ' => 'ђ', + 'Ѓ' => 'ѓ', + 'Є' => 'є', + 'Ѕ' => 'ѕ', + 'І' => 'і', + 'Ї' => 'ї', + 'Ј' => 'ј', + 'Љ' => 'љ', + 'Њ' => 'њ', + 'Ћ' => 'ћ', + 'Ќ' => 'ќ', + 'Ѝ' => 'ѝ', + 'Ў' => 'ў', + 'Џ' => 'џ', + 'А' => 'а', + 'Б' => 'б', + 'В' => 'в', + 'Г' => 'г', + 'Д' => 'д', + 'Е' => 'е', + 'Ж' => 'ж', + 'З' => 'з', + 'И' => 'и', + 'Й' => 'й', + 'К' => 'к', + 'Л' => 'л', + 'М' => 'м', + 'Н' => 'н', + 'О' => 'о', + 'П' => 'п', + 'Р' => 'р', + 'С' => 'с', + 'Т' => 'т', + 'У' => 'у', + 'Ф' => 'ф', + 'Х' => 'х', + 'Ц' => 'ц', + 'Ч' => 'ч', + 'Ш' => 'ш', + 'Щ' => 'щ', + 'Ъ' => 'ъ', + 'Ы' => 'ы', + 'Ь' => 'ь', + 'Э' => 'э', + 'Ю' => 'ю', + 'Я' => 'я', + 'Ѡ' => 'ѡ', + 'Ѣ' => 'ѣ', + 'Ѥ' => 'ѥ', + 'Ѧ' => 'ѧ', + 'Ѩ' => 'ѩ', + 'Ѫ' => 'ѫ', + 'Ѭ' => 'ѭ', + 'Ѯ' => 'ѯ', + 'Ѱ' => 'ѱ', + 'Ѳ' => 'ѳ', + 'Ѵ' => 'ѵ', + 'Ѷ' => 'ѷ', + 'Ѹ' => 'ѹ', + 'Ѻ' => 'ѻ', + 'Ѽ' => 'ѽ', + 'Ѿ' => 'ѿ', + 'Ҁ' => 'ҁ', + 'Ҋ' => 'ҋ', + 'Ҍ' => 'ҍ', + 'Ҏ' => 'ҏ', + 'Ґ' => 'ґ', + 'Ғ' => 'ғ', + 'Ҕ' => 'ҕ', + 'Җ' => 'җ', + 'Ҙ' => 'ҙ', + 'Қ' => 'қ', + 'Ҝ' => 'ҝ', + 'Ҟ' => 'ҟ', + 'Ҡ' => 'ҡ', + 'Ң' => 'ң', + 'Ҥ' => 'ҥ', + 'Ҧ' => 'ҧ', + 'Ҩ' => 'ҩ', + 'Ҫ' => 'ҫ', + 'Ҭ' => 'ҭ', + 'Ү' => 'ү', + 'Ұ' => 'ұ', + 'Ҳ' => 'ҳ', + 'Ҵ' => 'ҵ', + 'Ҷ' => 'ҷ', + 'Ҹ' => 'ҹ', + 'Һ' => 'һ', + 'Ҽ' => 'ҽ', + 'Ҿ' => 'ҿ', + 'Ӏ' => 'ӏ', + 'Ӂ' => 'ӂ', + 'Ӄ' => 'ӄ', + 'Ӆ' => 'ӆ', + 'Ӈ' => 'ӈ', + 'Ӊ' => 'ӊ', + 'Ӌ' => 'ӌ', + 'Ӎ' => 'ӎ', + 'Ӑ' => 'ӑ', + 'Ӓ' => 'ӓ', + 'Ӕ' => 'ӕ', + 'Ӗ' => 'ӗ', + 'Ә' => 'ә', + 'Ӛ' => 'ӛ', + 'Ӝ' => 'ӝ', + 'Ӟ' => 'ӟ', + 'Ӡ' => 'ӡ', + 'Ӣ' => 'ӣ', + 'Ӥ' => 'ӥ', + 'Ӧ' => 'ӧ', + 'Ө' => 'ө', + 'Ӫ' => 'ӫ', + 'Ӭ' => 'ӭ', + 'Ӯ' => 'ӯ', + 'Ӱ' => 'ӱ', + 'Ӳ' => 'ӳ', + 'Ӵ' => 'ӵ', + 'Ӷ' => 'ӷ', + 'Ӹ' => 'ӹ', + 'Ӻ' => 'ӻ', + 'Ӽ' => 'ӽ', + 'Ӿ' => 'ӿ', + 'Ԁ' => 'ԁ', + 'Ԃ' => 'ԃ', + 'Ԅ' => 'ԅ', + 'Ԇ' => 'ԇ', + 'Ԉ' => 'ԉ', + 'Ԋ' => 'ԋ', + 'Ԍ' => 'ԍ', + 'Ԏ' => 'ԏ', + 'Ԑ' => 'ԑ', + 'Ԓ' => 'ԓ', + 'Ԕ' => 'ԕ', + 'Ԗ' => 'ԗ', + 'Ԙ' => 'ԙ', + 'Ԛ' => 'ԛ', + 'Ԝ' => 'ԝ', + 'Ԟ' => 'ԟ', + 'Ԡ' => 'ԡ', + 'Ԣ' => 'ԣ', + 'Ԥ' => 'ԥ', + 'Ԧ' => 'ԧ', + 'Ԩ' => 'ԩ', + 'Ԫ' => 'ԫ', + 'Ԭ' => 'ԭ', + 'Ԯ' => 'ԯ', + 'Ա' => 'ա', + 'Բ' => 'բ', + 'Գ' => 'գ', + 'Դ' => 'դ', + 'Ե' => 'ե', + 'Զ' => 'զ', + 'Է' => 'է', + 'Ը' => 'ը', + 'Թ' => 'թ', + 'Ժ' => 'ժ', + 'Ի' => 'ի', + 'Լ' => 'լ', + 'Խ' => 'խ', + 'Ծ' => 'ծ', + 'Կ' => 'կ', + 'Հ' => 'հ', + 'Ձ' => 'ձ', + 'Ղ' => 'ղ', + 'Ճ' => 'ճ', + 'Մ' => 'մ', + 'Յ' => 'յ', + 'Ն' => 'ն', + 'Շ' => 'շ', + 'Ո' => 'ո', + 'Չ' => 'չ', + 'Պ' => 'պ', + 'Ջ' => 'ջ', + 'Ռ' => 'ռ', + 'Ս' => 'ս', + 'Վ' => 'վ', + 'Տ' => 'տ', + 'Ր' => 'ր', + 'Ց' => 'ց', + 'Ւ' => 'ւ', + 'Փ' => 'փ', + 'Ք' => 'ք', + 'Օ' => 'օ', + 'Ֆ' => 'ֆ', + 'Ⴀ' => 'ⴀ', + 'Ⴁ' => 'ⴁ', + 'Ⴂ' => 'ⴂ', + 'Ⴃ' => 'ⴃ', + 'Ⴄ' => 'ⴄ', + 'Ⴅ' => 'ⴅ', + 'Ⴆ' => 'ⴆ', + 'Ⴇ' => 'ⴇ', + 'Ⴈ' => 'ⴈ', + 'Ⴉ' => 'ⴉ', + 'Ⴊ' => 'ⴊ', + 'Ⴋ' => 'ⴋ', + 'Ⴌ' => 'ⴌ', + 'Ⴍ' => 'ⴍ', + 'Ⴎ' => 'ⴎ', + 'Ⴏ' => 'ⴏ', + 'Ⴐ' => 'ⴐ', + 'Ⴑ' => 'ⴑ', + 'Ⴒ' => 'ⴒ', + 'Ⴓ' => 'ⴓ', + 'Ⴔ' => 'ⴔ', + 'Ⴕ' => 'ⴕ', + 'Ⴖ' => 'ⴖ', + 'Ⴗ' => 'ⴗ', + 'Ⴘ' => 'ⴘ', + 'Ⴙ' => 'ⴙ', + 'Ⴚ' => 'ⴚ', + 'Ⴛ' => 'ⴛ', + 'Ⴜ' => 'ⴜ', + 'Ⴝ' => 'ⴝ', + 'Ⴞ' => 'ⴞ', + 'Ⴟ' => 'ⴟ', + 'Ⴠ' => 'ⴠ', + 'Ⴡ' => 'ⴡ', + 'Ⴢ' => 'ⴢ', + 'Ⴣ' => 'ⴣ', + 'Ⴤ' => 'ⴤ', + 'Ⴥ' => 'ⴥ', + 'Ⴧ' => 'ⴧ', + 'Ⴭ' => 'ⴭ', + 'Ḁ' => 'ḁ', + 'Ḃ' => 'ḃ', + 'Ḅ' => 'ḅ', + 'Ḇ' => 'ḇ', + 'Ḉ' => 'ḉ', + 'Ḋ' => 'ḋ', + 'Ḍ' => 'ḍ', + 'Ḏ' => 'ḏ', + 'Ḑ' => 'ḑ', + 'Ḓ' => 'ḓ', + 'Ḕ' => 'ḕ', + 'Ḗ' => 'ḗ', + 'Ḙ' => 'ḙ', + 'Ḛ' => 'ḛ', + 'Ḝ' => 'ḝ', + 'Ḟ' => 'ḟ', + 'Ḡ' => 'ḡ', + 'Ḣ' => 'ḣ', + 'Ḥ' => 'ḥ', + 'Ḧ' => 'ḧ', + 'Ḩ' => 'ḩ', + 'Ḫ' => 'ḫ', + 'Ḭ' => 'ḭ', + 'Ḯ' => 'ḯ', + 'Ḱ' => 'ḱ', + 'Ḳ' => 'ḳ', + 'Ḵ' => 'ḵ', + 'Ḷ' => 'ḷ', + 'Ḹ' => 'ḹ', + 'Ḻ' => 'ḻ', + 'Ḽ' => 'ḽ', + 'Ḿ' => 'ḿ', + 'Ṁ' => 'ṁ', + 'Ṃ' => 'ṃ', + 'Ṅ' => 'ṅ', + 'Ṇ' => 'ṇ', + 'Ṉ' => 'ṉ', + 'Ṋ' => 'ṋ', + 'Ṍ' => 'ṍ', + 'Ṏ' => 'ṏ', + 'Ṑ' => 'ṑ', + 'Ṓ' => 'ṓ', + 'Ṕ' => 'ṕ', + 'Ṗ' => 'ṗ', + 'Ṙ' => 'ṙ', + 'Ṛ' => 'ṛ', + 'Ṝ' => 'ṝ', + 'Ṟ' => 'ṟ', + 'Ṡ' => 'ṡ', + 'Ṣ' => 'ṣ', + 'Ṥ' => 'ṥ', + 'Ṧ' => 'ṧ', + 'Ṩ' => 'ṩ', + 'Ṫ' => 'ṫ', + 'Ṭ' => 'ṭ', + 'Ṯ' => 'ṯ', + 'Ṱ' => 'ṱ', + 'Ṳ' => 'ṳ', + 'Ṵ' => 'ṵ', + 'Ṷ' => 'ṷ', + 'Ṹ' => 'ṹ', + 'Ṻ' => 'ṻ', + 'Ṽ' => 'ṽ', + 'Ṿ' => 'ṿ', + 'Ẁ' => 'ẁ', + 'Ẃ' => 'ẃ', + 'Ẅ' => 'ẅ', + 'Ẇ' => 'ẇ', + 'Ẉ' => 'ẉ', + 'Ẋ' => 'ẋ', + 'Ẍ' => 'ẍ', + 'Ẏ' => 'ẏ', + 'Ẑ' => 'ẑ', + 'Ẓ' => 'ẓ', + 'Ẕ' => 'ẕ', + 'ẞ' => 'ß', + 'Ạ' => 'ạ', + 'Ả' => 'ả', + 'Ấ' => 'ấ', + 'Ầ' => 'ầ', + 'Ẩ' => 'ẩ', + 'Ẫ' => 'ẫ', + 'Ậ' => 'ậ', + 'Ắ' => 'ắ', + 'Ằ' => 'ằ', + 'Ẳ' => 'ẳ', + 'Ẵ' => 'ẵ', + 'Ặ' => 'ặ', + 'Ẹ' => 'ẹ', + 'Ẻ' => 'ẻ', + 'Ẽ' => 'ẽ', + 'Ế' => 'ế', + 'Ề' => 'ề', + 'Ể' => 'ể', + 'Ễ' => 'ễ', + 'Ệ' => 'ệ', + 'Ỉ' => 'ỉ', + 'Ị' => 'ị', + 'Ọ' => 'ọ', + 'Ỏ' => 'ỏ', + 'Ố' => 'ố', + 'Ồ' => 'ồ', + 'Ổ' => 'ổ', + 'Ỗ' => 'ỗ', + 'Ộ' => 'ộ', + 'Ớ' => 'ớ', + 'Ờ' => 'ờ', + 'Ở' => 'ở', + 'Ỡ' => 'ỡ', + 'Ợ' => 'ợ', + 'Ụ' => 'ụ', + 'Ủ' => 'ủ', + 'Ứ' => 'ứ', + 'Ừ' => 'ừ', + 'Ử' => 'ử', + 'Ữ' => 'ữ', + 'Ự' => 'ự', + 'Ỳ' => 'ỳ', + 'Ỵ' => 'ỵ', + 'Ỷ' => 'ỷ', + 'Ỹ' => 'ỹ', + 'Ỻ' => 'ỻ', + 'Ỽ' => 'ỽ', + 'Ỿ' => 'ỿ', + 'Ἀ' => 'ἀ', + 'Ἁ' => 'ἁ', + 'Ἂ' => 'ἂ', + 'Ἃ' => 'ἃ', + 'Ἄ' => 'ἄ', + 'Ἅ' => 'ἅ', + 'Ἆ' => 'ἆ', + 'Ἇ' => 'ἇ', + 'Ἐ' => 'ἐ', + 'Ἑ' => 'ἑ', + 'Ἒ' => 'ἒ', + 'Ἓ' => 'ἓ', + 'Ἔ' => 'ἔ', + 'Ἕ' => 'ἕ', + 'Ἠ' => 'ἠ', + 'Ἡ' => 'ἡ', + 'Ἢ' => 'ἢ', + 'Ἣ' => 'ἣ', + 'Ἤ' => 'ἤ', + 'Ἥ' => 'ἥ', + 'Ἦ' => 'ἦ', + 'Ἧ' => 'ἧ', + 'Ἰ' => 'ἰ', + 'Ἱ' => 'ἱ', + 'Ἲ' => 'ἲ', + 'Ἳ' => 'ἳ', + 'Ἴ' => 'ἴ', + 'Ἵ' => 'ἵ', + 'Ἶ' => 'ἶ', + 'Ἷ' => 'ἷ', + 'Ὀ' => 'ὀ', + 'Ὁ' => 'ὁ', + 'Ὂ' => 'ὂ', + 'Ὃ' => 'ὃ', + 'Ὄ' => 'ὄ', + 'Ὅ' => 'ὅ', + 'Ὑ' => 'ὑ', + 'Ὓ' => 'ὓ', + 'Ὕ' => 'ὕ', + 'Ὗ' => 'ὗ', + 'Ὠ' => 'ὠ', + 'Ὡ' => 'ὡ', + 'Ὢ' => 'ὢ', + 'Ὣ' => 'ὣ', + 'Ὤ' => 'ὤ', + 'Ὥ' => 'ὥ', + 'Ὦ' => 'ὦ', + 'Ὧ' => 'ὧ', + 'ᾈ' => 'ᾀ', + 'ᾉ' => 'ᾁ', + 'ᾊ' => 'ᾂ', + 'ᾋ' => 'ᾃ', + 'ᾌ' => 'ᾄ', + 'ᾍ' => 'ᾅ', + 'ᾎ' => 'ᾆ', + 'ᾏ' => 'ᾇ', + 'ᾘ' => 'ᾐ', + 'ᾙ' => 'ᾑ', + 'ᾚ' => 'ᾒ', + 'ᾛ' => 'ᾓ', + 'ᾜ' => 'ᾔ', + 'ᾝ' => 'ᾕ', + 'ᾞ' => 'ᾖ', + 'ᾟ' => 'ᾗ', + 'ᾨ' => 'ᾠ', + 'ᾩ' => 'ᾡ', + 'ᾪ' => 'ᾢ', + 'ᾫ' => 'ᾣ', + 'ᾬ' => 'ᾤ', + 'ᾭ' => 'ᾥ', + 'ᾮ' => 'ᾦ', + 'ᾯ' => 'ᾧ', + 'Ᾰ' => 'ᾰ', + 'Ᾱ' => 'ᾱ', + 'Ὰ' => 'ὰ', + 'Ά' => 'ά', + 'ᾼ' => 'ᾳ', + 'Ὲ' => 'ὲ', + 'Έ' => 'έ', + 'Ὴ' => 'ὴ', + 'Ή' => 'ή', + 'ῌ' => 'ῃ', + 'Ῐ' => 'ῐ', + 'Ῑ' => 'ῑ', + 'Ὶ' => 'ὶ', + 'Ί' => 'ί', + 'Ῠ' => 'ῠ', + 'Ῡ' => 'ῡ', + 'Ὺ' => 'ὺ', + 'Ύ' => 'ύ', + 'Ῥ' => 'ῥ', + 'Ὸ' => 'ὸ', + 'Ό' => 'ό', + 'Ὼ' => 'ὼ', + 'Ώ' => 'ώ', + 'ῼ' => 'ῳ', + 'Ω' => 'ω', + 'K' => 'k', + 'Å' => 'å', + 'Ⅎ' => 'ⅎ', + 'Ⅰ' => 'ⅰ', + 'Ⅱ' => 'ⅱ', + 'Ⅲ' => 'ⅲ', + 'Ⅳ' => 'ⅳ', + 'Ⅴ' => 'ⅴ', + 'Ⅵ' => 'ⅵ', + 'Ⅶ' => 'ⅶ', + 'Ⅷ' => 'ⅷ', + 'Ⅸ' => 'ⅸ', + 'Ⅹ' => 'ⅹ', + 'Ⅺ' => 'ⅺ', + 'Ⅻ' => 'ⅻ', + 'Ⅼ' => 'ⅼ', + 'Ⅽ' => 'ⅽ', + 'Ⅾ' => 'ⅾ', + 'Ⅿ' => 'ⅿ', + 'Ↄ' => 'ↄ', + 'Ⓐ' => 'ⓐ', + 'Ⓑ' => 'ⓑ', + 'Ⓒ' => 'ⓒ', + 'Ⓓ' => 'ⓓ', + 'Ⓔ' => 'ⓔ', + 'Ⓕ' => 'ⓕ', + 'Ⓖ' => 'ⓖ', + 'Ⓗ' => 'ⓗ', + 'Ⓘ' => 'ⓘ', + 'Ⓙ' => 'ⓙ', + 'Ⓚ' => 'ⓚ', + 'Ⓛ' => 'ⓛ', + 'Ⓜ' => 'ⓜ', + 'Ⓝ' => 'ⓝ', + 'Ⓞ' => 'ⓞ', + 'Ⓟ' => 'ⓟ', + 'Ⓠ' => 'ⓠ', + 'Ⓡ' => 'ⓡ', + 'Ⓢ' => 'ⓢ', + 'Ⓣ' => 'ⓣ', + 'Ⓤ' => 'ⓤ', + 'Ⓥ' => 'ⓥ', + 'Ⓦ' => 'ⓦ', + 'Ⓧ' => 'ⓧ', + 'Ⓨ' => 'ⓨ', + 'Ⓩ' => 'ⓩ', + 'Ⰰ' => 'ⰰ', + 'Ⰱ' => 'ⰱ', + 'Ⰲ' => 'ⰲ', + 'Ⰳ' => 'ⰳ', + 'Ⰴ' => 'ⰴ', + 'Ⰵ' => 'ⰵ', + 'Ⰶ' => 'ⰶ', + 'Ⰷ' => 'ⰷ', + 'Ⰸ' => 'ⰸ', + 'Ⰹ' => 'ⰹ', + 'Ⰺ' => 'ⰺ', + 'Ⰻ' => 'ⰻ', + 'Ⰼ' => 'ⰼ', + 'Ⰽ' => 'ⰽ', + 'Ⰾ' => 'ⰾ', + 'Ⰿ' => 'ⰿ', + 'Ⱀ' => 'ⱀ', + 'Ⱁ' => 'ⱁ', + 'Ⱂ' => 'ⱂ', + 'Ⱃ' => 'ⱃ', + 'Ⱄ' => 'ⱄ', + 'Ⱅ' => 'ⱅ', + 'Ⱆ' => 'ⱆ', + 'Ⱇ' => 'ⱇ', + 'Ⱈ' => 'ⱈ', + 'Ⱉ' => 'ⱉ', + 'Ⱊ' => 'ⱊ', + 'Ⱋ' => 'ⱋ', + 'Ⱌ' => 'ⱌ', + 'Ⱍ' => 'ⱍ', + 'Ⱎ' => 'ⱎ', + 'Ⱏ' => 'ⱏ', + 'Ⱐ' => 'ⱐ', + 'Ⱑ' => 'ⱑ', + 'Ⱒ' => 'ⱒ', + 'Ⱓ' => 'ⱓ', + 'Ⱔ' => 'ⱔ', + 'Ⱕ' => 'ⱕ', + 'Ⱖ' => 'ⱖ', + 'Ⱗ' => 'ⱗ', + 'Ⱘ' => 'ⱘ', + 'Ⱙ' => 'ⱙ', + 'Ⱚ' => 'ⱚ', + 'Ⱛ' => 'ⱛ', + 'Ⱜ' => 'ⱜ', + 'Ⱝ' => 'ⱝ', + 'Ⱞ' => 'ⱞ', + 'Ⱡ' => 'ⱡ', + 'Ɫ' => 'ɫ', + 'Ᵽ' => 'ᵽ', + 'Ɽ' => 'ɽ', + 'Ⱨ' => 'ⱨ', + 'Ⱪ' => 'ⱪ', + 'Ⱬ' => 'ⱬ', + 'Ɑ' => 'ɑ', + 'Ɱ' => 'ɱ', + 'Ɐ' => 'ɐ', + 'Ɒ' => 'ɒ', + 'Ⱳ' => 'ⱳ', + 'Ⱶ' => 'ⱶ', + 'Ȿ' => 'ȿ', + 'Ɀ' => 'ɀ', + 'Ⲁ' => 'ⲁ', + 'Ⲃ' => 'ⲃ', + 'Ⲅ' => 'ⲅ', + 'Ⲇ' => 'ⲇ', + 'Ⲉ' => 'ⲉ', + 'Ⲋ' => 'ⲋ', + 'Ⲍ' => 'ⲍ', + 'Ⲏ' => 'ⲏ', + 'Ⲑ' => 'ⲑ', + 'Ⲓ' => 'ⲓ', + 'Ⲕ' => 'ⲕ', + 'Ⲗ' => 'ⲗ', + 'Ⲙ' => 'ⲙ', + 'Ⲛ' => 'ⲛ', + 'Ⲝ' => 'ⲝ', + 'Ⲟ' => 'ⲟ', + 'Ⲡ' => 'ⲡ', + 'Ⲣ' => 'ⲣ', + 'Ⲥ' => 'ⲥ', + 'Ⲧ' => 'ⲧ', + 'Ⲩ' => 'ⲩ', + 'Ⲫ' => 'ⲫ', + 'Ⲭ' => 'ⲭ', + 'Ⲯ' => 'ⲯ', + 'Ⲱ' => 'ⲱ', + 'Ⲳ' => 'ⲳ', + 'Ⲵ' => 'ⲵ', + 'Ⲷ' => 'ⲷ', + 'Ⲹ' => 'ⲹ', + 'Ⲻ' => 'ⲻ', + 'Ⲽ' => 'ⲽ', + 'Ⲿ' => 'ⲿ', + 'Ⳁ' => 'ⳁ', + 'Ⳃ' => 'ⳃ', + 'Ⳅ' => 'ⳅ', + 'Ⳇ' => 'ⳇ', + 'Ⳉ' => 'ⳉ', + 'Ⳋ' => 'ⳋ', + 'Ⳍ' => 'ⳍ', + 'Ⳏ' => 'ⳏ', + 'Ⳑ' => 'ⳑ', + 'Ⳓ' => 'ⳓ', + 'Ⳕ' => 'ⳕ', + 'Ⳗ' => 'ⳗ', + 'Ⳙ' => 'ⳙ', + 'Ⳛ' => 'ⳛ', + 'Ⳝ' => 'ⳝ', + 'Ⳟ' => 'ⳟ', + 'Ⳡ' => 'ⳡ', + 'Ⳣ' => 'ⳣ', + 'Ⳬ' => 'ⳬ', + 'Ⳮ' => 'ⳮ', + 'Ⳳ' => 'ⳳ', + 'Ꙁ' => 'ꙁ', + 'Ꙃ' => 'ꙃ', + 'Ꙅ' => 'ꙅ', + 'Ꙇ' => 'ꙇ', + 'Ꙉ' => 'ꙉ', + 'Ꙋ' => 'ꙋ', + 'Ꙍ' => 'ꙍ', + 'Ꙏ' => 'ꙏ', + 'Ꙑ' => 'ꙑ', + 'Ꙓ' => 'ꙓ', + 'Ꙕ' => 'ꙕ', + 'Ꙗ' => 'ꙗ', + 'Ꙙ' => 'ꙙ', + 'Ꙛ' => 'ꙛ', + 'Ꙝ' => 'ꙝ', + 'Ꙟ' => 'ꙟ', + 'Ꙡ' => 'ꙡ', + 'Ꙣ' => 'ꙣ', + 'Ꙥ' => 'ꙥ', + 'Ꙧ' => 'ꙧ', + 'Ꙩ' => 'ꙩ', + 'Ꙫ' => 'ꙫ', + 'Ꙭ' => 'ꙭ', + 'Ꚁ' => 'ꚁ', + 'Ꚃ' => 'ꚃ', + 'Ꚅ' => 'ꚅ', + 'Ꚇ' => 'ꚇ', + 'Ꚉ' => 'ꚉ', + 'Ꚋ' => 'ꚋ', + 'Ꚍ' => 'ꚍ', + 'Ꚏ' => 'ꚏ', + 'Ꚑ' => 'ꚑ', + 'Ꚓ' => 'ꚓ', + 'Ꚕ' => 'ꚕ', + 'Ꚗ' => 'ꚗ', + 'Ꚙ' => 'ꚙ', + 'Ꚛ' => 'ꚛ', + 'Ꜣ' => 'ꜣ', + 'Ꜥ' => 'ꜥ', + 'Ꜧ' => 'ꜧ', + 'Ꜩ' => 'ꜩ', + 'Ꜫ' => 'ꜫ', + 'Ꜭ' => 'ꜭ', + 'Ꜯ' => 'ꜯ', + 'Ꜳ' => 'ꜳ', + 'Ꜵ' => 'ꜵ', + 'Ꜷ' => 'ꜷ', + 'Ꜹ' => 'ꜹ', + 'Ꜻ' => 'ꜻ', + 'Ꜽ' => 'ꜽ', + 'Ꜿ' => 'ꜿ', + 'Ꝁ' => 'ꝁ', + 'Ꝃ' => 'ꝃ', + 'Ꝅ' => 'ꝅ', + 'Ꝇ' => 'ꝇ', + 'Ꝉ' => 'ꝉ', + 'Ꝋ' => 'ꝋ', + 'Ꝍ' => 'ꝍ', + 'Ꝏ' => 'ꝏ', + 'Ꝑ' => 'ꝑ', + 'Ꝓ' => 'ꝓ', + 'Ꝕ' => 'ꝕ', + 'Ꝗ' => 'ꝗ', + 'Ꝙ' => 'ꝙ', + 'Ꝛ' => 'ꝛ', + 'Ꝝ' => 'ꝝ', + 'Ꝟ' => 'ꝟ', + 'Ꝡ' => 'ꝡ', + 'Ꝣ' => 'ꝣ', + 'Ꝥ' => 'ꝥ', + 'Ꝧ' => 'ꝧ', + 'Ꝩ' => 'ꝩ', + 'Ꝫ' => 'ꝫ', + 'Ꝭ' => 'ꝭ', + 'Ꝯ' => 'ꝯ', + 'Ꝺ' => 'ꝺ', + 'Ꝼ' => 'ꝼ', + 'Ᵹ' => 'ᵹ', + 'Ꝿ' => 'ꝿ', + 'Ꞁ' => 'ꞁ', + 'Ꞃ' => 'ꞃ', + 'Ꞅ' => 'ꞅ', + 'Ꞇ' => 'ꞇ', + 'Ꞌ' => 'ꞌ', + 'Ɥ' => 'ɥ', + 'Ꞑ' => 'ꞑ', + 'Ꞓ' => 'ꞓ', + 'Ꞗ' => 'ꞗ', + 'Ꞙ' => 'ꞙ', + 'Ꞛ' => 'ꞛ', + 'Ꞝ' => 'ꞝ', + 'Ꞟ' => 'ꞟ', + 'Ꞡ' => 'ꞡ', + 'Ꞣ' => 'ꞣ', + 'Ꞥ' => 'ꞥ', + 'Ꞧ' => 'ꞧ', + 'Ꞩ' => 'ꞩ', + 'Ɦ' => 'ɦ', + 'Ɜ' => 'ɜ', + 'Ɡ' => 'ɡ', + 'Ɬ' => 'ɬ', + 'Ʞ' => 'ʞ', + 'Ʇ' => 'ʇ', + 'A' => 'a', + 'B' => 'b', + 'C' => 'c', + 'D' => 'd', + 'E' => 'e', + 'F' => 'f', + 'G' => 'g', + 'H' => 'h', + 'I' => 'i', + 'J' => 'j', + 'K' => 'k', + 'L' => 'l', + 'M' => 'm', + 'N' => 'n', + 'O' => 'o', + 'P' => 'p', + 'Q' => 'q', + 'R' => 'r', + 'S' => 's', + 'T' => 't', + 'U' => 'u', + 'V' => 'v', + 'W' => 'w', + 'X' => 'x', + 'Y' => 'y', + 'Z' => 'z', + '𐐀' => '𐐨', + '𐐁' => '𐐩', + '𐐂' => '𐐪', + '𐐃' => '𐐫', + '𐐄' => '𐐬', + '𐐅' => '𐐭', + '𐐆' => '𐐮', + '𐐇' => '𐐯', + '𐐈' => '𐐰', + '𐐉' => '𐐱', + '𐐊' => '𐐲', + '𐐋' => '𐐳', + '𐐌' => '𐐴', + '𐐍' => '𐐵', + '𐐎' => '𐐶', + '𐐏' => '𐐷', + '𐐐' => '𐐸', + '𐐑' => '𐐹', + '𐐒' => '𐐺', + '𐐓' => '𐐻', + '𐐔' => '𐐼', + '𐐕' => '𐐽', + '𐐖' => '𐐾', + '𐐗' => '𐐿', + '𐐘' => '𐑀', + '𐐙' => '𐑁', + '𐐚' => '𐑂', + '𐐛' => '𐑃', + '𐐜' => '𐑄', + '𐐝' => '𐑅', + '𐐞' => '𐑆', + '𐐟' => '𐑇', + '𐐠' => '𐑈', + '𐐡' => '𐑉', + '𐐢' => '𐑊', + '𐐣' => '𐑋', + '𐐤' => '𐑌', + '𐐥' => '𐑍', + '𐐦' => '𐑎', + '𐐧' => '𐑏', + '𑢠' => '𑣀', + '𑢡' => '𑣁', + '𑢢' => '𑣂', + '𑢣' => '𑣃', + '𑢤' => '𑣄', + '𑢥' => '𑣅', + '𑢦' => '𑣆', + '𑢧' => '𑣇', + '𑢨' => '𑣈', + '𑢩' => '𑣉', + '𑢪' => '𑣊', + '𑢫' => '𑣋', + '𑢬' => '𑣌', + '𑢭' => '𑣍', + '𑢮' => '𑣎', + '𑢯' => '𑣏', + '𑢰' => '𑣐', + '𑢱' => '𑣑', + '𑢲' => '𑣒', + '𑢳' => '𑣓', + '𑢴' => '𑣔', + '𑢵' => '𑣕', + '𑢶' => '𑣖', + '𑢷' => '𑣗', + '𑢸' => '𑣘', + '𑢹' => '𑣙', + '𑢺' => '𑣚', + '𑢻' => '𑣛', + '𑢼' => '𑣜', + '𑢽' => '𑣝', + '𑢾' => '𑣞', + '𑢿' => '𑣟', +); diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php new file mode 100644 index 0000000..2a8f6e7 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php @@ -0,0 +1,5 @@ + 'A', + 'b' => 'B', + 'c' => 'C', + 'd' => 'D', + 'e' => 'E', + 'f' => 'F', + 'g' => 'G', + 'h' => 'H', + 'i' => 'I', + 'j' => 'J', + 'k' => 'K', + 'l' => 'L', + 'm' => 'M', + 'n' => 'N', + 'o' => 'O', + 'p' => 'P', + 'q' => 'Q', + 'r' => 'R', + 's' => 'S', + 't' => 'T', + 'u' => 'U', + 'v' => 'V', + 'w' => 'W', + 'x' => 'X', + 'y' => 'Y', + 'z' => 'Z', + 'µ' => 'Μ', + 'à' => 'À', + 'á' => 'Á', + 'â' => 'Â', + 'ã' => 'Ã', + 'ä' => 'Ä', + 'å' => 'Å', + 'æ' => 'Æ', + 'ç' => 'Ç', + 'è' => 'È', + 'é' => 'É', + 'ê' => 'Ê', + 'ë' => 'Ë', + 'ì' => 'Ì', + 'í' => 'Í', + 'î' => 'Î', + 'ï' => 'Ï', + 'ð' => 'Ð', + 'ñ' => 'Ñ', + 'ò' => 'Ò', + 'ó' => 'Ó', + 'ô' => 'Ô', + 'õ' => 'Õ', + 'ö' => 'Ö', + 'ø' => 'Ø', + 'ù' => 'Ù', + 'ú' => 'Ú', + 'û' => 'Û', + 'ü' => 'Ü', + 'ý' => 'Ý', + 'þ' => 'Þ', + 'ÿ' => 'Ÿ', + 'ā' => 'Ā', + 'ă' => 'Ă', + 'ą' => 'Ą', + 'ć' => 'Ć', + 'ĉ' => 'Ĉ', + 'ċ' => 'Ċ', + 'č' => 'Č', + 'ď' => 'Ď', + 'đ' => 'Đ', + 'ē' => 'Ē', + 'ĕ' => 'Ĕ', + 'ė' => 'Ė', + 'ę' => 'Ę', + 'ě' => 'Ě', + 'ĝ' => 'Ĝ', + 'ğ' => 'Ğ', + 'ġ' => 'Ġ', + 'ģ' => 'Ģ', + 'ĥ' => 'Ĥ', + 'ħ' => 'Ħ', + 'ĩ' => 'Ĩ', + 'ī' => 'Ī', + 'ĭ' => 'Ĭ', + 'į' => 'Į', + 'ı' => 'I', + 'ij' => 'IJ', + 'ĵ' => 'Ĵ', + 'ķ' => 'Ķ', + 'ĺ' => 'Ĺ', + 'ļ' => 'Ļ', + 'ľ' => 'Ľ', + 'ŀ' => 'Ŀ', + 'ł' => 'Ł', + 'ń' => 'Ń', + 'ņ' => 'Ņ', + 'ň' => 'Ň', + 'ŋ' => 'Ŋ', + 'ō' => 'Ō', + 'ŏ' => 'Ŏ', + 'ő' => 'Ő', + 'œ' => 'Œ', + 'ŕ' => 'Ŕ', + 'ŗ' => 'Ŗ', + 'ř' => 'Ř', + 'ś' => 'Ś', + 'ŝ' => 'Ŝ', + 'ş' => 'Ş', + 'š' => 'Š', + 'ţ' => 'Ţ', + 'ť' => 'Ť', + 'ŧ' => 'Ŧ', + 'ũ' => 'Ũ', + 'ū' => 'Ū', + 'ŭ' => 'Ŭ', + 'ů' => 'Ů', + 'ű' => 'Ű', + 'ų' => 'Ų', + 'ŵ' => 'Ŵ', + 'ŷ' => 'Ŷ', + 'ź' => 'Ź', + 'ż' => 'Ż', + 'ž' => 'Ž', + 'ſ' => 'S', + 'ƀ' => 'Ƀ', + 'ƃ' => 'Ƃ', + 'ƅ' => 'Ƅ', + 'ƈ' => 'Ƈ', + 'ƌ' => 'Ƌ', + 'ƒ' => 'Ƒ', + 'ƕ' => 'Ƕ', + 'ƙ' => 'Ƙ', + 'ƚ' => 'Ƚ', + 'ƞ' => 'Ƞ', + 'ơ' => 'Ơ', + 'ƣ' => 'Ƣ', + 'ƥ' => 'Ƥ', + 'ƨ' => 'Ƨ', + 'ƭ' => 'Ƭ', + 'ư' => 'Ư', + 'ƴ' => 'Ƴ', + 'ƶ' => 'Ƶ', + 'ƹ' => 'Ƹ', + 'ƽ' => 'Ƽ', + 'ƿ' => 'Ƿ', + 'Dž' => 'DŽ', + 'dž' => 'DŽ', + 'Lj' => 'LJ', + 'lj' => 'LJ', + 'Nj' => 'NJ', + 'nj' => 'NJ', + 'ǎ' => 'Ǎ', + 'ǐ' => 'Ǐ', + 'ǒ' => 'Ǒ', + 'ǔ' => 'Ǔ', + 'ǖ' => 'Ǖ', + 'ǘ' => 'Ǘ', + 'ǚ' => 'Ǚ', + 'ǜ' => 'Ǜ', + 'ǝ' => 'Ǝ', + 'ǟ' => 'Ǟ', + 'ǡ' => 'Ǡ', + 'ǣ' => 'Ǣ', + 'ǥ' => 'Ǥ', + 'ǧ' => 'Ǧ', + 'ǩ' => 'Ǩ', + 'ǫ' => 'Ǫ', + 'ǭ' => 'Ǭ', + 'ǯ' => 'Ǯ', + 'Dz' => 'DZ', + 'dz' => 'DZ', + 'ǵ' => 'Ǵ', + 'ǹ' => 'Ǹ', + 'ǻ' => 'Ǻ', + 'ǽ' => 'Ǽ', + 'ǿ' => 'Ǿ', + 'ȁ' => 'Ȁ', + 'ȃ' => 'Ȃ', + 'ȅ' => 'Ȅ', + 'ȇ' => 'Ȇ', + 'ȉ' => 'Ȉ', + 'ȋ' => 'Ȋ', + 'ȍ' => 'Ȍ', + 'ȏ' => 'Ȏ', + 'ȑ' => 'Ȑ', + 'ȓ' => 'Ȓ', + 'ȕ' => 'Ȕ', + 'ȗ' => 'Ȗ', + 'ș' => 'Ș', + 'ț' => 'Ț', + 'ȝ' => 'Ȝ', + 'ȟ' => 'Ȟ', + 'ȣ' => 'Ȣ', + 'ȥ' => 'Ȥ', + 'ȧ' => 'Ȧ', + 'ȩ' => 'Ȩ', + 'ȫ' => 'Ȫ', + 'ȭ' => 'Ȭ', + 'ȯ' => 'Ȯ', + 'ȱ' => 'Ȱ', + 'ȳ' => 'Ȳ', + 'ȼ' => 'Ȼ', + 'ȿ' => 'Ȿ', + 'ɀ' => 'Ɀ', + 'ɂ' => 'Ɂ', + 'ɇ' => 'Ɇ', + 'ɉ' => 'Ɉ', + 'ɋ' => 'Ɋ', + 'ɍ' => 'Ɍ', + 'ɏ' => 'Ɏ', + 'ɐ' => 'Ɐ', + 'ɑ' => 'Ɑ', + 'ɒ' => 'Ɒ', + 'ɓ' => 'Ɓ', + 'ɔ' => 'Ɔ', + 'ɖ' => 'Ɖ', + 'ɗ' => 'Ɗ', + 'ə' => 'Ə', + 'ɛ' => 'Ɛ', + 'ɜ' => 'Ɜ', + 'ɠ' => 'Ɠ', + 'ɡ' => 'Ɡ', + 'ɣ' => 'Ɣ', + 'ɥ' => 'Ɥ', + 'ɦ' => 'Ɦ', + 'ɨ' => 'Ɨ', + 'ɩ' => 'Ɩ', + 'ɫ' => 'Ɫ', + 'ɬ' => 'Ɬ', + 'ɯ' => 'Ɯ', + 'ɱ' => 'Ɱ', + 'ɲ' => 'Ɲ', + 'ɵ' => 'Ɵ', + 'ɽ' => 'Ɽ', + 'ʀ' => 'Ʀ', + 'ʃ' => 'Ʃ', + 'ʇ' => 'Ʇ', + 'ʈ' => 'Ʈ', + 'ʉ' => 'Ʉ', + 'ʊ' => 'Ʊ', + 'ʋ' => 'Ʋ', + 'ʌ' => 'Ʌ', + 'ʒ' => 'Ʒ', + 'ʞ' => 'Ʞ', + 'ͅ' => 'Ι', + 'ͱ' => 'Ͱ', + 'ͳ' => 'Ͳ', + 'ͷ' => 'Ͷ', + 'ͻ' => 'Ͻ', + 'ͼ' => 'Ͼ', + 'ͽ' => 'Ͽ', + 'ά' => 'Ά', + 'έ' => 'Έ', + 'ή' => 'Ή', + 'ί' => 'Ί', + 'α' => 'Α', + 'β' => 'Β', + 'γ' => 'Γ', + 'δ' => 'Δ', + 'ε' => 'Ε', + 'ζ' => 'Ζ', + 'η' => 'Η', + 'θ' => 'Θ', + 'ι' => 'Ι', + 'κ' => 'Κ', + 'λ' => 'Λ', + 'μ' => 'Μ', + 'ν' => 'Ν', + 'ξ' => 'Ξ', + 'ο' => 'Ο', + 'π' => 'Π', + 'ρ' => 'Ρ', + 'ς' => 'Σ', + 'σ' => 'Σ', + 'τ' => 'Τ', + 'υ' => 'Υ', + 'φ' => 'Φ', + 'χ' => 'Χ', + 'ψ' => 'Ψ', + 'ω' => 'Ω', + 'ϊ' => 'Ϊ', + 'ϋ' => 'Ϋ', + 'ό' => 'Ό', + 'ύ' => 'Ύ', + 'ώ' => 'Ώ', + 'ϐ' => 'Β', + 'ϑ' => 'Θ', + 'ϕ' => 'Φ', + 'ϖ' => 'Π', + 'ϗ' => 'Ϗ', + 'ϙ' => 'Ϙ', + 'ϛ' => 'Ϛ', + 'ϝ' => 'Ϝ', + 'ϟ' => 'Ϟ', + 'ϡ' => 'Ϡ', + 'ϣ' => 'Ϣ', + 'ϥ' => 'Ϥ', + 'ϧ' => 'Ϧ', + 'ϩ' => 'Ϩ', + 'ϫ' => 'Ϫ', + 'ϭ' => 'Ϭ', + 'ϯ' => 'Ϯ', + 'ϰ' => 'Κ', + 'ϱ' => 'Ρ', + 'ϲ' => 'Ϲ', + 'ϳ' => 'Ϳ', + 'ϵ' => 'Ε', + 'ϸ' => 'Ϸ', + 'ϻ' => 'Ϻ', + 'а' => 'А', + 'б' => 'Б', + 'в' => 'В', + 'г' => 'Г', + 'д' => 'Д', + 'е' => 'Е', + 'ж' => 'Ж', + 'з' => 'З', + 'и' => 'И', + 'й' => 'Й', + 'к' => 'К', + 'л' => 'Л', + 'м' => 'М', + 'н' => 'Н', + 'о' => 'О', + 'п' => 'П', + 'р' => 'Р', + 'с' => 'С', + 'т' => 'Т', + 'у' => 'У', + 'ф' => 'Ф', + 'х' => 'Х', + 'ц' => 'Ц', + 'ч' => 'Ч', + 'ш' => 'Ш', + 'щ' => 'Щ', + 'ъ' => 'Ъ', + 'ы' => 'Ы', + 'ь' => 'Ь', + 'э' => 'Э', + 'ю' => 'Ю', + 'я' => 'Я', + 'ѐ' => 'Ѐ', + 'ё' => 'Ё', + 'ђ' => 'Ђ', + 'ѓ' => 'Ѓ', + 'є' => 'Є', + 'ѕ' => 'Ѕ', + 'і' => 'І', + 'ї' => 'Ї', + 'ј' => 'Ј', + 'љ' => 'Љ', + 'њ' => 'Њ', + 'ћ' => 'Ћ', + 'ќ' => 'Ќ', + 'ѝ' => 'Ѝ', + 'ў' => 'Ў', + 'џ' => 'Џ', + 'ѡ' => 'Ѡ', + 'ѣ' => 'Ѣ', + 'ѥ' => 'Ѥ', + 'ѧ' => 'Ѧ', + 'ѩ' => 'Ѩ', + 'ѫ' => 'Ѫ', + 'ѭ' => 'Ѭ', + 'ѯ' => 'Ѯ', + 'ѱ' => 'Ѱ', + 'ѳ' => 'Ѳ', + 'ѵ' => 'Ѵ', + 'ѷ' => 'Ѷ', + 'ѹ' => 'Ѹ', + 'ѻ' => 'Ѻ', + 'ѽ' => 'Ѽ', + 'ѿ' => 'Ѿ', + 'ҁ' => 'Ҁ', + 'ҋ' => 'Ҋ', + 'ҍ' => 'Ҍ', + 'ҏ' => 'Ҏ', + 'ґ' => 'Ґ', + 'ғ' => 'Ғ', + 'ҕ' => 'Ҕ', + 'җ' => 'Җ', + 'ҙ' => 'Ҙ', + 'қ' => 'Қ', + 'ҝ' => 'Ҝ', + 'ҟ' => 'Ҟ', + 'ҡ' => 'Ҡ', + 'ң' => 'Ң', + 'ҥ' => 'Ҥ', + 'ҧ' => 'Ҧ', + 'ҩ' => 'Ҩ', + 'ҫ' => 'Ҫ', + 'ҭ' => 'Ҭ', + 'ү' => 'Ү', + 'ұ' => 'Ұ', + 'ҳ' => 'Ҳ', + 'ҵ' => 'Ҵ', + 'ҷ' => 'Ҷ', + 'ҹ' => 'Ҹ', + 'һ' => 'Һ', + 'ҽ' => 'Ҽ', + 'ҿ' => 'Ҿ', + 'ӂ' => 'Ӂ', + 'ӄ' => 'Ӄ', + 'ӆ' => 'Ӆ', + 'ӈ' => 'Ӈ', + 'ӊ' => 'Ӊ', + 'ӌ' => 'Ӌ', + 'ӎ' => 'Ӎ', + 'ӏ' => 'Ӏ', + 'ӑ' => 'Ӑ', + 'ӓ' => 'Ӓ', + 'ӕ' => 'Ӕ', + 'ӗ' => 'Ӗ', + 'ә' => 'Ә', + 'ӛ' => 'Ӛ', + 'ӝ' => 'Ӝ', + 'ӟ' => 'Ӟ', + 'ӡ' => 'Ӡ', + 'ӣ' => 'Ӣ', + 'ӥ' => 'Ӥ', + 'ӧ' => 'Ӧ', + 'ө' => 'Ө', + 'ӫ' => 'Ӫ', + 'ӭ' => 'Ӭ', + 'ӯ' => 'Ӯ', + 'ӱ' => 'Ӱ', + 'ӳ' => 'Ӳ', + 'ӵ' => 'Ӵ', + 'ӷ' => 'Ӷ', + 'ӹ' => 'Ӹ', + 'ӻ' => 'Ӻ', + 'ӽ' => 'Ӽ', + 'ӿ' => 'Ӿ', + 'ԁ' => 'Ԁ', + 'ԃ' => 'Ԃ', + 'ԅ' => 'Ԅ', + 'ԇ' => 'Ԇ', + 'ԉ' => 'Ԉ', + 'ԋ' => 'Ԋ', + 'ԍ' => 'Ԍ', + 'ԏ' => 'Ԏ', + 'ԑ' => 'Ԑ', + 'ԓ' => 'Ԓ', + 'ԕ' => 'Ԕ', + 'ԗ' => 'Ԗ', + 'ԙ' => 'Ԙ', + 'ԛ' => 'Ԛ', + 'ԝ' => 'Ԝ', + 'ԟ' => 'Ԟ', + 'ԡ' => 'Ԡ', + 'ԣ' => 'Ԣ', + 'ԥ' => 'Ԥ', + 'ԧ' => 'Ԧ', + 'ԩ' => 'Ԩ', + 'ԫ' => 'Ԫ', + 'ԭ' => 'Ԭ', + 'ԯ' => 'Ԯ', + 'ա' => 'Ա', + 'բ' => 'Բ', + 'գ' => 'Գ', + 'դ' => 'Դ', + 'ե' => 'Ե', + 'զ' => 'Զ', + 'է' => 'Է', + 'ը' => 'Ը', + 'թ' => 'Թ', + 'ժ' => 'Ժ', + 'ի' => 'Ի', + 'լ' => 'Լ', + 'խ' => 'Խ', + 'ծ' => 'Ծ', + 'կ' => 'Կ', + 'հ' => 'Հ', + 'ձ' => 'Ձ', + 'ղ' => 'Ղ', + 'ճ' => 'Ճ', + 'մ' => 'Մ', + 'յ' => 'Յ', + 'ն' => 'Ն', + 'շ' => 'Շ', + 'ո' => 'Ո', + 'չ' => 'Չ', + 'պ' => 'Պ', + 'ջ' => 'Ջ', + 'ռ' => 'Ռ', + 'ս' => 'Ս', + 'վ' => 'Վ', + 'տ' => 'Տ', + 'ր' => 'Ր', + 'ց' => 'Ց', + 'ւ' => 'Ւ', + 'փ' => 'Փ', + 'ք' => 'Ք', + 'օ' => 'Օ', + 'ֆ' => 'Ֆ', + 'ᵹ' => 'Ᵹ', + 'ᵽ' => 'Ᵽ', + 'ḁ' => 'Ḁ', + 'ḃ' => 'Ḃ', + 'ḅ' => 'Ḅ', + 'ḇ' => 'Ḇ', + 'ḉ' => 'Ḉ', + 'ḋ' => 'Ḋ', + 'ḍ' => 'Ḍ', + 'ḏ' => 'Ḏ', + 'ḑ' => 'Ḑ', + 'ḓ' => 'Ḓ', + 'ḕ' => 'Ḕ', + 'ḗ' => 'Ḗ', + 'ḙ' => 'Ḙ', + 'ḛ' => 'Ḛ', + 'ḝ' => 'Ḝ', + 'ḟ' => 'Ḟ', + 'ḡ' => 'Ḡ', + 'ḣ' => 'Ḣ', + 'ḥ' => 'Ḥ', + 'ḧ' => 'Ḧ', + 'ḩ' => 'Ḩ', + 'ḫ' => 'Ḫ', + 'ḭ' => 'Ḭ', + 'ḯ' => 'Ḯ', + 'ḱ' => 'Ḱ', + 'ḳ' => 'Ḳ', + 'ḵ' => 'Ḵ', + 'ḷ' => 'Ḷ', + 'ḹ' => 'Ḹ', + 'ḻ' => 'Ḻ', + 'ḽ' => 'Ḽ', + 'ḿ' => 'Ḿ', + 'ṁ' => 'Ṁ', + 'ṃ' => 'Ṃ', + 'ṅ' => 'Ṅ', + 'ṇ' => 'Ṇ', + 'ṉ' => 'Ṉ', + 'ṋ' => 'Ṋ', + 'ṍ' => 'Ṍ', + 'ṏ' => 'Ṏ', + 'ṑ' => 'Ṑ', + 'ṓ' => 'Ṓ', + 'ṕ' => 'Ṕ', + 'ṗ' => 'Ṗ', + 'ṙ' => 'Ṙ', + 'ṛ' => 'Ṛ', + 'ṝ' => 'Ṝ', + 'ṟ' => 'Ṟ', + 'ṡ' => 'Ṡ', + 'ṣ' => 'Ṣ', + 'ṥ' => 'Ṥ', + 'ṧ' => 'Ṧ', + 'ṩ' => 'Ṩ', + 'ṫ' => 'Ṫ', + 'ṭ' => 'Ṭ', + 'ṯ' => 'Ṯ', + 'ṱ' => 'Ṱ', + 'ṳ' => 'Ṳ', + 'ṵ' => 'Ṵ', + 'ṷ' => 'Ṷ', + 'ṹ' => 'Ṹ', + 'ṻ' => 'Ṻ', + 'ṽ' => 'Ṽ', + 'ṿ' => 'Ṿ', + 'ẁ' => 'Ẁ', + 'ẃ' => 'Ẃ', + 'ẅ' => 'Ẅ', + 'ẇ' => 'Ẇ', + 'ẉ' => 'Ẉ', + 'ẋ' => 'Ẋ', + 'ẍ' => 'Ẍ', + 'ẏ' => 'Ẏ', + 'ẑ' => 'Ẑ', + 'ẓ' => 'Ẓ', + 'ẕ' => 'Ẕ', + 'ẛ' => 'Ṡ', + 'ạ' => 'Ạ', + 'ả' => 'Ả', + 'ấ' => 'Ấ', + 'ầ' => 'Ầ', + 'ẩ' => 'Ẩ', + 'ẫ' => 'Ẫ', + 'ậ' => 'Ậ', + 'ắ' => 'Ắ', + 'ằ' => 'Ằ', + 'ẳ' => 'Ẳ', + 'ẵ' => 'Ẵ', + 'ặ' => 'Ặ', + 'ẹ' => 'Ẹ', + 'ẻ' => 'Ẻ', + 'ẽ' => 'Ẽ', + 'ế' => 'Ế', + 'ề' => 'Ề', + 'ể' => 'Ể', + 'ễ' => 'Ễ', + 'ệ' => 'Ệ', + 'ỉ' => 'Ỉ', + 'ị' => 'Ị', + 'ọ' => 'Ọ', + 'ỏ' => 'Ỏ', + 'ố' => 'Ố', + 'ồ' => 'Ồ', + 'ổ' => 'Ổ', + 'ỗ' => 'Ỗ', + 'ộ' => 'Ộ', + 'ớ' => 'Ớ', + 'ờ' => 'Ờ', + 'ở' => 'Ở', + 'ỡ' => 'Ỡ', + 'ợ' => 'Ợ', + 'ụ' => 'Ụ', + 'ủ' => 'Ủ', + 'ứ' => 'Ứ', + 'ừ' => 'Ừ', + 'ử' => 'Ử', + 'ữ' => 'Ữ', + 'ự' => 'Ự', + 'ỳ' => 'Ỳ', + 'ỵ' => 'Ỵ', + 'ỷ' => 'Ỷ', + 'ỹ' => 'Ỹ', + 'ỻ' => 'Ỻ', + 'ỽ' => 'Ỽ', + 'ỿ' => 'Ỿ', + 'ἀ' => 'Ἀ', + 'ἁ' => 'Ἁ', + 'ἂ' => 'Ἂ', + 'ἃ' => 'Ἃ', + 'ἄ' => 'Ἄ', + 'ἅ' => 'Ἅ', + 'ἆ' => 'Ἆ', + 'ἇ' => 'Ἇ', + 'ἐ' => 'Ἐ', + 'ἑ' => 'Ἑ', + 'ἒ' => 'Ἒ', + 'ἓ' => 'Ἓ', + 'ἔ' => 'Ἔ', + 'ἕ' => 'Ἕ', + 'ἠ' => 'Ἠ', + 'ἡ' => 'Ἡ', + 'ἢ' => 'Ἢ', + 'ἣ' => 'Ἣ', + 'ἤ' => 'Ἤ', + 'ἥ' => 'Ἥ', + 'ἦ' => 'Ἦ', + 'ἧ' => 'Ἧ', + 'ἰ' => 'Ἰ', + 'ἱ' => 'Ἱ', + 'ἲ' => 'Ἲ', + 'ἳ' => 'Ἳ', + 'ἴ' => 'Ἴ', + 'ἵ' => 'Ἵ', + 'ἶ' => 'Ἶ', + 'ἷ' => 'Ἷ', + 'ὀ' => 'Ὀ', + 'ὁ' => 'Ὁ', + 'ὂ' => 'Ὂ', + 'ὃ' => 'Ὃ', + 'ὄ' => 'Ὄ', + 'ὅ' => 'Ὅ', + 'ὑ' => 'Ὑ', + 'ὓ' => 'Ὓ', + 'ὕ' => 'Ὕ', + 'ὗ' => 'Ὗ', + 'ὠ' => 'Ὠ', + 'ὡ' => 'Ὡ', + 'ὢ' => 'Ὢ', + 'ὣ' => 'Ὣ', + 'ὤ' => 'Ὤ', + 'ὥ' => 'Ὥ', + 'ὦ' => 'Ὦ', + 'ὧ' => 'Ὧ', + 'ὰ' => 'Ὰ', + 'ά' => 'Ά', + 'ὲ' => 'Ὲ', + 'έ' => 'Έ', + 'ὴ' => 'Ὴ', + 'ή' => 'Ή', + 'ὶ' => 'Ὶ', + 'ί' => 'Ί', + 'ὸ' => 'Ὸ', + 'ό' => 'Ό', + 'ὺ' => 'Ὺ', + 'ύ' => 'Ύ', + 'ὼ' => 'Ὼ', + 'ώ' => 'Ώ', + 'ᾀ' => 'ᾈ', + 'ᾁ' => 'ᾉ', + 'ᾂ' => 'ᾊ', + 'ᾃ' => 'ᾋ', + 'ᾄ' => 'ᾌ', + 'ᾅ' => 'ᾍ', + 'ᾆ' => 'ᾎ', + 'ᾇ' => 'ᾏ', + 'ᾐ' => 'ᾘ', + 'ᾑ' => 'ᾙ', + 'ᾒ' => 'ᾚ', + 'ᾓ' => 'ᾛ', + 'ᾔ' => 'ᾜ', + 'ᾕ' => 'ᾝ', + 'ᾖ' => 'ᾞ', + 'ᾗ' => 'ᾟ', + 'ᾠ' => 'ᾨ', + 'ᾡ' => 'ᾩ', + 'ᾢ' => 'ᾪ', + 'ᾣ' => 'ᾫ', + 'ᾤ' => 'ᾬ', + 'ᾥ' => 'ᾭ', + 'ᾦ' => 'ᾮ', + 'ᾧ' => 'ᾯ', + 'ᾰ' => 'Ᾰ', + 'ᾱ' => 'Ᾱ', + 'ᾳ' => 'ᾼ', + 'ι' => 'Ι', + 'ῃ' => 'ῌ', + 'ῐ' => 'Ῐ', + 'ῑ' => 'Ῑ', + 'ῠ' => 'Ῠ', + 'ῡ' => 'Ῡ', + 'ῥ' => 'Ῥ', + 'ῳ' => 'ῼ', + 'ⅎ' => 'Ⅎ', + 'ⅰ' => 'Ⅰ', + 'ⅱ' => 'Ⅱ', + 'ⅲ' => 'Ⅲ', + 'ⅳ' => 'Ⅳ', + 'ⅴ' => 'Ⅴ', + 'ⅵ' => 'Ⅵ', + 'ⅶ' => 'Ⅶ', + 'ⅷ' => 'Ⅷ', + 'ⅸ' => 'Ⅸ', + 'ⅹ' => 'Ⅹ', + 'ⅺ' => 'Ⅺ', + 'ⅻ' => 'Ⅻ', + 'ⅼ' => 'Ⅼ', + 'ⅽ' => 'Ⅽ', + 'ⅾ' => 'Ⅾ', + 'ⅿ' => 'Ⅿ', + 'ↄ' => 'Ↄ', + 'ⓐ' => 'Ⓐ', + 'ⓑ' => 'Ⓑ', + 'ⓒ' => 'Ⓒ', + 'ⓓ' => 'Ⓓ', + 'ⓔ' => 'Ⓔ', + 'ⓕ' => 'Ⓕ', + 'ⓖ' => 'Ⓖ', + 'ⓗ' => 'Ⓗ', + 'ⓘ' => 'Ⓘ', + 'ⓙ' => 'Ⓙ', + 'ⓚ' => 'Ⓚ', + 'ⓛ' => 'Ⓛ', + 'ⓜ' => 'Ⓜ', + 'ⓝ' => 'Ⓝ', + 'ⓞ' => 'Ⓞ', + 'ⓟ' => 'Ⓟ', + 'ⓠ' => 'Ⓠ', + 'ⓡ' => 'Ⓡ', + 'ⓢ' => 'Ⓢ', + 'ⓣ' => 'Ⓣ', + 'ⓤ' => 'Ⓤ', + 'ⓥ' => 'Ⓥ', + 'ⓦ' => 'Ⓦ', + 'ⓧ' => 'Ⓧ', + 'ⓨ' => 'Ⓨ', + 'ⓩ' => 'Ⓩ', + 'ⰰ' => 'Ⰰ', + 'ⰱ' => 'Ⰱ', + 'ⰲ' => 'Ⰲ', + 'ⰳ' => 'Ⰳ', + 'ⰴ' => 'Ⰴ', + 'ⰵ' => 'Ⰵ', + 'ⰶ' => 'Ⰶ', + 'ⰷ' => 'Ⰷ', + 'ⰸ' => 'Ⰸ', + 'ⰹ' => 'Ⰹ', + 'ⰺ' => 'Ⰺ', + 'ⰻ' => 'Ⰻ', + 'ⰼ' => 'Ⰼ', + 'ⰽ' => 'Ⰽ', + 'ⰾ' => 'Ⰾ', + 'ⰿ' => 'Ⰿ', + 'ⱀ' => 'Ⱀ', + 'ⱁ' => 'Ⱁ', + 'ⱂ' => 'Ⱂ', + 'ⱃ' => 'Ⱃ', + 'ⱄ' => 'Ⱄ', + 'ⱅ' => 'Ⱅ', + 'ⱆ' => 'Ⱆ', + 'ⱇ' => 'Ⱇ', + 'ⱈ' => 'Ⱈ', + 'ⱉ' => 'Ⱉ', + 'ⱊ' => 'Ⱊ', + 'ⱋ' => 'Ⱋ', + 'ⱌ' => 'Ⱌ', + 'ⱍ' => 'Ⱍ', + 'ⱎ' => 'Ⱎ', + 'ⱏ' => 'Ⱏ', + 'ⱐ' => 'Ⱐ', + 'ⱑ' => 'Ⱑ', + 'ⱒ' => 'Ⱒ', + 'ⱓ' => 'Ⱓ', + 'ⱔ' => 'Ⱔ', + 'ⱕ' => 'Ⱕ', + 'ⱖ' => 'Ⱖ', + 'ⱗ' => 'Ⱗ', + 'ⱘ' => 'Ⱘ', + 'ⱙ' => 'Ⱙ', + 'ⱚ' => 'Ⱚ', + 'ⱛ' => 'Ⱛ', + 'ⱜ' => 'Ⱜ', + 'ⱝ' => 'Ⱝ', + 'ⱞ' => 'Ⱞ', + 'ⱡ' => 'Ⱡ', + 'ⱥ' => 'Ⱥ', + 'ⱦ' => 'Ⱦ', + 'ⱨ' => 'Ⱨ', + 'ⱪ' => 'Ⱪ', + 'ⱬ' => 'Ⱬ', + 'ⱳ' => 'Ⱳ', + 'ⱶ' => 'Ⱶ', + 'ⲁ' => 'Ⲁ', + 'ⲃ' => 'Ⲃ', + 'ⲅ' => 'Ⲅ', + 'ⲇ' => 'Ⲇ', + 'ⲉ' => 'Ⲉ', + 'ⲋ' => 'Ⲋ', + 'ⲍ' => 'Ⲍ', + 'ⲏ' => 'Ⲏ', + 'ⲑ' => 'Ⲑ', + 'ⲓ' => 'Ⲓ', + 'ⲕ' => 'Ⲕ', + 'ⲗ' => 'Ⲗ', + 'ⲙ' => 'Ⲙ', + 'ⲛ' => 'Ⲛ', + 'ⲝ' => 'Ⲝ', + 'ⲟ' => 'Ⲟ', + 'ⲡ' => 'Ⲡ', + 'ⲣ' => 'Ⲣ', + 'ⲥ' => 'Ⲥ', + 'ⲧ' => 'Ⲧ', + 'ⲩ' => 'Ⲩ', + 'ⲫ' => 'Ⲫ', + 'ⲭ' => 'Ⲭ', + 'ⲯ' => 'Ⲯ', + 'ⲱ' => 'Ⲱ', + 'ⲳ' => 'Ⲳ', + 'ⲵ' => 'Ⲵ', + 'ⲷ' => 'Ⲷ', + 'ⲹ' => 'Ⲹ', + 'ⲻ' => 'Ⲻ', + 'ⲽ' => 'Ⲽ', + 'ⲿ' => 'Ⲿ', + 'ⳁ' => 'Ⳁ', + 'ⳃ' => 'Ⳃ', + 'ⳅ' => 'Ⳅ', + 'ⳇ' => 'Ⳇ', + 'ⳉ' => 'Ⳉ', + 'ⳋ' => 'Ⳋ', + 'ⳍ' => 'Ⳍ', + 'ⳏ' => 'Ⳏ', + 'ⳑ' => 'Ⳑ', + 'ⳓ' => 'Ⳓ', + 'ⳕ' => 'Ⳕ', + 'ⳗ' => 'Ⳗ', + 'ⳙ' => 'Ⳙ', + 'ⳛ' => 'Ⳛ', + 'ⳝ' => 'Ⳝ', + 'ⳟ' => 'Ⳟ', + 'ⳡ' => 'Ⳡ', + 'ⳣ' => 'Ⳣ', + 'ⳬ' => 'Ⳬ', + 'ⳮ' => 'Ⳮ', + 'ⳳ' => 'Ⳳ', + 'ⴀ' => 'Ⴀ', + 'ⴁ' => 'Ⴁ', + 'ⴂ' => 'Ⴂ', + 'ⴃ' => 'Ⴃ', + 'ⴄ' => 'Ⴄ', + 'ⴅ' => 'Ⴅ', + 'ⴆ' => 'Ⴆ', + 'ⴇ' => 'Ⴇ', + 'ⴈ' => 'Ⴈ', + 'ⴉ' => 'Ⴉ', + 'ⴊ' => 'Ⴊ', + 'ⴋ' => 'Ⴋ', + 'ⴌ' => 'Ⴌ', + 'ⴍ' => 'Ⴍ', + 'ⴎ' => 'Ⴎ', + 'ⴏ' => 'Ⴏ', + 'ⴐ' => 'Ⴐ', + 'ⴑ' => 'Ⴑ', + 'ⴒ' => 'Ⴒ', + 'ⴓ' => 'Ⴓ', + 'ⴔ' => 'Ⴔ', + 'ⴕ' => 'Ⴕ', + 'ⴖ' => 'Ⴖ', + 'ⴗ' => 'Ⴗ', + 'ⴘ' => 'Ⴘ', + 'ⴙ' => 'Ⴙ', + 'ⴚ' => 'Ⴚ', + 'ⴛ' => 'Ⴛ', + 'ⴜ' => 'Ⴜ', + 'ⴝ' => 'Ⴝ', + 'ⴞ' => 'Ⴞ', + 'ⴟ' => 'Ⴟ', + 'ⴠ' => 'Ⴠ', + 'ⴡ' => 'Ⴡ', + 'ⴢ' => 'Ⴢ', + 'ⴣ' => 'Ⴣ', + 'ⴤ' => 'Ⴤ', + 'ⴥ' => 'Ⴥ', + 'ⴧ' => 'Ⴧ', + 'ⴭ' => 'Ⴭ', + 'ꙁ' => 'Ꙁ', + 'ꙃ' => 'Ꙃ', + 'ꙅ' => 'Ꙅ', + 'ꙇ' => 'Ꙇ', + 'ꙉ' => 'Ꙉ', + 'ꙋ' => 'Ꙋ', + 'ꙍ' => 'Ꙍ', + 'ꙏ' => 'Ꙏ', + 'ꙑ' => 'Ꙑ', + 'ꙓ' => 'Ꙓ', + 'ꙕ' => 'Ꙕ', + 'ꙗ' => 'Ꙗ', + 'ꙙ' => 'Ꙙ', + 'ꙛ' => 'Ꙛ', + 'ꙝ' => 'Ꙝ', + 'ꙟ' => 'Ꙟ', + 'ꙡ' => 'Ꙡ', + 'ꙣ' => 'Ꙣ', + 'ꙥ' => 'Ꙥ', + 'ꙧ' => 'Ꙧ', + 'ꙩ' => 'Ꙩ', + 'ꙫ' => 'Ꙫ', + 'ꙭ' => 'Ꙭ', + 'ꚁ' => 'Ꚁ', + 'ꚃ' => 'Ꚃ', + 'ꚅ' => 'Ꚅ', + 'ꚇ' => 'Ꚇ', + 'ꚉ' => 'Ꚉ', + 'ꚋ' => 'Ꚋ', + 'ꚍ' => 'Ꚍ', + 'ꚏ' => 'Ꚏ', + 'ꚑ' => 'Ꚑ', + 'ꚓ' => 'Ꚓ', + 'ꚕ' => 'Ꚕ', + 'ꚗ' => 'Ꚗ', + 'ꚙ' => 'Ꚙ', + 'ꚛ' => 'Ꚛ', + 'ꜣ' => 'Ꜣ', + 'ꜥ' => 'Ꜥ', + 'ꜧ' => 'Ꜧ', + 'ꜩ' => 'Ꜩ', + 'ꜫ' => 'Ꜫ', + 'ꜭ' => 'Ꜭ', + 'ꜯ' => 'Ꜯ', + 'ꜳ' => 'Ꜳ', + 'ꜵ' => 'Ꜵ', + 'ꜷ' => 'Ꜷ', + 'ꜹ' => 'Ꜹ', + 'ꜻ' => 'Ꜻ', + 'ꜽ' => 'Ꜽ', + 'ꜿ' => 'Ꜿ', + 'ꝁ' => 'Ꝁ', + 'ꝃ' => 'Ꝃ', + 'ꝅ' => 'Ꝅ', + 'ꝇ' => 'Ꝇ', + 'ꝉ' => 'Ꝉ', + 'ꝋ' => 'Ꝋ', + 'ꝍ' => 'Ꝍ', + 'ꝏ' => 'Ꝏ', + 'ꝑ' => 'Ꝑ', + 'ꝓ' => 'Ꝓ', + 'ꝕ' => 'Ꝕ', + 'ꝗ' => 'Ꝗ', + 'ꝙ' => 'Ꝙ', + 'ꝛ' => 'Ꝛ', + 'ꝝ' => 'Ꝝ', + 'ꝟ' => 'Ꝟ', + 'ꝡ' => 'Ꝡ', + 'ꝣ' => 'Ꝣ', + 'ꝥ' => 'Ꝥ', + 'ꝧ' => 'Ꝧ', + 'ꝩ' => 'Ꝩ', + 'ꝫ' => 'Ꝫ', + 'ꝭ' => 'Ꝭ', + 'ꝯ' => 'Ꝯ', + 'ꝺ' => 'Ꝺ', + 'ꝼ' => 'Ꝼ', + 'ꝿ' => 'Ꝿ', + 'ꞁ' => 'Ꞁ', + 'ꞃ' => 'Ꞃ', + 'ꞅ' => 'Ꞅ', + 'ꞇ' => 'Ꞇ', + 'ꞌ' => 'Ꞌ', + 'ꞑ' => 'Ꞑ', + 'ꞓ' => 'Ꞓ', + 'ꞗ' => 'Ꞗ', + 'ꞙ' => 'Ꞙ', + 'ꞛ' => 'Ꞛ', + 'ꞝ' => 'Ꞝ', + 'ꞟ' => 'Ꞟ', + 'ꞡ' => 'Ꞡ', + 'ꞣ' => 'Ꞣ', + 'ꞥ' => 'Ꞥ', + 'ꞧ' => 'Ꞧ', + 'ꞩ' => 'Ꞩ', + 'a' => 'A', + 'b' => 'B', + 'c' => 'C', + 'd' => 'D', + 'e' => 'E', + 'f' => 'F', + 'g' => 'G', + 'h' => 'H', + 'i' => 'I', + 'j' => 'J', + 'k' => 'K', + 'l' => 'L', + 'm' => 'M', + 'n' => 'N', + 'o' => 'O', + 'p' => 'P', + 'q' => 'Q', + 'r' => 'R', + 's' => 'S', + 't' => 'T', + 'u' => 'U', + 'v' => 'V', + 'w' => 'W', + 'x' => 'X', + 'y' => 'Y', + 'z' => 'Z', + '𐐨' => '𐐀', + '𐐩' => '𐐁', + '𐐪' => '𐐂', + '𐐫' => '𐐃', + '𐐬' => '𐐄', + '𐐭' => '𐐅', + '𐐮' => '𐐆', + '𐐯' => '𐐇', + '𐐰' => '𐐈', + '𐐱' => '𐐉', + '𐐲' => '𐐊', + '𐐳' => '𐐋', + '𐐴' => '𐐌', + '𐐵' => '𐐍', + '𐐶' => '𐐎', + '𐐷' => '𐐏', + '𐐸' => '𐐐', + '𐐹' => '𐐑', + '𐐺' => '𐐒', + '𐐻' => '𐐓', + '𐐼' => '𐐔', + '𐐽' => '𐐕', + '𐐾' => '𐐖', + '𐐿' => '𐐗', + '𐑀' => '𐐘', + '𐑁' => '𐐙', + '𐑂' => '𐐚', + '𐑃' => '𐐛', + '𐑄' => '𐐜', + '𐑅' => '𐐝', + '𐑆' => '𐐞', + '𐑇' => '𐐟', + '𐑈' => '𐐠', + '𐑉' => '𐐡', + '𐑊' => '𐐢', + '𐑋' => '𐐣', + '𐑌' => '𐐤', + '𐑍' => '𐐥', + '𐑎' => '𐐦', + '𐑏' => '𐐧', + '𑣀' => '𑢠', + '𑣁' => '𑢡', + '𑣂' => '𑢢', + '𑣃' => '𑢣', + '𑣄' => '𑢤', + '𑣅' => '𑢥', + '𑣆' => '𑢦', + '𑣇' => '𑢧', + '𑣈' => '𑢨', + '𑣉' => '𑢩', + '𑣊' => '𑢪', + '𑣋' => '𑢫', + '𑣌' => '𑢬', + '𑣍' => '𑢭', + '𑣎' => '𑢮', + '𑣏' => '𑢯', + '𑣐' => '𑢰', + '𑣑' => '𑢱', + '𑣒' => '𑢲', + '𑣓' => '𑢳', + '𑣔' => '𑢴', + '𑣕' => '𑢵', + '𑣖' => '𑢶', + '𑣗' => '𑢷', + '𑣘' => '𑢸', + '𑣙' => '𑢹', + '𑣚' => '𑢺', + '𑣛' => '𑢻', + '𑣜' => '𑢼', + '𑣝' => '𑢽', + '𑣞' => '𑢾', + '𑣟' => '𑢿', +); diff --git a/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php new file mode 100644 index 0000000..204a41b --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Mbstring as p; + +if (!function_exists('mb_strlen')) { + define('MB_CASE_UPPER', 0); + define('MB_CASE_LOWER', 1); + define('MB_CASE_TITLE', 2); + + function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); } + function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); } + function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); } + function mb_decode_numericentity($s, $convmap, $enc = null) { return p\Mbstring::mb_decode_numericentity($s, $convmap, $enc); } + function mb_encode_numericentity($s, $convmap, $enc = null, $is_hex = false) { return p\Mbstring::mb_encode_numericentity($s, $convmap, $enc, $is_hex); } + function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); } + function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); } + function mb_language($lang = null) { return p\Mbstring::mb_language($lang); } + function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } + function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } + function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); } + function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); } + function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); } + function mb_parse_str($s, &$result = array()) { parse_str($s, $result); } + function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); } + function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); } + function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); } + function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); } + function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); } + function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); } + function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); } + function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); } + function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); } + function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); } + function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); } + function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); } + function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); } + function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } + function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); } + function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); } + function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); } + function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); } + function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); } + function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); } +} +if (!function_exists('mb_chr')) { + function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); } + function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); } + function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); } +} + +if (!function_exists('mb_str_split')) { + function mb_str_split($string, $split_length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $split_length, $encoding); } +} diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json new file mode 100644 index 0000000..308f009 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/composer.json @@ -0,0 +1,34 @@ +{ + "name": "symfony/polyfill-mbstring", + "type": "library", + "description": "Symfony polyfill for the Mbstring extension", + "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + } +} diff --git a/vendor/symfony/polyfill-php72/LICENSE b/vendor/symfony/polyfill-php72/LICENSE new file mode 100644 index 0000000..4cd8bdd --- /dev/null +++ b/vendor/symfony/polyfill-php72/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-php72/Php72.php b/vendor/symfony/polyfill-php72/Php72.php new file mode 100644 index 0000000..d531e84 --- /dev/null +++ b/vendor/symfony/polyfill-php72/Php72.php @@ -0,0 +1,216 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php72; + +/** + * @author Nicolas Grekas + * @author Dariusz Rumiński + * + * @internal + */ +final class Php72 +{ + private static $hashMask; + + public static function utf8_encode($s) + { + $s .= $s; + $len = \strlen($s); + + for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) { + switch (true) { + case $s[$i] < "\x80": $s[$j] = $s[$i]; break; + case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break; + default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break; + } + } + + return substr($s, 0, $j); + } + + public static function utf8_decode($s) + { + $s = (string) $s; + $len = \strlen($s); + + for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) { + switch ($s[$i] & "\xF0") { + case "\xC0": + case "\xD0": + $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F"); + $s[$j] = $c < 256 ? \chr($c) : '?'; + break; + + case "\xF0": + ++$i; + // no break + + case "\xE0": + $s[$j] = '?'; + $i += 2; + break; + + default: + $s[$j] = $s[$i]; + } + } + + return substr($s, 0, $j); + } + + public static function php_os_family() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + return 'Windows'; + } + + $map = array( + 'Darwin' => 'Darwin', + 'DragonFly' => 'BSD', + 'FreeBSD' => 'BSD', + 'NetBSD' => 'BSD', + 'OpenBSD' => 'BSD', + 'Linux' => 'Linux', + 'SunOS' => 'Solaris', + ); + + return isset($map[PHP_OS]) ? $map[PHP_OS] : 'Unknown'; + } + + public static function spl_object_id($object) + { + if (null === self::$hashMask) { + self::initHashMask(); + } + if (null === $hash = spl_object_hash($object)) { + return; + } + + return self::$hashMask ^ hexdec(substr($hash, 16 - \PHP_INT_SIZE, \PHP_INT_SIZE)); + } + + public static function sapi_windows_vt100_support($stream, $enable = null) + { + if (!\is_resource($stream)) { + trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING); + + return false; + } + + $meta = stream_get_meta_data($stream); + + if ('STDIO' !== $meta['stream_type']) { + trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', E_USER_WARNING); + + return false; + } + + // We cannot actually disable vt100 support if it is set + if (false === $enable || !self::stream_isatty($stream)) { + return false; + } + + // The native function does not apply to stdin + $meta = array_map('strtolower', $meta); + $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri']; + + return !$stdin + && (false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM') + || 'Hyper' === getenv('TERM_PROGRAM')); + } + + public static function stream_isatty($stream) + { + if (!\is_resource($stream)) { + trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING); + + return false; + } + + if ('\\' === \DIRECTORY_SEPARATOR) { + $stat = @fstat($stream); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } + + return \function_exists('posix_isatty') && @posix_isatty($stream); + } + + private static function initHashMask() + { + $obj = (object) array(); + self::$hashMask = -1; + + // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below + $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'); + foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) { + if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) { + $frame['line'] = 0; + break; + } + } + if (!empty($frame['line'])) { + ob_start(); + debug_zval_dump($obj); + self::$hashMask = (int) substr(ob_get_clean(), 17); + } + + self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - \PHP_INT_SIZE, \PHP_INT_SIZE)); + } + + public static function mb_chr($code, $encoding = null) + { + if (0x80 > $code %= 0x200000) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); + } elseif (0x10000 > $code) { + $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } else { + $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } + + if ('UTF-8' !== $encoding) { + $s = mb_convert_encoding($s, $encoding, 'UTF-8'); + } + + return $s; + } + + public static function mb_ord($s, $encoding = null) + { + if (null == $encoding) { + $s = mb_convert_encoding($s, 'UTF-8'); + } elseif ('UTF-8' !== $encoding) { + $s = mb_convert_encoding($s, 'UTF-8', $encoding); + } + + if (1 === \strlen($s)) { + return \ord($s); + } + + $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; + if (0xF0 <= $code) { + return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; + } + if (0xE0 <= $code) { + return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; + } + if (0xC0 <= $code) { + return (($code - 0xC0) << 6) + $s[2] - 0x80; + } + + return $code; + } +} diff --git a/vendor/symfony/polyfill-php72/README.md b/vendor/symfony/polyfill-php72/README.md new file mode 100644 index 0000000..82c45f7 --- /dev/null +++ b/vendor/symfony/polyfill-php72/README.md @@ -0,0 +1,27 @@ +Symfony Polyfill / Php72 +======================== + +This component provides functions added to PHP 7.2 core: + +- [`spl_object_id`](https://php.net/spl_object_id) +- [`stream_isatty`](https://php.net/stream_isatty) + +On Windows only: + +- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support) + +Moved to core since 7.2 (was in the optional XML extension earlier): + +- [`utf8_encode`](https://php.net/utf8_encode) +- [`utf8_decode`](https://php.net/utf8_decode) + +Also, it provides a constant added to PHP 7.2: +- [`PHP_OS_FAMILY`](http://php.net/manual/en/reserved.constants.php#constant.php-os-family) + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-php72/bootstrap.php b/vendor/symfony/polyfill-php72/bootstrap.php new file mode 100644 index 0000000..519056d --- /dev/null +++ b/vendor/symfony/polyfill-php72/bootstrap.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php72 as p; + +if (PHP_VERSION_ID < 70200) { + if ('\\' === DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) { + function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); } + } + if (!function_exists('stream_isatty')) { + function stream_isatty($stream) { return p\Php72::stream_isatty($stream); } + } + if (!function_exists('utf8_encode')) { + function utf8_encode($s) { return p\Php72::utf8_encode($s); } + function utf8_decode($s) { return p\Php72::utf8_decode($s); } + } + if (!function_exists('spl_object_id')) { + function spl_object_id($s) { return p\Php72::spl_object_id($s); } + } + if (!defined('PHP_OS_FAMILY')) { + define('PHP_OS_FAMILY', p\Php72::php_os_family()); + } + if (!function_exists('mb_chr')) { + function mb_ord($s, $enc = null) { return p\Php72::mb_ord($s, $enc); } + function mb_chr($code, $enc = null) { return p\Php72::mb_chr($code, $enc); } + function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); } + } +} diff --git a/vendor/symfony/polyfill-php72/composer.json b/vendor/symfony/polyfill-php72/composer.json new file mode 100644 index 0000000..5cfcbb7 --- /dev/null +++ b/vendor/symfony/polyfill-php72/composer.json @@ -0,0 +1,31 @@ +{ + "name": "symfony/polyfill-php72", + "type": "library", + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php72\\": "" }, + "files": [ "bootstrap.php" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + } +} diff --git a/vendor/symfony/var-dumper/.gitignore b/vendor/symfony/var-dumper/.gitignore new file mode 100644 index 0000000..5414c2c --- /dev/null +++ b/vendor/symfony/var-dumper/.gitignore @@ -0,0 +1,3 @@ +composer.lock +phpunit.xml +vendor/ diff --git a/vendor/symfony/var-dumper/CHANGELOG.md b/vendor/symfony/var-dumper/CHANGELOG.md new file mode 100644 index 0000000..c07808f --- /dev/null +++ b/vendor/symfony/var-dumper/CHANGELOG.md @@ -0,0 +1,42 @@ +CHANGELOG +========= + +4.3.0 +----- + + * added `DsCaster` to support dumping the contents of data structures from the Ds extension + +4.2.0 +----- + + * support selecting the format to use by setting the environment variable `VAR_DUMPER_FORMAT` to `html` or `cli` + +4.1.0 +----- + + * added a `ServerDumper` to send serialized Data clones to a server + * added a `ServerDumpCommand` and `DumpServer` to run a server collecting + and displaying dumps on a single place with multiple formats support + * added `CliDescriptor` and `HtmlDescriptor` descriptors for `server:dump` CLI and HTML formats support + +4.0.0 +----- + + * support for passing `\ReflectionClass` instances to the `Caster::castObject()` + method has been dropped, pass class names as strings instead + * the `Data::getRawData()` method has been removed + * the `VarDumperTestTrait::assertDumpEquals()` method expects a 3rd `$filter = 0` + argument and moves `$message = ''` argument at 4th position. + * the `VarDumperTestTrait::assertDumpMatchesFormat()` method expects a 3rd `$filter = 0` + argument and moves `$message = ''` argument at 4th position. + +3.4.0 +----- + + * added `AbstractCloner::setMinDepth()` function to ensure minimum tree depth + * deprecated `MongoCaster` + +2.7.0 +----- + + * deprecated `Cloner\Data::getLimitedClone()`. Use `withMaxDepth`, `withMaxItemsPerDepth` or `withRefHandles` instead. diff --git a/vendor/symfony/var-dumper/Caster/AmqpCaster.php b/vendor/symfony/var-dumper/Caster/AmqpCaster.php new file mode 100644 index 0000000..19bdc29 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/AmqpCaster.php @@ -0,0 +1,210 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts Amqp related classes to array representation. + * + * @author Grégoire Pineau + */ +class AmqpCaster +{ + private static $flags = [ + AMQP_DURABLE => 'AMQP_DURABLE', + AMQP_PASSIVE => 'AMQP_PASSIVE', + AMQP_EXCLUSIVE => 'AMQP_EXCLUSIVE', + AMQP_AUTODELETE => 'AMQP_AUTODELETE', + AMQP_INTERNAL => 'AMQP_INTERNAL', + AMQP_NOLOCAL => 'AMQP_NOLOCAL', + AMQP_AUTOACK => 'AMQP_AUTOACK', + AMQP_IFEMPTY => 'AMQP_IFEMPTY', + AMQP_IFUNUSED => 'AMQP_IFUNUSED', + AMQP_MANDATORY => 'AMQP_MANDATORY', + AMQP_IMMEDIATE => 'AMQP_IMMEDIATE', + AMQP_MULTIPLE => 'AMQP_MULTIPLE', + AMQP_NOWAIT => 'AMQP_NOWAIT', + AMQP_REQUEUE => 'AMQP_REQUEUE', + ]; + + private static $exchangeTypes = [ + AMQP_EX_TYPE_DIRECT => 'AMQP_EX_TYPE_DIRECT', + AMQP_EX_TYPE_FANOUT => 'AMQP_EX_TYPE_FANOUT', + AMQP_EX_TYPE_TOPIC => 'AMQP_EX_TYPE_TOPIC', + AMQP_EX_TYPE_HEADERS => 'AMQP_EX_TYPE_HEADERS', + ]; + + public static function castConnection(\AMQPConnection $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + $a += [ + $prefix.'is_connected' => $c->isConnected(), + ]; + + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPConnection\x00login"])) { + return $a; + } + + // BC layer in the amqp lib + if (method_exists($c, 'getReadTimeout')) { + $timeout = $c->getReadTimeout(); + } else { + $timeout = $c->getTimeout(); + } + + $a += [ + $prefix.'is_connected' => $c->isConnected(), + $prefix.'login' => $c->getLogin(), + $prefix.'password' => $c->getPassword(), + $prefix.'host' => $c->getHost(), + $prefix.'vhost' => $c->getVhost(), + $prefix.'port' => $c->getPort(), + $prefix.'read_timeout' => $timeout, + ]; + + return $a; + } + + public static function castChannel(\AMQPChannel $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + $a += [ + $prefix.'is_connected' => $c->isConnected(), + $prefix.'channel_id' => $c->getChannelId(), + ]; + + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPChannel\x00connection"])) { + return $a; + } + + $a += [ + $prefix.'connection' => $c->getConnection(), + $prefix.'prefetch_size' => $c->getPrefetchSize(), + $prefix.'prefetch_count' => $c->getPrefetchCount(), + ]; + + return $a; + } + + public static function castQueue(\AMQPQueue $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + $a += [ + $prefix.'flags' => self::extractFlags($c->getFlags()), + ]; + + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPQueue\x00name"])) { + return $a; + } + + $a += [ + $prefix.'connection' => $c->getConnection(), + $prefix.'channel' => $c->getChannel(), + $prefix.'name' => $c->getName(), + $prefix.'arguments' => $c->getArguments(), + ]; + + return $a; + } + + public static function castExchange(\AMQPExchange $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + $a += [ + $prefix.'flags' => self::extractFlags($c->getFlags()), + ]; + + $type = isset(self::$exchangeTypes[$c->getType()]) ? new ConstStub(self::$exchangeTypes[$c->getType()], $c->getType()) : $c->getType(); + + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPExchange\x00name"])) { + $a["\x00AMQPExchange\x00type"] = $type; + + return $a; + } + + $a += [ + $prefix.'connection' => $c->getConnection(), + $prefix.'channel' => $c->getChannel(), + $prefix.'name' => $c->getName(), + $prefix.'type' => $type, + $prefix.'arguments' => $c->getArguments(), + ]; + + return $a; + } + + public static function castEnvelope(\AMQPEnvelope $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $prefix = Caster::PREFIX_VIRTUAL; + + $deliveryMode = new ConstStub($c->getDeliveryMode().(2 === $c->getDeliveryMode() ? ' (persistent)' : ' (non-persistent)'), $c->getDeliveryMode()); + + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPEnvelope\x00body"])) { + $a["\0AMQPEnvelope\0delivery_mode"] = $deliveryMode; + + return $a; + } + + if (!($filter & Caster::EXCLUDE_VERBOSE)) { + $a += [$prefix.'body' => $c->getBody()]; + } + + $a += [ + $prefix.'delivery_tag' => $c->getDeliveryTag(), + $prefix.'is_redelivery' => $c->isRedelivery(), + $prefix.'exchange_name' => $c->getExchangeName(), + $prefix.'routing_key' => $c->getRoutingKey(), + $prefix.'content_type' => $c->getContentType(), + $prefix.'content_encoding' => $c->getContentEncoding(), + $prefix.'headers' => $c->getHeaders(), + $prefix.'delivery_mode' => $deliveryMode, + $prefix.'priority' => $c->getPriority(), + $prefix.'correlation_id' => $c->getCorrelationId(), + $prefix.'reply_to' => $c->getReplyTo(), + $prefix.'expiration' => $c->getExpiration(), + $prefix.'message_id' => $c->getMessageId(), + $prefix.'timestamp' => $c->getTimeStamp(), + $prefix.'type' => $c->getType(), + $prefix.'user_id' => $c->getUserId(), + $prefix.'app_id' => $c->getAppId(), + ]; + + return $a; + } + + private static function extractFlags($flags) + { + $flagsArray = []; + + foreach (self::$flags as $value => $name) { + if ($flags & $value) { + $flagsArray[] = $name; + } + } + + if (!$flagsArray) { + $flagsArray = ['AMQP_NOPARAM']; + } + + return new ConstStub(implode('|', $flagsArray), $flags); + } +} diff --git a/vendor/symfony/var-dumper/Caster/ArgsStub.php b/vendor/symfony/var-dumper/Caster/ArgsStub.php new file mode 100644 index 0000000..1ca7a86 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ArgsStub.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents a list of function arguments. + * + * @author Nicolas Grekas + */ +class ArgsStub extends EnumStub +{ + private static $parameters = []; + + public function __construct(array $args, string $function, ?string $class) + { + list($variadic, $params) = self::getParameters($function, $class); + + $values = []; + foreach ($args as $k => $v) { + $values[$k] = !is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v; + } + if (null === $params) { + parent::__construct($values, false); + + return; + } + if (\count($values) < \count($params)) { + $params = \array_slice($params, 0, \count($values)); + } elseif (\count($values) > \count($params)) { + $values[] = new EnumStub(array_splice($values, \count($params)), false); + $params[] = $variadic; + } + if (['...'] === $params) { + $this->dumpKeys = false; + $this->value = $values[0]->value; + } else { + $this->value = array_combine($params, $values); + } + } + + private static function getParameters($function, $class) + { + if (isset(self::$parameters[$k = $class.'::'.$function])) { + return self::$parameters[$k]; + } + + try { + $r = null !== $class ? new \ReflectionMethod($class, $function) : new \ReflectionFunction($function); + } catch (\ReflectionException $e) { + return [null, null]; + } + + $variadic = '...'; + $params = []; + foreach ($r->getParameters() as $v) { + $k = '$'.$v->name; + if ($v->isPassedByReference()) { + $k = '&'.$k; + } + if ($v->isVariadic()) { + $variadic .= $k; + } else { + $params[] = $k; + } + } + + return self::$parameters[$k] = [$variadic, $params]; + } +} diff --git a/vendor/symfony/var-dumper/Caster/Caster.php b/vendor/symfony/var-dumper/Caster/Caster.php new file mode 100644 index 0000000..884e84d --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/Caster.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Helper for filtering out properties in casters. + * + * @author Nicolas Grekas + * + * @final + */ +class Caster +{ + const EXCLUDE_VERBOSE = 1; + const EXCLUDE_VIRTUAL = 2; + const EXCLUDE_DYNAMIC = 4; + const EXCLUDE_PUBLIC = 8; + const EXCLUDE_PROTECTED = 16; + const EXCLUDE_PRIVATE = 32; + const EXCLUDE_NULL = 64; + const EXCLUDE_EMPTY = 128; + const EXCLUDE_NOT_IMPORTANT = 256; + const EXCLUDE_STRICT = 512; + + const PREFIX_VIRTUAL = "\0~\0"; + const PREFIX_DYNAMIC = "\0+\0"; + const PREFIX_PROTECTED = "\0*\0"; + + /** + * Casts objects to arrays and adds the dynamic property prefix. + * + * @param object $obj The object to cast + * @param string $class The class of the object + * @param bool $hasDebugInfo Whether the __debugInfo method exists on $obj or not + * + * @return array The array-cast of the object, with prefixed dynamic properties + */ + public static function castObject($obj, $class, $hasDebugInfo = false) + { + $a = $obj instanceof \Closure ? [] : (array) $obj; + + if ($obj instanceof \__PHP_Incomplete_Class) { + return $a; + } + + if ($a) { + static $publicProperties = []; + + $i = 0; + $prefixedKeys = []; + foreach ($a as $k => $v) { + if (isset($k[0]) ? "\0" !== $k[0] : \PHP_VERSION_ID >= 70200) { + if (!isset($publicProperties[$class])) { + foreach ((new \ReflectionClass($class))->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) { + $publicProperties[$class][$prop->name] = true; + } + } + if (!isset($publicProperties[$class][$k])) { + $prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k; + } + } elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) { + $prefixedKeys[$i] = "\0".get_parent_class($class).'@anonymous'.strrchr($k, "\0"); + } + ++$i; + } + if ($prefixedKeys) { + $keys = array_keys($a); + foreach ($prefixedKeys as $i => $k) { + $keys[$i] = $k; + } + $a = array_combine($keys, $a); + } + } + + if ($hasDebugInfo && \is_array($debugInfo = $obj->__debugInfo())) { + foreach ($debugInfo as $k => $v) { + if (!isset($k[0]) || "\0" !== $k[0]) { + $k = self::PREFIX_VIRTUAL.$k; + } + + unset($a[$k]); + $a[$k] = $v; + } + } + + return $a; + } + + /** + * Filters out the specified properties. + * + * By default, a single match in the $filter bit field filters properties out, following an "or" logic. + * When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed. + * + * @param array $a The array containing the properties to filter + * @param int $filter A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out + * @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set + * @param int &$count Set to the number of removed properties + * + * @return array The filtered array + */ + public static function filter(array $a, $filter, array $listedProperties = [], &$count = 0) + { + $count = 0; + + foreach ($a as $k => $v) { + $type = self::EXCLUDE_STRICT & $filter; + + if (null === $v) { + $type |= self::EXCLUDE_NULL & $filter; + $type |= self::EXCLUDE_EMPTY & $filter; + } elseif (false === $v || '' === $v || '0' === $v || 0 === $v || 0.0 === $v || [] === $v) { + $type |= self::EXCLUDE_EMPTY & $filter; + } + if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !\in_array($k, $listedProperties, true)) { + $type |= self::EXCLUDE_NOT_IMPORTANT; + } + if ((self::EXCLUDE_VERBOSE & $filter) && \in_array($k, $listedProperties, true)) { + $type |= self::EXCLUDE_VERBOSE; + } + + if (!isset($k[1]) || "\0" !== $k[0]) { + $type |= self::EXCLUDE_PUBLIC & $filter; + } elseif ('~' === $k[1]) { + $type |= self::EXCLUDE_VIRTUAL & $filter; + } elseif ('+' === $k[1]) { + $type |= self::EXCLUDE_DYNAMIC & $filter; + } elseif ('*' === $k[1]) { + $type |= self::EXCLUDE_PROTECTED & $filter; + } else { + $type |= self::EXCLUDE_PRIVATE & $filter; + } + + if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) { + unset($a[$k]); + ++$count; + } + } + + return $a; + } + + public static function castPhpIncompleteClass(\__PHP_Incomplete_Class $c, array $a, Stub $stub, $isNested) + { + if (isset($a['__PHP_Incomplete_Class_Name'])) { + $stub->class .= '('.$a['__PHP_Incomplete_Class_Name'].')'; + unset($a['__PHP_Incomplete_Class_Name']); + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/ClassStub.php b/vendor/symfony/var-dumper/Caster/ClassStub.php new file mode 100644 index 0000000..0b9329d --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ClassStub.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents a PHP class identifier. + * + * @author Nicolas Grekas + */ +class ClassStub extends ConstStub +{ + /** + * @param string $identifier A PHP identifier, e.g. a class, method, interface, etc. name + * @param callable $callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier + */ + public function __construct(string $identifier, $callable = null) + { + $this->value = $identifier; + + try { + if (null !== $callable) { + if ($callable instanceof \Closure) { + $r = new \ReflectionFunction($callable); + } elseif (\is_object($callable)) { + $r = [$callable, '__invoke']; + } elseif (\is_array($callable)) { + $r = $callable; + } elseif (false !== $i = strpos($callable, '::')) { + $r = [substr($callable, 0, $i), substr($callable, 2 + $i)]; + } else { + $r = new \ReflectionFunction($callable); + } + } elseif (0 < $i = strpos($identifier, '::') ?: strpos($identifier, '->')) { + $r = [substr($identifier, 0, $i), substr($identifier, 2 + $i)]; + } else { + $r = new \ReflectionClass($identifier); + } + + if (\is_array($r)) { + try { + $r = new \ReflectionMethod($r[0], $r[1]); + } catch (\ReflectionException $e) { + $r = new \ReflectionClass($r[0]); + } + } + + if (false !== strpos($identifier, "class@anonymous\0")) { + $this->value = $identifier = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + }, $identifier); + } + + if (null !== $callable && $r instanceof \ReflectionFunctionAbstract) { + $s = ReflectionCaster::castFunctionAbstract($r, [], new Stub(), true); + $s = ReflectionCaster::getSignature($s); + + if ('()' === substr($identifier, -2)) { + $this->value = substr_replace($identifier, $s, -2); + } else { + $this->value .= $s; + } + } + } catch (\ReflectionException $e) { + return; + } finally { + if (0 < $i = strrpos($this->value, '\\')) { + $this->attr['ellipsis'] = \strlen($this->value) - $i; + $this->attr['ellipsis-type'] = 'class'; + $this->attr['ellipsis-tail'] = 1; + } + } + + if ($f = $r->getFileName()) { + $this->attr['file'] = $f; + $this->attr['line'] = $r->getStartLine(); + } + } + + public static function wrapCallable($callable) + { + if (\is_object($callable) || !\is_callable($callable)) { + return $callable; + } + + if (!\is_array($callable)) { + $callable = new static($callable, $callable); + } elseif (\is_string($callable[0])) { + $callable[0] = new static($callable[0], $callable); + } else { + $callable[1] = new static($callable[1], $callable); + } + + return $callable; + } +} diff --git a/vendor/symfony/var-dumper/Caster/ConstStub.php b/vendor/symfony/var-dumper/Caster/ConstStub.php new file mode 100644 index 0000000..15868b0 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ConstStub.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents a PHP constant and its value. + * + * @author Nicolas Grekas + */ +class ConstStub extends Stub +{ + public function __construct(string $name, $value = null) + { + $this->class = $name; + $this->value = 1 < \func_num_args() ? $value : $name; + } + + public function __toString() + { + return (string) $this->value; + } +} diff --git a/vendor/symfony/var-dumper/Caster/CutArrayStub.php b/vendor/symfony/var-dumper/Caster/CutArrayStub.php new file mode 100644 index 0000000..0e4fb36 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/CutArrayStub.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +/** + * Represents a cut array. + * + * @author Nicolas Grekas + */ +class CutArrayStub extends CutStub +{ + public $preservedSubset; + + public function __construct(array $value, array $preservedKeys) + { + parent::__construct($value); + + $this->preservedSubset = array_intersect_key($value, array_flip($preservedKeys)); + $this->cut -= \count($this->preservedSubset); + } +} diff --git a/vendor/symfony/var-dumper/Caster/CutStub.php b/vendor/symfony/var-dumper/Caster/CutStub.php new file mode 100644 index 0000000..690338f --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/CutStub.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents the main properties of a PHP variable, pre-casted by a caster. + * + * @author Nicolas Grekas + */ +class CutStub extends Stub +{ + public function __construct($value) + { + $this->value = $value; + + switch (\gettype($value)) { + case 'object': + $this->type = self::TYPE_OBJECT; + $this->class = \get_class($value); + $this->cut = -1; + break; + + case 'array': + $this->type = self::TYPE_ARRAY; + $this->class = self::ARRAY_ASSOC; + $this->cut = $this->value = \count($value); + break; + + case 'resource': + case 'unknown type': + case 'resource (closed)': + $this->type = self::TYPE_RESOURCE; + $this->handle = (int) $value; + if ('Unknown' === $this->class = @get_resource_type($value)) { + $this->class = 'Closed'; + } + $this->cut = -1; + break; + + case 'string': + $this->type = self::TYPE_STRING; + $this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY; + $this->cut = self::STRING_BINARY === $this->class ? \strlen($value) : mb_strlen($value, 'UTF-8'); + $this->value = ''; + break; + } + } +} diff --git a/vendor/symfony/var-dumper/Caster/DOMCaster.php b/vendor/symfony/var-dumper/Caster/DOMCaster.php new file mode 100644 index 0000000..65151b4 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/DOMCaster.php @@ -0,0 +1,302 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts DOM related classes to array representation. + * + * @author Nicolas Grekas + */ +class DOMCaster +{ + private static $errorCodes = [ + DOM_PHP_ERR => 'DOM_PHP_ERR', + DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR', + DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR', + DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR', + DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR', + DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR', + DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR', + DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR', + DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR', + DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR', + DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR', + DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR', + DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR', + DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR', + DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR', + DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR', + DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR', + ]; + + private static $nodeTypes = [ + XML_ELEMENT_NODE => 'XML_ELEMENT_NODE', + XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE', + XML_TEXT_NODE => 'XML_TEXT_NODE', + XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE', + XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE', + XML_ENTITY_NODE => 'XML_ENTITY_NODE', + XML_PI_NODE => 'XML_PI_NODE', + XML_COMMENT_NODE => 'XML_COMMENT_NODE', + XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE', + XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE', + XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE', + XML_NOTATION_NODE => 'XML_NOTATION_NODE', + XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE', + XML_DTD_NODE => 'XML_DTD_NODE', + XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE', + XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE', + XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE', + XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE', + ]; + + public static function castException(\DOMException $e, array $a, Stub $stub, $isNested) + { + $k = Caster::PREFIX_PROTECTED.'code'; + if (isset($a[$k], self::$errorCodes[$a[$k]])) { + $a[$k] = new ConstStub(self::$errorCodes[$a[$k]], $a[$k]); + } + + return $a; + } + + public static function castLength($dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'length' => $dom->length, + ]; + + return $a; + } + + public static function castImplementation($dom, array $a, Stub $stub, $isNested) + { + $a += [ + Caster::PREFIX_VIRTUAL.'Core' => '1.0', + Caster::PREFIX_VIRTUAL.'XML' => '2.0', + ]; + + return $a; + } + + public static function castNode(\DOMNode $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'nodeName' => $dom->nodeName, + 'nodeValue' => new CutStub($dom->nodeValue), + 'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType), + 'parentNode' => new CutStub($dom->parentNode), + 'childNodes' => $dom->childNodes, + 'firstChild' => new CutStub($dom->firstChild), + 'lastChild' => new CutStub($dom->lastChild), + 'previousSibling' => new CutStub($dom->previousSibling), + 'nextSibling' => new CutStub($dom->nextSibling), + 'attributes' => $dom->attributes, + 'ownerDocument' => new CutStub($dom->ownerDocument), + 'namespaceURI' => $dom->namespaceURI, + 'prefix' => $dom->prefix, + 'localName' => $dom->localName, + 'baseURI' => $dom->baseURI ? new LinkStub($dom->baseURI) : $dom->baseURI, + 'textContent' => new CutStub($dom->textContent), + ]; + + return $a; + } + + public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'nodeName' => $dom->nodeName, + 'nodeValue' => new CutStub($dom->nodeValue), + 'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType), + 'prefix' => $dom->prefix, + 'localName' => $dom->localName, + 'namespaceURI' => $dom->namespaceURI, + 'ownerDocument' => new CutStub($dom->ownerDocument), + 'parentNode' => new CutStub($dom->parentNode), + ]; + + return $a; + } + + public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, $isNested, $filter = 0) + { + $a += [ + 'doctype' => $dom->doctype, + 'implementation' => $dom->implementation, + 'documentElement' => new CutStub($dom->documentElement), + 'actualEncoding' => $dom->actualEncoding, + 'encoding' => $dom->encoding, + 'xmlEncoding' => $dom->xmlEncoding, + 'standalone' => $dom->standalone, + 'xmlStandalone' => $dom->xmlStandalone, + 'version' => $dom->version, + 'xmlVersion' => $dom->xmlVersion, + 'strictErrorChecking' => $dom->strictErrorChecking, + 'documentURI' => $dom->documentURI ? new LinkStub($dom->documentURI) : $dom->documentURI, + 'config' => $dom->config, + 'formatOutput' => $dom->formatOutput, + 'validateOnParse' => $dom->validateOnParse, + 'resolveExternals' => $dom->resolveExternals, + 'preserveWhiteSpace' => $dom->preserveWhiteSpace, + 'recover' => $dom->recover, + 'substituteEntities' => $dom->substituteEntities, + ]; + + if (!($filter & Caster::EXCLUDE_VERBOSE)) { + $formatOutput = $dom->formatOutput; + $dom->formatOutput = true; + $a += [Caster::PREFIX_VIRTUAL.'xml' => $dom->saveXML()]; + $dom->formatOutput = $formatOutput; + } + + return $a; + } + + public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'data' => $dom->data, + 'length' => $dom->length, + ]; + + return $a; + } + + public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'name' => $dom->name, + 'specified' => $dom->specified, + 'value' => $dom->value, + 'ownerElement' => $dom->ownerElement, + 'schemaTypeInfo' => $dom->schemaTypeInfo, + ]; + + return $a; + } + + public static function castElement(\DOMElement $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'tagName' => $dom->tagName, + 'schemaTypeInfo' => $dom->schemaTypeInfo, + ]; + + return $a; + } + + public static function castText(\DOMText $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'wholeText' => $dom->wholeText, + ]; + + return $a; + } + + public static function castTypeinfo(\DOMTypeinfo $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'typeName' => $dom->typeName, + 'typeNamespace' => $dom->typeNamespace, + ]; + + return $a; + } + + public static function castDomError(\DOMDomError $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'severity' => $dom->severity, + 'message' => $dom->message, + 'type' => $dom->type, + 'relatedException' => $dom->relatedException, + 'related_data' => $dom->related_data, + 'location' => $dom->location, + ]; + + return $a; + } + + public static function castLocator(\DOMLocator $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'lineNumber' => $dom->lineNumber, + 'columnNumber' => $dom->columnNumber, + 'offset' => $dom->offset, + 'relatedNode' => $dom->relatedNode, + 'uri' => $dom->uri ? new LinkStub($dom->uri, $dom->lineNumber) : $dom->uri, + ]; + + return $a; + } + + public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'name' => $dom->name, + 'entities' => $dom->entities, + 'notations' => $dom->notations, + 'publicId' => $dom->publicId, + 'systemId' => $dom->systemId, + 'internalSubset' => $dom->internalSubset, + ]; + + return $a; + } + + public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'publicId' => $dom->publicId, + 'systemId' => $dom->systemId, + ]; + + return $a; + } + + public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'publicId' => $dom->publicId, + 'systemId' => $dom->systemId, + 'notationName' => $dom->notationName, + 'actualEncoding' => $dom->actualEncoding, + 'encoding' => $dom->encoding, + 'version' => $dom->version, + ]; + + return $a; + } + + public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'target' => $dom->target, + 'data' => $dom->data, + ]; + + return $a; + } + + public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, $isNested) + { + $a += [ + 'document' => $dom->document, + ]; + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/DateCaster.php b/vendor/symfony/var-dumper/Caster/DateCaster.php new file mode 100644 index 0000000..4e83a99 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/DateCaster.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts DateTimeInterface related classes to array representation. + * + * @author Dany Maillard + */ +class DateCaster +{ + private const PERIOD_LIMIT = 3; + + public static function castDateTime(\DateTimeInterface $d, array $a, Stub $stub, $isNested, $filter) + { + $prefix = Caster::PREFIX_VIRTUAL; + $location = $d->getTimezone()->getLocation(); + $fromNow = (new \DateTime())->diff($d); + + $title = $d->format('l, F j, Y') + ."\n".self::formatInterval($fromNow).' from now' + .($location ? ($d->format('I') ? "\nDST On" : "\nDST Off") : '') + ; + + $a = []; + $a[$prefix.'date'] = new ConstStub(self::formatDateTime($d, $location ? ' e (P)' : ' P'), $title); + + $stub->class .= $d->format(' @U'); + + return $a; + } + + public static function castInterval(\DateInterval $interval, array $a, Stub $stub, $isNested, $filter) + { + $now = new \DateTimeImmutable(); + $numberOfSeconds = $now->add($interval)->getTimestamp() - $now->getTimestamp(); + $title = number_format($numberOfSeconds, 0, '.', ' ').'s'; + + $i = [Caster::PREFIX_VIRTUAL.'interval' => new ConstStub(self::formatInterval($interval), $title)]; + + return $filter & Caster::EXCLUDE_VERBOSE ? $i : $i + $a; + } + + private static function formatInterval(\DateInterval $i) + { + $format = '%R '; + + if (0 === $i->y && 0 === $i->m && ($i->h >= 24 || $i->i >= 60 || $i->s >= 60)) { + $i = date_diff($d = new \DateTime(), date_add(clone $d, $i)); // recalculate carry over points + $format .= 0 < $i->days ? '%ad ' : ''; + } else { + $format .= ($i->y ? '%yy ' : '').($i->m ? '%mm ' : '').($i->d ? '%dd ' : ''); + } + + $format .= $i->h || $i->i || $i->s || $i->f ? '%H:%I:'.self::formatSeconds($i->s, substr($i->f, 2)) : ''; + $format = '%R ' === $format ? '0s' : $format; + + return $i->format(rtrim($format)); + } + + public static function castTimeZone(\DateTimeZone $timeZone, array $a, Stub $stub, $isNested, $filter) + { + $location = $timeZone->getLocation(); + $formatted = (new \DateTime('now', $timeZone))->format($location ? 'e (P)' : 'P'); + $title = $location && \extension_loaded('intl') ? \Locale::getDisplayRegion('-'.$location['country_code']) : ''; + + $z = [Caster::PREFIX_VIRTUAL.'timezone' => new ConstStub($formatted, $title)]; + + return $filter & Caster::EXCLUDE_VERBOSE ? $z : $z + $a; + } + + public static function castPeriod(\DatePeriod $p, array $a, Stub $stub, $isNested, $filter) + { + $dates = []; + if (\PHP_VERSION_ID >= 70107) { // see https://bugs.php.net/74639 + foreach (clone $p as $i => $d) { + if (self::PERIOD_LIMIT === $i) { + $now = new \DateTimeImmutable(); + $dates[] = sprintf('%s more', ($end = $p->getEndDate()) + ? ceil(($end->format('U.u') - $d->format('U.u')) / ((int) $now->add($p->getDateInterval())->format('U.u') - (int) $now->format('U.u'))) + : $p->recurrences - $i + ); + break; + } + $dates[] = sprintf('%s) %s', $i + 1, self::formatDateTime($d)); + } + } + + $period = sprintf( + 'every %s, from %s (%s) %s', + self::formatInterval($p->getDateInterval()), + self::formatDateTime($p->getStartDate()), + $p->include_start_date ? 'included' : 'excluded', + ($end = $p->getEndDate()) ? 'to '.self::formatDateTime($end) : 'recurring '.$p->recurrences.' time/s' + ); + + $p = [Caster::PREFIX_VIRTUAL.'period' => new ConstStub($period, implode("\n", $dates))]; + + return $filter & Caster::EXCLUDE_VERBOSE ? $p : $p + $a; + } + + private static function formatDateTime(\DateTimeInterface $d, $extra = '') + { + return $d->format('Y-m-d H:i:'.self::formatSeconds($d->format('s'), $d->format('u')).$extra); + } + + private static function formatSeconds($s, $us) + { + return sprintf('%02d.%s', $s, 0 === ($len = \strlen($t = rtrim($us, '0'))) ? '0' : ($len <= 3 ? str_pad($t, 3, '0') : $us)); + } +} diff --git a/vendor/symfony/var-dumper/Caster/DoctrineCaster.php b/vendor/symfony/var-dumper/Caster/DoctrineCaster.php new file mode 100644 index 0000000..696b878 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/DoctrineCaster.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Doctrine\Common\Proxy\Proxy as CommonProxy; +use Doctrine\ORM\PersistentCollection; +use Doctrine\ORM\Proxy\Proxy as OrmProxy; +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts Doctrine related classes to array representation. + * + * @author Nicolas Grekas + */ +class DoctrineCaster +{ + public static function castCommonProxy(CommonProxy $proxy, array $a, Stub $stub, $isNested) + { + foreach (['__cloner__', '__initializer__'] as $k) { + if (\array_key_exists($k, $a)) { + unset($a[$k]); + ++$stub->cut; + } + } + + return $a; + } + + public static function castOrmProxy(OrmProxy $proxy, array $a, Stub $stub, $isNested) + { + foreach (['_entityPersister', '_identifier'] as $k) { + if (\array_key_exists($k = "\0Doctrine\\ORM\\Proxy\\Proxy\0".$k, $a)) { + unset($a[$k]); + ++$stub->cut; + } + } + + return $a; + } + + public static function castPersistentCollection(PersistentCollection $coll, array $a, Stub $stub, $isNested) + { + foreach (['snapshot', 'association', 'typeClass'] as $k) { + if (\array_key_exists($k = "\0Doctrine\\ORM\\PersistentCollection\0".$k, $a)) { + $a[$k] = new CutStub($a[$k]); + } + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/DsCaster.php b/vendor/symfony/var-dumper/Caster/DsCaster.php new file mode 100644 index 0000000..467aadf --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/DsCaster.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Ds\Collection; +use Ds\Map; +use Ds\Pair; +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts Ds extension classes to array representation. + * + * @author Jáchym Toušek + */ +class DsCaster +{ + public static function castCollection(Collection $c, array $a, Stub $stub, bool $isNested): array + { + $a[Caster::PREFIX_VIRTUAL.'count'] = $c->count(); + $a[Caster::PREFIX_VIRTUAL.'capacity'] = $c->capacity(); + + if (!$c instanceof Map) { + $a += $c->toArray(); + } + + return $a; + } + + public static function castMap(Map $c, array $a, Stub $stub, bool $isNested): array + { + foreach ($c as $k => $v) { + $a[] = new DsPairStub($k, $v); + } + + return $a; + } + + public static function castPair(Pair $c, array $a, Stub $stub, bool $isNested): array + { + foreach ($c->toArray() as $k => $v) { + $a[Caster::PREFIX_VIRTUAL.$k] = $v; + } + + return $a; + } + + public static function castPairStub(DsPairStub $c, array $a, Stub $stub, bool $isNested): array + { + if ($isNested) { + $stub->class = Pair::class; + $stub->value = null; + $stub->handle = 0; + + $a = $c->value; + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/DsPairStub.php b/vendor/symfony/var-dumper/Caster/DsPairStub.php new file mode 100644 index 0000000..a1dcc15 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/DsPairStub.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * @author Nicolas Grekas + */ +class DsPairStub extends Stub +{ + public function __construct($key, $value) + { + $this->value = [ + Caster::PREFIX_VIRTUAL.'key' => $key, + Caster::PREFIX_VIRTUAL.'value' => $value, + ]; + } +} diff --git a/vendor/symfony/var-dumper/Caster/EnumStub.php b/vendor/symfony/var-dumper/Caster/EnumStub.php new file mode 100644 index 0000000..7a4e98a --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/EnumStub.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents an enumeration of values. + * + * @author Nicolas Grekas + */ +class EnumStub extends Stub +{ + public $dumpKeys = true; + + public function __construct(array $values, bool $dumpKeys = true) + { + $this->value = $values; + $this->dumpKeys = $dumpKeys; + } +} diff --git a/vendor/symfony/var-dumper/Caster/ExceptionCaster.php b/vendor/symfony/var-dumper/Caster/ExceptionCaster.php new file mode 100644 index 0000000..ec168c8 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ExceptionCaster.php @@ -0,0 +1,357 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\Debug\Exception\SilencedErrorContext; +use Symfony\Component\VarDumper\Cloner\Stub; +use Symfony\Component\VarDumper\Exception\ThrowingCasterException; + +/** + * Casts common Exception classes to array representation. + * + * @author Nicolas Grekas + */ +class ExceptionCaster +{ + public static $srcContext = 1; + public static $traceArgs = true; + public static $errorTypes = [ + E_DEPRECATED => 'E_DEPRECATED', + E_USER_DEPRECATED => 'E_USER_DEPRECATED', + E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', + E_ERROR => 'E_ERROR', + E_WARNING => 'E_WARNING', + E_PARSE => 'E_PARSE', + E_NOTICE => 'E_NOTICE', + E_CORE_ERROR => 'E_CORE_ERROR', + E_CORE_WARNING => 'E_CORE_WARNING', + E_COMPILE_ERROR => 'E_COMPILE_ERROR', + E_COMPILE_WARNING => 'E_COMPILE_WARNING', + E_USER_ERROR => 'E_USER_ERROR', + E_USER_WARNING => 'E_USER_WARNING', + E_USER_NOTICE => 'E_USER_NOTICE', + E_STRICT => 'E_STRICT', + ]; + + private static $framesCache = []; + + public static function castError(\Error $e, array $a, Stub $stub, $isNested, $filter = 0) + { + return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter); + } + + public static function castException(\Exception $e, array $a, Stub $stub, $isNested, $filter = 0) + { + return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter); + } + + public static function castErrorException(\ErrorException $e, array $a, Stub $stub, $isNested) + { + if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) { + $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]); + } + + return $a; + } + + public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, $isNested) + { + $trace = Caster::PREFIX_VIRTUAL.'trace'; + $prefix = Caster::PREFIX_PROTECTED; + $xPrefix = "\0Exception\0"; + + if (isset($a[$xPrefix.'previous'], $a[$trace]) && $a[$xPrefix.'previous'] instanceof \Exception) { + $b = (array) $a[$xPrefix.'previous']; + $class = \get_class($a[$xPrefix.'previous']); + $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + self::traceUnshift($b[$xPrefix.'trace'], $class, $b[$prefix.'file'], $b[$prefix.'line']); + $a[$trace] = new TraceStub($b[$xPrefix.'trace'], false, 0, -\count($a[$trace]->value)); + } + + unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']); + + return $a; + } + + public static function castSilencedErrorContext(SilencedErrorContext $e, array $a, Stub $stub, $isNested) + { + $sPrefix = "\0".SilencedErrorContext::class."\0"; + + if (!isset($a[$s = $sPrefix.'severity'])) { + return $a; + } + + if (isset(self::$errorTypes[$a[$s]])) { + $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]); + } + + $trace = [[ + 'file' => $a[$sPrefix.'file'], + 'line' => $a[$sPrefix.'line'], + ]]; + + if (isset($a[$sPrefix.'trace'])) { + $trace = array_merge($trace, $a[$sPrefix.'trace']); + } + + unset($a[$sPrefix.'file'], $a[$sPrefix.'line'], $a[$sPrefix.'trace']); + $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs); + + return $a; + } + + public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $isNested) + { + if (!$isNested) { + return $a; + } + $stub->class = ''; + $stub->handle = 0; + $frames = $trace->value; + $prefix = Caster::PREFIX_VIRTUAL; + + $a = []; + $j = \count($frames); + if (0 > $i = $trace->sliceOffset) { + $i = max(0, $j + $i); + } + if (!isset($trace->value[$i])) { + return []; + } + $lastCall = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : ''; + $frames[] = ['function' => '']; + $collapse = false; + + for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) { + $f = $frames[$i]; + $call = isset($f['function']) ? (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'] : '???'; + + $frame = new FrameStub( + [ + 'object' => isset($f['object']) ? $f['object'] : null, + 'class' => isset($f['class']) ? $f['class'] : null, + 'type' => isset($f['type']) ? $f['type'] : null, + 'function' => isset($f['function']) ? $f['function'] : null, + ] + $frames[$i - 1], + false, + true + ); + $f = self::castFrameStub($frame, [], $frame, true); + if (isset($f[$prefix.'src'])) { + foreach ($f[$prefix.'src']->value as $label => $frame) { + if (0 === strpos($label, "\0~collapse=0")) { + if ($collapse) { + $label = substr_replace($label, '1', 11, 1); + } else { + $collapse = true; + } + } + $label = substr_replace($label, "title=Stack level $j.&", 2, 0); + } + $f = $frames[$i - 1]; + if ($trace->keepArgs && !empty($f['args']) && $frame instanceof EnumStub) { + $frame->value['arguments'] = new ArgsStub($f['args'], isset($f['function']) ? $f['function'] : null, isset($f['class']) ? $f['class'] : null); + } + } elseif ('???' !== $lastCall) { + $label = new ClassStub($lastCall); + if (isset($label->attr['ellipsis'])) { + $label->attr['ellipsis'] += 2; + $label = substr_replace($prefix, "ellipsis-type=class&ellipsis={$label->attr['ellipsis']}&ellipsis-tail=1&title=Stack level $j.", 2, 0).$label->value.'()'; + } else { + $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$label->value.'()'; + } + } else { + $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$lastCall; + } + $a[substr_replace($label, sprintf('separator=%s&', $frame instanceof EnumStub ? ' ' : ':'), 2, 0)] = $frame; + + $lastCall = $call; + } + if (null !== $trace->sliceLength) { + $a = \array_slice($a, 0, $trace->sliceLength, true); + } + + return $a; + } + + public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $isNested) + { + if (!$isNested) { + return $a; + } + $f = $frame->value; + $prefix = Caster::PREFIX_VIRTUAL; + + if (isset($f['file'], $f['line'])) { + $cacheKey = $f; + unset($cacheKey['object'], $cacheKey['args']); + $cacheKey[] = self::$srcContext; + $cacheKey = implode('-', $cacheKey); + + if (isset(self::$framesCache[$cacheKey])) { + $a[$prefix.'src'] = self::$framesCache[$cacheKey]; + } else { + if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) { + $f['file'] = substr($f['file'], 0, -\strlen($match[0])); + $f['line'] = (int) $match[1]; + } + $caller = isset($f['function']) ? sprintf('in %s() on line %d', (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'], $f['line']) : null; + $src = $f['line']; + $srcKey = $f['file']; + $ellipsis = new LinkStub($srcKey, 0); + $srcAttr = 'collapse='.(int) $ellipsis->inVendor; + $ellipsisTail = isset($ellipsis->attr['ellipsis-tail']) ? $ellipsis->attr['ellipsis-tail'] : 0; + $ellipsis = isset($ellipsis->attr['ellipsis']) ? $ellipsis->attr['ellipsis'] : 0; + + if (file_exists($f['file']) && 0 <= self::$srcContext) { + if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) { + $template = isset($f['object']) ? $f['object'] : unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class'])); + + $ellipsis = 0; + $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : ''); + $templateInfo = $template->getDebugInfo(); + if (isset($templateInfo[$f['line']])) { + if (!method_exists($template, 'getSourceContext') || !file_exists($templatePath = $template->getSourceContext()->getPath())) { + $templatePath = null; + } + if ($templateSrc) { + $src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, $caller, 'twig', $templatePath); + $srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']]; + } + } + } + if ($srcKey == $f['file']) { + $src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, $caller, 'php', $f['file']); + $srcKey .= ':'.$f['line']; + if ($ellipsis) { + $ellipsis += 1 + \strlen($f['line']); + } + } + $srcAttr .= sprintf('&separator= &file=%s&line=%d', rawurlencode($f['file']), $f['line']); + } else { + $srcAttr .= '&separator=:'; + } + $srcAttr .= $ellipsis ? '&ellipsis-type=path&ellipsis='.$ellipsis.'&ellipsis-tail='.$ellipsisTail : ''; + self::$framesCache[$cacheKey] = $a[$prefix.'src'] = new EnumStub(["\0~$srcAttr\0$srcKey" => $src]); + } + } + + unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']); + if ($frame->inTraceStub) { + unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']); + } + foreach ($a as $k => $v) { + if (!$v) { + unset($a[$k]); + } + } + if ($frame->keepArgs && !empty($f['args'])) { + $a[$prefix.'arguments'] = new ArgsStub($f['args'], $f['function'], $f['class']); + } + + return $a; + } + + private static function filterExceptionArray($xClass, array $a, $xPrefix, $filter) + { + if (isset($a[$xPrefix.'trace'])) { + $trace = $a[$xPrefix.'trace']; + unset($a[$xPrefix.'trace']); // Ensures the trace is always last + } else { + $trace = []; + } + + if (!($filter & Caster::EXCLUDE_VERBOSE) && $trace) { + if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) { + self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']); + } + $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs); + } + if (empty($a[$xPrefix.'previous'])) { + unset($a[$xPrefix.'previous']); + } + unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message'], $a[Caster::PREFIX_DYNAMIC.'__destructorException']); + + if (isset($a[Caster::PREFIX_PROTECTED.'message']) && false !== strpos($a[Caster::PREFIX_PROTECTED.'message'], "class@anonymous\0")) { + $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + }, $a[Caster::PREFIX_PROTECTED.'message']); + } + + if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) { + $a[Caster::PREFIX_PROTECTED.'file'] = new LinkStub($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']); + } + + return $a; + } + + private static function traceUnshift(&$trace, $class, $file, $line) + { + if (isset($trace[0]['file'], $trace[0]['line']) && $trace[0]['file'] === $file && $trace[0]['line'] === $line) { + return; + } + array_unshift($trace, [ + 'function' => $class ? 'new '.$class : null, + 'file' => $file, + 'line' => $line, + ]); + } + + private static function extractSource($srcLines, $line, $srcContext, $title, $lang, $file = null) + { + $srcLines = explode("\n", $srcLines); + $src = []; + + for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) { + $src[] = (isset($srcLines[$i]) ? $srcLines[$i] : '')."\n"; + } + + $srcLines = []; + $ltrim = 0; + do { + $pad = null; + for ($i = $srcContext << 1; $i >= 0; --$i) { + if (isset($src[$i][$ltrim]) && "\r" !== ($c = $src[$i][$ltrim]) && "\n" !== $c) { + if (null === $pad) { + $pad = $c; + } + if ((' ' !== $c && "\t" !== $c) || $pad !== $c) { + break; + } + } + } + ++$ltrim; + } while (0 > $i && null !== $pad); + + --$ltrim; + + foreach ($src as $i => $c) { + if ($ltrim) { + $c = isset($c[$ltrim]) && "\r" !== $c[$ltrim] ? substr($c, $ltrim) : ltrim($c, " \t"); + } + $c = substr($c, 0, -1); + if ($i !== $srcContext) { + $c = new ConstStub('default', $c); + } else { + $c = new ConstStub($c, $title); + if (null !== $file) { + $c->attr['file'] = $file; + $c->attr['line'] = $line; + } + } + $c->attr['lang'] = $lang; + $srcLines[sprintf("\0~separator=› &%d\0", $i + $line - $srcContext)] = $c; + } + + return new EnumStub($srcLines); + } +} diff --git a/vendor/symfony/var-dumper/Caster/FrameStub.php b/vendor/symfony/var-dumper/Caster/FrameStub.php new file mode 100644 index 0000000..8786755 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/FrameStub.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +/** + * Represents a single backtrace frame as returned by debug_backtrace() or Exception->getTrace(). + * + * @author Nicolas Grekas + */ +class FrameStub extends EnumStub +{ + public $keepArgs; + public $inTraceStub; + + public function __construct(array $frame, bool $keepArgs = true, bool $inTraceStub = false) + { + $this->value = $frame; + $this->keepArgs = $keepArgs; + $this->inTraceStub = $inTraceStub; + } +} diff --git a/vendor/symfony/var-dumper/Caster/GmpCaster.php b/vendor/symfony/var-dumper/Caster/GmpCaster.php new file mode 100644 index 0000000..504dc07 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/GmpCaster.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts GMP objects to array representation. + * + * @author Hamza Amrouche + * @author Nicolas Grekas + */ +class GmpCaster +{ + public static function castGmp(\GMP $gmp, array $a, Stub $stub, $isNested, $filter): array + { + $a[Caster::PREFIX_VIRTUAL.'value'] = new ConstStub(gmp_strval($gmp), gmp_strval($gmp)); + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/IntlCaster.php b/vendor/symfony/var-dumper/Caster/IntlCaster.php new file mode 100644 index 0000000..31d5cb3 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/IntlCaster.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * @author Nicolas Grekas + * @author Jan Schädlich + */ +class IntlCaster +{ + public static function castMessageFormatter(\MessageFormatter $c, array $a, Stub $stub, $isNested) + { + $a += [ + Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(), + Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(), + ]; + + return self::castError($c, $a); + } + + public static function castNumberFormatter(\NumberFormatter $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $a += [ + Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(), + Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(), + ]; + + if ($filter & Caster::EXCLUDE_VERBOSE) { + $stub->cut += 3; + + return self::castError($c, $a); + } + + $a += [ + Caster::PREFIX_VIRTUAL.'attributes' => new EnumStub( + [ + 'PARSE_INT_ONLY' => $c->getAttribute(\NumberFormatter::PARSE_INT_ONLY), + 'GROUPING_USED' => $c->getAttribute(\NumberFormatter::GROUPING_USED), + 'DECIMAL_ALWAYS_SHOWN' => $c->getAttribute(\NumberFormatter::DECIMAL_ALWAYS_SHOWN), + 'MAX_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_INTEGER_DIGITS), + 'MIN_INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_INTEGER_DIGITS), + 'INTEGER_DIGITS' => $c->getAttribute(\NumberFormatter::INTEGER_DIGITS), + 'MAX_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_FRACTION_DIGITS), + 'MIN_FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_FRACTION_DIGITS), + 'FRACTION_DIGITS' => $c->getAttribute(\NumberFormatter::FRACTION_DIGITS), + 'MULTIPLIER' => $c->getAttribute(\NumberFormatter::MULTIPLIER), + 'GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::GROUPING_SIZE), + 'ROUNDING_MODE' => $c->getAttribute(\NumberFormatter::ROUNDING_MODE), + 'ROUNDING_INCREMENT' => $c->getAttribute(\NumberFormatter::ROUNDING_INCREMENT), + 'FORMAT_WIDTH' => $c->getAttribute(\NumberFormatter::FORMAT_WIDTH), + 'PADDING_POSITION' => $c->getAttribute(\NumberFormatter::PADDING_POSITION), + 'SECONDARY_GROUPING_SIZE' => $c->getAttribute(\NumberFormatter::SECONDARY_GROUPING_SIZE), + 'SIGNIFICANT_DIGITS_USED' => $c->getAttribute(\NumberFormatter::SIGNIFICANT_DIGITS_USED), + 'MIN_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MIN_SIGNIFICANT_DIGITS), + 'MAX_SIGNIFICANT_DIGITS' => $c->getAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS), + 'LENIENT_PARSE' => $c->getAttribute(\NumberFormatter::LENIENT_PARSE), + ] + ), + Caster::PREFIX_VIRTUAL.'text_attributes' => new EnumStub( + [ + 'POSITIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_PREFIX), + 'POSITIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::POSITIVE_SUFFIX), + 'NEGATIVE_PREFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_PREFIX), + 'NEGATIVE_SUFFIX' => $c->getTextAttribute(\NumberFormatter::NEGATIVE_SUFFIX), + 'PADDING_CHARACTER' => $c->getTextAttribute(\NumberFormatter::PADDING_CHARACTER), + 'CURRENCY_CODE' => $c->getTextAttribute(\NumberFormatter::CURRENCY_CODE), + 'DEFAULT_RULESET' => $c->getTextAttribute(\NumberFormatter::DEFAULT_RULESET), + 'PUBLIC_RULESETS' => $c->getTextAttribute(\NumberFormatter::PUBLIC_RULESETS), + ] + ), + Caster::PREFIX_VIRTUAL.'symbols' => new EnumStub( + [ + 'DECIMAL_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL), + 'GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL), + 'PATTERN_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::PATTERN_SEPARATOR_SYMBOL), + 'PERCENT_SYMBOL' => $c->getSymbol(\NumberFormatter::PERCENT_SYMBOL), + 'ZERO_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::ZERO_DIGIT_SYMBOL), + 'DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::DIGIT_SYMBOL), + 'MINUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::MINUS_SIGN_SYMBOL), + 'PLUS_SIGN_SYMBOL' => $c->getSymbol(\NumberFormatter::PLUS_SIGN_SYMBOL), + 'CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::CURRENCY_SYMBOL), + 'INTL_CURRENCY_SYMBOL' => $c->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL), + 'MONETARY_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL), + 'EXPONENTIAL_SYMBOL' => $c->getSymbol(\NumberFormatter::EXPONENTIAL_SYMBOL), + 'PERMILL_SYMBOL' => $c->getSymbol(\NumberFormatter::PERMILL_SYMBOL), + 'PAD_ESCAPE_SYMBOL' => $c->getSymbol(\NumberFormatter::PAD_ESCAPE_SYMBOL), + 'INFINITY_SYMBOL' => $c->getSymbol(\NumberFormatter::INFINITY_SYMBOL), + 'NAN_SYMBOL' => $c->getSymbol(\NumberFormatter::NAN_SYMBOL), + 'SIGNIFICANT_DIGIT_SYMBOL' => $c->getSymbol(\NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL), + 'MONETARY_GROUPING_SEPARATOR_SYMBOL' => $c->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL), + ] + ), + ]; + + return self::castError($c, $a); + } + + public static function castIntlTimeZone(\IntlTimeZone $c, array $a, Stub $stub, $isNested) + { + $a += [ + Caster::PREFIX_VIRTUAL.'display_name' => $c->getDisplayName(), + Caster::PREFIX_VIRTUAL.'id' => $c->getID(), + Caster::PREFIX_VIRTUAL.'raw_offset' => $c->getRawOffset(), + ]; + + if ($c->useDaylightTime()) { + $a += [ + Caster::PREFIX_VIRTUAL.'dst_savings' => $c->getDSTSavings(), + ]; + } + + return self::castError($c, $a); + } + + public static function castIntlCalendar(\IntlCalendar $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $a += [ + Caster::PREFIX_VIRTUAL.'type' => $c->getType(), + Caster::PREFIX_VIRTUAL.'first_day_of_week' => $c->getFirstDayOfWeek(), + Caster::PREFIX_VIRTUAL.'minimal_days_in_first_week' => $c->getMinimalDaysInFirstWeek(), + Caster::PREFIX_VIRTUAL.'repeated_wall_time_option' => $c->getRepeatedWallTimeOption(), + Caster::PREFIX_VIRTUAL.'skipped_wall_time_option' => $c->getSkippedWallTimeOption(), + Caster::PREFIX_VIRTUAL.'time' => $c->getTime(), + Caster::PREFIX_VIRTUAL.'in_daylight_time' => $c->inDaylightTime(), + Caster::PREFIX_VIRTUAL.'is_lenient' => $c->isLenient(), + Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(), + ]; + + return self::castError($c, $a); + } + + public static function castIntlDateFormatter(\IntlDateFormatter $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $a += [ + Caster::PREFIX_VIRTUAL.'locale' => $c->getLocale(), + Caster::PREFIX_VIRTUAL.'pattern' => $c->getPattern(), + Caster::PREFIX_VIRTUAL.'calendar' => $c->getCalendar(), + Caster::PREFIX_VIRTUAL.'time_zone_id' => $c->getTimeZoneId(), + Caster::PREFIX_VIRTUAL.'time_type' => $c->getTimeType(), + Caster::PREFIX_VIRTUAL.'date_type' => $c->getDateType(), + Caster::PREFIX_VIRTUAL.'calendar_object' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getCalendarObject()) : $c->getCalendarObject(), + Caster::PREFIX_VIRTUAL.'time_zone' => ($filter & Caster::EXCLUDE_VERBOSE) ? new CutStub($c->getTimeZone()) : $c->getTimeZone(), + ]; + + return self::castError($c, $a); + } + + private static function castError($c, array $a): array + { + if ($errorCode = $c->getErrorCode()) { + $a += [ + Caster::PREFIX_VIRTUAL.'error_code' => $errorCode, + Caster::PREFIX_VIRTUAL.'error_message' => $c->getErrorMessage(), + ]; + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/LinkStub.php b/vendor/symfony/var-dumper/Caster/LinkStub.php new file mode 100644 index 0000000..d18b359 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/LinkStub.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +/** + * Represents a file or a URL. + * + * @author Nicolas Grekas + */ +class LinkStub extends ConstStub +{ + public $inVendor = false; + + private static $vendorRoots; + private static $composerRoots; + + public function __construct($label, int $line = 0, $href = null) + { + $this->value = $label; + + if (null === $href) { + $href = $label; + } + if (!\is_string($href)) { + return; + } + if (0 === strpos($href, 'file://')) { + if ($href === $label) { + $label = substr($label, 7); + } + $href = substr($href, 7); + } elseif (false !== strpos($href, '://')) { + $this->attr['href'] = $href; + + return; + } + if (!file_exists($href)) { + return; + } + if ($line) { + $this->attr['line'] = $line; + } + if ($label !== $this->attr['file'] = realpath($href) ?: $href) { + return; + } + if ($composerRoot = $this->getComposerRoot($href, $this->inVendor)) { + $this->attr['ellipsis'] = \strlen($href) - \strlen($composerRoot) + 1; + $this->attr['ellipsis-type'] = 'path'; + $this->attr['ellipsis-tail'] = 1 + ($this->inVendor ? 2 + \strlen(implode('', \array_slice(explode(\DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0); + } elseif (3 < \count($ellipsis = explode(\DIRECTORY_SEPARATOR, $href))) { + $this->attr['ellipsis'] = 2 + \strlen(implode('', \array_slice($ellipsis, -2))); + $this->attr['ellipsis-type'] = 'path'; + $this->attr['ellipsis-tail'] = 1; + } + } + + private function getComposerRoot($file, &$inVendor) + { + if (null === self::$vendorRoots) { + self::$vendorRoots = []; + + foreach (get_declared_classes() as $class) { + if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { + $r = new \ReflectionClass($class); + $v = \dirname($r->getFileName(), 2); + if (file_exists($v.'/composer/installed.json')) { + self::$vendorRoots[] = $v.\DIRECTORY_SEPARATOR; + } + } + } + } + $inVendor = false; + + if (isset(self::$composerRoots[$dir = \dirname($file)])) { + return self::$composerRoots[$dir]; + } + + foreach (self::$vendorRoots as $root) { + if ($inVendor = 0 === strpos($file, $root)) { + return $root; + } + } + + $parent = $dir; + while (!@file_exists($parent.'/composer.json')) { + if (!@file_exists($parent)) { + // open_basedir restriction in effect + break; + } + if ($parent === \dirname($parent)) { + return self::$composerRoots[$dir] = false; + } + + $parent = \dirname($parent); + } + + return self::$composerRoots[$dir] = $parent.\DIRECTORY_SEPARATOR; + } +} diff --git a/vendor/symfony/var-dumper/Caster/MemcachedCaster.php b/vendor/symfony/var-dumper/Caster/MemcachedCaster.php new file mode 100644 index 0000000..a326546 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/MemcachedCaster.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * @author Jan Schädlich + */ +class MemcachedCaster +{ + private static $optionConstants; + private static $defaultOptions; + + public static function castMemcached(\Memcached $c, array $a, Stub $stub, $isNested) + { + $a += [ + Caster::PREFIX_VIRTUAL.'servers' => $c->getServerList(), + Caster::PREFIX_VIRTUAL.'options' => new EnumStub( + self::getNonDefaultOptions($c) + ), + ]; + + return $a; + } + + private static function getNonDefaultOptions(\Memcached $c) + { + self::$defaultOptions = self::$defaultOptions ?? self::discoverDefaultOptions(); + self::$optionConstants = self::$optionConstants ?? self::getOptionConstants(); + + $nonDefaultOptions = []; + foreach (self::$optionConstants as $constantKey => $value) { + if (self::$defaultOptions[$constantKey] !== $option = $c->getOption($value)) { + $nonDefaultOptions[$constantKey] = $option; + } + } + + return $nonDefaultOptions; + } + + private static function discoverDefaultOptions() + { + $defaultMemcached = new \Memcached(); + $defaultMemcached->addServer('127.0.0.1', 11211); + + $defaultOptions = []; + self::$optionConstants = self::$optionConstants ?? self::getOptionConstants(); + + foreach (self::$optionConstants as $constantKey => $value) { + $defaultOptions[$constantKey] = $defaultMemcached->getOption($value); + } + + return $defaultOptions; + } + + private static function getOptionConstants() + { + $reflectedMemcached = new \ReflectionClass(\Memcached::class); + + $optionConstants = []; + foreach ($reflectedMemcached->getConstants() as $constantKey => $value) { + if (0 === strpos($constantKey, 'OPT_')) { + $optionConstants[$constantKey] = $value; + } + } + + return $optionConstants; + } +} diff --git a/vendor/symfony/var-dumper/Caster/PdoCaster.php b/vendor/symfony/var-dumper/Caster/PdoCaster.php new file mode 100644 index 0000000..8af5182 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/PdoCaster.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts PDO related classes to array representation. + * + * @author Nicolas Grekas + */ +class PdoCaster +{ + private static $pdoAttributes = [ + 'CASE' => [ + \PDO::CASE_LOWER => 'LOWER', + \PDO::CASE_NATURAL => 'NATURAL', + \PDO::CASE_UPPER => 'UPPER', + ], + 'ERRMODE' => [ + \PDO::ERRMODE_SILENT => 'SILENT', + \PDO::ERRMODE_WARNING => 'WARNING', + \PDO::ERRMODE_EXCEPTION => 'EXCEPTION', + ], + 'TIMEOUT', + 'PREFETCH', + 'AUTOCOMMIT', + 'PERSISTENT', + 'DRIVER_NAME', + 'SERVER_INFO', + 'ORACLE_NULLS' => [ + \PDO::NULL_NATURAL => 'NATURAL', + \PDO::NULL_EMPTY_STRING => 'EMPTY_STRING', + \PDO::NULL_TO_STRING => 'TO_STRING', + ], + 'CLIENT_VERSION', + 'SERVER_VERSION', + 'STATEMENT_CLASS', + 'EMULATE_PREPARES', + 'CONNECTION_STATUS', + 'STRINGIFY_FETCHES', + 'DEFAULT_FETCH_MODE' => [ + \PDO::FETCH_ASSOC => 'ASSOC', + \PDO::FETCH_BOTH => 'BOTH', + \PDO::FETCH_LAZY => 'LAZY', + \PDO::FETCH_NUM => 'NUM', + \PDO::FETCH_OBJ => 'OBJ', + ], + ]; + + public static function castPdo(\PDO $c, array $a, Stub $stub, $isNested) + { + $attr = []; + $errmode = $c->getAttribute(\PDO::ATTR_ERRMODE); + $c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + + foreach (self::$pdoAttributes as $k => $v) { + if (!isset($k[0])) { + $k = $v; + $v = []; + } + + try { + $attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(\constant('PDO::ATTR_'.$k)); + if ($v && isset($v[$attr[$k]])) { + $attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]); + } + } catch (\Exception $e) { + } + } + if (isset($attr[$k = 'STATEMENT_CLASS'][1])) { + if ($attr[$k][1]) { + $attr[$k][1] = new ArgsStub($attr[$k][1], '__construct', $attr[$k][0]); + } + $attr[$k][0] = new ClassStub($attr[$k][0]); + } + + $prefix = Caster::PREFIX_VIRTUAL; + $a += [ + $prefix.'inTransaction' => method_exists($c, 'inTransaction'), + $prefix.'errorInfo' => $c->errorInfo(), + $prefix.'attributes' => new EnumStub($attr), + ]; + + if ($a[$prefix.'inTransaction']) { + $a[$prefix.'inTransaction'] = $c->inTransaction(); + } else { + unset($a[$prefix.'inTransaction']); + } + + if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { + unset($a[$prefix.'errorInfo']); + } + + $c->setAttribute(\PDO::ATTR_ERRMODE, $errmode); + + return $a; + } + + public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $a[$prefix.'errorInfo'] = $c->errorInfo(); + + if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { + unset($a[$prefix.'errorInfo']); + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/PgSqlCaster.php b/vendor/symfony/var-dumper/Caster/PgSqlCaster.php new file mode 100644 index 0000000..cd6bf5b --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/PgSqlCaster.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts pqsql resources to array representation. + * + * @author Nicolas Grekas + */ +class PgSqlCaster +{ + private static $paramCodes = [ + 'server_encoding', + 'client_encoding', + 'is_superuser', + 'session_authorization', + 'DateStyle', + 'TimeZone', + 'IntervalStyle', + 'integer_datetimes', + 'application_name', + 'standard_conforming_strings', + ]; + + private static $transactionStatus = [ + PGSQL_TRANSACTION_IDLE => 'PGSQL_TRANSACTION_IDLE', + PGSQL_TRANSACTION_ACTIVE => 'PGSQL_TRANSACTION_ACTIVE', + PGSQL_TRANSACTION_INTRANS => 'PGSQL_TRANSACTION_INTRANS', + PGSQL_TRANSACTION_INERROR => 'PGSQL_TRANSACTION_INERROR', + PGSQL_TRANSACTION_UNKNOWN => 'PGSQL_TRANSACTION_UNKNOWN', + ]; + + private static $resultStatus = [ + PGSQL_EMPTY_QUERY => 'PGSQL_EMPTY_QUERY', + PGSQL_COMMAND_OK => 'PGSQL_COMMAND_OK', + PGSQL_TUPLES_OK => 'PGSQL_TUPLES_OK', + PGSQL_COPY_OUT => 'PGSQL_COPY_OUT', + PGSQL_COPY_IN => 'PGSQL_COPY_IN', + PGSQL_BAD_RESPONSE => 'PGSQL_BAD_RESPONSE', + PGSQL_NONFATAL_ERROR => 'PGSQL_NONFATAL_ERROR', + PGSQL_FATAL_ERROR => 'PGSQL_FATAL_ERROR', + ]; + + private static $diagCodes = [ + 'severity' => PGSQL_DIAG_SEVERITY, + 'sqlstate' => PGSQL_DIAG_SQLSTATE, + 'message' => PGSQL_DIAG_MESSAGE_PRIMARY, + 'detail' => PGSQL_DIAG_MESSAGE_DETAIL, + 'hint' => PGSQL_DIAG_MESSAGE_HINT, + 'statement position' => PGSQL_DIAG_STATEMENT_POSITION, + 'internal position' => PGSQL_DIAG_INTERNAL_POSITION, + 'internal query' => PGSQL_DIAG_INTERNAL_QUERY, + 'context' => PGSQL_DIAG_CONTEXT, + 'file' => PGSQL_DIAG_SOURCE_FILE, + 'line' => PGSQL_DIAG_SOURCE_LINE, + 'function' => PGSQL_DIAG_SOURCE_FUNCTION, + ]; + + public static function castLargeObject($lo, array $a, Stub $stub, $isNested) + { + $a['seek position'] = pg_lo_tell($lo); + + return $a; + } + + public static function castLink($link, array $a, Stub $stub, $isNested) + { + $a['status'] = pg_connection_status($link); + $a['status'] = new ConstStub(PGSQL_CONNECTION_OK === $a['status'] ? 'PGSQL_CONNECTION_OK' : 'PGSQL_CONNECTION_BAD', $a['status']); + $a['busy'] = pg_connection_busy($link); + + $a['transaction'] = pg_transaction_status($link); + if (isset(self::$transactionStatus[$a['transaction']])) { + $a['transaction'] = new ConstStub(self::$transactionStatus[$a['transaction']], $a['transaction']); + } + + $a['pid'] = pg_get_pid($link); + $a['last error'] = pg_last_error($link); + $a['last notice'] = pg_last_notice($link); + $a['host'] = pg_host($link); + $a['port'] = pg_port($link); + $a['dbname'] = pg_dbname($link); + $a['options'] = pg_options($link); + $a['version'] = pg_version($link); + + foreach (self::$paramCodes as $v) { + if (false !== $s = pg_parameter_status($link, $v)) { + $a['param'][$v] = $s; + } + } + + $a['param']['client_encoding'] = pg_client_encoding($link); + $a['param'] = new EnumStub($a['param']); + + return $a; + } + + public static function castResult($result, array $a, Stub $stub, $isNested) + { + $a['num rows'] = pg_num_rows($result); + $a['status'] = pg_result_status($result); + if (isset(self::$resultStatus[$a['status']])) { + $a['status'] = new ConstStub(self::$resultStatus[$a['status']], $a['status']); + } + $a['command-completion tag'] = pg_result_status($result, PGSQL_STATUS_STRING); + + if (-1 === $a['num rows']) { + foreach (self::$diagCodes as $k => $v) { + $a['error'][$k] = pg_result_error_field($result, $v); + } + } + + $a['affected rows'] = pg_affected_rows($result); + $a['last OID'] = pg_last_oid($result); + + $fields = pg_num_fields($result); + + for ($i = 0; $i < $fields; ++$i) { + $field = [ + 'name' => pg_field_name($result, $i), + 'table' => sprintf('%s (OID: %s)', pg_field_table($result, $i), pg_field_table($result, $i, true)), + 'type' => sprintf('%s (OID: %s)', pg_field_type($result, $i), pg_field_type_oid($result, $i)), + 'nullable' => (bool) pg_field_is_null($result, $i), + 'storage' => pg_field_size($result, $i).' bytes', + 'display' => pg_field_prtlen($result, $i).' chars', + ]; + if (' (OID: )' === $field['table']) { + $field['table'] = null; + } + if ('-1 bytes' === $field['storage']) { + $field['storage'] = 'variable size'; + } elseif ('1 bytes' === $field['storage']) { + $field['storage'] = '1 byte'; + } + if ('1 chars' === $field['display']) { + $field['display'] = '1 char'; + } + $a['fields'][] = new EnumStub($field); + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php b/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php new file mode 100644 index 0000000..d8afd70 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use ProxyManager\Proxy\ProxyInterface; +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * @author Nicolas Grekas + */ +class ProxyManagerCaster +{ + public static function castProxy(ProxyInterface $c, array $a, Stub $stub, $isNested) + { + if ($parent = get_parent_class($c)) { + $stub->class .= ' - '.$parent; + } + $stub->class .= '@proxy'; + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/RedisCaster.php b/vendor/symfony/var-dumper/Caster/RedisCaster.php new file mode 100644 index 0000000..558a080 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/RedisCaster.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts Redis class from ext-redis to array representation. + * + * @author Nicolas Grekas + */ +class RedisCaster +{ + private static $serializer = [ + \Redis::SERIALIZER_NONE => 'NONE', + \Redis::SERIALIZER_PHP => 'PHP', + 2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY + ]; + + private static $mode = [ + \Redis::ATOMIC => 'ATOMIC', + \Redis::MULTI => 'MULTI', + \Redis::PIPELINE => 'PIPELINE', + ]; + + private static $compression = [ + 0 => 'NONE', // Redis::COMPRESSION_NONE + 1 => 'LZF', // Redis::COMPRESSION_LZF + ]; + + private static $failover = [ + \RedisCluster::FAILOVER_NONE => 'NONE', + \RedisCluster::FAILOVER_ERROR => 'ERROR', + \RedisCluster::FAILOVER_DISTRIBUTE => 'DISTRIBUTE', + \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES => 'DISTRIBUTE_SLAVES', + ]; + + public static function castRedis(\Redis $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + if (!$connected = $c->isConnected()) { + return $a + [ + $prefix.'isConnected' => $connected, + ]; + } + + $mode = $c->getMode(); + + return $a + [ + $prefix.'isConnected' => $connected, + $prefix.'host' => $c->getHost(), + $prefix.'port' => $c->getPort(), + $prefix.'auth' => $c->getAuth(), + $prefix.'mode' => isset(self::$mode[$mode]) ? new ConstStub(self::$mode[$mode], $mode) : $mode, + $prefix.'dbNum' => $c->getDbNum(), + $prefix.'timeout' => $c->getTimeout(), + $prefix.'lastError' => $c->getLastError(), + $prefix.'persistentId' => $c->getPersistentID(), + $prefix.'options' => self::getRedisOptions($c), + ]; + } + + public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + return $a + [ + $prefix.'hosts' => $c->_hosts(), + $prefix.'function' => ClassStub::wrapCallable($c->_function()), + $prefix.'lastError' => $c->getLastError(), + $prefix.'options' => self::getRedisOptions($c), + ]; + } + + public static function castRedisCluster(\RedisCluster $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $failover = $c->getOption(\RedisCluster::OPT_SLAVE_FAILOVER); + + $a += [ + $prefix.'_masters' => $c->_masters(), + $prefix.'_redir' => $c->_redir(), + $prefix.'mode' => new ConstStub($c->getMode() ? 'MULTI' : 'ATOMIC', $c->getMode()), + $prefix.'lastError' => $c->getLastError(), + $prefix.'options' => self::getRedisOptions($c, [ + 'SLAVE_FAILOVER' => isset(self::$failover[$failover]) ? new ConstStub(self::$failover[$failover], $failover) : $failover, + ]), + ]; + + return $a; + } + + /** + * @param \Redis|\RedisArray|\RedisCluster $redis + */ + private static function getRedisOptions($redis, array $options = []): EnumStub + { + $serializer = $redis->getOption(\Redis::OPT_SERIALIZER); + if (\is_array($serializer)) { + foreach ($serializer as &$v) { + if (isset(self::$serializer[$v])) { + $v = new ConstStub(self::$serializer[$v], $v); + } + } + } elseif (isset(self::$serializer[$serializer])) { + $serializer = new ConstStub(self::$serializer[$serializer], $serializer); + } + + $compression = \defined('Redis::OPT_COMPRESSION') ? $redis->getOption(\Redis::OPT_COMPRESSION) : 0; + if (\is_array($compression)) { + foreach ($compression as &$v) { + if (isset(self::$compression[$v])) { + $v = new ConstStub(self::$compression[$v], $v); + } + } + } elseif (isset(self::$compression[$compression])) { + $compression = new ConstStub(self::$compression[$compression], $compression); + } + + $retry = \defined('Redis::OPT_SCAN') ? $redis->getOption(\Redis::OPT_SCAN) : 0; + if (\is_array($retry)) { + foreach ($retry as &$v) { + $v = new ConstStub($v ? 'RETRY' : 'NORETRY', $v); + } + } else { + $retry = new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry); + } + + $options += [ + 'TCP_KEEPALIVE' => \defined('Redis::OPT_TCP_KEEPALIVE') ? $redis->getOption(\Redis::OPT_TCP_KEEPALIVE) : 0, + 'READ_TIMEOUT' => $redis->getOption(\Redis::OPT_READ_TIMEOUT), + 'COMPRESSION' => $compression, + 'SERIALIZER' => $serializer, + 'PREFIX' => $redis->getOption(\Redis::OPT_PREFIX), + 'SCAN' => $retry, + ]; + + return new EnumStub($options); + } +} diff --git a/vendor/symfony/var-dumper/Caster/ReflectionCaster.php b/vendor/symfony/var-dumper/Caster/ReflectionCaster.php new file mode 100644 index 0000000..8dfe7ea --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ReflectionCaster.php @@ -0,0 +1,388 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts Reflector related classes to array representation. + * + * @author Nicolas Grekas + */ +class ReflectionCaster +{ + const UNSET_CLOSURE_FILE_INFO = ['Closure' => __CLASS__.'::unsetClosureFileInfo']; + + private static $extraMap = [ + 'docComment' => 'getDocComment', + 'extension' => 'getExtensionName', + 'isDisabled' => 'isDisabled', + 'isDeprecated' => 'isDeprecated', + 'isInternal' => 'isInternal', + 'isUserDefined' => 'isUserDefined', + 'isGenerator' => 'isGenerator', + 'isVariadic' => 'isVariadic', + ]; + + public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $prefix = Caster::PREFIX_VIRTUAL; + $c = new \ReflectionFunction($c); + + $a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter); + + if (false === strpos($c->name, '{closure}')) { + $stub->class = isset($a[$prefix.'class']) ? $a[$prefix.'class']->value.'::'.$c->name : $c->name; + unset($a[$prefix.'class']); + } + unset($a[$prefix.'extra']); + + $stub->class .= self::getSignature($a); + + if ($f = $c->getFileName()) { + $stub->attr['file'] = $f; + $stub->attr['line'] = $c->getStartLine(); + } + + unset($a[$prefix.'parameters']); + + if ($filter & Caster::EXCLUDE_VERBOSE) { + $stub->cut += ($c->getFileName() ? 2 : 0) + \count($a); + + return []; + } + + if ($f) { + $a[$prefix.'file'] = new LinkStub($f, $c->getStartLine()); + $a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine(); + } + + return $a; + } + + public static function unsetClosureFileInfo(\Closure $c, array $a) + { + unset($a[Caster::PREFIX_VIRTUAL.'file'], $a[Caster::PREFIX_VIRTUAL.'line']); + + return $a; + } + + public static function castGenerator(\Generator $c, array $a, Stub $stub, $isNested) + { + if (!class_exists('ReflectionGenerator', false)) { + return $a; + } + + // Cannot create ReflectionGenerator based on a terminated Generator + try { + $reflectionGenerator = new \ReflectionGenerator($c); + } catch (\Exception $e) { + $a[Caster::PREFIX_VIRTUAL.'closed'] = true; + + return $a; + } + + return self::castReflectionGenerator($reflectionGenerator, $a, $stub, $isNested); + } + + public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + $a += [ + $prefix.'name' => $c->getName(), + $prefix.'allowsNull' => $c->allowsNull(), + $prefix.'isBuiltin' => $c->isBuiltin(), + ]; + + return $a; + } + + public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + if ($c->getThis()) { + $a[$prefix.'this'] = new CutStub($c->getThis()); + } + $function = $c->getFunction(); + $frame = [ + 'class' => isset($function->class) ? $function->class : null, + 'type' => isset($function->class) ? ($function->isStatic() ? '::' : '->') : null, + 'function' => $function->name, + 'file' => $c->getExecutingFile(), + 'line' => $c->getExecutingLine(), + ]; + if ($trace = $c->getTrace(DEBUG_BACKTRACE_IGNORE_ARGS)) { + $function = new \ReflectionGenerator($c->getExecutingGenerator()); + array_unshift($trace, [ + 'function' => 'yield', + 'file' => $function->getExecutingFile(), + 'line' => $function->getExecutingLine() - 1, + ]); + $trace[] = $frame; + $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1); + } else { + $function = new FrameStub($frame, false, true); + $function = ExceptionCaster::castFrameStub($function, [], $function, true); + $a[$prefix.'executing'] = new EnumStub([ + "\0~separator= \0".$frame['class'].$frame['type'].$frame['function'].'()' => $function[$prefix.'src'], + ]); + } + + $a[Caster::PREFIX_VIRTUAL.'closed'] = false; + + return $a; + } + + public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $prefix = Caster::PREFIX_VIRTUAL; + + if ($n = \Reflection::getModifierNames($c->getModifiers())) { + $a[$prefix.'modifiers'] = implode(' ', $n); + } + + self::addMap($a, $c, [ + 'extends' => 'getParentClass', + 'implements' => 'getInterfaceNames', + 'constants' => 'getConstants', + ]); + + foreach ($c->getProperties() as $n) { + $a[$prefix.'properties'][$n->name] = $n; + } + + foreach ($c->getMethods() as $n) { + $a[$prefix.'methods'][$n->name] = $n; + } + + if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { + self::addExtra($a, $c); + } + + return $a; + } + + public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $prefix = Caster::PREFIX_VIRTUAL; + + self::addMap($a, $c, [ + 'returnsReference' => 'returnsReference', + 'returnType' => 'getReturnType', + 'class' => 'getClosureScopeClass', + 'this' => 'getClosureThis', + ]); + + if (isset($a[$prefix.'returnType'])) { + $v = $a[$prefix.'returnType']; + $v = $v->getName(); + $a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType']->allowsNull() ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']); + } + if (isset($a[$prefix.'class'])) { + $a[$prefix.'class'] = new ClassStub($a[$prefix.'class']); + } + if (isset($a[$prefix.'this'])) { + $a[$prefix.'this'] = new CutStub($a[$prefix.'this']); + } + + foreach ($c->getParameters() as $v) { + $k = '$'.$v->name; + if ($v->isVariadic()) { + $k = '...'.$k; + } + if ($v->isPassedByReference()) { + $k = '&'.$k; + } + $a[$prefix.'parameters'][$k] = $v; + } + if (isset($a[$prefix.'parameters'])) { + $a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']); + } + + if ($v = $c->getStaticVariables()) { + foreach ($v as $k => &$v) { + if (\is_object($v)) { + $a[$prefix.'use']['$'.$k] = new CutStub($v); + } else { + $a[$prefix.'use']['$'.$k] = &$v; + } + } + unset($v); + $a[$prefix.'use'] = new EnumStub($a[$prefix.'use']); + } + + if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { + self::addExtra($a, $c); + } + + return $a; + } + + public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); + + return $a; + } + + public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + self::addMap($a, $c, [ + 'position' => 'getPosition', + 'isVariadic' => 'isVariadic', + 'byReference' => 'isPassedByReference', + 'allowsNull' => 'allowsNull', + ]); + + if ($v = $c->getType()) { + $a[$prefix.'typeHint'] = $v->getName(); + } + + if (isset($a[$prefix.'typeHint'])) { + $v = $a[$prefix.'typeHint']; + $a[$prefix.'typeHint'] = new ClassStub($v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']); + } else { + unset($a[$prefix.'allowsNull']); + } + + try { + $a[$prefix.'default'] = $v = $c->getDefaultValue(); + if ($c->isDefaultValueConstant()) { + $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v); + } + if (null === $v) { + unset($a[$prefix.'allowsNull']); + } + } catch (\ReflectionException $e) { + } + + return $a; + } + + public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); + self::addExtra($a, $c); + + return $a; + } + + public static function castReference(\ReflectionReference $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'id'] = $c->getId(); + + return $a; + } + + public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, $isNested) + { + self::addMap($a, $c, [ + 'version' => 'getVersion', + 'dependencies' => 'getDependencies', + 'iniEntries' => 'getIniEntries', + 'isPersistent' => 'isPersistent', + 'isTemporary' => 'isTemporary', + 'constants' => 'getConstants', + 'functions' => 'getFunctions', + 'classes' => 'getClasses', + ]); + + return $a; + } + + public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, $isNested) + { + self::addMap($a, $c, [ + 'version' => 'getVersion', + 'author' => 'getAuthor', + 'copyright' => 'getCopyright', + 'url' => 'getURL', + ]); + + return $a; + } + + public static function getSignature(array $a) + { + $prefix = Caster::PREFIX_VIRTUAL; + $signature = ''; + + if (isset($a[$prefix.'parameters'])) { + foreach ($a[$prefix.'parameters']->value as $k => $param) { + $signature .= ', '; + if ($type = $param->getType()) { + if (!$param->isOptional() && $param->allowsNull()) { + $signature .= '?'; + } + $signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' '; + } + $signature .= $k; + + if (!$param->isDefaultValueAvailable()) { + continue; + } + $v = $param->getDefaultValue(); + $signature .= ' = '; + + if ($param->isDefaultValueConstant()) { + $signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1); + } elseif (null === $v) { + $signature .= 'null'; + } elseif (\is_array($v)) { + $signature .= $v ? '[…'.\count($v).']' : '[]'; + } elseif (\is_string($v)) { + $signature .= 10 > \strlen($v) && false === strpos($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'"; + } elseif (\is_bool($v)) { + $signature .= $v ? 'true' : 'false'; + } else { + $signature .= $v; + } + } + } + $signature = (empty($a[$prefix.'returnsReference']) ? '' : '&').'('.substr($signature, 2).')'; + + if (isset($a[$prefix.'returnType'])) { + $signature .= ': '.substr(strrchr('\\'.$a[$prefix.'returnType'], '\\'), 1); + } + + return $signature; + } + + private static function addExtra(&$a, \Reflector $c) + { + $x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : []; + + if (method_exists($c, 'getFileName') && $m = $c->getFileName()) { + $x['file'] = new LinkStub($m, $c->getStartLine()); + $x['line'] = $c->getStartLine().' to '.$c->getEndLine(); + } + + self::addMap($x, $c, self::$extraMap, ''); + + if ($x) { + $a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x); + } + } + + private static function addMap(&$a, \Reflector $c, $map, $prefix = Caster::PREFIX_VIRTUAL) + { + foreach ($map as $k => $m) { + if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) { + $a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m; + } + } + } +} diff --git a/vendor/symfony/var-dumper/Caster/ResourceCaster.php b/vendor/symfony/var-dumper/Caster/ResourceCaster.php new file mode 100644 index 0000000..5d9b80d --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ResourceCaster.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts common resource types to array representation. + * + * @author Nicolas Grekas + */ +class ResourceCaster +{ + public static function castCurl($h, array $a, Stub $stub, $isNested) + { + return curl_getinfo($h); + } + + public static function castDba($dba, array $a, Stub $stub, $isNested) + { + $list = dba_list(); + $a['file'] = $list[(int) $dba]; + + return $a; + } + + public static function castProcess($process, array $a, Stub $stub, $isNested) + { + return proc_get_status($process); + } + + public static function castStream($stream, array $a, Stub $stub, $isNested) + { + $a = stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested); + if (isset($a['uri'])) { + $a['uri'] = new LinkStub($a['uri']); + } + + return $a; + } + + public static function castStreamContext($stream, array $a, Stub $stub, $isNested) + { + return @stream_context_get_params($stream) ?: $a; + } + + public static function castGd($gd, array $a, Stub $stub, $isNested) + { + $a['size'] = imagesx($gd).'x'.imagesy($gd); + $a['trueColor'] = imageistruecolor($gd); + + return $a; + } + + public static function castMysqlLink($h, array $a, Stub $stub, $isNested) + { + $a['host'] = mysql_get_host_info($h); + $a['protocol'] = mysql_get_proto_info($h); + $a['server'] = mysql_get_server_info($h); + + return $a; + } + + public static function castOpensslX509($h, array $a, Stub $stub, $isNested) + { + $stub->cut = -1; + $info = openssl_x509_parse($h, false); + + $pin = openssl_pkey_get_public($h); + $pin = openssl_pkey_get_details($pin)['key']; + $pin = \array_slice(explode("\n", $pin), 1, -2); + $pin = base64_decode(implode('', $pin)); + $pin = base64_encode(hash('sha256', $pin, true)); + + $a += [ + 'subject' => new EnumStub(array_intersect_key($info['subject'], ['organizationName' => true, 'commonName' => true])), + 'issuer' => new EnumStub(array_intersect_key($info['issuer'], ['organizationName' => true, 'commonName' => true])), + 'expiry' => new ConstStub(date(\DateTime::ISO8601, $info['validTo_time_t']), $info['validTo_time_t']), + 'fingerprint' => new EnumStub([ + 'md5' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'md5')), 2, ':', true)), + 'sha1' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha1')), 2, ':', true)), + 'sha256' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha256')), 2, ':', true)), + 'pin-sha256' => new ConstStub($pin), + ]), + ]; + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/SplCaster.php b/vendor/symfony/var-dumper/Caster/SplCaster.php new file mode 100644 index 0000000..c6d360e --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/SplCaster.php @@ -0,0 +1,226 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts SPL related classes to array representation. + * + * @author Nicolas Grekas + */ +class SplCaster +{ + private static $splFileObjectFlags = [ + \SplFileObject::DROP_NEW_LINE => 'DROP_NEW_LINE', + \SplFileObject::READ_AHEAD => 'READ_AHEAD', + \SplFileObject::SKIP_EMPTY => 'SKIP_EMPTY', + \SplFileObject::READ_CSV => 'READ_CSV', + ]; + + public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, $isNested) + { + return self::castSplArray($c, $a, $stub, $isNested); + } + + public static function castArrayIterator(\ArrayIterator $c, array $a, Stub $stub, $isNested) + { + return self::castSplArray($c, $a, $stub, $isNested); + } + + public static function castHeap(\Iterator $c, array $a, Stub $stub, $isNested) + { + $a += [ + Caster::PREFIX_VIRTUAL.'heap' => iterator_to_array(clone $c), + ]; + + return $a; + } + + public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $mode = $c->getIteratorMode(); + $c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE); + + $a += [ + $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode), + $prefix.'dllist' => iterator_to_array($c), + ]; + $c->setIteratorMode($mode); + + return $a; + } + + public static function castFileInfo(\SplFileInfo $c, array $a, Stub $stub, $isNested) + { + static $map = [ + 'path' => 'getPath', + 'filename' => 'getFilename', + 'basename' => 'getBasename', + 'pathname' => 'getPathname', + 'extension' => 'getExtension', + 'realPath' => 'getRealPath', + 'aTime' => 'getATime', + 'mTime' => 'getMTime', + 'cTime' => 'getCTime', + 'inode' => 'getInode', + 'size' => 'getSize', + 'perms' => 'getPerms', + 'owner' => 'getOwner', + 'group' => 'getGroup', + 'type' => 'getType', + 'writable' => 'isWritable', + 'readable' => 'isReadable', + 'executable' => 'isExecutable', + 'file' => 'isFile', + 'dir' => 'isDir', + 'link' => 'isLink', + 'linkTarget' => 'getLinkTarget', + ]; + + $prefix = Caster::PREFIX_VIRTUAL; + + if (false === $c->getPathname()) { + $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state'; + + return $a; + } + + foreach ($map as $key => $accessor) { + try { + $a[$prefix.$key] = $c->$accessor(); + } catch (\Exception $e) { + } + } + + if (isset($a[$prefix.'realPath'])) { + $a[$prefix.'realPath'] = new LinkStub($a[$prefix.'realPath']); + } + + if (isset($a[$prefix.'perms'])) { + $a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']); + } + + static $mapDate = ['aTime', 'mTime', 'cTime']; + foreach ($mapDate as $key) { + if (isset($a[$prefix.$key])) { + $a[$prefix.$key] = new ConstStub(date('Y-m-d H:i:s', $a[$prefix.$key]), $a[$prefix.$key]); + } + } + + return $a; + } + + public static function castFileObject(\SplFileObject $c, array $a, Stub $stub, $isNested) + { + static $map = [ + 'csvControl' => 'getCsvControl', + 'flags' => 'getFlags', + 'maxLineLen' => 'getMaxLineLen', + 'fstat' => 'fstat', + 'eof' => 'eof', + 'key' => 'key', + ]; + + $prefix = Caster::PREFIX_VIRTUAL; + + foreach ($map as $key => $accessor) { + try { + $a[$prefix.$key] = $c->$accessor(); + } catch (\Exception $e) { + } + } + + if (isset($a[$prefix.'flags'])) { + $flagsArray = []; + foreach (self::$splFileObjectFlags as $value => $name) { + if ($a[$prefix.'flags'] & $value) { + $flagsArray[] = $name; + } + } + $a[$prefix.'flags'] = new ConstStub(implode('|', $flagsArray), $a[$prefix.'flags']); + } + + if (isset($a[$prefix.'fstat'])) { + $a[$prefix.'fstat'] = new CutArrayStub($a[$prefix.'fstat'], ['dev', 'ino', 'nlink', 'rdev', 'blksize', 'blocks']); + } + + return $a; + } + + public static function castFixedArray(\SplFixedArray $c, array $a, Stub $stub, $isNested) + { + $a += [ + Caster::PREFIX_VIRTUAL.'storage' => $c->toArray(), + ]; + + return $a; + } + + public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, $isNested) + { + $storage = []; + unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967 + + $clone = clone $c; + foreach ($clone as $obj) { + $storage[] = [ + 'object' => $obj, + 'info' => $clone->getInfo(), + ]; + } + + $a += [ + Caster::PREFIX_VIRTUAL.'storage' => $storage, + ]; + + return $a; + } + + public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'innerIterator'] = $c->getInnerIterator(); + + return $a; + } + + public static function castWeakReference(\WeakReference $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'object'] = $c->get(); + + return $a; + } + + private static function castSplArray($c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $class = $stub->class; + $flags = $c->getFlags(); + + if (!($flags & \ArrayObject::STD_PROP_LIST)) { + $c->setFlags(\ArrayObject::STD_PROP_LIST); + $a = Caster::castObject($c, $class); + $c->setFlags($flags); + } + $a += [ + $prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST), + $prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS), + ]; + if ($c instanceof \ArrayObject) { + $a[$prefix.'iteratorClass'] = new ClassStub($c->getIteratorClass()); + } + $a[$prefix.'storage'] = $c->getArrayCopy(); + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/StubCaster.php b/vendor/symfony/var-dumper/Caster/StubCaster.php new file mode 100644 index 0000000..9927d42 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/StubCaster.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts a caster's Stub. + * + * @author Nicolas Grekas + */ +class StubCaster +{ + public static function castStub(Stub $c, array $a, Stub $stub, $isNested) + { + if ($isNested) { + $stub->type = $c->type; + $stub->class = $c->class; + $stub->value = $c->value; + $stub->handle = $c->handle; + $stub->cut = $c->cut; + $stub->attr = $c->attr; + + if (Stub::TYPE_REF === $c->type && !$c->class && \is_string($c->value) && !preg_match('//u', $c->value)) { + $stub->type = Stub::TYPE_STRING; + $stub->class = Stub::STRING_BINARY; + } + + $a = []; + } + + return $a; + } + + public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, $isNested) + { + return $isNested ? $c->preservedSubset : $a; + } + + public static function cutInternals($obj, array $a, Stub $stub, $isNested) + { + if ($isNested) { + $stub->cut += \count($a); + + return []; + } + + return $a; + } + + public static function castEnum(EnumStub $c, array $a, Stub $stub, $isNested) + { + if ($isNested) { + $stub->class = $c->dumpKeys ? '' : null; + $stub->handle = 0; + $stub->value = null; + $stub->cut = $c->cut; + $stub->attr = $c->attr; + + $a = []; + + if ($c->value) { + foreach (array_keys($c->value) as $k) { + $keys[] = !isset($k[0]) || "\0" !== $k[0] ? Caster::PREFIX_VIRTUAL.$k : $k; + } + // Preserve references with array_combine() + $a = array_combine($keys, $c->value); + } + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/SymfonyCaster.php b/vendor/symfony/var-dumper/Caster/SymfonyCaster.php new file mode 100644 index 0000000..78acb90 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/SymfonyCaster.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\VarDumper\Cloner\Stub; + +class SymfonyCaster +{ + private static $requestGetters = [ + 'pathInfo' => 'getPathInfo', + 'requestUri' => 'getRequestUri', + 'baseUrl' => 'getBaseUrl', + 'basePath' => 'getBasePath', + 'method' => 'getMethod', + 'format' => 'getRequestFormat', + ]; + + public static function castRequest(Request $request, array $a, Stub $stub, $isNested) + { + $clone = null; + + foreach (self::$requestGetters as $prop => $getter) { + if (null === $a[Caster::PREFIX_PROTECTED.$prop]) { + if (null === $clone) { + $clone = clone $request; + } + $a[Caster::PREFIX_VIRTUAL.$prop] = $clone->{$getter}(); + } + } + + return $a; + } + + public static function castHttpClient($client, array $a, Stub $stub, $isNested) + { + $multiKey = sprintf("\0%s\0multi", \get_class($client)); + $a[$multiKey] = new CutStub($a[$multiKey]); + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/TraceStub.php b/vendor/symfony/var-dumper/Caster/TraceStub.php new file mode 100644 index 0000000..5eea1c8 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/TraceStub.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents a backtrace as returned by debug_backtrace() or Exception->getTrace(). + * + * @author Nicolas Grekas + */ +class TraceStub extends Stub +{ + public $keepArgs; + public $sliceOffset; + public $sliceLength; + public $numberingOffset; + + public function __construct(array $trace, bool $keepArgs = true, int $sliceOffset = 0, int $sliceLength = null, int $numberingOffset = 0) + { + $this->value = $trace; + $this->keepArgs = $keepArgs; + $this->sliceOffset = $sliceOffset; + $this->sliceLength = $sliceLength; + $this->numberingOffset = $numberingOffset; + } +} diff --git a/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php b/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php new file mode 100644 index 0000000..3ae9ec0 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/XmlReaderCaster.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts XmlReader class to array representation. + * + * @author Baptiste Clavié + */ +class XmlReaderCaster +{ + private static $nodeTypes = [ + \XMLReader::NONE => 'NONE', + \XMLReader::ELEMENT => 'ELEMENT', + \XMLReader::ATTRIBUTE => 'ATTRIBUTE', + \XMLReader::TEXT => 'TEXT', + \XMLReader::CDATA => 'CDATA', + \XMLReader::ENTITY_REF => 'ENTITY_REF', + \XMLReader::ENTITY => 'ENTITY', + \XMLReader::PI => 'PI (Processing Instruction)', + \XMLReader::COMMENT => 'COMMENT', + \XMLReader::DOC => 'DOC', + \XMLReader::DOC_TYPE => 'DOC_TYPE', + \XMLReader::DOC_FRAGMENT => 'DOC_FRAGMENT', + \XMLReader::NOTATION => 'NOTATION', + \XMLReader::WHITESPACE => 'WHITESPACE', + \XMLReader::SIGNIFICANT_WHITESPACE => 'SIGNIFICANT_WHITESPACE', + \XMLReader::END_ELEMENT => 'END_ELEMENT', + \XMLReader::END_ENTITY => 'END_ENTITY', + \XMLReader::XML_DECLARATION => 'XML_DECLARATION', + ]; + + public static function castXmlReader(\XMLReader $reader, array $a, Stub $stub, $isNested) + { + $props = Caster::PREFIX_VIRTUAL.'parserProperties'; + $info = [ + 'localName' => $reader->localName, + 'prefix' => $reader->prefix, + 'nodeType' => new ConstStub(self::$nodeTypes[$reader->nodeType], $reader->nodeType), + 'depth' => $reader->depth, + 'isDefault' => $reader->isDefault, + 'isEmptyElement' => \XMLReader::NONE === $reader->nodeType ? null : $reader->isEmptyElement, + 'xmlLang' => $reader->xmlLang, + 'attributeCount' => $reader->attributeCount, + 'value' => $reader->value, + 'namespaceURI' => $reader->namespaceURI, + 'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI, + $props => [ + 'LOADDTD' => $reader->getParserProperty(\XMLReader::LOADDTD), + 'DEFAULTATTRS' => $reader->getParserProperty(\XMLReader::DEFAULTATTRS), + 'VALIDATE' => $reader->getParserProperty(\XMLReader::VALIDATE), + 'SUBST_ENTITIES' => $reader->getParserProperty(\XMLReader::SUBST_ENTITIES), + ], + ]; + + if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, [], $count)) { + $info[$props] = new EnumStub($info[$props]); + $info[$props]->cut = $count; + } + + $info = Caster::filter($info, Caster::EXCLUDE_EMPTY, [], $count); + // +2 because hasValue and hasAttributes are always filtered + $stub->cut += $count + 2; + + return $a + $info; + } +} diff --git a/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php b/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php new file mode 100644 index 0000000..117138c --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/XmlResourceCaster.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts XML resources to array representation. + * + * @author Nicolas Grekas + */ +class XmlResourceCaster +{ + private static $xmlErrors = [ + XML_ERROR_NONE => 'XML_ERROR_NONE', + XML_ERROR_NO_MEMORY => 'XML_ERROR_NO_MEMORY', + XML_ERROR_SYNTAX => 'XML_ERROR_SYNTAX', + XML_ERROR_NO_ELEMENTS => 'XML_ERROR_NO_ELEMENTS', + XML_ERROR_INVALID_TOKEN => 'XML_ERROR_INVALID_TOKEN', + XML_ERROR_UNCLOSED_TOKEN => 'XML_ERROR_UNCLOSED_TOKEN', + XML_ERROR_PARTIAL_CHAR => 'XML_ERROR_PARTIAL_CHAR', + XML_ERROR_TAG_MISMATCH => 'XML_ERROR_TAG_MISMATCH', + XML_ERROR_DUPLICATE_ATTRIBUTE => 'XML_ERROR_DUPLICATE_ATTRIBUTE', + XML_ERROR_JUNK_AFTER_DOC_ELEMENT => 'XML_ERROR_JUNK_AFTER_DOC_ELEMENT', + XML_ERROR_PARAM_ENTITY_REF => 'XML_ERROR_PARAM_ENTITY_REF', + XML_ERROR_UNDEFINED_ENTITY => 'XML_ERROR_UNDEFINED_ENTITY', + XML_ERROR_RECURSIVE_ENTITY_REF => 'XML_ERROR_RECURSIVE_ENTITY_REF', + XML_ERROR_ASYNC_ENTITY => 'XML_ERROR_ASYNC_ENTITY', + XML_ERROR_BAD_CHAR_REF => 'XML_ERROR_BAD_CHAR_REF', + XML_ERROR_BINARY_ENTITY_REF => 'XML_ERROR_BINARY_ENTITY_REF', + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF => 'XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF', + XML_ERROR_MISPLACED_XML_PI => 'XML_ERROR_MISPLACED_XML_PI', + XML_ERROR_UNKNOWN_ENCODING => 'XML_ERROR_UNKNOWN_ENCODING', + XML_ERROR_INCORRECT_ENCODING => 'XML_ERROR_INCORRECT_ENCODING', + XML_ERROR_UNCLOSED_CDATA_SECTION => 'XML_ERROR_UNCLOSED_CDATA_SECTION', + XML_ERROR_EXTERNAL_ENTITY_HANDLING => 'XML_ERROR_EXTERNAL_ENTITY_HANDLING', + ]; + + public static function castXml($h, array $a, Stub $stub, $isNested) + { + $a['current_byte_index'] = xml_get_current_byte_index($h); + $a['current_column_number'] = xml_get_current_column_number($h); + $a['current_line_number'] = xml_get_current_line_number($h); + $a['error_code'] = xml_get_error_code($h); + + if (isset(self::$xmlErrors[$a['error_code']])) { + $a['error_code'] = new ConstStub(self::$xmlErrors[$a['error_code']], $a['error_code']); + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Cloner/AbstractCloner.php b/vendor/symfony/var-dumper/Cloner/AbstractCloner.php new file mode 100644 index 0000000..79519a7 --- /dev/null +++ b/vendor/symfony/var-dumper/Cloner/AbstractCloner.php @@ -0,0 +1,362 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Cloner; + +use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Exception\ThrowingCasterException; + +/** + * AbstractCloner implements a generic caster mechanism for objects and resources. + * + * @author Nicolas Grekas + */ +abstract class AbstractCloner implements ClonerInterface +{ + public static $defaultCasters = [ + '__PHP_Incomplete_Class' => ['Symfony\Component\VarDumper\Caster\Caster', 'castPhpIncompleteClass'], + + 'Symfony\Component\VarDumper\Caster\CutStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'], + 'Symfony\Component\VarDumper\Caster\CutArrayStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castCutArray'], + 'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'], + 'Symfony\Component\VarDumper\Caster\EnumStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castEnum'], + + 'Closure' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClosure'], + 'Generator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castGenerator'], + 'ReflectionType' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castType'], + 'ReflectionGenerator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReflectionGenerator'], + 'ReflectionClass' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClass'], + 'ReflectionFunctionAbstract' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castFunctionAbstract'], + 'ReflectionMethod' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castMethod'], + 'ReflectionParameter' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castParameter'], + 'ReflectionProperty' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castProperty'], + 'ReflectionReference' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReference'], + 'ReflectionExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castExtension'], + 'ReflectionZendExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castZendExtension'], + + 'Doctrine\Common\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + 'Doctrine\Common\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castCommonProxy'], + 'Doctrine\ORM\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castOrmProxy'], + 'Doctrine\ORM\PersistentCollection' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castPersistentCollection'], + + 'DOMException' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castException'], + 'DOMStringList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], + 'DOMNameList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], + 'DOMImplementation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castImplementation'], + 'DOMImplementationList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], + 'DOMNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNode'], + 'DOMNameSpaceNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNameSpaceNode'], + 'DOMDocument' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocument'], + 'DOMNodeList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], + 'DOMNamedNodeMap' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'], + 'DOMCharacterData' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castCharacterData'], + 'DOMAttr' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castAttr'], + 'DOMElement' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castElement'], + 'DOMText' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castText'], + 'DOMTypeinfo' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castTypeinfo'], + 'DOMDomError' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDomError'], + 'DOMLocator' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLocator'], + 'DOMDocumentType' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocumentType'], + 'DOMNotation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNotation'], + 'DOMEntity' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castEntity'], + 'DOMProcessingInstruction' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castProcessingInstruction'], + 'DOMXPath' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castXPath'], + + 'XMLReader' => ['Symfony\Component\VarDumper\Caster\XmlReaderCaster', 'castXmlReader'], + + 'ErrorException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castErrorException'], + 'Exception' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castException'], + 'Error' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castError'], + 'Symfony\Component\DependencyInjection\ContainerInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + 'Symfony\Component\HttpClient\CurlHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'], + 'Symfony\Component\HttpClient\NativeHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'], + 'Symfony\Component\HttpClient\Response\CurlResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'], + 'Symfony\Component\HttpClient\Response\NativeResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'], + 'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castRequest'], + 'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castThrowingCasterException'], + 'Symfony\Component\VarDumper\Caster\TraceStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castTraceStub'], + 'Symfony\Component\VarDumper\Caster\FrameStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFrameStub'], + 'Symfony\Component\VarDumper\Cloner\AbstractCloner' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + 'Symfony\Component\Debug\Exception\SilencedErrorContext' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castSilencedErrorContext'], + + 'ProxyManager\Proxy\ProxyInterface' => ['Symfony\Component\VarDumper\Caster\ProxyManagerCaster', 'castProxy'], + 'PHPUnit_Framework_MockObject_MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + 'PHPUnit\Framework\MockObject\MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + 'PHPUnit\Framework\MockObject\Stub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + 'Prophecy\Prophecy\ProphecySubjectInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + 'Mockery\MockInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'], + + 'PDO' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdo'], + 'PDOStatement' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdoStatement'], + + 'AMQPConnection' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castConnection'], + 'AMQPChannel' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castChannel'], + 'AMQPQueue' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castQueue'], + 'AMQPExchange' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castExchange'], + 'AMQPEnvelope' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castEnvelope'], + + 'ArrayObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayObject'], + 'ArrayIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayIterator'], + 'SplDoublyLinkedList' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castDoublyLinkedList'], + 'SplFileInfo' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileInfo'], + 'SplFileObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileObject'], + 'SplFixedArray' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFixedArray'], + 'SplHeap' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'], + 'SplObjectStorage' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castObjectStorage'], + 'SplPriorityQueue' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'], + 'OuterIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castOuterIterator'], + 'WeakReference' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castWeakReference'], + + 'Redis' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'], + 'RedisArray' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisArray'], + 'RedisCluster' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisCluster'], + + 'DateTimeInterface' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castDateTime'], + 'DateInterval' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castInterval'], + 'DateTimeZone' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castTimeZone'], + 'DatePeriod' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castPeriod'], + + 'GMP' => ['Symfony\Component\VarDumper\Caster\GmpCaster', 'castGmp'], + + 'MessageFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castMessageFormatter'], + 'NumberFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castNumberFormatter'], + 'IntlTimeZone' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlTimeZone'], + 'IntlCalendar' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlCalendar'], + 'IntlDateFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlDateFormatter'], + + 'Memcached' => ['Symfony\Component\VarDumper\Caster\MemcachedCaster', 'castMemcached'], + + 'Ds\Collection' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castCollection'], + 'Ds\Map' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castMap'], + 'Ds\Pair' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPair'], + 'Symfony\Component\VarDumper\Caster\DsPairStub' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPairStub'], + + ':curl' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'], + ':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'], + ':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'], + ':gd' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'], + ':mysql link' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castMysqlLink'], + ':pgsql large object' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLargeObject'], + ':pgsql link' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'], + ':pgsql link persistent' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'], + ':pgsql result' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castResult'], + ':process' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castProcess'], + ':stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'], + ':OpenSSL X.509' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'], + ':persistent stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'], + ':stream-context' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStreamContext'], + ':xml' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'], + ]; + + protected $maxItems = 2500; + protected $maxString = -1; + protected $minDepth = 1; + + private $casters = []; + private $prevErrorHandler; + private $classInfo = []; + private $filter = 0; + + /** + * @param callable[]|null $casters A map of casters + * + * @see addCasters + */ + public function __construct(array $casters = null) + { + if (null === $casters) { + $casters = static::$defaultCasters; + } + $this->addCasters($casters); + } + + /** + * Adds casters for resources and objects. + * + * Maps resources or objects types to a callback. + * Types are in the key, with a callable caster for value. + * Resource types are to be prefixed with a `:`, + * see e.g. static::$defaultCasters. + * + * @param callable[] $casters A map of casters + */ + public function addCasters(array $casters) + { + foreach ($casters as $type => $callback) { + $this->casters[$type][] = $callback; + } + } + + /** + * Sets the maximum number of items to clone past the minimum depth in nested structures. + * + * @param int $maxItems + */ + public function setMaxItems($maxItems) + { + $this->maxItems = (int) $maxItems; + } + + /** + * Sets the maximum cloned length for strings. + * + * @param int $maxString + */ + public function setMaxString($maxString) + { + $this->maxString = (int) $maxString; + } + + /** + * Sets the minimum tree depth where we are guaranteed to clone all the items. After this + * depth is reached, only setMaxItems items will be cloned. + * + * @param int $minDepth + */ + public function setMinDepth($minDepth) + { + $this->minDepth = (int) $minDepth; + } + + /** + * Clones a PHP variable. + * + * @param mixed $var Any PHP variable + * @param int $filter A bit field of Caster::EXCLUDE_* constants + * + * @return Data The cloned variable represented by a Data object + */ + public function cloneVar($var, $filter = 0) + { + $this->prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) { + if (E_RECOVERABLE_ERROR === $type || E_USER_ERROR === $type) { + // Cloner never dies + throw new \ErrorException($msg, 0, $type, $file, $line); + } + + if ($this->prevErrorHandler) { + return ($this->prevErrorHandler)($type, $msg, $file, $line, $context); + } + + return false; + }); + $this->filter = $filter; + + if ($gc = gc_enabled()) { + gc_disable(); + } + try { + return new Data($this->doClone($var)); + } finally { + if ($gc) { + gc_enable(); + } + restore_error_handler(); + $this->prevErrorHandler = null; + } + } + + /** + * Effectively clones the PHP variable. + * + * @param mixed $var Any PHP variable + * + * @return array The cloned variable represented in an array + */ + abstract protected function doClone($var); + + /** + * Casts an object to an array representation. + * + * @param Stub $stub The Stub for the casted object + * @param bool $isNested True if the object is nested in the dumped structure + * + * @return array The object casted as array + */ + protected function castObject(Stub $stub, $isNested) + { + $obj = $stub->value; + $class = $stub->class; + + if (isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00")) { + $stub->class = get_parent_class($class).'@anonymous'; + } + if (isset($this->classInfo[$class])) { + list($i, $parents, $hasDebugInfo, $fileInfo) = $this->classInfo[$class]; + } else { + $i = 2; + $parents = [$class]; + $hasDebugInfo = method_exists($class, '__debugInfo'); + + foreach (class_parents($class) as $p) { + $parents[] = $p; + ++$i; + } + foreach (class_implements($class) as $p) { + $parents[] = $p; + ++$i; + } + $parents[] = '*'; + + $r = new \ReflectionClass($class); + $fileInfo = $r->isInternal() || $r->isSubclassOf(Stub::class) ? [] : [ + 'file' => $r->getFileName(), + 'line' => $r->getStartLine(), + ]; + + $this->classInfo[$class] = [$i, $parents, $hasDebugInfo, $fileInfo]; + } + + $stub->attr += $fileInfo; + $a = Caster::castObject($obj, $class, $hasDebugInfo); + + try { + while ($i--) { + if (!empty($this->casters[$p = $parents[$i]])) { + foreach ($this->casters[$p] as $callback) { + $a = $callback($obj, $a, $stub, $isNested, $this->filter); + } + } + } + } catch (\Exception $e) { + $a = [(Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠' => new ThrowingCasterException($e)] + $a; + } + + return $a; + } + + /** + * Casts a resource to an array representation. + * + * @param Stub $stub The Stub for the casted resource + * @param bool $isNested True if the object is nested in the dumped structure + * + * @return array The resource casted as array + */ + protected function castResource(Stub $stub, $isNested) + { + $a = []; + $res = $stub->value; + $type = $stub->class; + + try { + if (!empty($this->casters[':'.$type])) { + foreach ($this->casters[':'.$type] as $callback) { + $a = $callback($res, $a, $stub, $isNested, $this->filter); + } + } + } catch (\Exception $e) { + $a = [(Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠' => new ThrowingCasterException($e)] + $a; + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Cloner/ClonerInterface.php b/vendor/symfony/var-dumper/Cloner/ClonerInterface.php new file mode 100644 index 0000000..7ed287a --- /dev/null +++ b/vendor/symfony/var-dumper/Cloner/ClonerInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Cloner; + +/** + * @author Nicolas Grekas + */ +interface ClonerInterface +{ + /** + * Clones a PHP variable. + * + * @param mixed $var Any PHP variable + * + * @return Data The cloned variable represented by a Data object + */ + public function cloneVar($var); +} diff --git a/vendor/symfony/var-dumper/Cloner/Cursor.php b/vendor/symfony/var-dumper/Cloner/Cursor.php new file mode 100644 index 0000000..5b0542f --- /dev/null +++ b/vendor/symfony/var-dumper/Cloner/Cursor.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Cloner; + +/** + * Represents the current state of a dumper while dumping. + * + * @author Nicolas Grekas + */ +class Cursor +{ + const HASH_INDEXED = Stub::ARRAY_INDEXED; + const HASH_ASSOC = Stub::ARRAY_ASSOC; + const HASH_OBJECT = Stub::TYPE_OBJECT; + const HASH_RESOURCE = Stub::TYPE_RESOURCE; + + public $depth = 0; + public $refIndex = 0; + public $softRefTo = 0; + public $softRefCount = 0; + public $softRefHandle = 0; + public $hardRefTo = 0; + public $hardRefCount = 0; + public $hardRefHandle = 0; + public $hashType; + public $hashKey; + public $hashKeyIsBinary; + public $hashIndex = 0; + public $hashLength = 0; + public $hashCut = 0; + public $stop = false; + public $attr = []; + public $skipChildren = false; +} diff --git a/vendor/symfony/var-dumper/Cloner/Data.php b/vendor/symfony/var-dumper/Cloner/Data.php new file mode 100644 index 0000000..178fba3 --- /dev/null +++ b/vendor/symfony/var-dumper/Cloner/Data.php @@ -0,0 +1,427 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Cloner; + +use Symfony\Component\VarDumper\Caster\Caster; + +/** + * @author Nicolas Grekas + */ +class Data implements \ArrayAccess, \Countable, \IteratorAggregate +{ + private $data; + private $position = 0; + private $key = 0; + private $maxDepth = 20; + private $maxItemsPerDepth = -1; + private $useRefHandles = -1; + + /** + * @param array $data An array as returned by ClonerInterface::cloneVar() + */ + public function __construct(array $data) + { + $this->data = $data; + } + + /** + * @return string|null The type of the value + */ + public function getType() + { + $item = $this->data[$this->position][$this->key]; + + if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) { + $item = $item->value; + } + if (!$item instanceof Stub) { + return \gettype($item); + } + if (Stub::TYPE_STRING === $item->type) { + return 'string'; + } + if (Stub::TYPE_ARRAY === $item->type) { + return 'array'; + } + if (Stub::TYPE_OBJECT === $item->type) { + return $item->class; + } + if (Stub::TYPE_RESOURCE === $item->type) { + return $item->class.' resource'; + } + + return null; + } + + /** + * @param array|bool $recursive Whether values should be resolved recursively or not + * + * @return string|int|float|bool|array|Data[]|null A native representation of the original value + */ + public function getValue($recursive = false) + { + $item = $this->data[$this->position][$this->key]; + + if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) { + $item = $item->value; + } + if (!($item = $this->getStub($item)) instanceof Stub) { + return $item; + } + if (Stub::TYPE_STRING === $item->type) { + return $item->value; + } + + $children = $item->position ? $this->data[$item->position] : []; + + foreach ($children as $k => $v) { + if ($recursive && !($v = $this->getStub($v)) instanceof Stub) { + continue; + } + $children[$k] = clone $this; + $children[$k]->key = $k; + $children[$k]->position = $item->position; + + if ($recursive) { + if (Stub::TYPE_REF === $v->type && ($v = $this->getStub($v->value)) instanceof Stub) { + $recursive = (array) $recursive; + if (isset($recursive[$v->position])) { + continue; + } + $recursive[$v->position] = true; + } + $children[$k] = $children[$k]->getValue($recursive); + } + } + + return $children; + } + + public function count() + { + return \count($this->getValue()); + } + + public function getIterator() + { + if (!\is_array($value = $this->getValue())) { + throw new \LogicException(sprintf('%s object holds non-iterable type "%s".', self::class, \gettype($value))); + } + + yield from $value; + } + + public function __get($key) + { + if (null !== $data = $this->seek($key)) { + $item = $this->getStub($data->data[$data->position][$data->key]); + + return $item instanceof Stub || [] === $item ? $data : $item; + } + + return null; + } + + public function __isset($key) + { + return null !== $this->seek($key); + } + + public function offsetExists($key) + { + return $this->__isset($key); + } + + public function offsetGet($key) + { + return $this->__get($key); + } + + public function offsetSet($key, $value) + { + throw new \BadMethodCallException(self::class.' objects are immutable.'); + } + + public function offsetUnset($key) + { + throw new \BadMethodCallException(self::class.' objects are immutable.'); + } + + public function __toString() + { + $value = $this->getValue(); + + if (!\is_array($value)) { + return (string) $value; + } + + return sprintf('%s (count=%d)', $this->getType(), \count($value)); + } + + /** + * Returns a depth limited clone of $this. + * + * @param int $maxDepth The max dumped depth level + * + * @return static + */ + public function withMaxDepth($maxDepth) + { + $data = clone $this; + $data->maxDepth = (int) $maxDepth; + + return $data; + } + + /** + * Limits the number of elements per depth level. + * + * @param int $maxItemsPerDepth The max number of items dumped per depth level + * + * @return static + */ + public function withMaxItemsPerDepth($maxItemsPerDepth) + { + $data = clone $this; + $data->maxItemsPerDepth = (int) $maxItemsPerDepth; + + return $data; + } + + /** + * Enables/disables objects' identifiers tracking. + * + * @param bool $useRefHandles False to hide global ref. handles + * + * @return static + */ + public function withRefHandles($useRefHandles) + { + $data = clone $this; + $data->useRefHandles = $useRefHandles ? -1 : 0; + + return $data; + } + + /** + * Seeks to a specific key in nested data structures. + * + * @param string|int $key The key to seek to + * + * @return static|null Null if the key is not set + */ + public function seek($key) + { + $item = $this->data[$this->position][$this->key]; + + if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) { + $item = $item->value; + } + if (!($item = $this->getStub($item)) instanceof Stub || !$item->position) { + return null; + } + $keys = [$key]; + + switch ($item->type) { + case Stub::TYPE_OBJECT: + $keys[] = Caster::PREFIX_DYNAMIC.$key; + $keys[] = Caster::PREFIX_PROTECTED.$key; + $keys[] = Caster::PREFIX_VIRTUAL.$key; + $keys[] = "\0$item->class\0$key"; + // no break + case Stub::TYPE_ARRAY: + case Stub::TYPE_RESOURCE: + break; + default: + return null; + } + + $data = null; + $children = $this->data[$item->position]; + + foreach ($keys as $key) { + if (isset($children[$key]) || \array_key_exists($key, $children)) { + $data = clone $this; + $data->key = $key; + $data->position = $item->position; + break; + } + } + + return $data; + } + + /** + * Dumps data with a DumperInterface dumper. + */ + public function dump(DumperInterface $dumper) + { + $refs = [0]; + $this->dumpItem($dumper, new Cursor(), $refs, $this->data[$this->position][$this->key]); + } + + /** + * Depth-first dumping of items. + * + * @param DumperInterface $dumper The dumper being used for dumping + * @param Cursor $cursor A cursor used for tracking dumper state position + * @param array &$refs A map of all references discovered while dumping + * @param mixed $item A Stub object or the original value being dumped + */ + private function dumpItem($dumper, $cursor, &$refs, $item) + { + $cursor->refIndex = 0; + $cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0; + $cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0; + $firstSeen = true; + + if (!$item instanceof Stub) { + $cursor->attr = []; + $type = \gettype($item); + if ($item && 'array' === $type) { + $item = $this->getStub($item); + } + } elseif (Stub::TYPE_REF === $item->type) { + if ($item->handle) { + if (!isset($refs[$r = $item->handle - (PHP_INT_MAX >> 1)])) { + $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; + } else { + $firstSeen = false; + } + $cursor->hardRefTo = $refs[$r]; + $cursor->hardRefHandle = $this->useRefHandles & $item->handle; + $cursor->hardRefCount = $item->refCount; + } + $cursor->attr = $item->attr; + $type = $item->class ?: \gettype($item->value); + $item = $this->getStub($item->value); + } + if ($item instanceof Stub) { + if ($item->refCount) { + if (!isset($refs[$r = $item->handle])) { + $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; + } else { + $firstSeen = false; + } + $cursor->softRefTo = $refs[$r]; + } + $cursor->softRefHandle = $this->useRefHandles & $item->handle; + $cursor->softRefCount = $item->refCount; + $cursor->attr = $item->attr; + $cut = $item->cut; + + if ($item->position && $firstSeen) { + $children = $this->data[$item->position]; + + if ($cursor->stop) { + if ($cut >= 0) { + $cut += \count($children); + } + $children = []; + } + } else { + $children = []; + } + switch ($item->type) { + case Stub::TYPE_STRING: + $dumper->dumpString($cursor, $item->value, Stub::STRING_BINARY === $item->class, $cut); + break; + + case Stub::TYPE_ARRAY: + $item = clone $item; + $item->type = $item->class; + $item->class = $item->value; + // no break + case Stub::TYPE_OBJECT: + case Stub::TYPE_RESOURCE: + $withChildren = $children && $cursor->depth !== $this->maxDepth && $this->maxItemsPerDepth; + $dumper->enterHash($cursor, $item->type, $item->class, $withChildren); + if ($withChildren) { + if ($cursor->skipChildren) { + $withChildren = false; + $cut = -1; + } else { + $cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class); + } + } elseif ($children && 0 <= $cut) { + $cut += \count($children); + } + $cursor->skipChildren = false; + $dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut); + break; + + default: + throw new \RuntimeException(sprintf('Unexpected Stub type: %s', $item->type)); + } + } elseif ('array' === $type) { + $dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false); + $dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0); + } elseif ('string' === $type) { + $dumper->dumpString($cursor, $item, false, 0); + } else { + $dumper->dumpScalar($cursor, $type, $item); + } + } + + /** + * Dumps children of hash structures. + * + * @param DumperInterface $dumper + * @param Cursor $parentCursor The cursor of the parent hash + * @param array &$refs A map of all references discovered while dumping + * @param array $children The children to dump + * @param int $hashCut The number of items removed from the original hash + * @param string $hashType A Cursor::HASH_* const + * @param bool $dumpKeys Whether keys should be dumped or not + * + * @return int The final number of removed items + */ + private function dumpChildren($dumper, $parentCursor, &$refs, $children, $hashCut, $hashType, $dumpKeys) + { + $cursor = clone $parentCursor; + ++$cursor->depth; + $cursor->hashType = $hashType; + $cursor->hashIndex = 0; + $cursor->hashLength = \count($children); + $cursor->hashCut = $hashCut; + foreach ($children as $key => $child) { + $cursor->hashKeyIsBinary = isset($key[0]) && !preg_match('//u', $key); + $cursor->hashKey = $dumpKeys ? $key : null; + $this->dumpItem($dumper, $cursor, $refs, $child); + if (++$cursor->hashIndex === $this->maxItemsPerDepth || $cursor->stop) { + $parentCursor->stop = true; + + return $hashCut >= 0 ? $hashCut + $cursor->hashLength - $cursor->hashIndex : $hashCut; + } + } + + return $hashCut; + } + + private function getStub($item) + { + if (!$item || !\is_array($item)) { + return $item; + } + + $stub = new Stub(); + $stub->type = Stub::TYPE_ARRAY; + foreach ($item as $stub->class => $stub->position) { + } + if (isset($item[0])) { + $stub->cut = $item[0]; + } + $stub->value = $stub->cut + ($stub->position ? \count($this->data[$stub->position]) : 0); + + return $stub; + } +} diff --git a/vendor/symfony/var-dumper/Cloner/DumperInterface.php b/vendor/symfony/var-dumper/Cloner/DumperInterface.php new file mode 100644 index 0000000..912bb52 --- /dev/null +++ b/vendor/symfony/var-dumper/Cloner/DumperInterface.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Cloner; + +/** + * DumperInterface used by Data objects. + * + * @author Nicolas Grekas + */ +interface DumperInterface +{ + /** + * Dumps a scalar value. + * + * @param Cursor $cursor The Cursor position in the dump + * @param string $type The PHP type of the value being dumped + * @param string|int|float|bool $value The scalar value being dumped + */ + public function dumpScalar(Cursor $cursor, $type, $value); + + /** + * Dumps a string. + * + * @param Cursor $cursor The Cursor position in the dump + * @param string $str The string being dumped + * @param bool $bin Whether $str is UTF-8 or binary encoded + * @param int $cut The number of characters $str has been cut by + */ + public function dumpString(Cursor $cursor, $str, $bin, $cut); + + /** + * Dumps while entering an hash. + * + * @param Cursor $cursor The Cursor position in the dump + * @param int $type A Cursor::HASH_* const for the type of hash + * @param string|int $class The object class, resource type or array count + * @param bool $hasChild When the dump of the hash has child item + */ + public function enterHash(Cursor $cursor, $type, $class, $hasChild); + + /** + * Dumps while leaving an hash. + * + * @param Cursor $cursor The Cursor position in the dump + * @param int $type A Cursor::HASH_* const for the type of hash + * @param string|int $class The object class, resource type or array count + * @param bool $hasChild When the dump of the hash has child item + * @param int $cut The number of items the hash has been cut by + */ + public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut); +} diff --git a/vendor/symfony/var-dumper/Cloner/Stub.php b/vendor/symfony/var-dumper/Cloner/Stub.php new file mode 100644 index 0000000..27dd3ef --- /dev/null +++ b/vendor/symfony/var-dumper/Cloner/Stub.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Cloner; + +/** + * Represents the main properties of a PHP variable. + * + * @author Nicolas Grekas + */ +class Stub +{ + const TYPE_REF = 1; + const TYPE_STRING = 2; + const TYPE_ARRAY = 3; + const TYPE_OBJECT = 4; + const TYPE_RESOURCE = 5; + + const STRING_BINARY = 1; + const STRING_UTF8 = 2; + + const ARRAY_ASSOC = 1; + const ARRAY_INDEXED = 2; + + public $type = self::TYPE_REF; + public $class = ''; + public $value; + public $cut = 0; + public $handle = 0; + public $refCount = 0; + public $position = 0; + public $attr = []; + + private static $defaultProperties = []; + + /** + * @internal + */ + public function __sleep() + { + $properties = []; + + if (!isset(self::$defaultProperties[$c = \get_class($this)])) { + self::$defaultProperties[$c] = get_class_vars($c); + + foreach ((new \ReflectionClass($c))->getStaticProperties() as $k => $v) { + unset(self::$defaultProperties[$c][$k]); + } + } + + foreach (self::$defaultProperties[$c] as $k => $v) { + if ($this->$k !== $v) { + $properties[] = $k; + } + } + + return $properties; + } +} diff --git a/vendor/symfony/var-dumper/Cloner/VarCloner.php b/vendor/symfony/var-dumper/Cloner/VarCloner.php new file mode 100644 index 0000000..f640338 --- /dev/null +++ b/vendor/symfony/var-dumper/Cloner/VarCloner.php @@ -0,0 +1,302 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Cloner; + +/** + * @author Nicolas Grekas + */ +class VarCloner extends AbstractCloner +{ + private static $gid; + private static $arrayCache = []; + + /** + * {@inheritdoc} + */ + protected function doClone($var) + { + $len = 1; // Length of $queue + $pos = 0; // Number of cloned items past the minimum depth + $refsCounter = 0; // Hard references counter + $queue = [[$var]]; // This breadth-first queue is the return value + $indexedArrays = []; // Map of queue indexes that hold numerically indexed arrays + $hardRefs = []; // Map of original zval ids to stub objects + $objRefs = []; // Map of original object handles to their stub object counterpart + $objects = []; // Keep a ref to objects to ensure their handle cannot be reused while cloning + $resRefs = []; // Map of original resource handles to their stub object counterpart + $values = []; // Map of stub objects' ids to original values + $maxItems = $this->maxItems; + $maxString = $this->maxString; + $minDepth = $this->minDepth; + $currentDepth = 0; // Current tree depth + $currentDepthFinalIndex = 0; // Final $queue index for current tree depth + $minimumDepthReached = 0 === $minDepth; // Becomes true when minimum tree depth has been reached + $cookie = (object) []; // Unique object used to detect hard references + $a = null; // Array cast for nested structures + $stub = null; // Stub capturing the main properties of an original item value + // or null if the original value is used directly + + if (!$gid = self::$gid) { + $gid = self::$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable + } + $arrayStub = new Stub(); + $arrayStub->type = Stub::TYPE_ARRAY; + $fromObjCast = false; + + for ($i = 0; $i < $len; ++$i) { + // Detect when we move on to the next tree depth + if ($i > $currentDepthFinalIndex) { + ++$currentDepth; + $currentDepthFinalIndex = $len - 1; + if ($currentDepth >= $minDepth) { + $minimumDepthReached = true; + } + } + + $refs = $vals = $queue[$i]; + if (\PHP_VERSION_ID < 70200 && empty($indexedArrays[$i])) { + // see https://wiki.php.net/rfc/convert_numeric_keys_in_object_array_casts + foreach ($vals as $k => $v) { + if (\is_int($k)) { + continue; + } + foreach ([$k => true] as $gk => $gv) { + } + if ($gk !== $k) { + $fromObjCast = true; + $refs = $vals = array_values($queue[$i]); + break; + } + } + } + foreach ($vals as $k => $v) { + // $v is the original value or a stub object in case of hard references + + if (\PHP_VERSION_ID >= 70400) { + $zvalIsRef = null !== \ReflectionReference::fromArrayElement($vals, $k); + } else { + $refs[$k] = $cookie; + $zvalIsRef = $vals[$k] === $cookie; + } + + if ($zvalIsRef) { + $vals[$k] = &$stub; // Break hard references to make $queue completely + unset($stub); // independent from the original structure + if ($v instanceof Stub && isset($hardRefs[spl_object_id($v)])) { + $vals[$k] = $refs[$k] = $v; + if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) { + ++$v->value->refCount; + } + ++$v->refCount; + continue; + } + $refs[$k] = $vals[$k] = new Stub(); + $refs[$k]->value = $v; + $h = spl_object_id($refs[$k]); + $hardRefs[$h] = &$refs[$k]; + $values[$h] = $v; + $vals[$k]->handle = ++$refsCounter; + } + // Create $stub when the original value $v can not be used directly + // If $v is a nested structure, put that structure in array $a + switch (true) { + case null === $v: + case \is_bool($v): + case \is_int($v): + case \is_float($v): + continue 2; + + case \is_string($v): + if ('' === $v) { + continue 2; + } + if (!preg_match('//u', $v)) { + $stub = new Stub(); + $stub->type = Stub::TYPE_STRING; + $stub->class = Stub::STRING_BINARY; + if (0 <= $maxString && 0 < $cut = \strlen($v) - $maxString) { + $stub->cut = $cut; + $stub->value = substr($v, 0, -$cut); + } else { + $stub->value = $v; + } + } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) { + $stub = new Stub(); + $stub->type = Stub::TYPE_STRING; + $stub->class = Stub::STRING_UTF8; + $stub->cut = $cut; + $stub->value = mb_substr($v, 0, $maxString, 'UTF-8'); + } else { + continue 2; + } + $a = null; + break; + + case \is_array($v): + if (!$v) { + continue 2; + } + $stub = $arrayStub; + $stub->class = Stub::ARRAY_INDEXED; + + $j = -1; + foreach ($v as $gk => $gv) { + if ($gk !== ++$j) { + $stub->class = Stub::ARRAY_ASSOC; + break; + } + } + $a = $v; + + if (Stub::ARRAY_ASSOC === $stub->class) { + // Copies of $GLOBALS have very strange behavior, + // let's detect them with some black magic + $a[$gid] = true; + + // Happens with copies of $GLOBALS + if (isset($v[$gid])) { + unset($v[$gid]); + $a = []; + foreach ($v as $gk => &$gv) { + $a[$gk] = &$gv; + } + unset($gv); + } else { + $a = $v; + } + } elseif (\PHP_VERSION_ID < 70200) { + $indexedArrays[$len] = true; + } + break; + + case \is_object($v): + case $v instanceof \__PHP_Incomplete_Class: + if (empty($objRefs[$h = spl_object_id($v)])) { + $stub = new Stub(); + $stub->type = Stub::TYPE_OBJECT; + $stub->class = \get_class($v); + $stub->value = $v; + $stub->handle = $h; + $a = $this->castObject($stub, 0 < $i); + if ($v !== $stub->value) { + if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) { + break; + } + $stub->handle = $h = spl_object_id($stub->value); + } + $stub->value = null; + if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) { + $stub->cut = \count($a); + $a = null; + } + } + if (empty($objRefs[$h])) { + $objRefs[$h] = $stub; + $objects[] = $v; + } else { + $stub = $objRefs[$h]; + ++$stub->refCount; + $a = null; + } + break; + + default: // resource + if (empty($resRefs[$h = (int) $v])) { + $stub = new Stub(); + $stub->type = Stub::TYPE_RESOURCE; + if ('Unknown' === $stub->class = @get_resource_type($v)) { + $stub->class = 'Closed'; + } + $stub->value = $v; + $stub->handle = $h; + $a = $this->castResource($stub, 0 < $i); + $stub->value = null; + if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) { + $stub->cut = \count($a); + $a = null; + } + } + if (empty($resRefs[$h])) { + $resRefs[$h] = $stub; + } else { + $stub = $resRefs[$h]; + ++$stub->refCount; + $a = null; + } + break; + } + + if ($a) { + if (!$minimumDepthReached || 0 > $maxItems) { + $queue[$len] = $a; + $stub->position = $len++; + } elseif ($pos < $maxItems) { + if ($maxItems < $pos += \count($a)) { + $a = \array_slice($a, 0, $maxItems - $pos); + if ($stub->cut >= 0) { + $stub->cut += $pos - $maxItems; + } + } + $queue[$len] = $a; + $stub->position = $len++; + } elseif ($stub->cut >= 0) { + $stub->cut += \count($a); + $stub->position = 0; + } + } + + if ($arrayStub === $stub) { + if ($arrayStub->cut) { + $stub = [$arrayStub->cut, $arrayStub->class => $arrayStub->position]; + $arrayStub->cut = 0; + } elseif (isset(self::$arrayCache[$arrayStub->class][$arrayStub->position])) { + $stub = self::$arrayCache[$arrayStub->class][$arrayStub->position]; + } else { + self::$arrayCache[$arrayStub->class][$arrayStub->position] = $stub = [$arrayStub->class => $arrayStub->position]; + } + } + + if ($zvalIsRef) { + $refs[$k]->value = $stub; + } else { + $vals[$k] = $stub; + } + } + + if ($fromObjCast) { + $fromObjCast = false; + $refs = $vals; + $vals = []; + $j = -1; + foreach ($queue[$i] as $k => $v) { + foreach ([$k => true] as $gk => $gv) { + } + if ($gk !== $k) { + $vals = (object) $vals; + $vals->{$k} = $refs[++$j]; + $vals = (array) $vals; + } else { + $vals[$k] = $refs[++$j]; + } + } + } + + $queue[$i] = $vals; + } + + foreach ($values as $h => $v) { + $hardRefs[$h] = $v; + } + + return $queue; + } +} diff --git a/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php b/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php new file mode 100644 index 0000000..dc77d03 --- /dev/null +++ b/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Command\Descriptor; + +use Symfony\Component\Console\Formatter\OutputFormatterStyle; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Dumper\CliDumper; + +/** + * Describe collected data clones for cli output. + * + * @author Maxime Steinhausser + * + * @final + */ +class CliDescriptor implements DumpDescriptorInterface +{ + private $dumper; + private $lastIdentifier; + private $supportsHref; + + public function __construct(CliDumper $dumper) + { + $this->dumper = $dumper; + $this->supportsHref = method_exists(OutputFormatterStyle::class, 'setHref'); + } + + public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void + { + $io = $output instanceof SymfonyStyle ? $output : new SymfonyStyle(new ArrayInput([]), $output); + $this->dumper->setColors($output->isDecorated()); + + $rows = [['date', date('r', $context['timestamp'])]]; + $lastIdentifier = $this->lastIdentifier; + $this->lastIdentifier = $clientId; + + $section = "Received from client #$clientId"; + if (isset($context['request'])) { + $request = $context['request']; + $this->lastIdentifier = $request['identifier']; + $section = sprintf('%s %s', $request['method'], $request['uri']); + if ($controller = $request['controller']) { + $rows[] = ['controller', rtrim($this->dumper->dump($controller, true), "\n")]; + } + } elseif (isset($context['cli'])) { + $this->lastIdentifier = $context['cli']['identifier']; + $section = '$ '.$context['cli']['command_line']; + } + + if ($this->lastIdentifier !== $lastIdentifier) { + $io->section($section); + } + + if (isset($context['source'])) { + $source = $context['source']; + $sourceInfo = sprintf('%s on line %d', $source['name'], $source['line']); + $fileLink = $source['file_link'] ?? null; + if ($this->supportsHref && $fileLink) { + $sourceInfo = sprintf('%s', $fileLink, $sourceInfo); + } + $rows[] = ['source', $sourceInfo]; + $file = $source['file_relative'] ?? $source['file']; + $rows[] = ['file', $file]; + } + + $io->table([], $rows); + + if (!$this->supportsHref && isset($fileLink)) { + $io->writeln(['Open source in your IDE/browser:', $fileLink]); + $io->newLine(); + } + + $this->dumper->dump($data); + $io->newLine(); + } +} diff --git a/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php b/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php new file mode 100644 index 0000000..267d27b --- /dev/null +++ b/vendor/symfony/var-dumper/Command/Descriptor/DumpDescriptorInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Command\Descriptor; + +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\VarDumper\Cloner\Data; + +/** + * @author Maxime Steinhausser + */ +interface DumpDescriptorInterface +{ + public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void; +} diff --git a/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php b/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php new file mode 100644 index 0000000..35a203b --- /dev/null +++ b/vendor/symfony/var-dumper/Command/Descriptor/HtmlDescriptor.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Command\Descriptor; + +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; + +/** + * Describe collected data clones for html output. + * + * @author Maxime Steinhausser + * + * @final + */ +class HtmlDescriptor implements DumpDescriptorInterface +{ + private $dumper; + private $initialized = false; + + public function __construct(HtmlDumper $dumper) + { + $this->dumper = $dumper; + } + + public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void + { + if (!$this->initialized) { + $styles = file_get_contents(__DIR__.'/../../Resources/css/htmlDescriptor.css'); + $scripts = file_get_contents(__DIR__.'/../../Resources/js/htmlDescriptor.js'); + $output->writeln(""); + $this->initialized = true; + } + + $title = '-'; + if (isset($context['request'])) { + $request = $context['request']; + $controller = "{$this->dumper->dump($request['controller'], true, ['maxDepth' => 0])}"; + $title = sprintf('%s %s', $request['method'], $uri = $request['uri'], $uri); + $dedupIdentifier = $request['identifier']; + } elseif (isset($context['cli'])) { + $title = '$ '.$context['cli']['command_line']; + $dedupIdentifier = $context['cli']['identifier']; + } else { + $dedupIdentifier = uniqid('', true); + } + + $sourceDescription = ''; + if (isset($context['source'])) { + $source = $context['source']; + $projectDir = $source['project_dir'] ?? null; + $sourceDescription = sprintf('%s on line %d', $source['name'], $source['line']); + if (isset($source['file_link'])) { + $sourceDescription = sprintf('%s', $source['file_link'], $sourceDescription); + } + } + + $isoDate = $this->extractDate($context, 'c'); + $tags = array_filter([ + 'controller' => $controller ?? null, + 'project dir' => $projectDir ?? null, + ]); + + $output->writeln(<< +
+
+

$title

+ +
+ {$this->renderTags($tags)} +
+
+

+ $sourceDescription +

+ {$this->dumper->dump($data, true)} +
+ +HTML + ); + } + + private function extractDate(array $context, string $format = 'r'): string + { + return date($format, $context['timestamp']); + } + + private function renderTags(array $tags): string + { + if (!$tags) { + return ''; + } + + $renderedTags = ''; + foreach ($tags as $key => $value) { + $renderedTags .= sprintf('
  • %s%s
  • ', $key, $value); + } + + return << +
      + $renderedTags +
    + +HTML; + } +} diff --git a/vendor/symfony/var-dumper/Command/ServerDumpCommand.php b/vendor/symfony/var-dumper/Command/ServerDumpCommand.php new file mode 100644 index 0000000..eb807e3 --- /dev/null +++ b/vendor/symfony/var-dumper/Command/ServerDumpCommand.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Command\Descriptor\CliDescriptor; +use Symfony\Component\VarDumper\Command\Descriptor\DumpDescriptorInterface; +use Symfony\Component\VarDumper\Command\Descriptor\HtmlDescriptor; +use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; +use Symfony\Component\VarDumper\Server\DumpServer; + +/** + * Starts a dump server to collect and output dumps on a single place with multiple formats support. + * + * @author Maxime Steinhausser + * + * @final + */ +class ServerDumpCommand extends Command +{ + protected static $defaultName = 'server:dump'; + + private $server; + + /** @var DumpDescriptorInterface[] */ + private $descriptors; + + public function __construct(DumpServer $server, array $descriptors = []) + { + $this->server = $server; + $this->descriptors = $descriptors + [ + 'cli' => new CliDescriptor(new CliDumper()), + 'html' => new HtmlDescriptor(new HtmlDumper()), + ]; + + parent::__construct(); + } + + protected function configure() + { + $availableFormats = implode(', ', array_keys($this->descriptors)); + + $this + ->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', $availableFormats), 'cli') + ->setDescription('Starts a dump server that collects and displays dumps in a single place') + ->setHelp(<<<'EOF' +%command.name% starts a dump server that collects and displays +dumps in a single place for debugging you application: + + php %command.full_name% + +You can consult dumped data in HTML format in your browser by providing the --format=html option +and redirecting the output to a file: + + php %command.full_name% --format="html" > dump.html + +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + $format = $input->getOption('format'); + + if (!$descriptor = $this->descriptors[$format] ?? null) { + throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $format)); + } + + $errorIo = $io->getErrorStyle(); + $errorIo->title('Symfony Var Dumper Server'); + + $this->server->start(); + + $errorIo->success(sprintf('Server listening on %s', $this->server->getHost())); + $errorIo->comment('Quit the server with CONTROL-C.'); + + $this->server->listen(function (Data $data, array $context, int $clientId) use ($descriptor, $io) { + $descriptor->describe($io, $data, $context, $clientId); + }); + } +} diff --git a/vendor/symfony/var-dumper/Dumper/AbstractDumper.php b/vendor/symfony/var-dumper/Dumper/AbstractDumper.php new file mode 100644 index 0000000..be8b3f7 --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/AbstractDumper.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper; + +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\DumperInterface; + +/** + * Abstract mechanism for dumping a Data object. + * + * @author Nicolas Grekas + */ +abstract class AbstractDumper implements DataDumperInterface, DumperInterface +{ + const DUMP_LIGHT_ARRAY = 1; + const DUMP_STRING_LENGTH = 2; + const DUMP_COMMA_SEPARATOR = 4; + const DUMP_TRAILING_COMMA = 8; + + public static $defaultOutput = 'php://output'; + + protected $line = ''; + protected $lineDumper; + protected $outputStream; + protected $decimalPoint; // This is locale dependent + protected $indentPad = ' '; + protected $flags; + + private $charset = ''; + + /** + * @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput + * @param string|null $charset The default character encoding to use for non-UTF8 strings + * @param int $flags A bit field of static::DUMP_* constants to fine tune dumps representation + */ + public function __construct($output = null, string $charset = null, int $flags = 0) + { + $this->flags = $flags; + $this->setCharset($charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8'); + $this->decimalPoint = localeconv(); + $this->decimalPoint = $this->decimalPoint['decimal_point']; + $this->setOutput($output ?: static::$defaultOutput); + if (!$output && \is_string(static::$defaultOutput)) { + static::$defaultOutput = $this->outputStream; + } + } + + /** + * Sets the output destination of the dumps. + * + * @param callable|resource|string $output A line dumper callable, an opened stream or an output path + * + * @return callable|resource|string The previous output destination + */ + public function setOutput($output) + { + $prev = null !== $this->outputStream ? $this->outputStream : $this->lineDumper; + + if (\is_callable($output)) { + $this->outputStream = null; + $this->lineDumper = $output; + } else { + if (\is_string($output)) { + $output = fopen($output, 'wb'); + } + $this->outputStream = $output; + $this->lineDumper = [$this, 'echoLine']; + } + + return $prev; + } + + /** + * Sets the default character encoding to use for non-UTF8 strings. + * + * @param string $charset The default character encoding to use for non-UTF8 strings + * + * @return string The previous charset + */ + public function setCharset($charset) + { + $prev = $this->charset; + + $charset = strtoupper($charset); + $charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset; + + $this->charset = $charset; + + return $prev; + } + + /** + * Sets the indentation pad string. + * + * @param string $pad A string that will be prepended to dumped lines, repeated by nesting level + * + * @return string The previous indent pad + */ + public function setIndentPad($pad) + { + $prev = $this->indentPad; + $this->indentPad = $pad; + + return $prev; + } + + /** + * Dumps a Data object. + * + * @param Data $data A Data object + * @param callable|resource|string|true|null $output A line dumper callable, an opened stream, an output path or true to return the dump + * + * @return string|null The dump as string when $output is true + */ + public function dump(Data $data, $output = null) + { + $this->decimalPoint = localeconv(); + $this->decimalPoint = $this->decimalPoint['decimal_point']; + + if ($locale = $this->flags & (self::DUMP_COMMA_SEPARATOR | self::DUMP_TRAILING_COMMA) ? setlocale(LC_NUMERIC, 0) : null) { + setlocale(LC_NUMERIC, 'C'); + } + + if ($returnDump = true === $output) { + $output = fopen('php://memory', 'r+b'); + } + if ($output) { + $prevOutput = $this->setOutput($output); + } + try { + $data->dump($this); + $this->dumpLine(-1); + + if ($returnDump) { + $result = stream_get_contents($output, -1, 0); + fclose($output); + + return $result; + } + } finally { + if ($output) { + $this->setOutput($prevOutput); + } + if ($locale) { + setlocale(LC_NUMERIC, $locale); + } + } + + return null; + } + + /** + * Dumps the current line. + * + * @param int $depth The recursive depth in the dumped structure for the line being dumped, + * or -1 to signal the end-of-dump to the line dumper callable + */ + protected function dumpLine($depth) + { + ($this->lineDumper)($this->line, $depth, $this->indentPad); + $this->line = ''; + } + + /** + * Generic line dumper callback. + * + * @param string $line The line to write + * @param int $depth The recursive depth in the dumped structure + * @param string $indentPad The line indent pad + */ + protected function echoLine($line, $depth, $indentPad) + { + if (-1 !== $depth) { + fwrite($this->outputStream, str_repeat($indentPad, $depth).$line."\n"); + } + } + + /** + * Converts a non-UTF-8 string to UTF-8. + * + * @param string|null $s The non-UTF-8 string to convert + * + * @return string|null The string converted to UTF-8 + */ + protected function utf8Encode($s) + { + if (null === $s || preg_match('//u', $s)) { + return $s; + } + + if (!\function_exists('iconv')) { + throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.'); + } + + if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) { + return $c; + } + if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) { + return $c; + } + + return iconv('CP850', 'UTF-8', $s); + } +} diff --git a/vendor/symfony/var-dumper/Dumper/CliDumper.php b/vendor/symfony/var-dumper/Dumper/CliDumper.php new file mode 100644 index 0000000..9b258f4 --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/CliDumper.php @@ -0,0 +1,643 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper; + +use Symfony\Component\VarDumper\Cloner\Cursor; +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * CliDumper dumps variables for command line output. + * + * @author Nicolas Grekas + */ +class CliDumper extends AbstractDumper +{ + public static $defaultColors; + public static $defaultOutput = 'php://stdout'; + + protected $colors; + protected $maxStringWidth = 0; + protected $styles = [ + // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics + 'default' => '38;5;208', + 'num' => '1;38;5;38', + 'const' => '1;38;5;208', + 'str' => '1;38;5;113', + 'note' => '38;5;38', + 'ref' => '38;5;247', + 'public' => '', + 'protected' => '', + 'private' => '', + 'meta' => '38;5;170', + 'key' => '38;5;113', + 'index' => '38;5;38', + ]; + + protected static $controlCharsRx = '/[\x00-\x1F\x7F]+/'; + protected static $controlCharsMap = [ + "\t" => '\t', + "\n" => '\n', + "\v" => '\v', + "\f" => '\f', + "\r" => '\r', + "\033" => '\e', + ]; + + protected $collapseNextHash = false; + protected $expandNextHash = false; + + private $displayOptions = [ + 'fileLinkFormat' => null, + ]; + + private $handlesHrefGracefully; + + /** + * {@inheritdoc} + */ + public function __construct($output = null, string $charset = null, int $flags = 0) + { + parent::__construct($output, $charset, $flags); + + if ('\\' === \DIRECTORY_SEPARATOR && !$this->isWindowsTrueColor()) { + // Use only the base 16 xterm colors when using ANSICON or standard Windows 10 CLI + $this->setStyles([ + 'default' => '31', + 'num' => '1;34', + 'const' => '1;31', + 'str' => '1;32', + 'note' => '34', + 'ref' => '1;30', + 'meta' => '35', + 'key' => '32', + 'index' => '34', + ]); + } + + $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f'; + } + + /** + * Enables/disables colored output. + * + * @param bool $colors + */ + public function setColors($colors) + { + $this->colors = (bool) $colors; + } + + /** + * Sets the maximum number of characters per line for dumped strings. + * + * @param int $maxStringWidth + */ + public function setMaxStringWidth($maxStringWidth) + { + $this->maxStringWidth = (int) $maxStringWidth; + } + + /** + * Configures styles. + * + * @param array $styles A map of style names to style definitions + */ + public function setStyles(array $styles) + { + $this->styles = $styles + $this->styles; + } + + /** + * Configures display options. + * + * @param array $displayOptions A map of display options to customize the behavior + */ + public function setDisplayOptions(array $displayOptions) + { + $this->displayOptions = $displayOptions + $this->displayOptions; + } + + /** + * {@inheritdoc} + */ + public function dumpScalar(Cursor $cursor, $type, $value) + { + $this->dumpKey($cursor); + + $style = 'const'; + $attr = $cursor->attr; + + switch ($type) { + case 'default': + $style = 'default'; + break; + + case 'integer': + $style = 'num'; + break; + + case 'double': + $style = 'num'; + + switch (true) { + case INF === $value: $value = 'INF'; break; + case -INF === $value: $value = '-INF'; break; + case is_nan($value): $value = 'NAN'; break; + default: + $value = (string) $value; + if (false === strpos($value, $this->decimalPoint)) { + $value .= $this->decimalPoint.'0'; + } + break; + } + break; + + case 'NULL': + $value = 'null'; + break; + + case 'boolean': + $value = $value ? 'true' : 'false'; + break; + + default: + $attr += ['value' => $this->utf8Encode($value)]; + $value = $this->utf8Encode($type); + break; + } + + $this->line .= $this->style($style, $value, $attr); + + $this->endValue($cursor); + } + + /** + * {@inheritdoc} + */ + public function dumpString(Cursor $cursor, $str, $bin, $cut) + { + $this->dumpKey($cursor); + $attr = $cursor->attr; + + if ($bin) { + $str = $this->utf8Encode($str); + } + if ('' === $str) { + $this->line .= '""'; + $this->endValue($cursor); + } else { + $attr += [ + 'length' => 0 <= $cut ? mb_strlen($str, 'UTF-8') + $cut : 0, + 'binary' => $bin, + ]; + $str = explode("\n", $str); + if (isset($str[1]) && !isset($str[2]) && !isset($str[1][0])) { + unset($str[1]); + $str[0] .= "\n"; + } + $m = \count($str) - 1; + $i = $lineCut = 0; + + if (self::DUMP_STRING_LENGTH & $this->flags) { + $this->line .= '('.$attr['length'].') '; + } + if ($bin) { + $this->line .= 'b'; + } + + if ($m) { + $this->line .= '"""'; + $this->dumpLine($cursor->depth); + } else { + $this->line .= '"'; + } + + foreach ($str as $str) { + if ($i < $m) { + $str .= "\n"; + } + if (0 < $this->maxStringWidth && $this->maxStringWidth < $len = mb_strlen($str, 'UTF-8')) { + $str = mb_substr($str, 0, $this->maxStringWidth, 'UTF-8'); + $lineCut = $len - $this->maxStringWidth; + } + if ($m && 0 < $cursor->depth) { + $this->line .= $this->indentPad; + } + if ('' !== $str) { + $this->line .= $this->style('str', $str, $attr); + } + if ($i++ == $m) { + if ($m) { + if ('' !== $str) { + $this->dumpLine($cursor->depth); + if (0 < $cursor->depth) { + $this->line .= $this->indentPad; + } + } + $this->line .= '"""'; + } else { + $this->line .= '"'; + } + if ($cut < 0) { + $this->line .= '…'; + $lineCut = 0; + } elseif ($cut) { + $lineCut += $cut; + } + } + if ($lineCut) { + $this->line .= '…'.$lineCut; + $lineCut = 0; + } + + if ($i > $m) { + $this->endValue($cursor); + } else { + $this->dumpLine($cursor->depth); + } + } + } + } + + /** + * {@inheritdoc} + */ + public function enterHash(Cursor $cursor, $type, $class, $hasChild) + { + $this->dumpKey($cursor); + $attr = $cursor->attr; + + if ($this->collapseNextHash) { + $cursor->skipChildren = true; + $this->collapseNextHash = $hasChild = false; + } + + $class = $this->utf8Encode($class); + if (Cursor::HASH_OBJECT === $type) { + $prefix = $class && 'stdClass' !== $class ? $this->style('note', $class, $attr).' {' : '{'; + } elseif (Cursor::HASH_RESOURCE === $type) { + $prefix = $this->style('note', $class.' resource', $attr).($hasChild ? ' {' : ' '); + } else { + $prefix = $class && !(self::DUMP_LIGHT_ARRAY & $this->flags) ? $this->style('note', 'array:'.$class, $attr).' [' : '['; + } + + if ($cursor->softRefCount || 0 < $cursor->softRefHandle) { + $prefix .= $this->style('ref', (Cursor::HASH_RESOURCE === $type ? '@' : '#').(0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->softRefTo), ['count' => $cursor->softRefCount]); + } elseif ($cursor->hardRefTo && !$cursor->refIndex && $class) { + $prefix .= $this->style('ref', '&'.$cursor->hardRefTo, ['count' => $cursor->hardRefCount]); + } elseif (!$hasChild && Cursor::HASH_RESOURCE === $type) { + $prefix = substr($prefix, 0, -1); + } + + $this->line .= $prefix; + + if ($hasChild) { + $this->dumpLine($cursor->depth); + } + } + + /** + * {@inheritdoc} + */ + public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut) + { + $this->dumpEllipsis($cursor, $hasChild, $cut); + $this->line .= Cursor::HASH_OBJECT === $type ? '}' : (Cursor::HASH_RESOURCE !== $type ? ']' : ($hasChild ? '}' : '')); + $this->endValue($cursor); + } + + /** + * Dumps an ellipsis for cut children. + * + * @param Cursor $cursor The Cursor position in the dump + * @param bool $hasChild When the dump of the hash has child item + * @param int $cut The number of items the hash has been cut by + */ + protected function dumpEllipsis(Cursor $cursor, $hasChild, $cut) + { + if ($cut) { + $this->line .= ' …'; + if (0 < $cut) { + $this->line .= $cut; + } + if ($hasChild) { + $this->dumpLine($cursor->depth + 1); + } + } + } + + /** + * Dumps a key in a hash structure. + * + * @param Cursor $cursor The Cursor position in the dump + */ + protected function dumpKey(Cursor $cursor) + { + if (null !== $key = $cursor->hashKey) { + if ($cursor->hashKeyIsBinary) { + $key = $this->utf8Encode($key); + } + $attr = ['binary' => $cursor->hashKeyIsBinary]; + $bin = $cursor->hashKeyIsBinary ? 'b' : ''; + $style = 'key'; + switch ($cursor->hashType) { + default: + case Cursor::HASH_INDEXED: + if (self::DUMP_LIGHT_ARRAY & $this->flags) { + break; + } + $style = 'index'; + // no break + case Cursor::HASH_ASSOC: + if (\is_int($key)) { + $this->line .= $this->style($style, $key).' => '; + } else { + $this->line .= $bin.'"'.$this->style($style, $key).'" => '; + } + break; + + case Cursor::HASH_RESOURCE: + $key = "\0~\0".$key; + // no break + case Cursor::HASH_OBJECT: + if (!isset($key[0]) || "\0" !== $key[0]) { + $this->line .= '+'.$bin.$this->style('public', $key).': '; + } elseif (0 < strpos($key, "\0", 1)) { + $key = explode("\0", substr($key, 1), 2); + + switch ($key[0][0]) { + case '+': // User inserted keys + $attr['dynamic'] = true; + $this->line .= '+'.$bin.'"'.$this->style('public', $key[1], $attr).'": '; + break 2; + case '~': + $style = 'meta'; + if (isset($key[0][1])) { + parse_str(substr($key[0], 1), $attr); + $attr += ['binary' => $cursor->hashKeyIsBinary]; + } + break; + case '*': + $style = 'protected'; + $bin = '#'.$bin; + break; + default: + $attr['class'] = $key[0]; + $style = 'private'; + $bin = '-'.$bin; + break; + } + + if (isset($attr['collapse'])) { + if ($attr['collapse']) { + $this->collapseNextHash = true; + } else { + $this->expandNextHash = true; + } + } + + $this->line .= $bin.$this->style($style, $key[1], $attr).(isset($attr['separator']) ? $attr['separator'] : ': '); + } else { + // This case should not happen + $this->line .= '-'.$bin.'"'.$this->style('private', $key, ['class' => '']).'": '; + } + break; + } + + if ($cursor->hardRefTo) { + $this->line .= $this->style('ref', '&'.($cursor->hardRefCount ? $cursor->hardRefTo : ''), ['count' => $cursor->hardRefCount]).' '; + } + } + } + + /** + * Decorates a value with some style. + * + * @param string $style The type of style being applied + * @param string $value The value being styled + * @param array $attr Optional context information + * + * @return string The value with style decoration + */ + protected function style($style, $value, $attr = []) + { + if (null === $this->colors) { + $this->colors = $this->supportsColors(); + } + + if (null === $this->handlesHrefGracefully) { + $this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR') && !getenv('KONSOLE_VERSION'); + } + + if (isset($attr['ellipsis'], $attr['ellipsis-type'])) { + $prefix = substr($value, 0, -$attr['ellipsis']); + if ('cli' === \PHP_SAPI && 'path' === $attr['ellipsis-type'] && isset($_SERVER[$pwd = '\\' === \DIRECTORY_SEPARATOR ? 'CD' : 'PWD']) && 0 === strpos($prefix, $_SERVER[$pwd])) { + $prefix = '.'.substr($prefix, \strlen($_SERVER[$pwd])); + } + if (!empty($attr['ellipsis-tail'])) { + $prefix .= substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']); + $value = substr($value, -$attr['ellipsis'] + $attr['ellipsis-tail']); + } else { + $value = substr($value, -$attr['ellipsis']); + } + + $value = $this->style('default', $prefix).$this->style($style, $value); + + goto href; + } + + $map = static::$controlCharsMap; + $startCchr = $this->colors ? "\033[m\033[{$this->styles['default']}m" : ''; + $endCchr = $this->colors ? "\033[m\033[{$this->styles[$style]}m" : ''; + $value = preg_replace_callback(static::$controlCharsRx, function ($c) use ($map, $startCchr, $endCchr) { + $s = $startCchr; + $c = $c[$i = 0]; + do { + $s .= isset($map[$c[$i]]) ? $map[$c[$i]] : sprintf('\x%02X', \ord($c[$i])); + } while (isset($c[++$i])); + + return $s.$endCchr; + }, $value, -1, $cchrCount); + + if ($this->colors) { + if ($cchrCount && "\033" === $value[0]) { + $value = substr($value, \strlen($startCchr)); + } else { + $value = "\033[{$this->styles[$style]}m".$value; + } + if ($cchrCount && $endCchr === substr($value, -\strlen($endCchr))) { + $value = substr($value, 0, -\strlen($endCchr)); + } else { + $value .= "\033[{$this->styles['default']}m"; + } + } + + href: + if ($this->colors && $this->handlesHrefGracefully) { + if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], isset($attr['line']) ? $attr['line'] : 0)) { + if ('note' === $style) { + $value .= "\033]8;;{$href}\033\\^\033]8;;\033\\"; + } else { + $attr['href'] = $href; + } + } + if (isset($attr['href'])) { + $value = "\033]8;;{$attr['href']}\033\\{$value}\033]8;;\033\\"; + } + } + + return $value; + } + + /** + * @return bool Tells if the current output stream supports ANSI colors or not + */ + protected function supportsColors() + { + if ($this->outputStream !== static::$defaultOutput) { + return $this->hasColorSupport($this->outputStream); + } + if (null !== static::$defaultColors) { + return static::$defaultColors; + } + if (isset($_SERVER['argv'][1])) { + $colors = $_SERVER['argv']; + $i = \count($colors); + while (--$i > 0) { + if (isset($colors[$i][5])) { + switch ($colors[$i]) { + case '--ansi': + case '--color': + case '--color=yes': + case '--color=force': + case '--color=always': + return static::$defaultColors = true; + + case '--no-ansi': + case '--color=no': + case '--color=none': + case '--color=never': + return static::$defaultColors = false; + } + } + } + } + + $h = stream_get_meta_data($this->outputStream) + ['wrapper_type' => null]; + $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'wb') : $this->outputStream; + + return static::$defaultColors = $this->hasColorSupport($h); + } + + /** + * {@inheritdoc} + */ + protected function dumpLine($depth, $endOfValue = false) + { + if ($this->colors) { + $this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line); + } + parent::dumpLine($depth); + } + + protected function endValue(Cursor $cursor) + { + if (Stub::ARRAY_INDEXED === $cursor->hashType || Stub::ARRAY_ASSOC === $cursor->hashType) { + if (self::DUMP_TRAILING_COMMA & $this->flags && 0 < $cursor->depth) { + $this->line .= ','; + } elseif (self::DUMP_COMMA_SEPARATOR & $this->flags && 1 < $cursor->hashLength - $cursor->hashIndex) { + $this->line .= ','; + } + } + + $this->dumpLine($cursor->depth, true); + } + + /** + * Returns true if the stream supports colorization. + * + * Reference: Composer\XdebugHandler\Process::supportsColor + * https://github.com/composer/xdebug-handler + * + * @param mixed $stream A CLI output stream + * + * @return bool + */ + private function hasColorSupport($stream) + { + if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) { + return false; + } + + if ('Hyper' === getenv('TERM_PROGRAM')) { + return true; + } + + if (\DIRECTORY_SEPARATOR === '\\') { + return (\function_exists('sapi_windows_vt100_support') + && @sapi_windows_vt100_support($stream)) + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + } + + if (\function_exists('stream_isatty')) { + return @stream_isatty($stream); + } + + if (\function_exists('posix_isatty')) { + return @posix_isatty($stream); + } + + $stat = @fstat($stream); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } + + /** + * Returns true if the Windows terminal supports true color. + * + * Note that this does not check an output stream, but relies on environment + * variables from known implementations, or a PHP and Windows version that + * supports true color. + * + * @return bool + */ + private function isWindowsTrueColor() + { + $result = 183 <= getenv('ANSICON_VER') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM') + || 'Hyper' === getenv('TERM_PROGRAM'); + + if (!$result && \PHP_VERSION_ID >= 70200) { + $version = sprintf( + '%s.%s.%s', + PHP_WINDOWS_VERSION_MAJOR, + PHP_WINDOWS_VERSION_MINOR, + PHP_WINDOWS_VERSION_BUILD + ); + $result = $version >= '10.0.15063'; + } + + return $result; + } + + private function getSourceLink($file, $line) + { + if ($fmt = $this->displayOptions['fileLinkFormat']) { + return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file); + } + + return false; + } +} diff --git a/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php b/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php new file mode 100644 index 0000000..e7f8ccf --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper\ContextProvider; + +/** + * Tries to provide context on CLI. + * + * @author Maxime Steinhausser + */ +final class CliContextProvider implements ContextProviderInterface +{ + public function getContext(): ?array + { + if ('cli' !== \PHP_SAPI) { + return null; + } + + return [ + 'command_line' => $commandLine = implode(' ', $_SERVER['argv']), + 'identifier' => hash('crc32b', $commandLine.$_SERVER['REQUEST_TIME_FLOAT']), + ]; + } +} diff --git a/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php b/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php new file mode 100644 index 0000000..38ef3b0 --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/ContextProvider/ContextProviderInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper\ContextProvider; + +/** + * Interface to provide contextual data about dump data clones sent to a server. + * + * @author Maxime Steinhausser + */ +interface ContextProviderInterface +{ + /** + * @return array|null Context data or null if unable to provide any context + */ + public function getContext(): ?array; +} diff --git a/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php b/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php new file mode 100644 index 0000000..3684a47 --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/ContextProvider/RequestContextProvider.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper\ContextProvider; + +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\VarDumper\Caster\ReflectionCaster; +use Symfony\Component\VarDumper\Cloner\VarCloner; + +/** + * Tries to provide context from a request. + * + * @author Maxime Steinhausser + */ +final class RequestContextProvider implements ContextProviderInterface +{ + private $requestStack; + private $cloner; + + public function __construct(RequestStack $requestStack) + { + $this->requestStack = $requestStack; + $this->cloner = new VarCloner(); + $this->cloner->setMaxItems(0); + $this->cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO); + } + + public function getContext(): ?array + { + if (null === $request = $this->requestStack->getCurrentRequest()) { + return null; + } + + $controller = $request->attributes->get('_controller'); + + return [ + 'uri' => $request->getUri(), + 'method' => $request->getMethod(), + 'controller' => $controller ? $this->cloner->cloneVar($controller) : $controller, + 'identifier' => spl_object_hash($request), + ]; + } +} diff --git a/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php b/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php new file mode 100644 index 0000000..e43e19f --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/ContextProvider/SourceContextProvider.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper\ContextProvider; + +use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; +use Symfony\Component\VarDumper\VarDumper; +use Twig\Template; + +/** + * Tries to provide context from sources (class name, file, line, code excerpt, ...). + * + * @author Nicolas Grekas + * @author Maxime Steinhausser + */ +final class SourceContextProvider implements ContextProviderInterface +{ + private $limit; + private $charset; + private $projectDir; + private $fileLinkFormatter; + + public function __construct(string $charset = null, string $projectDir = null, FileLinkFormatter $fileLinkFormatter = null, int $limit = 9) + { + $this->charset = $charset; + $this->projectDir = $projectDir; + $this->fileLinkFormatter = $fileLinkFormatter; + $this->limit = $limit; + } + + public function getContext(): ?array + { + $trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS, $this->limit); + + $file = $trace[1]['file']; + $line = $trace[1]['line']; + $name = false; + $fileExcerpt = false; + + for ($i = 2; $i < $this->limit; ++$i) { + if (isset($trace[$i]['class'], $trace[$i]['function']) + && 'dump' === $trace[$i]['function'] + && VarDumper::class === $trace[$i]['class'] + ) { + $file = $trace[$i]['file']; + $line = $trace[$i]['line']; + + while (++$i < $this->limit) { + if (isset($trace[$i]['function'], $trace[$i]['file']) && empty($trace[$i]['class']) && 0 !== strpos($trace[$i]['function'], 'call_user_func')) { + $file = $trace[$i]['file']; + $line = $trace[$i]['line']; + + break; + } elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof Template) { + $template = $trace[$i]['object']; + $name = $template->getTemplateName(); + $src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false); + $info = $template->getDebugInfo(); + if (isset($info[$trace[$i - 1]['line']])) { + $line = $info[$trace[$i - 1]['line']]; + $file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : null; + + if ($src) { + $src = explode("\n", $src); + $fileExcerpt = []; + + for ($i = max($line - 3, 1), $max = min($line + 3, \count($src)); $i <= $max; ++$i) { + $fileExcerpt[] = ''.$this->htmlEncode($src[$i - 1]).''; + } + + $fileExcerpt = '
      '.implode("\n", $fileExcerpt).'
    '; + } + } + break; + } + } + break; + } + } + + if (false === $name) { + $name = str_replace('\\', '/', $file); + $name = substr($name, strrpos($name, '/') + 1); + } + + $context = ['name' => $name, 'file' => $file, 'line' => $line]; + $context['file_excerpt'] = $fileExcerpt; + + if (null !== $this->projectDir) { + $context['project_dir'] = $this->projectDir; + if (0 === strpos($file, $this->projectDir)) { + $context['file_relative'] = ltrim(substr($file, \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); + } + } + + if ($this->fileLinkFormatter && $fileLink = $this->fileLinkFormatter->format($context['file'], $context['line'])) { + $context['file_link'] = $fileLink; + } + + return $context; + } + + private function htmlEncode(string $s): string + { + $html = ''; + + $dumper = new HtmlDumper(function ($line) use (&$html) { $html .= $line; }, $this->charset); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + + $cloner = new VarCloner(); + $dumper->dump($cloner->cloneVar($s)); + + return substr(strip_tags($html), 1, -1); + } +} diff --git a/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php b/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php new file mode 100644 index 0000000..b173bcc --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/DataDumperInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper; + +use Symfony\Component\VarDumper\Cloner\Data; + +/** + * DataDumperInterface for dumping Data objects. + * + * @author Nicolas Grekas + */ +interface DataDumperInterface +{ + public function dump(Data $data); +} diff --git a/vendor/symfony/var-dumper/Dumper/HtmlDumper.php b/vendor/symfony/var-dumper/Dumper/HtmlDumper.php new file mode 100644 index 0000000..e3845df --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/HtmlDumper.php @@ -0,0 +1,969 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper; + +use Symfony\Component\VarDumper\Cloner\Cursor; +use Symfony\Component\VarDumper\Cloner\Data; + +/** + * HtmlDumper dumps variables as HTML. + * + * @author Nicolas Grekas + */ +class HtmlDumper extends CliDumper +{ + public static $defaultOutput = 'php://output'; + + protected static $themes = [ + 'dark' => [ + 'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all', + 'num' => 'font-weight:bold; color:#1299DA', + 'const' => 'font-weight:bold', + 'str' => 'font-weight:bold; color:#56DB3A', + 'note' => 'color:#1299DA', + 'ref' => 'color:#A0A0A0', + 'public' => 'color:#FFFFFF', + 'protected' => 'color:#FFFFFF', + 'private' => 'color:#FFFFFF', + 'meta' => 'color:#B729D9', + 'key' => 'color:#56DB3A', + 'index' => 'color:#1299DA', + 'ellipsis' => 'color:#FF8400', + 'ns' => 'user-select:none;', + ], + 'light' => [ + 'default' => 'background:none; color:#CC7832; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all', + 'num' => 'font-weight:bold; color:#1299DA', + 'const' => 'font-weight:bold', + 'str' => 'font-weight:bold; color:#629755;', + 'note' => 'color:#6897BB', + 'ref' => 'color:#6E6E6E', + 'public' => 'color:#262626', + 'protected' => 'color:#262626', + 'private' => 'color:#262626', + 'meta' => 'color:#B729D9', + 'key' => 'color:#789339', + 'index' => 'color:#1299DA', + 'ellipsis' => 'color:#CC7832', + 'ns' => 'user-select:none;', + ], + ]; + + protected $dumpHeader; + protected $dumpPrefix = '
    ';
    +    protected $dumpSuffix = '
    '; + protected $dumpId = 'sf-dump'; + protected $colors = true; + protected $headerIsDumped = false; + protected $lastDepth = -1; + protected $styles; + + private $displayOptions = [ + 'maxDepth' => 1, + 'maxStringLength' => 160, + 'fileLinkFormat' => null, + ]; + private $extraDisplayOptions = []; + + /** + * {@inheritdoc} + */ + public function __construct($output = null, string $charset = null, int $flags = 0) + { + AbstractDumper::__construct($output, $charset, $flags); + $this->dumpId = 'sf-dump-'.mt_rand(); + $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + $this->styles = static::$themes['dark'] ?? self::$themes['dark']; + } + + /** + * {@inheritdoc} + */ + public function setStyles(array $styles) + { + $this->headerIsDumped = false; + $this->styles = $styles + $this->styles; + } + + public function setTheme(string $themeName) + { + if (!isset(static::$themes[$themeName])) { + throw new \InvalidArgumentException(sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class)); + } + + $this->setStyles(static::$themes[$themeName]); + } + + /** + * Configures display options. + * + * @param array $displayOptions A map of display options to customize the behavior + */ + public function setDisplayOptions(array $displayOptions) + { + $this->headerIsDumped = false; + $this->displayOptions = $displayOptions + $this->displayOptions; + } + + /** + * Sets an HTML header that will be dumped once in the output stream. + * + * @param string $header An HTML string + */ + public function setDumpHeader($header) + { + $this->dumpHeader = $header; + } + + /** + * Sets an HTML prefix and suffix that will encapse every single dump. + * + * @param string $prefix The prepended HTML string + * @param string $suffix The appended HTML string + */ + public function setDumpBoundaries($prefix, $suffix) + { + $this->dumpPrefix = $prefix; + $this->dumpSuffix = $suffix; + } + + /** + * {@inheritdoc} + */ + public function dump(Data $data, $output = null, array $extraDisplayOptions = []) + { + $this->extraDisplayOptions = $extraDisplayOptions; + $result = parent::dump($data, $output); + $this->dumpId = 'sf-dump-'.mt_rand(); + + return $result; + } + + /** + * Dumps the HTML header. + */ + protected function getDumpHeader() + { + $this->headerIsDumped = null !== $this->outputStream ? $this->outputStream : $this->lineDumper; + + if (null !== $this->dumpHeader) { + return $this->dumpHeader; + } + + $line = str_replace('{$options}', json_encode($this->displayOptions, JSON_FORCE_OBJECT), <<<'EOHTML' +'.$this->dumpHeader; + } + + /** + * {@inheritdoc} + */ + public function enterHash(Cursor $cursor, $type, $class, $hasChild) + { + parent::enterHash($cursor, $type, $class, false); + + if ($cursor->skipChildren) { + $cursor->skipChildren = false; + $eol = ' class=sf-dump-compact>'; + } elseif ($this->expandNextHash) { + $this->expandNextHash = false; + $eol = ' class=sf-dump-expanded>'; + } else { + $eol = '>'; + } + + if ($hasChild) { + $this->line .= 'refIndex) { + $r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2; + $r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex; + + $this->line .= sprintf(' id=%s-ref%s', $this->dumpId, $r); + } + $this->line .= $eol; + $this->dumpLine($cursor->depth); + } + } + + /** + * {@inheritdoc} + */ + public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut) + { + $this->dumpEllipsis($cursor, $hasChild, $cut); + if ($hasChild) { + $this->line .= ''; + } + parent::leaveHash($cursor, $type, $class, $hasChild, 0); + } + + /** + * {@inheritdoc} + */ + protected function style($style, $value, $attr = []) + { + if ('' === $value) { + return ''; + } + + $v = esc($value); + + if ('ref' === $style) { + if (empty($attr['count'])) { + return sprintf('%s', $v); + } + $r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1); + + return sprintf('%s', $this->dumpId, $r, 1 + $attr['count'], $v); + } + + if ('const' === $style && isset($attr['value'])) { + $style .= sprintf(' title="%s"', esc(is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value']))); + } elseif ('public' === $style) { + $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property'); + } elseif ('str' === $style && 1 < $attr['length']) { + $style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : ''); + } elseif ('note' === $style && false !== $c = strrpos($v, '\\')) { + if (isset($attr['file']) && $link = $this->getSourceLink($attr['file'], isset($attr['line']) ? $attr['line'] : 0)) { + $link = sprintf('^', esc($this->utf8Encode($link))); + } else { + $link = ''; + } + + return sprintf('%s%s', $v, $style, substr($v, $c + 1), $link); + } elseif ('protected' === $style) { + $style .= ' title="Protected property"'; + } elseif ('meta' === $style && isset($attr['title'])) { + $style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title']))); + } elseif ('private' === $style) { + $style .= sprintf(' title="Private property defined in class: `%s`"', esc($this->utf8Encode($attr['class']))); + } + $map = static::$controlCharsMap; + + if (isset($attr['ellipsis'])) { + $class = 'sf-dump-ellipsis'; + if (isset($attr['ellipsis-type'])) { + $class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']); + } + $label = esc(substr($value, -$attr['ellipsis'])); + $style = str_replace(' title="', " title=\"$v\n", $style); + $v = sprintf('%s', $class, substr($v, 0, -\strlen($label))); + + if (!empty($attr['ellipsis-tail'])) { + $tail = \strlen(esc(substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']))); + $v .= sprintf('%s%s', substr($label, 0, $tail), substr($label, $tail)); + } else { + $v .= $label; + } + } + + $v = "".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) { + $s = $b = ''; + }, $v).''; + + if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], isset($attr['line']) ? $attr['line'] : 0)) { + $attr['href'] = $href; + } + if (isset($attr['href'])) { + $target = isset($attr['file']) ? '' : ' target="_blank"'; + $v = sprintf('%s', esc($this->utf8Encode($attr['href'])), $target, $v); + } + if (isset($attr['lang'])) { + $v = sprintf('%s', esc($attr['lang']), $v); + } + + return $v; + } + + /** + * {@inheritdoc} + */ + protected function dumpLine($depth, $endOfValue = false) + { + if (-1 === $this->lastDepth) { + $this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line; + } + if ($this->headerIsDumped !== (null !== $this->outputStream ? $this->outputStream : $this->lineDumper)) { + $this->line = $this->getDumpHeader().$this->line; + } + + if (-1 === $depth) { + $args = ['"'.$this->dumpId.'"']; + if ($this->extraDisplayOptions) { + $args[] = json_encode($this->extraDisplayOptions, JSON_FORCE_OBJECT); + } + // Replace is for BC + $this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args)); + } + $this->lastDepth = $depth; + + $this->line = mb_convert_encoding($this->line, 'HTML-ENTITIES', 'UTF-8'); + + if (-1 === $depth) { + AbstractDumper::dumpLine(0); + } + AbstractDumper::dumpLine($depth); + } + + private function getSourceLink($file, $line) + { + $options = $this->extraDisplayOptions + $this->displayOptions; + + if ($fmt = $options['fileLinkFormat']) { + return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line); + } + + return false; + } +} + +function esc($str) +{ + return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); +} diff --git a/vendor/symfony/var-dumper/Dumper/ServerDumper.php b/vendor/symfony/var-dumper/Dumper/ServerDumper.php new file mode 100644 index 0000000..94795bf --- /dev/null +++ b/vendor/symfony/var-dumper/Dumper/ServerDumper.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Dumper; + +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; +use Symfony\Component\VarDumper\Server\Connection; + +/** + * ServerDumper forwards serialized Data clones to a server. + * + * @author Maxime Steinhausser + */ +class ServerDumper implements DataDumperInterface +{ + private $connection; + private $wrappedDumper; + + /** + * @param string $host The server host + * @param DataDumperInterface|null $wrappedDumper A wrapped instance used whenever we failed contacting the server + * @param ContextProviderInterface[] $contextProviders Context providers indexed by context name + */ + public function __construct(string $host, DataDumperInterface $wrappedDumper = null, array $contextProviders = []) + { + $this->connection = new Connection($host, $contextProviders); + $this->wrappedDumper = $wrappedDumper; + } + + public function getContextProviders(): array + { + return $this->connection->getContextProviders(); + } + + /** + * {@inheritdoc} + */ + public function dump(Data $data) + { + if (!$this->connection->write($data) && $this->wrappedDumper) { + $this->wrappedDumper->dump($data); + } + } +} diff --git a/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php b/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php new file mode 100644 index 0000000..af47753 --- /dev/null +++ b/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Exception; + +/** + * @author Nicolas Grekas + */ +class ThrowingCasterException extends \Exception +{ + /** + * @param \Exception $prev The exception thrown from the caster + */ + public function __construct(\Exception $prev) + { + parent::__construct('Unexpected '.\get_class($prev).' thrown from a caster: '.$prev->getMessage(), 0, $prev); + } +} diff --git a/vendor/symfony/var-dumper/LICENSE b/vendor/symfony/var-dumper/LICENSE new file mode 100644 index 0000000..cf8b3eb --- /dev/null +++ b/vendor/symfony/var-dumper/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/var-dumper/README.md b/vendor/symfony/var-dumper/README.md new file mode 100644 index 0000000..339f73e --- /dev/null +++ b/vendor/symfony/var-dumper/README.md @@ -0,0 +1,15 @@ +VarDumper Component +=================== + +The VarDumper component provides mechanisms for walking through any arbitrary +PHP variable. It provides a better `dump()` function that you can use instead +of `var_dump`. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/var_dumper/introduction.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/var-dumper/Resources/bin/var-dump-server b/vendor/symfony/var-dumper/Resources/bin/var-dump-server new file mode 100644 index 0000000..98c813a --- /dev/null +++ b/vendor/symfony/var-dumper/Resources/bin/var-dump-server @@ -0,0 +1,63 @@ +#!/usr/bin/env php + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Starts a dump server to collect and output dumps on a single place with multiple formats support. + * + * @author Maxime Steinhausser + */ + +use Psr\Log\LoggerInterface; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Logger\ConsoleLogger; +use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\VarDumper\Command\ServerDumpCommand; +use Symfony\Component\VarDumper\Server\DumpServer; + +function includeIfExists(string $file): bool +{ + return file_exists($file) && include $file; +} + +if ( + !includeIfExists(__DIR__ . '/../../../../autoload.php') && + !includeIfExists(__DIR__ . '/../../vendor/autoload.php') && + !includeIfExists(__DIR__ . '/../../../../../../vendor/autoload.php') +) { + fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL); + exit(1); +} + +if (!class_exists(Application::class)) { + fwrite(STDERR, 'You need the "symfony/console" component in order to run the VarDumper server.'.PHP_EOL); + exit(1); +} + +$input = new ArgvInput(); +$output = new ConsoleOutput(); +$defaultHost = '127.0.0.1:9912'; +$host = $input->getParameterOption(['--host'], $_SERVER['VAR_DUMPER_SERVER'] ?? $defaultHost, true); +$logger = interface_exists(LoggerInterface::class) ? new ConsoleLogger($output->getErrorOutput()) : null; + +$app = new Application(); + +$app->getDefinition()->addOption( + new InputOption('--host', null, InputOption::VALUE_REQUIRED, 'The address the server should listen to', $defaultHost) +); + +$app->add($command = new ServerDumpCommand(new DumpServer($host, $logger))) + ->getApplication() + ->setDefaultCommand($command->getName(), true) + ->run($input, $output) +; diff --git a/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css b/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css new file mode 100644 index 0000000..8f706d6 --- /dev/null +++ b/vendor/symfony/var-dumper/Resources/css/htmlDescriptor.css @@ -0,0 +1,130 @@ +body { + display: flex; + flex-direction: column-reverse; + justify-content: flex-end; + max-width: 1140px; + margin: auto; + padding: 15px; + word-wrap: break-word; + background-color: #F9F9F9; + color: #222; + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.4; +} +p { + margin: 0; +} +a { + color: #218BC3; + text-decoration: none; +} +a:hover { + text-decoration: underline; +} +.text-small { + font-size: 12px !important; +} +article { + margin: 5px; + margin-bottom: 10px; +} +article > header > .row { + display: flex; + flex-direction: row; + align-items: baseline; + margin-bottom: 10px; +} +article > header > .row > .col { + flex: 1; + display: flex; + align-items: baseline; +} +article > header > .row > h2 { + font-size: 14px; + color: #222; + font-weight: normal; + font-family: "Lucida Console", monospace, sans-serif; + word-break: break-all; + margin: 20px 5px 0 0; + user-select: all; +} +article > header > .row > h2 > code { + white-space: nowrap; + user-select: none; + color: #cc2255; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; + border-radius: 3px; + margin-right: 5px; + padding: 0 3px; +} +article > header > .row > time.col { + flex: 0; + text-align: right; + white-space: nowrap; + color: #999; + font-style: italic; +} +article > header ul.tags { + list-style: none; + padding: 0; + margin: 0; + font-size: 12px; +} +article > header ul.tags > li { + user-select: all; + margin-bottom: 2px; +} +article > header ul.tags > li > span.badge { + display: inline-block; + padding: .25em .4em; + margin-right: 5px; + border-radius: 4px; + background-color: #6c757d3b; + color: #524d4d; + font-size: 12px; + text-align: center; + font-weight: 700; + line-height: 1; + white-space: nowrap; + vertical-align: baseline; + user-select: none; +} +article > section.body { + border: 1px solid #d8d8d8; + background: #FFF; + padding: 10px; + border-radius: 3px; +} +pre.sf-dump { + border-radius: 3px; + margin-bottom: 0; +} +.hidden { + display: none !important; +} +.dumped-tag > .sf-dump { + display: inline-block; + margin: 0; + padding: 1px 5px; + line-height: 1.4; + vertical-align: top; + background-color: transparent; + user-select: auto; +} +.dumped-tag > pre.sf-dump, +.dumped-tag > .sf-dump-default { + color: #CC7832; + background: none; +} +.dumped-tag > .sf-dump .sf-dump-str { color: #629755; } +.dumped-tag > .sf-dump .sf-dump-private, +.dumped-tag > .sf-dump .sf-dump-protected, +.dumped-tag > .sf-dump .sf-dump-public { color: #262626; } +.dumped-tag > .sf-dump .sf-dump-note { color: #6897BB; } +.dumped-tag > .sf-dump .sf-dump-key { color: #789339; } +.dumped-tag > .sf-dump .sf-dump-ref { color: #6E6E6E; } +.dumped-tag > .sf-dump .sf-dump-ellipsis { color: #CC7832; max-width: 100em; } +.dumped-tag > .sf-dump .sf-dump-ellipsis-path { max-width: 5em; } +.dumped-tag > .sf-dump .sf-dump-ns { user-select: none; } diff --git a/vendor/symfony/var-dumper/Resources/functions/dump.php b/vendor/symfony/var-dumper/Resources/functions/dump.php new file mode 100644 index 0000000..e1543a8 --- /dev/null +++ b/vendor/symfony/var-dumper/Resources/functions/dump.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Component\VarDumper\VarDumper; + +if (!function_exists('dump')) { + /** + * @author Nicolas Grekas + */ + function dump($var, ...$moreVars) + { + VarDumper::dump($var); + + foreach ($moreVars as $v) { + VarDumper::dump($v); + } + + if (1 < func_num_args()) { + return func_get_args(); + } + + return $var; + } +} + +if (!function_exists('dd')) { + function dd(...$vars) + { + foreach ($vars as $v) { + VarDumper::dump($v); + } + + die(1); + } +} diff --git a/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js b/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js new file mode 100644 index 0000000..63101e5 --- /dev/null +++ b/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js @@ -0,0 +1,10 @@ +document.addEventListener('DOMContentLoaded', function() { + let prev = null; + Array.from(document.getElementsByTagName('article')).reverse().forEach(function (article) { + const dedupId = article.dataset.dedupId; + if (dedupId === prev) { + article.getElementsByTagName('header')[0].classList.add('hidden'); + } + prev = dedupId; + }); +}); diff --git a/vendor/symfony/var-dumper/Server/Connection.php b/vendor/symfony/var-dumper/Server/Connection.php new file mode 100644 index 0000000..8b814cb --- /dev/null +++ b/vendor/symfony/var-dumper/Server/Connection.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Server; + +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; + +/** + * Forwards serialized Data clones to a server. + * + * @author Maxime Steinhausser + */ +class Connection +{ + private $host; + private $contextProviders; + private $socket; + + /** + * @param string $host The server host + * @param ContextProviderInterface[] $contextProviders Context providers indexed by context name + */ + public function __construct(string $host, array $contextProviders = []) + { + if (false === strpos($host, '://')) { + $host = 'tcp://'.$host; + } + + $this->host = $host; + $this->contextProviders = $contextProviders; + } + + public function getContextProviders(): array + { + return $this->contextProviders; + } + + public function write(Data $data): bool + { + $socketIsFresh = !$this->socket; + if (!$this->socket = $this->socket ?: $this->createSocket()) { + return false; + } + + $context = ['timestamp' => microtime(true)]; + foreach ($this->contextProviders as $name => $provider) { + $context[$name] = $provider->getContext(); + } + $context = array_filter($context); + $encodedPayload = base64_encode(serialize([$data, $context]))."\n"; + + set_error_handler([self::class, 'nullErrorHandler']); + try { + if (-1 !== stream_socket_sendto($this->socket, $encodedPayload)) { + return true; + } + if (!$socketIsFresh) { + stream_socket_shutdown($this->socket, STREAM_SHUT_RDWR); + fclose($this->socket); + $this->socket = $this->createSocket(); + } + if (-1 !== stream_socket_sendto($this->socket, $encodedPayload)) { + return true; + } + } finally { + restore_error_handler(); + } + + return false; + } + + private static function nullErrorHandler($t, $m) + { + // no-op + } + + private function createSocket() + { + set_error_handler([self::class, 'nullErrorHandler']); + try { + return stream_socket_client($this->host, $errno, $errstr, 3, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT); + } finally { + restore_error_handler(); + } + } +} diff --git a/vendor/symfony/var-dumper/Server/DumpServer.php b/vendor/symfony/var-dumper/Server/DumpServer.php new file mode 100644 index 0000000..ad920bd --- /dev/null +++ b/vendor/symfony/var-dumper/Server/DumpServer.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Server; + +use Psr\Log\LoggerInterface; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * A server collecting Data clones sent by a ServerDumper. + * + * @author Maxime Steinhausser + * + * @final + */ +class DumpServer +{ + private $host; + private $socket; + private $logger; + + public function __construct(string $host, LoggerInterface $logger = null) + { + if (false === strpos($host, '://')) { + $host = 'tcp://'.$host; + } + + $this->host = $host; + $this->logger = $logger; + } + + public function start(): void + { + if (!$this->socket = stream_socket_server($this->host, $errno, $errstr)) { + throw new \RuntimeException(sprintf('Server start failed on "%s": %s %s.', $this->host, $errstr, $errno)); + } + } + + public function listen(callable $callback): void + { + if (null === $this->socket) { + $this->start(); + } + + foreach ($this->getMessages() as $clientId => $message) { + $payload = @unserialize(base64_decode($message), ['allowed_classes' => [Data::class, Stub::class]]); + + // Impossible to decode the message, give up. + if (false === $payload) { + if ($this->logger) { + $this->logger->warning('Unable to decode a message from {clientId} client.', ['clientId' => $clientId]); + } + + continue; + } + + if (!\is_array($payload) || \count($payload) < 2 || !$payload[0] instanceof Data || !\is_array($payload[1])) { + if ($this->logger) { + $this->logger->warning('Invalid payload from {clientId} client. Expected an array of two elements (Data $data, array $context)', ['clientId' => $clientId]); + } + + continue; + } + + list($data, $context) = $payload; + + $callback($data, $context, $clientId); + } + } + + public function getHost(): string + { + return $this->host; + } + + private function getMessages(): iterable + { + $sockets = [(int) $this->socket => $this->socket]; + $write = []; + + while (true) { + $read = $sockets; + stream_select($read, $write, $write, null); + + foreach ($read as $stream) { + if ($this->socket === $stream) { + $stream = stream_socket_accept($this->socket); + $sockets[(int) $stream] = $stream; + } elseif (feof($stream)) { + unset($sockets[(int) $stream]); + fclose($stream); + } else { + yield (int) $stream => fgets($stream); + } + } + } + } +} diff --git a/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php b/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php new file mode 100644 index 0000000..6aa965d --- /dev/null +++ b/vendor/symfony/var-dumper/Test/VarDumperTestTrait.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Test; + +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\CliDumper; + +/** + * @author Nicolas Grekas + */ +trait VarDumperTestTrait +{ + public function assertDumpEquals($expected, $data, $filter = 0, $message = '') + { + $this->assertSame($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message); + } + + public function assertDumpMatchesFormat($expected, $data, $filter = 0, $message = '') + { + $this->assertStringMatchesFormat($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message); + } + + /** + * @return string|null + */ + protected function getDump($data, $key = null, $filter = 0) + { + $flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0; + $flags |= getenv('DUMP_STRING_LENGTH') ? CliDumper::DUMP_STRING_LENGTH : 0; + $flags |= getenv('DUMP_COMMA_SEPARATOR') ? CliDumper::DUMP_COMMA_SEPARATOR : 0; + + $cloner = new VarCloner(); + $cloner->setMaxItems(-1); + $dumper = new CliDumper(null, null, $flags); + $dumper->setColors(false); + $data = $cloner->cloneVar($data, $filter)->withRefHandles(false); + if (null !== $key && null === $data = $data->seek($key)) { + return null; + } + + return rtrim($dumper->dump($data, true)); + } + + private function prepareExpectation($expected, $filter) + { + if (!\is_string($expected)) { + $expected = $this->getDump($expected, null, $filter); + } + + return rtrim($expected); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/CasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/CasterTest.php new file mode 100644 index 0000000..2c2189c --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/CasterTest.php @@ -0,0 +1,178 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Nicolas Grekas + */ +class CasterTest extends TestCase +{ + use VarDumperTestTrait; + + private $referenceArray = [ + 'null' => null, + 'empty' => false, + 'public' => 'pub', + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + "\0*\0protected" => 'prot', + "\0Foo\0private" => 'priv', + ]; + + /** + * @dataProvider provideFilter + */ + public function testFilter($filter, $expectedDiff, $listedProperties = null) + { + if (null === $listedProperties) { + $filteredArray = Caster::filter($this->referenceArray, $filter); + } else { + $filteredArray = Caster::filter($this->referenceArray, $filter, $listedProperties); + } + + $this->assertSame($expectedDiff, array_diff_assoc($this->referenceArray, $filteredArray)); + } + + public function provideFilter() + { + return [ + [ + 0, + [], + ], + [ + Caster::EXCLUDE_PUBLIC, + [ + 'null' => null, + 'empty' => false, + 'public' => 'pub', + ], + ], + [ + Caster::EXCLUDE_NULL, + [ + 'null' => null, + ], + ], + [ + Caster::EXCLUDE_EMPTY, + [ + 'null' => null, + 'empty' => false, + ], + ], + [ + Caster::EXCLUDE_VIRTUAL, + [ + "\0~\0virtual" => 'virt', + ], + ], + [ + Caster::EXCLUDE_DYNAMIC, + [ + "\0+\0dynamic" => 'dyn', + ], + ], + [ + Caster::EXCLUDE_PROTECTED, + [ + "\0*\0protected" => 'prot', + ], + ], + [ + Caster::EXCLUDE_PRIVATE, + [ + "\0Foo\0private" => 'priv', + ], + ], + [ + Caster::EXCLUDE_VERBOSE, + [ + 'public' => 'pub', + "\0*\0protected" => 'prot', + ], + ['public', "\0*\0protected"], + ], + [ + Caster::EXCLUDE_NOT_IMPORTANT, + [ + 'null' => null, + 'empty' => false, + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + "\0Foo\0private" => 'priv', + ], + ['public', "\0*\0protected"], + ], + [ + Caster::EXCLUDE_VIRTUAL | Caster::EXCLUDE_DYNAMIC, + [ + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + ], + ], + [ + Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_VERBOSE, + $this->referenceArray, + ['public', "\0*\0protected"], + ], + [ + Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_EMPTY, + [ + 'null' => null, + 'empty' => false, + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + "\0*\0protected" => 'prot', + "\0Foo\0private" => 'priv', + ], + ['public', 'empty'], + ], + [ + Caster::EXCLUDE_VERBOSE | Caster::EXCLUDE_EMPTY | Caster::EXCLUDE_STRICT, + [ + 'empty' => false, + ], + ['public', 'empty'], + ], + ]; + } + + public function testAnonymousClass() + { + $c = eval('return new class extends stdClass { private $foo = "foo"; };'); + + $this->assertDumpMatchesFormat( + <<<'EOTXT' +stdClass@anonymous { + -foo: "foo" +} +EOTXT + , $c + ); + + $c = eval('return new class { private $foo = "foo"; };'); + + $this->assertDumpMatchesFormat( + <<<'EOTXT' +@anonymous { + -foo: "foo" +} +EOTXT + , $c + ); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/DateCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/DateCasterTest.php new file mode 100644 index 0000000..dae13ef --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/DateCasterTest.php @@ -0,0 +1,390 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Caster\DateCaster; +use Symfony\Component\VarDumper\Cloner\Stub; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Dany Maillard + */ +class DateCasterTest extends TestCase +{ + use VarDumperTestTrait; + + /** + * @dataProvider provideDateTimes + */ + public function testDumpDateTime($time, $timezone, $xDate, $xTimestamp) + { + $date = new \DateTime($time, new \DateTimeZone($timezone)); + + $xDump = <<assertDumpEquals($xDump, $date); + } + + /** + * @dataProvider provideDateTimes + */ + public function testCastDateTime($time, $timezone, $xDate, $xTimestamp, $xInfos) + { + $stub = new Stub(); + $date = new \DateTime($time, new \DateTimeZone($timezone)); + $cast = DateCaster::castDateTime($date, ['foo' => 'bar'], $stub, false, 0); + + $xDump = << $xDate +] +EODUMP; + + $this->assertDumpEquals($xDump, $cast); + + $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0date"]); + } + + public function provideDateTimes() + { + return [ + ['2017-04-30 00:00:00.000000', 'Europe/Zurich', '2017-04-30 00:00:00.0 Europe/Zurich (+02:00)', 1493503200, 'Sunday, April 30, 2017%Afrom now%ADST On'], + ['2017-12-31 00:00:00.000000', 'Europe/Zurich', '2017-12-31 00:00:00.0 Europe/Zurich (+01:00)', 1514674800, 'Sunday, December 31, 2017%Afrom now%ADST Off'], + ['2017-04-30 00:00:00.000000', '+02:00', '2017-04-30 00:00:00.0 +02:00', 1493503200, 'Sunday, April 30, 2017%Afrom now'], + + ['2017-04-30 00:00:00.100000', '+00:00', '2017-04-30 00:00:00.100 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'], + ['2017-04-30 00:00:00.120000', '+00:00', '2017-04-30 00:00:00.120 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'], + ['2017-04-30 00:00:00.123000', '+00:00', '2017-04-30 00:00:00.123 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'], + ['2017-04-30 00:00:00.123400', '+00:00', '2017-04-30 00:00:00.123400 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'], + ['2017-04-30 00:00:00.123450', '+00:00', '2017-04-30 00:00:00.123450 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'], + ['2017-04-30 00:00:00.123456', '+00:00', '2017-04-30 00:00:00.123456 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'], + ]; + } + + /** + * @dataProvider provideIntervals + */ + public function testDumpInterval($intervalSpec, $ms, $invert, $expected) + { + if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) { + $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.'); + } + + $interval = $this->createInterval($intervalSpec, $ms, $invert); + + $xDump = <<assertDumpMatchesFormat($xDump, $interval); + } + + /** + * @dataProvider provideIntervals + */ + public function testDumpIntervalExcludingVerbosity($intervalSpec, $ms, $invert, $expected) + { + if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) { + $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.'); + } + + $interval = $this->createInterval($intervalSpec, $ms, $invert); + + $xDump = <<assertDumpEquals($xDump, $interval, Caster::EXCLUDE_VERBOSE); + } + + /** + * @dataProvider provideIntervals + */ + public function testCastInterval($intervalSpec, $ms, $invert, $xInterval, $xSeconds) + { + if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) { + $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.'); + } + + $interval = $this->createInterval($intervalSpec, $ms, $invert); + $stub = new Stub(); + + $cast = DateCaster::castInterval($interval, ['foo' => 'bar'], $stub, false, Caster::EXCLUDE_VERBOSE); + + $xDump = << $xInterval +] +EODUMP; + + $this->assertDumpEquals($xDump, $cast); + + if (null === $xSeconds) { + return; + } + + $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0interval"]); + } + + public function provideIntervals() + { + return [ + ['PT0S', 0, 0, '0s', '0s'], + ['PT0S', 0.1, 0, '+ 00:00:00.100', '%is'], + ['PT1S', 0, 0, '+ 00:00:01.0', '%is'], + ['PT2M', 0, 0, '+ 00:02:00.0', '%is'], + ['PT3H', 0, 0, '+ 03:00:00.0', '%ss'], + ['P4D', 0, 0, '+ 4d', '%ss'], + ['P5M', 0, 0, '+ 5m', null], + ['P6Y', 0, 0, '+ 6y', null], + ['P1Y2M3DT4H5M6S', 0, 0, '+ 1y 2m 3d 04:05:06.0', null], + ['PT1M60S', 0, 0, '+ 00:02:00.0', null], + ['PT1H60M', 0, 0, '+ 02:00:00.0', null], + ['P1DT24H', 0, 0, '+ 2d', null], + ['P1M32D', 0, 0, '+ 1m 32d', null], + + ['PT0S', 0, 1, '0s', '0s'], + ['PT0S', 0.1, 1, '- 00:00:00.100', '%is'], + ['PT1S', 0, 1, '- 00:00:01.0', '%is'], + ['PT2M', 0, 1, '- 00:02:00.0', '%is'], + ['PT3H', 0, 1, '- 03:00:00.0', '%ss'], + ['P4D', 0, 1, '- 4d', '%ss'], + ['P5M', 0, 1, '- 5m', null], + ['P6Y', 0, 1, '- 6y', null], + ['P1Y2M3DT4H5M6S', 0, 1, '- 1y 2m 3d 04:05:06.0', null], + ['PT1M60S', 0, 1, '- 00:02:00.0', null], + ['PT1H60M', 0, 1, '- 02:00:00.0', null], + ['P1DT24H', 0, 1, '- 2d', null], + ['P1M32D', 0, 1, '- 1m 32d', null], + ]; + } + + /** + * @dataProvider provideTimeZones + */ + public function testDumpTimeZone($timezone, $expected) + { + $timezone = new \DateTimeZone($timezone); + + $xDump = <<assertDumpMatchesFormat($xDump, $timezone); + } + + /** + * @dataProvider provideTimeZones + */ + public function testDumpTimeZoneExcludingVerbosity($timezone, $expected) + { + $timezone = new \DateTimeZone($timezone); + + $xDump = <<assertDumpMatchesFormat($xDump, $timezone, Caster::EXCLUDE_VERBOSE); + } + + /** + * @dataProvider provideTimeZones + */ + public function testCastTimeZone($timezone, $xTimezone, $xRegion) + { + $timezone = new \DateTimeZone($timezone); + $stub = new Stub(); + + $cast = DateCaster::castTimeZone($timezone, ['foo' => 'bar'], $stub, false, Caster::EXCLUDE_VERBOSE); + + $xDump = << $xTimezone +] +EODUMP; + + $this->assertDumpMatchesFormat($xDump, $cast); + + $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0timezone"]); + } + + public function provideTimeZones() + { + $xRegion = \extension_loaded('intl') ? '%s' : ''; + + return [ + // type 1 (UTC offset) + ['-12:00', '-12:00', ''], + ['+00:00', '+00:00', ''], + ['+14:00', '+14:00', ''], + + // type 2 (timezone abbreviation) + ['GMT', '+00:00', ''], + ['a', '+01:00', ''], + ['b', '+02:00', ''], + ['z', '+00:00', ''], + + // type 3 (timezone identifier) + ['Africa/Tunis', 'Africa/Tunis (%s:00)', $xRegion], + ['America/Panama', 'America/Panama (%s:00)', $xRegion], + ['Asia/Jerusalem', 'Asia/Jerusalem (%s:00)', $xRegion], + ['Atlantic/Canary', 'Atlantic/Canary (%s:00)', $xRegion], + ['Australia/Perth', 'Australia/Perth (%s:00)', $xRegion], + ['Europe/Zurich', 'Europe/Zurich (%s:00)', $xRegion], + ['Pacific/Tahiti', 'Pacific/Tahiti (%s:00)', $xRegion], + ]; + } + + /** + * @dataProvider providePeriods + */ + public function testDumpPeriod($start, $interval, $end, $options, $expected) + { + $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), \is_int($end) ? $end : new \DateTime($end), $options); + + $xDump = <<assertDumpMatchesFormat($xDump, $p); + } + + /** + * @dataProvider providePeriods + */ + public function testCastPeriod($start, $interval, $end, $options, $xPeriod, $xDates) + { + $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), \is_int($end) ? $end : new \DateTime($end), $options); + $stub = new Stub(); + + $cast = DateCaster::castPeriod($p, [], $stub, false, 0); + + $xDump = << $xPeriod +] +EODUMP; + + $this->assertDumpEquals($xDump, $cast); + + $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0period"]); + } + + public function providePeriods() + { + $periods = [ + ['2017-01-01', 'P1D', '2017-01-03', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-03 00:00:00.0', '1) 2017-01-01%a2) 2017-01-02'], + ['2017-01-01', 'P1D', 1, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 2 time/s', '1) 2017-01-01%a2) 2017-01-02'], + + ['2017-01-01', 'P1D', '2017-01-04', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-04 00:00:00.0', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03'], + ['2017-01-01', 'P1D', 2, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 3 time/s', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03'], + + ['2017-01-01', 'P1D', '2017-01-05', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-05 00:00:00.0', '1) 2017-01-01%a2) 2017-01-02%a1 more'], + ['2017-01-01', 'P1D', 3, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 4 time/s', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03%a1 more'], + + ['2017-01-01', 'P1D', '2017-01-21', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-21 00:00:00.0', '1) 2017-01-01%a17 more'], + ['2017-01-01', 'P1D', 19, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 20 time/s', '1) 2017-01-01%a17 more'], + + ['2017-01-01 01:00:00', 'P1D', '2017-01-03 01:00:00', 0, 'every + 1d, from 2017-01-01 01:00:00.0 (included) to 2017-01-03 01:00:00.0', '1) 2017-01-01 01:00:00.0%a2) 2017-01-02 01:00:00.0'], + ['2017-01-01 01:00:00', 'P1D', 1, 0, 'every + 1d, from 2017-01-01 01:00:00.0 (included) recurring 2 time/s', '1) 2017-01-01 01:00:00.0%a2) 2017-01-02 01:00:00.0'], + + ['2017-01-01', 'P1DT1H', '2017-01-03', 0, 'every + 1d 01:00:00.0, from 2017-01-01 00:00:00.0 (included) to 2017-01-03 00:00:00.0', '1) 2017-01-01 00:00:00.0%a2) 2017-01-02 01:00:00.0'], + ['2017-01-01', 'P1DT1H', 1, 0, 'every + 1d 01:00:00.0, from 2017-01-01 00:00:00.0 (included) recurring 2 time/s', '1) 2017-01-01 00:00:00.0%a2) 2017-01-02 01:00:00.0'], + + ['2017-01-01', 'P1D', '2017-01-04', \DatePeriod::EXCLUDE_START_DATE, 'every + 1d, from 2017-01-01 00:00:00.0 (excluded) to 2017-01-04 00:00:00.0', '1) 2017-01-02%a2) 2017-01-03'], + ['2017-01-01', 'P1D', 2, \DatePeriod::EXCLUDE_START_DATE, 'every + 1d, from 2017-01-01 00:00:00.0 (excluded) recurring 2 time/s', '1) 2017-01-02%a2) 2017-01-03'], + ]; + + if (\PHP_VERSION_ID < 70107) { + array_walk($periods, function (&$i) { $i[5] = ''; }); + } + + return $periods; + } + + private function createInterval($intervalSpec, $ms, $invert) + { + $interval = new \DateInterval($intervalSpec); + $interval->f = $ms; + $interval->invert = $invert; + + return $interval; + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php new file mode 100644 index 0000000..7625977 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php @@ -0,0 +1,244 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Caster\ExceptionCaster; +use Symfony\Component\VarDumper\Caster\FrameStub; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +class ExceptionCasterTest extends TestCase +{ + use VarDumperTestTrait; + + private function getTestException($msg, &$ref = null) + { + return new \Exception(''.$msg); + } + + protected function tearDown(): void + { + ExceptionCaster::$srcContext = 1; + ExceptionCaster::$traceArgs = true; + } + + public function testDefaultSettings() + { + $ref = ['foo']; + $e = $this->getTestException('foo', $ref); + + $expectedDump = <<<'EODUMP' +Exception { + #message: "foo" + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: 28 + trace: { + %s%eTests%eCaster%eExceptionCasterTest.php:28 { + › { + › return new \Exception(''.$msg); + › } + } + %s%eTests%eCaster%eExceptionCasterTest.php:40 { …} +%A +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e); + $this->assertSame(['foo'], $ref); + } + + public function testSeek() + { + $e = $this->getTestException(2); + + $expectedDump = <<<'EODUMP' +{ + %s%eTests%eCaster%eExceptionCasterTest.php:28 { + › { + › return new \Exception(''.$msg); + › } + } + %s%eTests%eCaster%eExceptionCasterTest.php:64 { …} +%A +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $this->getDump($e, 'trace')); + } + + public function testNoArgs() + { + $e = $this->getTestException(1); + ExceptionCaster::$traceArgs = false; + + $expectedDump = <<<'EODUMP' +Exception { + #message: "1" + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: 28 + trace: { + %sExceptionCasterTest.php:28 { + › { + › return new \Exception(''.$msg); + › } + } + %s%eTests%eCaster%eExceptionCasterTest.php:82 { …} +%A +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e); + } + + public function testNoSrcContext() + { + $e = $this->getTestException(1); + ExceptionCaster::$srcContext = -1; + + $expectedDump = <<<'EODUMP' +Exception { + #message: "1" + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: 28 + trace: { + %s%eTests%eCaster%eExceptionCasterTest.php:28 + %s%eTests%eCaster%eExceptionCasterTest.php:%d +%A +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e); + } + + public function testHtmlDump() + { + if (ini_get('xdebug.file_link_format') || get_cfg_var('xdebug.file_link_format')) { + $this->markTestSkipped('A custom file_link_format is defined.'); + } + + $e = $this->getTestException(1); + ExceptionCaster::$srcContext = -1; + + $cloner = new VarCloner(); + $cloner->setMaxItems(1); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($e)->withRefHandles(false), true); + + $expectedDump = <<<'EODUMP' +Exception { + #message: "1" + #code: 0 + #file: "%s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php" + #line: 28 + trace: { + %s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php:28 + …%d + } +} + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + /** + * @requires function Twig\Template::getSourceContext + */ + public function testFrameWithTwig() + { + require_once \dirname(__DIR__).'/Fixtures/Twig.php'; + + $f = [ + new FrameStub([ + 'file' => \dirname(__DIR__).'/Fixtures/Twig.php', + 'line' => 20, + 'class' => '__TwigTemplate_VarDumperFixture_u75a09', + ]), + new FrameStub([ + 'file' => \dirname(__DIR__).'/Fixtures/Twig.php', + 'line' => 21, + 'class' => '__TwigTemplate_VarDumperFixture_u75a09', + 'object' => new \__TwigTemplate_VarDumperFixture_u75a09(null, __FILE__), + ]), + ]; + + $expectedDump = <<<'EODUMP' +array:2 [ + 0 => { + class: "__TwigTemplate_VarDumperFixture_u75a09" + src: { + %sTwig.php:1 { + › + › foo bar + › twig source + } + } + } + 1 => { + class: "__TwigTemplate_VarDumperFixture_u75a09" + object: __TwigTemplate_VarDumperFixture_u75a09 { + %A + } + src: { + %sExceptionCasterTest.php:2 { + › foo bar + › twig source + › + } + } + } +] + +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $f); + } + + public function testExcludeVerbosity() + { + $e = $this->getTestException('foo'); + + $expectedDump = <<<'EODUMP' +Exception { + #message: "foo" + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: 28 +} +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e, Caster::EXCLUDE_VERBOSE); + } + + public function testAnonymous() + { + $e = new \Exception(sprintf('Boo "%s" ba.', \get_class(new class('Foo') extends \Exception { + }))); + + $expectedDump = <<<'EODUMP' +Exception { + #message: "Boo "Exception@anonymous" ba." + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: %d +} +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e, Caster::EXCLUDE_VERBOSE); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/GmpCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/GmpCasterTest.php new file mode 100644 index 0000000..eb758e8 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/GmpCasterTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\GmpCaster; +use Symfony\Component\VarDumper\Cloner\Stub; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +class GmpCasterTest extends TestCase +{ + use VarDumperTestTrait; + + /** + * @requires extension gmp + */ + public function testCastGmp() + { + $gmpString = gmp_init('1234'); + $gmpOctal = gmp_init(010); + $gmp = gmp_init('01101'); + $gmpDump = << %s +] +EODUMP; + $this->assertDumpEquals(sprintf($gmpDump, $gmpString), GmpCaster::castGmp($gmpString, [], new Stub(), false, 0)); + $this->assertDumpEquals(sprintf($gmpDump, $gmpOctal), GmpCaster::castGmp($gmpOctal, [], new Stub(), false, 0)); + $this->assertDumpEquals(sprintf($gmpDump, $gmp), GmpCaster::castGmp($gmp, [], new Stub(), false, 0)); + + $dump = <<assertDumpEquals($dump, $gmp); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/IntlCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/IntlCasterTest.php new file mode 100644 index 0000000..0bff5bf --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/IntlCasterTest.php @@ -0,0 +1,297 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @requires extension intl + */ +class IntlCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function testMessageFormatter() + { + $var = new \MessageFormatter('en', 'Hello {name}'); + + $expected = <<assertDumpEquals($expected, $var); + } + + public function testCastNumberFormatter() + { + $var = new \NumberFormatter('en', \NumberFormatter::DECIMAL); + + $expectedLocale = $var->getLocale(); + $expectedPattern = $var->getPattern(); + + $expectedAttribute1 = $var->getAttribute(\NumberFormatter::PARSE_INT_ONLY); + $expectedAttribute2 = $var->getAttribute(\NumberFormatter::GROUPING_USED); + $expectedAttribute3 = $var->getAttribute(\NumberFormatter::DECIMAL_ALWAYS_SHOWN); + $expectedAttribute4 = $var->getAttribute(\NumberFormatter::MAX_INTEGER_DIGITS); + $expectedAttribute5 = $var->getAttribute(\NumberFormatter::MIN_INTEGER_DIGITS); + $expectedAttribute6 = $var->getAttribute(\NumberFormatter::INTEGER_DIGITS); + $expectedAttribute7 = $var->getAttribute(\NumberFormatter::MAX_FRACTION_DIGITS); + $expectedAttribute8 = $var->getAttribute(\NumberFormatter::MIN_FRACTION_DIGITS); + $expectedAttribute9 = $var->getAttribute(\NumberFormatter::FRACTION_DIGITS); + $expectedAttribute10 = $var->getAttribute(\NumberFormatter::MULTIPLIER); + $expectedAttribute11 = $var->getAttribute(\NumberFormatter::GROUPING_SIZE); + $expectedAttribute12 = $var->getAttribute(\NumberFormatter::ROUNDING_MODE); + $expectedAttribute13 = number_format($var->getAttribute(\NumberFormatter::ROUNDING_INCREMENT), 1); + $expectedAttribute14 = $this->getDump($var->getAttribute(\NumberFormatter::FORMAT_WIDTH)); + $expectedAttribute15 = $var->getAttribute(\NumberFormatter::PADDING_POSITION); + $expectedAttribute16 = $var->getAttribute(\NumberFormatter::SECONDARY_GROUPING_SIZE); + $expectedAttribute17 = $var->getAttribute(\NumberFormatter::SIGNIFICANT_DIGITS_USED); + $expectedAttribute18 = $this->getDump($var->getAttribute(\NumberFormatter::MIN_SIGNIFICANT_DIGITS)); + $expectedAttribute19 = $this->getDump($var->getAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS)); + $expectedAttribute20 = $var->getAttribute(\NumberFormatter::LENIENT_PARSE); + + $expectedTextAttribute1 = $var->getTextAttribute(\NumberFormatter::POSITIVE_PREFIX); + $expectedTextAttribute2 = $var->getTextAttribute(\NumberFormatter::POSITIVE_SUFFIX); + $expectedTextAttribute3 = $var->getTextAttribute(\NumberFormatter::NEGATIVE_PREFIX); + $expectedTextAttribute4 = $var->getTextAttribute(\NumberFormatter::NEGATIVE_SUFFIX); + $expectedTextAttribute5 = $var->getTextAttribute(\NumberFormatter::PADDING_CHARACTER); + $expectedTextAttribute6 = $var->getTextAttribute(\NumberFormatter::CURRENCY_CODE); + $expectedTextAttribute7 = $var->getTextAttribute(\NumberFormatter::DEFAULT_RULESET) ? 'true' : 'false'; + $expectedTextAttribute8 = $var->getTextAttribute(\NumberFormatter::PUBLIC_RULESETS) ? 'true' : 'false'; + + $expectedSymbol1 = $var->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); + $expectedSymbol2 = $var->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL); + $expectedSymbol3 = $var->getSymbol(\NumberFormatter::PATTERN_SEPARATOR_SYMBOL); + $expectedSymbol4 = $var->getSymbol(\NumberFormatter::PERCENT_SYMBOL); + $expectedSymbol5 = $var->getSymbol(\NumberFormatter::ZERO_DIGIT_SYMBOL); + $expectedSymbol6 = $var->getSymbol(\NumberFormatter::DIGIT_SYMBOL); + $expectedSymbol7 = $var->getSymbol(\NumberFormatter::MINUS_SIGN_SYMBOL); + $expectedSymbol8 = $var->getSymbol(\NumberFormatter::PLUS_SIGN_SYMBOL); + $expectedSymbol9 = $var->getSymbol(\NumberFormatter::CURRENCY_SYMBOL); + $expectedSymbol10 = $var->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL); + $expectedSymbol11 = $var->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL); + $expectedSymbol12 = $var->getSymbol(\NumberFormatter::EXPONENTIAL_SYMBOL); + $expectedSymbol13 = $var->getSymbol(\NumberFormatter::PERMILL_SYMBOL); + $expectedSymbol14 = $var->getSymbol(\NumberFormatter::PAD_ESCAPE_SYMBOL); + $expectedSymbol15 = $var->getSymbol(\NumberFormatter::INFINITY_SYMBOL); + $expectedSymbol16 = $var->getSymbol(\NumberFormatter::NAN_SYMBOL); + $expectedSymbol17 = $var->getSymbol(\NumberFormatter::SIGNIFICANT_DIGIT_SYMBOL); + $expectedSymbol18 = $var->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL); + + $expected = <<assertDumpEquals($expected, $var); + } + + public function testCastIntlTimeZoneWithDST() + { + $var = \IntlTimeZone::createTimeZone('America/Los_Angeles'); + + $expectedDisplayName = $var->getDisplayName(); + $expectedDSTSavings = $var->getDSTSavings(); + $expectedID = $var->getID(); + $expectedRawOffset = $var->getRawOffset(); + + $expected = <<assertDumpEquals($expected, $var); + } + + public function testCastIntlTimeZoneWithoutDST() + { + $var = \IntlTimeZone::createTimeZone('Asia/Bangkok'); + + $expectedDisplayName = $var->getDisplayName(); + $expectedID = $var->getID(); + $expectedRawOffset = $var->getRawOffset(); + + $expected = <<assertDumpEquals($expected, $var); + } + + public function testCastIntlCalendar() + { + $var = \IntlCalendar::createInstance('America/Los_Angeles', 'en'); + + $expectedType = $var->getType(); + $expectedFirstDayOfWeek = $var->getFirstDayOfWeek(); + $expectedMinimalDaysInFirstWeek = $var->getMinimalDaysInFirstWeek(); + $expectedRepeatedWallTimeOption = $var->getRepeatedWallTimeOption(); + $expectedSkippedWallTimeOption = $var->getSkippedWallTimeOption(); + $expectedTime = $var->getTime().'.0'; + $expectedInDaylightTime = $var->inDaylightTime() ? 'true' : 'false'; + $expectedIsLenient = $var->isLenient() ? 'true' : 'false'; + + $expectedTimeZone = $var->getTimeZone(); + $expectedTimeZoneDisplayName = $expectedTimeZone->getDisplayName(); + $expectedTimeZoneID = $expectedTimeZone->getID(); + $expectedTimeZoneRawOffset = $expectedTimeZone->getRawOffset(); + $expectedTimeZoneDSTSavings = $expectedTimeZone->getDSTSavings(); + + $expected = <<assertDumpEquals($expected, $var); + } + + public function testCastDateFormatter() + { + $var = new \IntlDateFormatter('en', \IntlDateFormatter::TRADITIONAL, \IntlDateFormatter::TRADITIONAL); + + $expectedLocale = $var->getLocale(); + $expectedPattern = $var->getPattern(); + $expectedCalendar = $var->getCalendar(); + $expectedTimeZoneId = $var->getTimeZoneId(); + $expectedTimeType = $var->getTimeType(); + $expectedDateType = $var->getDateType(); + + $expectedTimeZone = $var->getTimeZone(); + $expectedTimeZoneDisplayName = $expectedTimeZone->getDisplayName(); + $expectedTimeZoneID = $expectedTimeZone->getID(); + $expectedTimeZoneRawOffset = $expectedTimeZone->getRawOffset(); + $expectedTimeZoneDSTSavings = $expectedTimeZone->useDaylightTime() ? "\n dst_savings: ".$expectedTimeZone->getDSTSavings() : ''; + + $expectedCalendarObject = $var->getCalendarObject(); + $expectedCalendarObjectType = $expectedCalendarObject->getType(); + $expectedCalendarObjectFirstDayOfWeek = $expectedCalendarObject->getFirstDayOfWeek(); + $expectedCalendarObjectMinimalDaysInFirstWeek = $expectedCalendarObject->getMinimalDaysInFirstWeek(); + $expectedCalendarObjectRepeatedWallTimeOption = $expectedCalendarObject->getRepeatedWallTimeOption(); + $expectedCalendarObjectSkippedWallTimeOption = $expectedCalendarObject->getSkippedWallTimeOption(); + $expectedCalendarObjectTime = $expectedCalendarObject->getTime().'.0'; + $expectedCalendarObjectInDaylightTime = $expectedCalendarObject->inDaylightTime() ? 'true' : 'false'; + $expectedCalendarObjectIsLenient = $expectedCalendarObject->isLenient() ? 'true' : 'false'; + + $expectedCalendarObjectTimeZone = $expectedCalendarObject->getTimeZone(); + $expectedCalendarObjectTimeZoneDisplayName = $expectedCalendarObjectTimeZone->getDisplayName(); + $expectedCalendarObjectTimeZoneID = $expectedCalendarObjectTimeZone->getID(); + $expectedCalendarObjectTimeZoneRawOffset = $expectedCalendarObjectTimeZone->getRawOffset(); + $expectedCalendarObjectTimeZoneDSTSavings = $expectedTimeZone->useDaylightTime() ? "\n dst_savings: ".$expectedCalendarObjectTimeZone->getDSTSavings() : ''; + + $expected = <<assertDumpEquals($expected, $var); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/MemcachedCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/MemcachedCasterTest.php new file mode 100644 index 0000000..df48390 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/MemcachedCasterTest.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Jan Schädlich + */ +class MemcachedCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function testCastMemcachedWithDefaultOptions() + { + if (!class_exists('Memcached')) { + $this->markTestSkipped('Memcached not available'); + } + + $var = new \Memcached(); + $var->addServer('127.0.0.1', 11211); + $var->addServer('127.0.0.2', 11212); + + $expected = << array:3 [ + "host" => "127.0.0.1" + "port" => 11211 + "type" => "TCP" + ] + 1 => array:3 [ + "host" => "127.0.0.2" + "port" => 11212 + "type" => "TCP" + ] + ] + options: {} +} +EOTXT; + $this->assertDumpEquals($expected, $var); + } + + public function testCastMemcachedWithCustomOptions() + { + if (!class_exists('Memcached')) { + $this->markTestSkipped('Memcached not available'); + } + + $var = new \Memcached(); + $var->addServer('127.0.0.1', 11211); + $var->addServer('127.0.0.2', 11212); + + // set a subset of non default options to test boolean, string and integer output + $var->setOption(\Memcached::OPT_COMPRESSION, false); + $var->setOption(\Memcached::OPT_PREFIX_KEY, 'pre'); + $var->setOption(\Memcached::OPT_DISTRIBUTION, \Memcached::DISTRIBUTION_CONSISTENT); + + $expected = <<<'EOTXT' +Memcached { + servers: array:2 [ + 0 => array:3 [ + "host" => "127.0.0.1" + "port" => 11211 + "type" => "TCP" + ] + 1 => array:3 [ + "host" => "127.0.0.2" + "port" => 11212 + "type" => "TCP" + ] + ] + options: { + OPT_COMPRESSION: false + OPT_PREFIX_KEY: "pre" + OPT_DISTRIBUTION: 1 + } +} +EOTXT; + + $this->assertDumpEquals($expected, $var); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/PdoCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/PdoCasterTest.php new file mode 100644 index 0000000..19bbe0f --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/PdoCasterTest.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\PdoCaster; +use Symfony\Component\VarDumper\Cloner\Stub; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Nicolas Grekas + */ +class PdoCasterTest extends TestCase +{ + use VarDumperTestTrait; + + /** + * @requires extension pdo_sqlite + */ + public function testCastPdo() + { + $pdo = new \PDO('sqlite::memory:'); + $pdo->setAttribute(\PDO::ATTR_STATEMENT_CLASS, ['PDOStatement', [$pdo]]); + + $cast = PdoCaster::castPdo($pdo, [], new Stub(), false); + + $this->assertInstanceOf('Symfony\Component\VarDumper\Caster\EnumStub', $cast["\0~\0attributes"]); + + $attr = $cast["\0~\0attributes"] = $cast["\0~\0attributes"]->value; + $this->assertInstanceOf('Symfony\Component\VarDumper\Caster\ConstStub', $attr['CASE']); + $this->assertSame('NATURAL', $attr['CASE']->class); + $this->assertSame('BOTH', $attr['DEFAULT_FETCH_MODE']->class); + + $xDump = <<<'EODUMP' +array:2 [ + "\x00~\x00inTransaction" => false + "\x00~\x00attributes" => array:9 [ + "CASE" => NATURAL + "ERRMODE" => SILENT + "PERSISTENT" => false + "DRIVER_NAME" => "sqlite" + "ORACLE_NULLS" => NATURAL + "CLIENT_VERSION" => "%s" + "SERVER_VERSION" => "%s" + "STATEMENT_CLASS" => array:%d [ + 0 => "PDOStatement"%A + ] + "DEFAULT_FETCH_MODE" => BOTH + ] +] +EODUMP; + + $this->assertDumpMatchesFormat($xDump, $cast); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/RedisCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/RedisCasterTest.php new file mode 100644 index 0000000..3edbed6 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/RedisCasterTest.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Nicolas Grekas + * @requires extension redis + */ +class RedisCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function testNotConnected() + { + $redis = new \Redis(); + + $xCast = <<<'EODUMP' +Redis { + isConnected: false +} +EODUMP; + + $this->assertDumpMatchesFormat($xCast, $redis); + } + + public function testConnected() + { + $redis = new \Redis(); + if (!@$redis->connect('127.0.0.1')) { + $e = error_get_last(); + self::markTestSkipped($e['message']); + } + + $xCast = <<<'EODUMP' +Redis {%A + isConnected: true + host: "127.0.0.1" + port: 6379 + auth: null + mode: ATOMIC + dbNum: 0 + timeout: 0.0 + lastError: null + persistentId: null + options: { + TCP_KEEPALIVE: 0 + READ_TIMEOUT: 0.0 + COMPRESSION: NONE + SERIALIZER: NONE + PREFIX: null + SCAN: NORETRY + } +} +EODUMP; + + $this->assertDumpMatchesFormat($xCast, $redis); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php new file mode 100644 index 0000000..a0b8e1d --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php @@ -0,0 +1,256 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; +use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo; +use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass; + +/** + * @author Nicolas Grekas + */ +class ReflectionCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function testReflectionCaster() + { + $var = new \ReflectionClass('ReflectionClass'); + + $this->assertDumpMatchesFormat( + <<<'EOTXT' +ReflectionClass { + +name: "ReflectionClass" +%Aimplements: array:%d [ + 0 => "Reflector" +%A] + constants: array:3 [ + "IS_IMPLICIT_ABSTRACT" => 16 + "IS_EXPLICIT_ABSTRACT" => %d + "IS_FINAL" => %d + ] + properties: array:%d [ + "name" => ReflectionProperty { +%A +name: "name" + +class: "ReflectionClass" +%A modifiers: "public" + } +%A] + methods: array:%d [ +%A + "export" => ReflectionMethod { + +name: "export" + +class: "ReflectionClass" +%A parameters: { + $%s: ReflectionParameter { +%A position: 0 +%A +} +EOTXT + , $var + ); + } + + public function testClosureCaster() + { + $a = $b = 123; + $var = function ($x) use ($a, &$b) {}; + + $this->assertDumpMatchesFormat( + <<<'EOTXT' +Closure($x) { +%Ause: { + $a: 123 + $b: & 123 + } + file: "%sReflectionCasterTest.php" + line: "68 to 68" +} +EOTXT + , $var + ); + } + + public function testFromCallableClosureCaster() + { + if (\defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('Not for HHVM.'); + } + $var = [ + (new \ReflectionMethod($this, __FUNCTION__))->getClosure($this), + (new \ReflectionMethod(__CLASS__, 'stub'))->getClosure(), + ]; + + $this->assertDumpMatchesFormat( + << Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest::testFromCallableClosureCaster() { + this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …} + file: "%sReflectionCasterTest.php" + line: "%d to %d" + } + 1 => Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest::stub(): void { + returnType: "void" + file: "%sReflectionCasterTest.php" + line: "%d to %d" + } +] +EOTXT + , $var + ); + } + + public function testClosureCasterExcludingVerbosity() + { + $var = function &($a = 5) {}; + + $this->assertDumpEquals('Closure&($a = 5) { …5}', $var, Caster::EXCLUDE_VERBOSE); + } + + public function testReflectionParameter() + { + $var = new \ReflectionParameter(__NAMESPACE__.'\reflectionParameterFixture', 0); + + $this->assertDumpMatchesFormat( + <<<'EOTXT' +ReflectionParameter { + +name: "arg1" + position: 0 + typeHint: "Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass" + default: null +} +EOTXT + , $var + ); + } + + public function testReflectionParameterScalar() + { + $f = eval('return function (int $a) {};'); + $var = new \ReflectionParameter($f, 0); + + $this->assertDumpMatchesFormat( + <<<'EOTXT' +ReflectionParameter { + +name: "a" + position: 0 + typeHint: "int" +} +EOTXT + , $var + ); + } + + public function testReturnType() + { + $f = eval('return function ():int {};'); + $line = __LINE__ - 1; + + $this->assertDumpMatchesFormat( + <<markTestSkipped('xdebug is active'); + } + + $generator = new GeneratorDemo(); + $generator = $generator->baz(); + + $expectedDump = <<<'EODUMP' +Generator { + this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} + executing: { + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() { + %sGeneratorDemo.php:14 { + › { + › yield from bar(); + › } + } + } + } + closed: false +} +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $generator); + + foreach ($generator as $v) { + break; + } + + $expectedDump = <<<'EODUMP' +array:2 [ + 0 => ReflectionGenerator { + this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} + trace: { + %s%eTests%eFixtures%eGeneratorDemo.php:9 { + › { + › yield 1; + › } + } + %s%eTests%eFixtures%eGeneratorDemo.php:20 { …} + %s%eTests%eFixtures%eGeneratorDemo.php:14 { …} + } + closed: false + } + 1 => Generator { + executing: { + Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() { + %sGeneratorDemo.php:10 { + › yield 1; + › } + › + } + } + } + closed: false + } +] +EODUMP; + + $r = new \ReflectionGenerator($generator); + $this->assertDumpMatchesFormat($expectedDump, [$r, $r->getExecutingGenerator()]); + + foreach ($generator as $v) { + } + + $expectedDump = <<<'EODUMP' +Generator { + closed: true +} +EODUMP; + $this->assertDumpMatchesFormat($expectedDump, $generator); + } + + public static function stub(): void + { + } +} + +function reflectionParameterFixture(NotLoadableClass $arg1 = null, $arg2) +{ +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/SplCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/SplCasterTest.php new file mode 100644 index 0000000..e26c371 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/SplCasterTest.php @@ -0,0 +1,226 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Grégoire Pineau + */ +class SplCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function getCastFileInfoTests() + { + return [ + [__FILE__, <<<'EOTXT' +SplFileInfo { +%Apath: "%sCaster" + filename: "SplCasterTest.php" + basename: "SplCasterTest.php" + pathname: "%sSplCasterTest.php" + extension: "php" + realPath: "%sSplCasterTest.php" + aTime: %s-%s-%d %d:%d:%d + mTime: %s-%s-%d %d:%d:%d + cTime: %s-%s-%d %d:%d:%d + inode: %i + size: %d + perms: 0%d + owner: %d + group: %d + type: "file" + writable: true + readable: true + executable: false + file: true + dir: false + link: false +%A} +EOTXT + ], + ['https://example.com/about', <<<'EOTXT' +SplFileInfo { +%Apath: "https://example.com" + filename: "about" + basename: "about" + pathname: "https://example.com/about" + extension: "" + realPath: false +%A} +EOTXT + ], + ]; + } + + /** @dataProvider getCastFileInfoTests */ + public function testCastFileInfo($file, $dump) + { + $this->assertDumpMatchesFormat($dump, new \SplFileInfo($file)); + } + + public function testCastFileObject() + { + $var = new \SplFileObject(__FILE__); + $var->setFlags(\SplFileObject::DROP_NEW_LINE | \SplFileObject::SKIP_EMPTY); + $dump = <<<'EOTXT' +SplFileObject { +%Apath: "%sCaster" + filename: "SplCasterTest.php" + basename: "SplCasterTest.php" + pathname: "%sSplCasterTest.php" + extension: "php" + realPath: "%sSplCasterTest.php" + aTime: %s-%s-%d %d:%d:%d + mTime: %s-%s-%d %d:%d:%d + cTime: %s-%s-%d %d:%d:%d + inode: %i + size: %d + perms: 0%d + owner: %d + group: %d + type: "file" + writable: true + readable: true + executable: false + file: true + dir: false + link: false +%AcsvControl: array:%d [ + 0 => "," + 1 => """ +%A] + flags: DROP_NEW_LINE|SKIP_EMPTY + maxLineLen: 0 + fstat: array:26 [ + "dev" => %d + "ino" => %i + "nlink" => %d + "rdev" => 0 + "blksize" => %i + "blocks" => %i + …20 + ] + eof: false + key: 0 +} +EOTXT; + $this->assertDumpMatchesFormat($dump, $var); + } + + /** + * @dataProvider provideCastSplDoublyLinkedList + */ + public function testCastSplDoublyLinkedList($modeValue, $modeDump) + { + $var = new \SplDoublyLinkedList(); + $var->setIteratorMode($modeValue); + $dump = <<assertDumpMatchesFormat($dump, $var); + } + + public function provideCastSplDoublyLinkedList() + { + return [ + [\SplDoublyLinkedList::IT_MODE_FIFO, 'IT_MODE_FIFO | IT_MODE_KEEP'], + [\SplDoublyLinkedList::IT_MODE_LIFO, 'IT_MODE_LIFO | IT_MODE_KEEP'], + [\SplDoublyLinkedList::IT_MODE_FIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_FIFO | IT_MODE_DELETE'], + [\SplDoublyLinkedList::IT_MODE_LIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_LIFO | IT_MODE_DELETE'], + ]; + } + + public function testCastObjectStorageIsntModified() + { + $var = new \SplObjectStorage(); + $var->attach(new \stdClass()); + $var->rewind(); + $current = $var->current(); + + $this->assertDumpMatchesFormat('%A', $var); + $this->assertSame($current, $var->current()); + } + + public function testCastObjectStorageDumpsInfo() + { + $var = new \SplObjectStorage(); + $var->attach(new \stdClass(), new \DateTime()); + + $this->assertDumpMatchesFormat('%ADateTime%A', $var); + } + + public function testCastArrayObject() + { + $var = new \ArrayObject([123]); + $var->foo = 234; + + $expected = << 123 + ] +} +EOTXT; + $this->assertDumpEquals($expected, $var); + } + + public function testArrayIterator() + { + $var = new MyArrayIterator([234]); + + $expected = << 234 + ] +} +EOTXT; + $this->assertDumpEquals($expected, $var); + } + + public function testBadSplFileInfo() + { + $var = new BadSplFileInfo(); + + $expected = <<assertDumpEquals($expected, $var); + } +} + +class MyArrayIterator extends \ArrayIterator +{ + private $foo = 123; +} + +class BadSplFileInfo extends \SplFileInfo +{ + public function __construct() + { + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/StubCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/StubCasterTest.php new file mode 100644 index 0000000..8056f70 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/StubCasterTest.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\ArgsStub; +use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Caster\LinkStub; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; +use Symfony\Component\VarDumper\Tests\Fixtures\FooInterface; + +class StubCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function testArgsStubWithDefaults($foo = 234, $bar = 456) + { + $args = [new ArgsStub([123], __FUNCTION__, __CLASS__)]; + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + $foo: 123 + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testArgsStubWithExtraArgs($foo = 234) + { + $args = [new ArgsStub([123, 456], __FUNCTION__, __CLASS__)]; + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + $foo: 123 + ...: { + 456 + } + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testArgsStubNoParamWithExtraArgs() + { + $args = [new ArgsStub([123], __FUNCTION__, __CLASS__)]; + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + 123 + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testArgsStubWithClosure() + { + $args = [new ArgsStub([123], '{closure}', null)]; + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + 123 + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testLinkStub() + { + $var = [new LinkStub(__CLASS__, 0, __FILE__)]; + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dumper->setDisplayOptions(['fileLinkFormat' => '%f:%l']); + $dump = $dumper->dump($cloner->cloneVar($var), true); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "Symfony\Component\VarDumper\Tests\Caster\StubCasterTest" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testLinkStubWithNoFileLink() + { + $var = [new LinkStub('example.com', 0, 'http://example.com')]; + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dumper->setDisplayOptions(['fileLinkFormat' => '%f:%l']); + $dump = $dumper->dump($cloner->cloneVar($var), true); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "example.com" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testClassStub() + { + $var = [new ClassStub('hello', [FooInterface::class, 'foo'])]; + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($var), true, ['fileLinkFormat' => '%f:%l']); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "hello(?stdClass $a, stdClass $b = null)" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testClassStubWithNotExistingClass() + { + $var = [new ClassStub(NotExisting::class)]; + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($var), true); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "Symfony\Component\VarDumper\Tests\Caster\NotExisting" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testClassStubWithNotExistingMethod() + { + $var = [new ClassStub('hello', [FooInterface::class, 'missing'])]; + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($var), true, ['fileLinkFormat' => '%f:%l']); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "hello" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testClassStubWithAnonymousClass() + { + $var = [new ClassStub(\get_class(new class() extends \Exception { + }))]; + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($var), true, ['fileLinkFormat' => '%f:%l']); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "Exception@anonymous" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Caster/XmlReaderCasterTest.php b/vendor/symfony/var-dumper/Tests/Caster/XmlReaderCasterTest.php new file mode 100644 index 0000000..8c0bc6e --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Caster/XmlReaderCasterTest.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Baptiste Clavié + */ +class XmlReaderCasterTest extends TestCase +{ + use VarDumperTestTrait; + + /** @var \XmlReader */ + private $reader; + + protected function setUp(): void + { + $this->reader = new \XmlReader(); + $this->reader->open(__DIR__.'/../Fixtures/xml_reader.xml'); + } + + protected function tearDown(): void + { + $this->reader->close(); + } + + public function testParserProperty() + { + $this->reader->setParserProperty(\XMLReader::SUBST_ENTITIES, true); + + $expectedDump = <<<'EODUMP' +XMLReader { + +nodeType: NONE + parserProperties: { + SUBST_ENTITIES: true + …3 + } + …12 +} +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $this->reader); + } + + /** + * @dataProvider provideNodes + */ + public function testNodes($seek, $expectedDump) + { + while ($seek--) { + $this->reader->read(); + } + $this->assertDumpMatchesFormat($expectedDump, $this->reader); + } + + public function provideNodes() + { + return [ + [0, <<<'EODUMP' +XMLReader { + +nodeType: NONE + …13 +} +EODUMP + ], + [1, <<<'EODUMP' +XMLReader { + +localName: "foo" + +nodeType: ELEMENT + +baseURI: "%sxml_reader.xml" + …11 +} +EODUMP + ], + [2, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 1 + +value: """ + \n + + """ + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [3, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +baseURI: "%sxml_reader.xml" + …10 +} +EODUMP + ], + [4, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: END_ELEMENT + +depth: 1 + +baseURI: "%sxml_reader.xml" + …10 +} +EODUMP + ], + [6, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +isEmptyElement: true + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [9, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: TEXT + +depth: 2 + +value: "With text" + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [12, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +attributeCount: 2 + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [13, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: END_ELEMENT + +depth: 1 + +baseURI: "%sxml_reader.xml" + …10 +} +EODUMP + ], + [15, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +attributeCount: 1 + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [16, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 2 + +value: """ + \n + + """ + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [17, <<<'EODUMP' +XMLReader { + +localName: "baz" + +prefix: "baz" + +nodeType: ELEMENT + +depth: 2 + +namespaceURI: "http://symfony.com" + +baseURI: "%sxml_reader.xml" + …8 +} +EODUMP + ], + [18, <<<'EODUMP' +XMLReader { + +localName: "baz" + +prefix: "baz" + +nodeType: END_ELEMENT + +depth: 2 + +namespaceURI: "http://symfony.com" + +baseURI: "%sxml_reader.xml" + …8 +} +EODUMP + ], + [19, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 2 + +value: """ + \n + + """ + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [21, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 1 + +value: "\n" + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ], + [22, <<<'EODUMP' +XMLReader { + +localName: "foo" + +nodeType: END_ELEMENT + +baseURI: "%sxml_reader.xml" + …11 +} +EODUMP + ], + ]; + } +} diff --git a/vendor/symfony/var-dumper/Tests/Cloner/DataTest.php b/vendor/symfony/var-dumper/Tests/Cloner/DataTest.php new file mode 100644 index 0000000..d4b6c24 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Cloner/DataTest.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Cloner; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\Caster; +use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Cloner\VarCloner; + +class DataTest extends TestCase +{ + public function testBasicData() + { + $values = [1 => 123, 4.5, 'abc', null, false]; + $data = $this->cloneVar($values); + $clonedValues = []; + + $this->assertInstanceOf(Data::class, $data); + $this->assertCount(\count($values), $data); + $this->assertFalse(isset($data->{0})); + $this->assertFalse(isset($data[0])); + + foreach ($data as $k => $v) { + $this->assertTrue(isset($data->{$k})); + $this->assertTrue(isset($data[$k])); + $this->assertSame(\gettype($values[$k]), $data->seek($k)->getType()); + $this->assertSame($values[$k], $data->seek($k)->getValue()); + $this->assertSame($values[$k], $data->{$k}); + $this->assertSame($values[$k], $data[$k]); + $this->assertSame((string) $values[$k], (string) $data->seek($k)); + + $clonedValues[$k] = $v->getValue(); + } + + $this->assertSame($values, $clonedValues); + } + + public function testObject() + { + $data = $this->cloneVar(new \Exception('foo')); + + $this->assertSame('Exception', $data->getType()); + + $this->assertSame('foo', $data->message); + $this->assertSame('foo', $data->{Caster::PREFIX_PROTECTED.'message'}); + + $this->assertSame('foo', $data['message']); + $this->assertSame('foo', $data[Caster::PREFIX_PROTECTED.'message']); + + $this->assertStringMatchesFormat('Exception (count=%d)', (string) $data); + } + + public function testArray() + { + $values = [[], [123]]; + $data = $this->cloneVar($values); + + $this->assertSame($values, $data->getValue(true)); + + $children = $data->getValue(); + + $this->assertIsArray($children); + + $this->assertInstanceOf(Data::class, $children[0]); + $this->assertInstanceOf(Data::class, $children[1]); + + $this->assertEquals($children[0], $data[0]); + $this->assertEquals($children[1], $data[1]); + + $this->assertSame($values[0], $children[0]->getValue(true)); + $this->assertSame($values[1], $children[1]->getValue(true)); + } + + public function testStub() + { + $data = $this->cloneVar([new ClassStub('stdClass')]); + $data = $data[0]; + + $this->assertSame('string', $data->getType()); + $this->assertSame('stdClass', $data->getValue()); + $this->assertSame('stdClass', (string) $data); + } + + public function testHardRefs() + { + $values = [[]]; + $values[1] = &$values[0]; + $values[2][0] = &$values[2]; + + $data = $this->cloneVar($values); + + $this->assertSame([], $data[0]->getValue()); + $this->assertSame([], $data[1]->getValue()); + $this->assertEquals([$data[2]->getValue()], $data[2]->getValue(true)); + + $this->assertSame('array (count=3)', (string) $data); + } + + private function cloneVar($value) + { + $cloner = new VarCloner(); + + return $cloner->cloneVar($value); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Cloner/VarClonerTest.php b/vendor/symfony/var-dumper/Tests/Cloner/VarClonerTest.php new file mode 100644 index 0000000..334d587 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Cloner/VarClonerTest.php @@ -0,0 +1,509 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Cloner; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Tests\Fixtures\Php74; + +/** + * @author Nicolas Grekas + */ +class VarClonerTest extends TestCase +{ + public function testMaxIntBoundary() + { + $data = [PHP_INT_MAX => 123]; + + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($data); + + $expected = << Array + ( + [0] => Array + ( + [0] => Array + ( + [1] => 1 + ) + + ) + + [1] => Array + ( + [%s] => 123 + ) + + ) + + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 + [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 +) + +EOTXT; + $this->assertSame(sprintf($expected, PHP_INT_MAX), print_r($clone, true)); + } + + public function testClone() + { + $json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}'); + + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($json); + + $expected = << Array + ( + [0] => Array + ( + [0] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => 4 + [class] => stdClass + [value] => + [cut] => 0 + [handle] => %i + [refCount] => 0 + [position] => 1 + [attr] => Array + ( + ) + + ) + + ) + + [1] => Array + ( + [\000+\0001] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => 4 + [class] => stdClass + [value] => + [cut] => 0 + [handle] => %i + [refCount] => 0 + [position] => 2 + [attr] => Array + ( + ) + + ) + + [\000+\0002] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => 4 + [class] => stdClass + [value] => + [cut] => 0 + [handle] => %i + [refCount] => 0 + [position] => 3 + [attr] => Array + ( + ) + + ) + + ) + + [2] => Array + ( + [\000+\000var] => val + ) + + [3] => Array + ( + [\000+\000var] => val + ) + + ) + + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 + [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 +) + +EOTXT; + $this->assertStringMatchesFormat($expected, print_r($clone, true)); + } + + public function testLimits() + { + // Level 0: + $data = [ + // Level 1: + [ + // Level 2: + [ + // Level 3: + 'Level 3 Item 0', + 'Level 3 Item 1', + 'Level 3 Item 2', + 'Level 3 Item 3', + ], + [ + 'Level 3 Item 4', + 'Level 3 Item 5', + 'Level 3 Item 6', + ], + [ + 'Level 3 Item 7', + ], + ], + [ + [ + 'Level 3 Item 8', + ], + 'Level 2 Item 0', + ], + [ + 'Level 2 Item 1', + ], + 'Level 1 Item 0', + [ + // Test setMaxString: + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + 'SHORT', + ], + ]; + + $cloner = new VarCloner(); + $cloner->setMinDepth(2); + $cloner->setMaxItems(5); + $cloner->setMaxString(20); + $clone = $cloner->cloneVar($data); + + $expected = << Array + ( + [0] => Array + ( + [0] => Array + ( + [2] => 1 + ) + + ) + + [1] => Array + ( + [0] => Array + ( + [2] => 2 + ) + + [1] => Array + ( + [2] => 3 + ) + + [2] => Array + ( + [2] => 4 + ) + + [3] => Level 1 Item 0 + [4] => Array + ( + [2] => 5 + ) + + ) + + [2] => Array + ( + [0] => Array + ( + [2] => 6 + ) + + [1] => Array + ( + [0] => 2 + [2] => 7 + ) + + [2] => Array + ( + [0] => 1 + [2] => 0 + ) + + ) + + [3] => Array + ( + [0] => Array + ( + [0] => 1 + [2] => 0 + ) + + [1] => Level 2 Item 0 + ) + + [4] => Array + ( + [0] => Level 2 Item 1 + ) + + [5] => Array + ( + [0] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => 2 + [class] => 2 + [value] => ABCDEFGHIJKLMNOPQRST + [cut] => 6 + [handle] => 0 + [refCount] => 0 + [position] => 0 + [attr] => Array + ( + ) + + ) + + [1] => SHORT + ) + + [6] => Array + ( + [0] => Level 3 Item 0 + [1] => Level 3 Item 1 + [2] => Level 3 Item 2 + [3] => Level 3 Item 3 + ) + + [7] => Array + ( + [0] => Level 3 Item 4 + ) + + ) + + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 + [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 +) + +EOTXT; + $this->assertStringMatchesFormat($expected, print_r($clone, true)); + } + + public function testJsonCast() + { + if (2 == ini_get('xdebug.overload_var_dump')) { + $this->markTestSkipped('xdebug is active'); + } + + $data = (array) json_decode('{"1":{}}'); + + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($data); + + $expected = <<<'EOTXT' +object(Symfony\Component\VarDumper\Cloner\Data)#%i (6) { + ["data":"Symfony\Component\VarDumper\Cloner\Data":private]=> + array(2) { + [0]=> + array(1) { + [0]=> + array(1) { + [1]=> + int(1) + } + } + [1]=> + array(1) { + ["1"]=> + object(Symfony\Component\VarDumper\Cloner\Stub)#%i (8) { + ["type"]=> + int(4) + ["class"]=> + string(8) "stdClass" + ["value"]=> + NULL + ["cut"]=> + int(0) + ["handle"]=> + int(%i) + ["refCount"]=> + int(0) + ["position"]=> + int(0) + ["attr"]=> + array(0) { + } + } + } + } + ["position":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(0) + ["key":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(0) + ["maxDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(20) + ["maxItemsPerDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(-1) + ["useRefHandles":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(-1) +} + +EOTXT; + ob_start(); + var_dump($clone); + $this->assertStringMatchesFormat(\PHP_VERSION_ID >= 70200 ? str_replace('"1"', '1', $expected) : $expected, ob_get_clean()); + } + + public function testCaster() + { + $cloner = new VarCloner([ + '*' => function ($obj, $array) { + return ['foo' => 123]; + }, + __CLASS__ => function ($obj, $array) { + ++$array['foo']; + + return $array; + }, + ]); + $clone = $cloner->cloneVar($this); + + $expected = << Array + ( + [0] => Array + ( + [0] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => 4 + [class] => %s + [value] => + [cut] => 0 + [handle] => %i + [refCount] => 0 + [position] => 1 + [attr] => Array + ( + [file] => %a%eVarClonerTest.php + [line] => 21 + ) + + ) + + ) + + [1] => Array + ( + [foo] => 124 + ) + + ) + + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 + [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 +) + +EOTXT; + $this->assertStringMatchesFormat($expected, print_r($clone, true)); + } + + /** + * @requires PHP 7.4 + */ + public function testPhp74() + { + $data = new Php74(); + + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($data); + + $expected = <<<'EOTXT' +Symfony\Component\VarDumper\Cloner\Data Object +( + [data:Symfony\Component\VarDumper\Cloner\Data:private] => Array + ( + [0] => Array + ( + [0] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => 4 + [class] => Symfony\Component\VarDumper\Tests\Fixtures\Php74 + [value] => + [cut] => 0 + [handle] => %i + [refCount] => 0 + [position] => 1 + [attr] => Array + ( + [file] => %s + [line] => 5 + ) + + ) + + ) + + [1] => Array + ( + [p1] => 123 + [p2] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => 4 + [class] => stdClass + [value] => + [cut] => 0 + [handle] => %i + [refCount] => 0 + [position] => 0 + [attr] => Array + ( + ) + + ) + + ) + + ) + + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 + [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 +) + +EOTXT; + $this->assertStringMatchesFormat($expected, print_r($clone, true)); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Command/Descriptor/CliDescriptorTest.php b/vendor/symfony/var-dumper/Tests/Command/Descriptor/CliDescriptorTest.php new file mode 100644 index 0000000..ccd8c50 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Command/Descriptor/CliDescriptorTest.php @@ -0,0 +1,173 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Command\Descriptor; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; +use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Command\Descriptor\CliDescriptor; +use Symfony\Component\VarDumper\Dumper\CliDumper; + +class CliDescriptorTest extends TestCase +{ + private static $timezone; + private static $prevTerminalEmulator; + + public static function setUpBeforeClass(): void + { + self::$timezone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + + self::$prevTerminalEmulator = getenv('TERMINAL_EMULATOR'); + putenv('TERMINAL_EMULATOR'); + } + + public static function tearDownAfterClass(): void + { + date_default_timezone_set(self::$timezone); + putenv('TERMINAL_EMULATOR'.(self::$prevTerminalEmulator ? '='.self::$prevTerminalEmulator : '')); + } + + /** + * @dataProvider provideContext + */ + public function testDescribe(array $context, string $expectedOutput, bool $decorated = false) + { + $output = new BufferedOutput(); + $output->setDecorated($decorated); + $descriptor = new CliDescriptor(new CliDumper(function ($s) { + return $s; + })); + + $descriptor->describe($output, new Data([[123]]), $context + ['timestamp' => 1544804268.3668], 1); + + $this->assertStringMatchesFormat(trim($expectedOutput), str_replace(PHP_EOL, "\n", trim($output->fetch()))); + } + + public function provideContext() + { + yield 'source' => [ + [ + 'source' => [ + 'name' => 'CliDescriptorTest.php', + 'line' => 30, + 'file' => '/Users/ogi/symfony/src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php', + ], + ], + << [ + [ + 'source' => [ + 'name' => 'CliDescriptorTest.php', + 'line' => 30, + 'file_relative' => 'src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php', + 'file' => '/Users/ogi/symfony/src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php', + 'file_link' => 'phpstorm://open?file=/Users/ogi/symfony/src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php&line=30', + ], + ], + method_exists(OutputFormatterStyle::class, 'setHref') ? + << [ + [ + 'source' => [ + 'name' => 'CliDescriptorTest.php', + 'line' => 30, + 'file_relative' => 'src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php', + 'file_link' => 'phpstorm://open?file=/Users/ogi/symfony/src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php&line=30', + ], + ], + << [ + [ + 'cli' => [ + 'identifier' => 'd8bece1c', + 'command_line' => 'bin/phpunit', + ], + ], + << [ + [ + 'request' => [ + 'identifier' => 'd8bece1c', + 'controller' => new Data([['FooController.php']]), + 'method' => 'GET', + 'uri' => 'http://localhost/foo', + ], + ], + << + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Command\Descriptor; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\VarDumper\Cloner\Data; +use Symfony\Component\VarDumper\Command\Descriptor\HtmlDescriptor; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; + +class HtmlDescriptorTest extends TestCase +{ + private static $timezone; + + public static function setUpBeforeClass(): void + { + self::$timezone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + } + + public static function tearDownAfterClass(): void + { + date_default_timezone_set(self::$timezone); + } + + public function testItOutputsStylesAndScriptsOnFirstDescribeCall() + { + $output = new BufferedOutput(); + $dumper = $this->createMock(HtmlDumper::class); + $dumper->method('dump')->willReturn('[DUMPED]'); + $descriptor = new HtmlDescriptor($dumper); + + $descriptor->describe($output, new Data([[123]]), ['timestamp' => 1544804268.3668], 1); + + $this->assertStringMatchesFormat('%A', $output->fetch(), 'styles & scripts are output'); + + $descriptor->describe($output, new Data([[123]]), ['timestamp' => 1544804268.3668], 1); + + $this->assertStringNotMatchesFormat('%A', $output->fetch(), 'styles & scripts are output only once'); + } + + /** + * @dataProvider provideContext + */ + public function testDescribe(array $context, string $expectedOutput) + { + $output = new BufferedOutput(); + $dumper = $this->createMock(HtmlDumper::class); + $dumper->method('dump')->willReturn('[DUMPED]'); + $descriptor = new HtmlDescriptor($dumper); + + $descriptor->describe($output, new Data([[123]]), $context + ['timestamp' => 1544804268.3668], 1); + + $this->assertStringMatchesFormat(trim($expectedOutput), trim(preg_replace('@@s', '', $output->fetch()))); + } + + public function provideContext() + { + yield 'source' => [ + [ + 'source' => [ + 'name' => 'CliDescriptorTest.php', + 'line' => 30, + 'file' => '/Users/ogi/symfony/src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php', + ], + ], + << +
    +
    +

    -

    + +
    + +
    +
    +

    + CliDescriptorTest.php on line 30 +

    + [DUMPED] +
    + +TXT + ]; + + yield 'source full' => [ + [ + 'source' => [ + 'name' => 'CliDescriptorTest.php', + 'project_dir' => 'src/Symfony/', + 'line' => 30, + 'file_relative' => 'src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php', + 'file' => '/Users/ogi/symfony/src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php', + 'file_link' => 'phpstorm://open?file=/Users/ogi/symfony/src/Symfony/Component/VarDumper/Tests/Command/Descriptor/CliDescriptorTest.php&line=30', + ], + ], + << +
    +
    +

    -

    + +
    +
    +
      +
    • project dirsrc/Symfony/
    • +
    +
    +
    +
    +

    + CliDescriptorTest.php on line 30 +

    + [DUMPED] +
    + +TXT + ]; + + yield 'cli' => [ + [ + 'cli' => [ + 'identifier' => 'd8bece1c', + 'command_line' => 'bin/phpunit', + ], + ], + << +
    +
    +

    $ bin/phpunit

    + +
    + +
    +
    +

    + +

    + [DUMPED] +
    + +TXT + ]; + + yield 'request' => [ + [ + 'request' => [ + 'identifier' => 'd8bece1c', + 'controller' => new Data([['FooController.php']]), + 'method' => 'GET', + 'uri' => 'http://localhost/foo', + ], + ], + << +
    +
    +

    GET http://localhost/foo

    + +
    +
    +
      +
    • controller[DUMPED]
    • +
    +
    +
    +
    +

    + +

    + [DUMPED] +
    + +TXT + ]; + } +} diff --git a/vendor/symfony/var-dumper/Tests/Dumper/CliDumperTest.php b/vendor/symfony/var-dumper/Tests/Dumper/CliDumperTest.php new file mode 100644 index 0000000..fc62380 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Dumper/CliDumperTest.php @@ -0,0 +1,534 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; +use Twig\Environment; +use Twig\Loader\FilesystemLoader; + +/** + * @author Nicolas Grekas + */ +class CliDumperTest extends TestCase +{ + use VarDumperTestTrait; + + public function testGet() + { + require __DIR__.'/../Fixtures/dumb-var.php'; + + $dumper = new CliDumper('php://output'); + $dumper->setColors(false); + $cloner = new VarCloner(); + $cloner->addCasters([ + ':stream' => function ($res, $a) { + unset($a['uri'], $a['wrapper_data']); + + return $a; + }, + ]); + $data = $cloner->cloneVar($var); + + ob_start(); + $dumper->dump($data); + $out = ob_get_clean(); + $out = preg_replace('/[ \t]+$/m', '', $out); + $intMax = PHP_INT_MAX; + $res = (int) $var['res']; + + $this->assertStringMatchesFormat( + << 1 + 0 => &1 null + "const" => 1.1 + 1 => true + 2 => false + 3 => NAN + 4 => INF + 5 => -INF + 6 => {$intMax} + "str" => "déjà\\n" + 7 => b""" + é\\x00test\\t\\n + ing + """ + "[]" => [] + "res" => stream resource {@{$res} +%A wrapper_type: "plainfile" + stream_type: "STDIO" + mode: "r" + unread_bytes: 0 + seekable: true +%A options: [] + } + "obj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d + +foo: "foo" + +"bar": "bar" + } + "closure" => Closure(\$a, PDO &\$b = null) {#%d + class: "Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest" + this: Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest {#%d …} + file: "%s%eTests%eFixtures%edumb-var.php" + line: "{$var['line']} to {$var['line']}" + } + "line" => {$var['line']} + "nobj" => array:1 [ + 0 => &3 {#%d} + ] + "recurs" => &4 array:1 [ + 0 => &4 array:1 [&4] + ] + 8 => &1 null + "sobj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d} + "snobj" => &3 {#%d} + "snobj2" => {#%d} + "file" => "{$var['file']}" + b"bin-key-é" => "" +] + +EOTXT + , + $out + ); + } + + /** + * @dataProvider provideDumpWithCommaFlagTests + */ + public function testDumpWithCommaFlag($expected, $flags) + { + $dumper = new CliDumper(null, null, $flags); + $dumper->setColors(false); + $cloner = new VarCloner(); + + $var = [ + 'array' => ['a', 'b'], + 'string' => 'hello', + 'multiline string' => "this\nis\na\multiline\nstring", + ]; + + $dump = $dumper->dump($cloner->cloneVar($var), true); + + $this->assertSame($expected, $dump); + } + + public function testDumpWithCommaFlagsAndExceptionCodeExcerpt() + { + $dumper = new CliDumper(null, null, CliDumper::DUMP_TRAILING_COMMA); + $dumper->setColors(false); + $cloner = new VarCloner(); + + $ex = new \RuntimeException('foo'); + + $dump = $dumper->dump($cloner->cloneVar($ex)->withRefHandles(false), true); + + $this->assertStringMatchesFormat(<<<'EOTXT' +RuntimeException { + #message: "foo" + #code: 0 + #file: "%ACliDumperTest.php" + #line: %d + trace: { + %ACliDumperTest.php:%d { + › + › $ex = new \RuntimeException('foo'); + › + } + %A + } +} + +EOTXT + , $dump); + } + + public function provideDumpWithCommaFlagTests() + { + $expected = <<<'EOTXT' +array:3 [ + "array" => array:2 [ + 0 => "a", + 1 => "b" + ], + "string" => "hello", + "multiline string" => """ + this\n + is\n + a\multiline\n + string + """ +] + +EOTXT; + + yield [$expected, CliDumper::DUMP_COMMA_SEPARATOR]; + + $expected = <<<'EOTXT' +array:3 [ + "array" => array:2 [ + 0 => "a", + 1 => "b", + ], + "string" => "hello", + "multiline string" => """ + this\n + is\n + a\multiline\n + string + """, +] + +EOTXT; + + yield [$expected, CliDumper::DUMP_TRAILING_COMMA]; + } + + /** + * @requires extension xml + */ + public function testXmlResource() + { + $var = xml_parser_create(); + + $this->assertDumpMatchesFormat( + <<<'EOTXT' +xml resource { + current_byte_index: %i + current_column_number: %i + current_line_number: 1 + error_code: XML_ERROR_NONE +} +EOTXT + , + $var + ); + } + + public function testJsonCast() + { + $var = (array) json_decode('{"0":{},"1":null}'); + foreach ($var as &$v) { + } + $var[] = &$v; + $var[''] = 2; + + if (\PHP_VERSION_ID >= 70200) { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +array:4 [ + 0 => {} + 1 => &1 null + 2 => &1 null + "" => 2 +] +EOTXT + , + $var + ); + } else { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +array:4 [ + "0" => {} + "1" => &1 null + 0 => &1 null + "" => 2 +] +EOTXT + , + $var + ); + } + } + + public function testObjectCast() + { + $var = (object) [1 => 1]; + $var->{1} = 2; + + if (\PHP_VERSION_ID >= 70200) { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +{ + +"1": 2 +} +EOTXT + , + $var + ); + } else { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +{ + +1: 1 + +"1": 2 +} +EOTXT + , + $var + ); + } + } + + public function testClosedResource() + { + $var = fopen(__FILE__, 'r'); + fclose($var); + + $dumper = new CliDumper('php://output'); + $dumper->setColors(false); + $cloner = new VarCloner(); + $data = $cloner->cloneVar($var); + + ob_start(); + $dumper->dump($data); + $out = ob_get_clean(); + $res = (int) $var; + + $this->assertStringMatchesFormat( + << 'bar'], + ]; + + $this->assertDumpEquals( + << (3) "foo" + 2 => (3) "bar" + ] +] +EOTXT + , + $var + ); + + putenv('DUMP_LIGHT_ARRAY='); + putenv('DUMP_STRING_LENGTH='); + } + + /** + * @requires function Twig\Template::getSourceContext + */ + public function testThrowingCaster() + { + $out = fopen('php://memory', 'r+b'); + + require_once __DIR__.'/../Fixtures/Twig.php'; + $twig = new \__TwigTemplate_VarDumperFixture_u75a09(new Environment(new FilesystemLoader())); + + $dumper = new CliDumper(); + $dumper->setColors(false); + $cloner = new VarCloner(); + $cloner->addCasters([ + ':stream' => function ($res, $a) { + unset($a['wrapper_data']); + + return $a; + }, + ]); + $cloner->addCasters([ + ':stream' => eval('return function () use ($twig) { + try { + $twig->render([]); + } catch (\Twig\Error\RuntimeError $e) { + throw $e->getPrevious(); + } + };'), + ]); + $ref = (int) $out; + + $data = $cloner->cloneVar($out); + $dumper->dump($data, $out); + $out = stream_get_contents($out, -1, 0); + + $this->assertStringMatchesFormat( + << 'foo']; + $var->bar = &$var->foo; + + $dumper = new CliDumper(); + $dumper->setColors(false); + $cloner = new VarCloner(); + + $data = $cloner->cloneVar($var); + $out = $dumper->dump($data, true); + + $this->assertStringMatchesFormat( + <<getSpecialVars(); + + $this->assertDumpEquals( + <<<'EOTXT' +array:3 [ + 0 => array:1 [ + 0 => &1 array:1 [ + 0 => &1 array:1 [&1] + ] + ] + 1 => array:1 [ + "GLOBALS" => &2 array:1 [ + "GLOBALS" => &2 array:1 [&2] + ] + ] + 2 => &2 array:1 [&2] +] +EOTXT + , + $var + ); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testGlobals() + { + $var = $this->getSpecialVars(); + unset($var[0]); + $out = ''; + + $dumper = new CliDumper(function ($line, $depth) use (&$out) { + if ($depth >= 0) { + $out .= str_repeat(' ', $depth).$line."\n"; + } + }); + $dumper->setColors(false); + $cloner = new VarCloner(); + + $data = $cloner->cloneVar($var); + $dumper->dump($data); + + $this->assertSame( + <<<'EOTXT' +array:2 [ + 1 => array:1 [ + "GLOBALS" => &1 array:1 [ + "GLOBALS" => &1 array:1 [&1] + ] + ] + 2 => &1 array:1 [&1] +] + +EOTXT + , + $out + ); + } + + public function testIncompleteClass() + { + $unserializeCallbackHandler = ini_set('unserialize_callback_func', null); + $var = unserialize('O:8:"Foo\Buzz":0:{}'); + ini_set('unserialize_callback_func', $unserializeCallbackHandler); + + $this->assertDumpMatchesFormat( + << + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\VarDumper; + +class FunctionsTest extends TestCase +{ + public function testDumpReturnsFirstArg() + { + $this->setupVarDumper(); + + $var1 = 'a'; + + ob_start(); + $return = dump($var1); + ob_end_clean(); + + $this->assertEquals($var1, $return); + } + + public function testDumpReturnsAllArgsInArray() + { + $this->setupVarDumper(); + + $var1 = 'a'; + $var2 = 'b'; + $var3 = 'c'; + + ob_start(); + $return = dump($var1, $var2, $var3); + ob_end_clean(); + + $this->assertEquals([$var1, $var2, $var3], $return); + } + + protected function setupVarDumper() + { + $cloner = new VarCloner(); + $dumper = new CliDumper('php://output'); + VarDumper::setHandler(function ($var) use ($cloner, $dumper) { + $dumper->dump($cloner->cloneVar($var)); + }); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Dumper/HtmlDumperTest.php b/vendor/symfony/var-dumper/Tests/Dumper/HtmlDumperTest.php new file mode 100644 index 0000000..ae4ee8e --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Dumper/HtmlDumperTest.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; + +/** + * @author Nicolas Grekas + */ +class HtmlDumperTest extends TestCase +{ + public function testGet() + { + if (ini_get('xdebug.file_link_format') || get_cfg_var('xdebug.file_link_format')) { + $this->markTestSkipped('A custom file_link_format is defined.'); + } + + require __DIR__.'/../Fixtures/dumb-var.php'; + + $dumper = new HtmlDumper('php://output'); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $cloner = new VarCloner(); + $cloner->addCasters([ + ':stream' => function ($res, $a) { + unset($a['uri'], $a['wrapper_data']); + + return $a; + }, + ]); + $data = $cloner->cloneVar($var); + + ob_start(); + $dumper->dump($data); + $out = ob_get_clean(); + $out = preg_replace('/[ \t]+$/m', '', $out); + $var['file'] = htmlspecialchars($var['file'], ENT_QUOTES, 'UTF-8'); + $intMax = PHP_INT_MAX; + preg_match('/sf-dump-\d+/', $out, $dumpId); + $dumpId = $dumpId[0]; + $res = (int) $var['res']; + + $this->assertStringMatchesFormat( + <<array:24 [ + "number" => 1 + 0 => &1 null + "const" => 1.1 + 1 => true + 2 => false + 3 => NAN + 4 => INF + 5 => -INF + 6 => {$intMax} + "str" => "d&%s;j&%s;\\n" + 7 => b""" + é\\x00test\\t\\n + ing + """ + "[]" => [] + "res" => stream resource @{$res} +%A wrapper_type: "plainfile" + stream_type: "STDIO" + mode: "r" + unread_bytes: 0 + seekable: true +%A options: [] + } + "obj" => DumbFoo {#%d + +foo: "foo" + +"bar": "bar" + } + "closure" => Closure(\$a, PDO &\$b = null) {#%d + class: "Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest" + this: HtmlDumperTest {#%d &%s;} + file: "%s%eVarDumper%eTests%eFixtures%edumb-var.php" + line: "{$var['line']} to {$var['line']}" + } + "line" => {$var['line']} + "nobj" => array:1 [ + 0 => &3 {#%d} + ] + "recurs" => &4 array:1 [ + 0 => &4 array:1 [&4] + ] + 8 => &1 null + "sobj" => DumbFoo {#%d} + "snobj" => &3 {#%d} + "snobj2" => {#%d} + "file" => "{$var['file']}" + b"bin-key-&%s;" => "" +] + + +EOTXT + , + + $out + ); + } + + public function testCharset() + { + $var = mb_convert_encoding('Словарь', 'CP1251', 'UTF-8'); + + $dumper = new HtmlDumper('php://output', 'CP1251'); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $cloner = new VarCloner(); + + $data = $cloner->cloneVar($var); + $out = $dumper->dump($data, true); + + $this->assertStringMatchesFormat( + <<<'EOTXT' +b"Словарь" + + +EOTXT + , + $out + ); + } + + public function testAppend() + { + $out = fopen('php://memory', 'r+b'); + + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $cloner = new VarCloner(); + + $dumper->dump($cloner->cloneVar(123), $out); + $dumper->dump($cloner->cloneVar(456), $out); + + $out = stream_get_contents($out, -1, 0); + + $this->assertSame(<<<'EOTXT' +123 + +456 + + +EOTXT + , + $out + ); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Dumper/ServerDumperTest.php b/vendor/symfony/var-dumper/Tests/Dumper/ServerDumperTest.php new file mode 100644 index 0000000..b4bef49 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Dumper/ServerDumperTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Process\PhpProcess; +use Symfony\Component\Process\Process; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; +use Symfony\Component\VarDumper\Dumper\DataDumperInterface; +use Symfony\Component\VarDumper\Dumper\ServerDumper; + +class ServerDumperTest extends TestCase +{ + private const VAR_DUMPER_SERVER = 'tcp://127.0.0.1:9913'; + + public function testDumpForwardsToWrappedDumperWhenServerIsUnavailable() + { + $wrappedDumper = $this->getMockBuilder(DataDumperInterface::class)->getMock(); + + $dumper = new ServerDumper(self::VAR_DUMPER_SERVER, $wrappedDumper); + + $cloner = new VarCloner(); + $data = $cloner->cloneVar('foo'); + + $wrappedDumper->expects($this->once())->method('dump')->with($data); + + $dumper->dump($data); + } + + public function testDump() + { + $wrappedDumper = $this->getMockBuilder(DataDumperInterface::class)->getMock(); + $wrappedDumper->expects($this->never())->method('dump'); // test wrapped dumper is not used + + $cloner = new VarCloner(); + $data = $cloner->cloneVar('foo'); + $dumper = new ServerDumper(self::VAR_DUMPER_SERVER, $wrappedDumper, [ + 'foo_provider' => new class() implements ContextProviderInterface { + public function getContext(): ?array + { + return ['foo']; + } + }, + ]); + + $dumped = null; + $process = $this->getServerProcess(); + $process->start(function ($type, $buffer) use ($process, &$dumped, $dumper, $data) { + if (Process::ERR === $type) { + $process->stop(); + $this->fail(); + } elseif ("READY\n" === $buffer) { + $dumper->dump($data); + } else { + $dumped .= $buffer; + } + }); + + $process->wait(); + + $this->assertTrue($process->isSuccessful()); + $this->assertStringMatchesFormat(<<<'DUMP' +(3) "foo" +[ + "timestamp" => %d.%d + "foo_provider" => [ + (3) "foo" + ] +] +%d +DUMP + , $dumped); + } + + private function getServerProcess(): Process + { + $process = new PhpProcess(file_get_contents(__DIR__.'/../Fixtures/dump_server.php'), null, [ + 'COMPONENT_ROOT' => __DIR__.'/../../', + 'VAR_DUMPER_SERVER' => self::VAR_DUMPER_SERVER, + ]); + $process->inheritEnvironmentVariables(true); + + return $process->setTimeout(9); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Fixtures/FooInterface.php b/vendor/symfony/var-dumper/Tests/Fixtures/FooInterface.php new file mode 100644 index 0000000..172958b --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Fixtures/FooInterface.php @@ -0,0 +1,11 @@ +p2 = new \stdClass(); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php b/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php new file mode 100644 index 0000000..8b84d82 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Fixtures/Twig.php @@ -0,0 +1,38 @@ +parent = false; + $this->blocks = []; + $this->path = $path; + } + + protected function doDisplay(array $context, array $blocks = []) + { + // line 2 + throw new \Exception('Foobar'); + } + + public function getTemplateName() + { + return 'foo.twig'; + } + + public function getDebugInfo() + { + return [20 => 1, 21 => 2]; + } + + public function getSourceContext() + { + return new Twig\Source(" foo bar\n twig source\n\n", 'foo.twig', $this->path ?: __FILE__); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Fixtures/dumb-var.php b/vendor/symfony/var-dumper/Tests/Fixtures/dumb-var.php new file mode 100644 index 0000000..dcce237 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Fixtures/dumb-var.php @@ -0,0 +1,40 @@ +bar = 'bar'; + +$g = fopen(__FILE__, 'r'); + +$var = [ + 'number' => 1, null, + 'const' => 1.1, true, false, NAN, INF, -INF, PHP_INT_MAX, + 'str' => "déjà\n", "\xE9\x00test\t\ning", + '[]' => [], + 'res' => $g, + 'obj' => $foo, + 'closure' => function ($a, \PDO &$b = null) {}, + 'line' => __LINE__ - 1, + 'nobj' => [(object) []], +]; + +$r = []; +$r[] = &$r; + +$var['recurs'] = &$r; +$var[] = &$var[0]; +$var['sobj'] = $var['obj']; +$var['snobj'] = &$var['nobj'][0]; +$var['snobj2'] = $var['nobj'][0]; +$var['file'] = __FILE__; +$var["bin-key-\xE9"] = ''; + +unset($g, $r); diff --git a/vendor/symfony/var-dumper/Tests/Fixtures/dump_server.php b/vendor/symfony/var-dumper/Tests/Fixtures/dump_server.php new file mode 100644 index 0000000..ed8bbfb --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Fixtures/dump_server.php @@ -0,0 +1,38 @@ +setMaxItems(-1); + +$dumper = new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_STRING_LENGTH); +$dumper->setColors(false); + +VarDumper::setHandler(function ($var) use ($cloner, $dumper) { + $data = $cloner->cloneVar($var)->withRefHandles(false); + $dumper->dump($data); +}); + +$server = new DumpServer(getenv('VAR_DUMPER_SERVER')); + +$server->start(); + +echo "READY\n"; + +$server->listen(function (Data $data, array $context, $clientId) { + dump((string) $data, $context, $clientId); + + exit(0); +}); diff --git a/vendor/symfony/var-dumper/Tests/Fixtures/xml_reader.xml b/vendor/symfony/var-dumper/Tests/Fixtures/xml_reader.xml new file mode 100644 index 0000000..740c399 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Fixtures/xml_reader.xml @@ -0,0 +1,10 @@ + + + + + With text + + + + + diff --git a/vendor/symfony/var-dumper/Tests/Server/ConnectionTest.php b/vendor/symfony/var-dumper/Tests/Server/ConnectionTest.php new file mode 100644 index 0000000..21902b5 --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Server/ConnectionTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Server; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Process\PhpProcess; +use Symfony\Component\Process\Process; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface; +use Symfony\Component\VarDumper\Server\Connection; + +class ConnectionTest extends TestCase +{ + private const VAR_DUMPER_SERVER = 'tcp://127.0.0.1:9913'; + + public function testDump() + { + $cloner = new VarCloner(); + $data = $cloner->cloneVar('foo'); + $connection = new Connection(self::VAR_DUMPER_SERVER, [ + 'foo_provider' => new class() implements ContextProviderInterface { + public function getContext(): ?array + { + return ['foo']; + } + }, + ]); + + $dumped = null; + $process = $this->getServerProcess(); + $process->start(function ($type, $buffer) use ($process, &$dumped, $connection, $data) { + if (Process::ERR === $type) { + $process->stop(); + $this->fail(); + } elseif ("READY\n" === $buffer) { + $connection->write($data); + } else { + $dumped .= $buffer; + } + }); + + $process->wait(); + + $this->assertTrue($process->isSuccessful()); + $this->assertStringMatchesFormat(<<<'DUMP' +(3) "foo" +[ + "timestamp" => %d.%d + "foo_provider" => [ + (3) "foo" + ] +] +%d + +DUMP + , $dumped); + } + + public function testNoServer() + { + $cloner = new VarCloner(); + $data = $cloner->cloneVar('foo'); + $connection = new Connection(self::VAR_DUMPER_SERVER); + $start = microtime(true); + $this->assertFalse($connection->write($data)); + $this->assertLessThan(1, microtime(true) - $start); + } + + private function getServerProcess(): Process + { + $process = new PhpProcess(file_get_contents(__DIR__.'/../Fixtures/dump_server.php'), null, [ + 'COMPONENT_ROOT' => __DIR__.'/../../', + 'VAR_DUMPER_SERVER' => self::VAR_DUMPER_SERVER, + ]); + $process->inheritEnvironmentVariables(true); + + return $process->setTimeout(9); + } +} diff --git a/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php b/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php new file mode 100644 index 0000000..a4d489c --- /dev/null +++ b/vendor/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Test; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +class VarDumperTestTraitTest extends TestCase +{ + use VarDumperTestTrait; + + public function testItComparesLargeData() + { + $howMany = 700; + $data = array_fill_keys(range(0, $howMany), ['a', 'b', 'c', 'd']); + + $expected = sprintf("array:%d [\n", $howMany + 1); + for ($i = 0; $i <= $howMany; ++$i) { + $expected .= << array:4 [ + 0 => "a" + 1 => "b" + 2 => "c" + 3 => "d" + ]\n +EODUMP; + } + $expected .= "]\n"; + + $this->assertDumpEquals($expected, $data); + } + + public function testAllowsNonScalarExpectation() + { + $this->assertDumpEquals(new \ArrayObject(['bim' => 'bam']), new \ArrayObject(['bim' => 'bam'])); + } +} diff --git a/vendor/symfony/var-dumper/VarDumper.php b/vendor/symfony/var-dumper/VarDumper.php new file mode 100644 index 0000000..009f662 --- /dev/null +++ b/vendor/symfony/var-dumper/VarDumper.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper; + +use Symfony\Component\VarDumper\Caster\ReflectionCaster; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; + +// Load the global dump() function +require_once __DIR__.'/Resources/functions/dump.php'; + +/** + * @author Nicolas Grekas + */ +class VarDumper +{ + private static $handler; + + public static function dump($var) + { + if (null === self::$handler) { + $cloner = new VarCloner(); + $cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO); + + if (isset($_SERVER['VAR_DUMPER_FORMAT'])) { + $dumper = 'html' === $_SERVER['VAR_DUMPER_FORMAT'] ? new HtmlDumper() : new CliDumper(); + } else { + $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg']) ? new CliDumper() : new HtmlDumper(); + } + + self::$handler = function ($var) use ($cloner, $dumper) { + $dumper->dump($cloner->cloneVar($var)); + }; + } + + return (self::$handler)($var); + } + + public static function setHandler(callable $callable = null) + { + $prevHandler = self::$handler; + self::$handler = $callable; + + return $prevHandler; + } +} diff --git a/vendor/symfony/var-dumper/composer.json b/vendor/symfony/var-dumper/composer.json new file mode 100644 index 0000000..b0c0273 --- /dev/null +++ b/vendor/symfony/var-dumper/composer.json @@ -0,0 +1,54 @@ +{ + "name": "symfony/var-dumper", + "type": "library", + "description": "Symfony mechanism for exploring and dumping PHP variables", + "keywords": ["dump", "debug"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0", + "twig/twig": "~1.34|~2.4" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/console": "<3.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "autoload": { + "files": [ "Resources/functions/dump.php" ], + "psr-4": { "Symfony\\Component\\VarDumper\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + } +} diff --git a/vendor/symfony/var-dumper/phpunit.xml.dist b/vendor/symfony/var-dumper/phpunit.xml.dist new file mode 100644 index 0000000..3243fcd --- /dev/null +++ b/vendor/symfony/var-dumper/phpunit.xml.dist @@ -0,0 +1,33 @@ + + + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/vendor/topthink/framework/.gitignore b/vendor/topthink/framework/.gitignore new file mode 100644 index 0000000..b267fba --- /dev/null +++ b/vendor/topthink/framework/.gitignore @@ -0,0 +1,7 @@ +/vendor +composer.phar +composer.lock +.DS_Store +Thumbs.db +/.idea +/.vscode \ No newline at end of file diff --git a/vendor/topthink/framework/.travis.yml b/vendor/topthink/framework/.travis.yml new file mode 100644 index 0000000..73e6681 --- /dev/null +++ b/vendor/topthink/framework/.travis.yml @@ -0,0 +1,34 @@ +dist: xenial +language: php + +matrix: + fast_finish: true + include: + - php: 7.1 + - php: 7.2 + - php: 7.3 + +cache: + directories: + - $HOME/.composer/cache + +services: + - memcached + - redis-server + - mysql + +before_install: + - echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + - printf "\n" | pecl install -f redis + - travis_retry composer self-update + - mysql -e 'CREATE DATABASE test;' + +install: + - travis_retry composer update --prefer-dist --no-interaction --prefer-stable --no-suggest + +script: + - vendor/bin/phpunit --coverage-clover build/logs/coverage.xml + +after_script: + - travis_retry wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover build/logs/coverage.xml \ No newline at end of file diff --git a/vendor/topthink/framework/CONTRIBUTING.md b/vendor/topthink/framework/CONTRIBUTING.md new file mode 100644 index 0000000..efa3ad9 --- /dev/null +++ b/vendor/topthink/framework/CONTRIBUTING.md @@ -0,0 +1,119 @@ +如何贡献我的源代码 +=== + +此文档介绍了 ThinkPHP 团队的组成以及运转机制,您提交的代码将给 ThinkPHP 项目带来什么好处,以及如何才能加入我们的行列。 + +## 通过 Github 贡献代码 + +ThinkPHP 目前使用 Git 来控制程序版本,如果你想为 ThinkPHP 贡献源代码,请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上,任何 GitHub 用户都可以向我们贡献代码。 + +参与的方式很简单,`fork`一份 ThinkPHP 的代码到你的仓库中,修改后提交,并向我们发起`pull request`申请,我们会及时对代码进行审查并处理你的申请并。审查通过后,你的代码将被`merge`进我们的仓库中,这样你就会自动出现在贡献者名单里了,非常方便。 + +我们希望你贡献的代码符合: + +* ThinkPHP 的编码规范 +* 适当的注释,能让其他人读懂 +* 遵循 Apache2 开源协议 + +**如果想要了解更多细节或有任何疑问,请继续阅读下面的内容** + +### 注意事项 + +* 本项目代码格式化标准选用 [**PSR-2**](http://www.kancloud.cn/thinkphp/php-fig-psr/3141); +* 类名和类文件名遵循 [**PSR-4**](http://www.kancloud.cn/thinkphp/php-fig-psr/3144); +* 对于 Issues 的处理,请使用诸如 `fix #xxx(Issue ID)` 的 commit title 直接关闭 issue。 +* 系统会自动在 PHP 7.1 ~ 7.3 上测试修改,请确保你的修改符合 PHP 7.1 ~ 7.3 的语法规范; +* 管理员不会合并造成 CI faild 的修改,若出现 CI faild 请检查自己的源代码或修改相应的[单元测试文件](tests); + +## GitHub Issue + +GitHub 提供了 Issue 功能,该功能可以用于: + +* 提出 bug +* 提出功能改进 +* 反馈使用体验 + +该功能不应该用于: + + * 提出修改意见(涉及代码署名和修订追溯问题) + * 不友善的言论 + +## 快速修改 + +**GitHub 提供了快速编辑文件的功能** + +1. 登录 GitHub 帐号; +2. 浏览项目文件,找到要进行修改的文件; +3. 点击右上角铅笔图标进行修改; +4. 填写 `Commit changes` 相关内容(Title 必填); +5. 提交修改,等待 CI 验证和管理员合并。 + +**若您需要一次提交大量修改,请继续阅读下面的内容** + +## 完整流程 + +1. `fork`本项目; +2. 克隆(`clone`)你 `fork` 的项目到本地; +3. 新建分支(`branch`)并检出(`checkout`)新分支; +4. 添加本项目到你的本地 git 仓库作为上游(`upstream`); +5. 进行修改,若你的修改包含方法或函数的增减,请记得修改[单元测试文件](tests); +6. 变基(衍合 `rebase`)你的分支到上游 master 分支; +7. `push` 你的本地仓库到 GitHub; +8. 提交 `pull request`; +9. 等待 CI 验证(若不通过则重复 5~7,GitHub 会自动更新你的 `pull request`); +10. 等待管理员处理,并及时 `rebase` 你的分支到上游 master 分支(若上游 master 分支有修改)。 + +*若有必要,可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`* + +*绝对不可以使用 `git push -f` 强行推送修改到上游* + +### 注意事项 + +* 若对上述流程有任何不清楚的地方,请查阅 GIT 教程,如 [这个](http://backlogtool.com/git-guide/cn/); +* 对于代码**不同方面**的修改,请在自己 `fork` 的项目中**创建不同的分支**(原因参见`完整流程`第9条备注部分); +* 变基及交互式变基操作参见 [Git 交互式变基](http://pakchoi.me/2015/03/17/git-interactive-rebase/) + +## 推荐资源 + +### 开发环境 + +* XAMPP for Windows 5.5.x +* WampServer (for Windows) +* upupw Apache PHP5.4 ( for Windows) + +或自行安装 + +- Apache / Nginx +- PHP 7.1 ~ 7.3 +- MySQL / MariaDB + +*Windows 用户推荐添加 PHP bin 目录到 PATH,方便使用 composer* + +*Linux 用户自行配置环境, Mac 用户推荐使用内置 Apache 配合 Homebrew 安装 PHP 和 MariaDB* + +### 编辑器 + +Sublime Text 3 + phpfmt 插件 + +phpfmt 插件参数 + +```json +{ + "autocomplete": true, + "enable_auto_align": true, + "format_on_save": true, + "indent_with_space": true, + "psr1_naming": false, + "psr2": true, + "version": 4 +} +``` + +或其他 编辑器 / IDE 配合 PSR2 自动格式化工具 + +### Git GUI + +* SourceTree +* GitHub Desktop + +或其他 Git 图形界面客户端 diff --git a/vendor/topthink/framework/LICENSE.txt b/vendor/topthink/framework/LICENSE.txt new file mode 100644 index 0000000..4e910bb --- /dev/null +++ b/vendor/topthink/framework/LICENSE.txt @@ -0,0 +1,32 @@ + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 +版权所有Copyright © 2006-2019 by ThinkPHP (http://thinkphp.cn) +All rights reserved。 +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +Apache Licence是著名的非盈利开源组织Apache采用的协议。 +该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, +允许代码修改,再作为开源或商业软件发布。需要满足 +的条件: +1. 需要给代码的用户一份Apache Licence ; +2. 如果你修改了代码,需要在被修改的文件中说明; +3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 +带有原来代码中的协议,商标,专利声明和其他原来作者规 +定需要包含的说明; +4. 如果再发布的产品中包含一个Notice文件,则在Notice文 +件中需要带有本协议内容。你可以在Notice中增加自己的 +许可,但不可以表现为对Apache Licence构成更改。 +具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/topthink/framework/README.md b/vendor/topthink/framework/README.md new file mode 100644 index 0000000..8c856b4 --- /dev/null +++ b/vendor/topthink/framework/README.md @@ -0,0 +1,86 @@ +![](https://box.kancloud.cn/5a0aaa69a5ff42657b5c4715f3d49221) + +ThinkPHP 6.0 +=============== + +[![Build Status](https://travis-ci.org/top-think/framework.svg?branch=6.0)](https://travis-ci.org/top-think/framework) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/top-think/framework/badges/quality-score.png?b=6.0)](https://scrutinizer-ci.com/g/top-think/framework/?branch=6.0) +[![Code Coverage](https://scrutinizer-ci.com/g/top-think/framework/badges/coverage.png?b=6.0)](https://scrutinizer-ci.com/g/top-think/framework/?branch=6.0) +[![Total Downloads](https://poser.pugx.org/topthink/framework/downloads)](https://packagist.org/packages/topthink/framework) +[![Latest Stable Version](https://poser.pugx.org/topthink/framework/v/stable)](https://packagist.org/packages/topthink/framework) +[![PHP Version](https://img.shields.io/badge/php-%3E%3D7.1-8892BF.svg)](http://www.php.net/) +[![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework) + +ThinkPHP6.0底层架构采用PHP7.1改写和进一步优化。 + +## 主要新特性 + +* 采用`PHP7`强类型(严格模式) +* 支持更多的`PSR`规范 +* 原生多应用支持 +* 系统服务注入支持 +* ORM作为独立组件使用 +* 增加Filesystem +* 全新的事件系统 +* 模板引擎分离出核心 +* 内部功能中间件化 +* SESSION机制改进 +* 日志多通道支持 +* 规范扩展接口 +* 更强大的控制台 +* 对Swoole以及协程支持改进 +* 对IDE更加友好 +* 统一和精简大量用法 + + +> ThinkPHP6.0的运行环境要求PHP7.1+。 + +## 安装 + +~~~ +composer create-project topthink/think tp +~~~ + +启动服务 + +~~~ +cd tp +php think run +~~~ + +然后就可以在浏览器中访问 + +~~~ +http://localhost:8000 +~~~ + +如果需要更新框架使用 +~~~ +composer update topthink/framework +~~~ + +## 文档 + +[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content) + +## 命名规范 + +`ThinkPHP6`遵循PSR-2命名规范和PSR-4自动加载规范。 + +## 参与开发 + +请参阅 [ThinkPHP核心框架包](https://github.com/top-think/framework)。 + +## 版权信息 + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 + +本项目包含的第三方源码和二进制文件之版权信息另行标注。 + +版权所有Copyright © 2006-2019 by ThinkPHP (http://thinkphp.cn) + +All rights reserved。 + +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +更多细节参阅 [LICENSE.txt](LICENSE.txt) diff --git a/vendor/topthink/framework/composer.json b/vendor/topthink/framework/composer.json new file mode 100644 index 0000000..017b3d9 --- /dev/null +++ b/vendor/topthink/framework/composer.json @@ -0,0 +1,55 @@ +{ + "name": "topthink/framework", + "description": "The ThinkPHP Framework.", + "keywords": [ + "framework", + "thinkphp", + "ORM" + ], + "homepage": "http://thinkphp.cn/", + "license": "Apache-2.0", + "authors": [ + { + "name": "liu21st", + "email": "liu21st@gmail.com" + }, + { + "name": "yunwuxin", + "email": "448901948@qq.com" + } + ], + "require": { + "php": ">=7.1.0", + "ext-json": "*", + "ext-mbstring": "*", + "league/flysystem": "^1.0", + "league/flysystem-cached-adapter": "^1.0", + "opis/closure": "^3.1", + "psr/log": "~1.0", + "psr/container": "~1.0", + "psr/simple-cache": "^1.0", + "topthink/think-orm": "^2.0", + "topthink/think-helper": "^3.1.1" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^7.0" + }, + "autoload": { + "files": [], + "psr-4": { + "think\\": "src/think/" + } + }, + "autoload-dev": { + "psr-4": { + "think\\tests\\": "src/tests/" + } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true + } +} diff --git a/vendor/topthink/framework/logo.png b/vendor/topthink/framework/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..25fd0593688de5c9f4cd321da1a72ab9566fe331 GIT binary patch literal 6995 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 literal 0 HcmV?d00001 diff --git a/vendor/topthink/framework/phpunit.xml.dist b/vendor/topthink/framework/phpunit.xml.dist new file mode 100644 index 0000000..e20a133 --- /dev/null +++ b/vendor/topthink/framework/phpunit.xml.dist @@ -0,0 +1,25 @@ + + + + + ./tests + + + + + ./src/think + + + diff --git a/vendor/topthink/framework/src/helper.php b/vendor/topthink/framework/src/helper.php new file mode 100644 index 0000000..d1ba047 --- /dev/null +++ b/vendor/topthink/framework/src/helper.php @@ -0,0 +1,663 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +//------------------------ +// ThinkPHP 助手函数 +//------------------------- + +use think\App; +use think\Container; +use think\exception\HttpException; +use think\exception\HttpResponseException; +use think\facade\Cache; +use think\facade\Config; +use think\facade\Cookie; +use think\facade\Env; +use think\facade\Event; +use think\facade\Lang; +use think\facade\Log; +use think\facade\Request; +use think\facade\Route; +use think\facade\Session; +use think\Response; +use think\response\File; +use think\response\Json; +use think\response\Jsonp; +use think\response\Redirect; +use think\response\View; +use think\response\Xml; +use think\route\Url as UrlBuild; +use think\Validate; + +if (!function_exists('abort')) { + /** + * 抛出HTTP异常 + * @param integer|Response $code 状态码 或者 Response对象实例 + * @param string $message 错误信息 + * @param array $header 参数 + */ + function abort($code, string $message = '', array $header = []) + { + if ($code instanceof Response) { + throw new HttpResponseException($code); + } else { + throw new HttpException($code, $message, null, $header); + } + } +} + +if (!function_exists('app')) { + /** + * 快速获取容器中的实例 支持依赖注入 + * @param string $name 类名或标识 默认获取当前应用实例 + * @param array $args 参数 + * @param bool $newInstance 是否每次创建新的实例 + * @return object|App + */ + function app(string $name = '', array $args = [], bool $newInstance = false) + { + return Container::getInstance()->make($name ?: App::class, $args, $newInstance); + } +} + +if (!function_exists('bind')) { + /** + * 绑定一个类到容器 + * @param string|array $abstract 类标识、接口(支持批量绑定) + * @param mixed $concrete 要绑定的类、闭包或者实例 + * @return Container + */ + function bind($abstract, $concrete = null) + { + return Container::getInstance()->bind($abstract, $concrete); + } +} + +if (!function_exists('cache')) { + /** + * 缓存管理 + * @param string $name 缓存名称 + * @param mixed $value 缓存值 + * @param mixed $options 缓存参数 + * @param string $tag 缓存标签 + * @return mixed + */ + function cache(string $name = null, $value = '', $options = null, $tag = null) + { + if (is_null($name)) { + return app('cache'); + } + + if ('' === $value) { + // 获取缓存 + return 0 === strpos($name, '?') ? Cache::has(substr($name, 1)) : Cache::get($name); + } elseif (is_null($value)) { + // 删除缓存 + return Cache::delete($name); + } + + // 缓存数据 + if (is_array($options)) { + $expire = $options['expire'] ?? null; //修复查询缓存无法设置过期时间 + } else { + $expire = $options; + } + + if (is_null($tag)) { + return Cache::set($name, $value, $expire); + } else { + return Cache::tag($tag)->set($name, $value, $expire); + } + } +} + +if (!function_exists('config')) { + /** + * 获取和设置配置参数 + * @param string|array $name 参数名 + * @param mixed $value 参数值 + * @return mixed + */ + function config($name = '', $value = null) + { + if (is_array($name)) { + return Config::set($name, $value); + } + + return 0 === strpos($name, '?') ? Config::has(substr($name, 1)) : Config::get($name, $value); + } +} + +if (!function_exists('cookie')) { + /** + * Cookie管理 + * @param string $name cookie名称 + * @param mixed $value cookie值 + * @param mixed $option 参数 + * @return mixed + */ + function cookie(string $name, $value = '', $option = null) + { + if (is_null($value)) { + // 删除 + Cookie::delete($name); + } elseif ('' === $value) { + // 获取 + return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1)) : Cookie::get($name); + } else { + // 设置 + return Cookie::set($name, $value, $option); + } + } +} + +if (!function_exists('download')) { + /** + * 获取\think\response\Download对象实例 + * @param string $filename 要下载的文件 + * @param string $name 显示文件名 + * @param bool $content 是否为内容 + * @param int $expire 有效期(秒) + * @return \think\response\File + */ + function download(string $filename, string $name = '', bool $content = false, int $expire = 180): File + { + return Response::create($filename, 'file')->name($name)->isContent($content)->expire($expire); + } +} + +if (!function_exists('dump')) { + /** + * 浏览器友好的变量输出 + * @param mixed $vars 要输出的变量 + * @return void + */ + function dump(...$vars) + { + ob_start(); + var_dump(...$vars); + + $output = ob_get_clean(); + $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output); + + if (PHP_SAPI == 'cli') { + $output = PHP_EOL . $output . PHP_EOL; + } else { + if (!extension_loaded('xdebug')) { + $output = htmlspecialchars($output, ENT_SUBSTITUTE); + } + $output = '
    ' . $output . '
    '; + } + + echo $output; + } +} + +if (!function_exists('env')) { + /** + * 获取环境变量值 + * @access public + * @param string $name 环境变量名(支持二级 .号分割) + * @param string $default 默认值 + * @return mixed + */ + function env(string $name = null, $default = null) + { + return Env::get($name, $default); + } +} + +if (!function_exists('event')) { + /** + * 触发事件 + * @param mixed $event 事件名(或者类名) + * @param mixed $args 参数 + * @return mixed + */ + function event($event, $args = null) + { + return Event::trigger($event, $args); + } +} + +if (!function_exists('halt')) { + /** + * 调试变量并且中断输出 + * @param mixed $vars 调试变量或者信息 + */ + function halt(...$vars) + { + dump(...$vars); + + throw new HttpResponseException(Response::create()); + } +} + +if (!function_exists('input')) { + /** + * 获取输入数据 支持默认值和过滤 + * @param string $key 获取的变量名 + * @param mixed $default 默认值 + * @param string $filter 过滤方法 + * @return mixed + */ + function input(string $key = '', $default = null, $filter = '') + { + if (0 === strpos($key, '?')) { + $key = substr($key, 1); + $has = true; + } + + if ($pos = strpos($key, '.')) { + // 指定参数来源 + $method = substr($key, 0, $pos); + if (in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) { + $key = substr($key, $pos + 1); + if ('server' == $method && is_null($default)) { + $default = ''; + } + } else { + $method = 'param'; + } + } else { + // 默认为自动判断 + $method = 'param'; + } + + return isset($has) ? + request()->has($key, $method) : + request()->$method($key, $default, $filter); + } +} + +if (!function_exists('invoke')) { + /** + * 调用反射实例化对象或者执行方法 支持依赖注入 + * @param mixed $call 类名或者callable + * @param array $args 参数 + * @return mixed + */ + function invoke($call, array $args = []) + { + if (is_callable($call)) { + return Container::getInstance()->invoke($call, $args); + } + + return Container::getInstance()->invokeClass($call, $args); + } +} + +if (!function_exists('json')) { + /** + * 获取\think\response\Json对象实例 + * @param mixed $data 返回的数据 + * @param int $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Json + */ + function json($data = [], $code = 200, $header = [], $options = []): Json + { + return Response::create($data, 'json', $code)->header($header)->options($options); + } +} + +if (!function_exists('jsonp')) { + /** + * 获取\think\response\Jsonp对象实例 + * @param mixed $data 返回的数据 + * @param int $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Jsonp + */ + function jsonp($data = [], $code = 200, $header = [], $options = []): Jsonp + { + return Response::create($data, 'jsonp', $code)->header($header)->options($options); + } +} + +if (!function_exists('lang')) { + /** + * 获取语言变量值 + * @param string $name 语言变量名 + * @param array $vars 动态变量值 + * @param string $lang 语言 + * @return mixed + */ + function lang(string $name, array $vars = [], string $lang = '') + { + return Lang::get($name, $vars, $lang); + } +} + +if (!function_exists('parse_name')) { + /** + * 字符串命名风格转换 + * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格 + * @param string $name 字符串 + * @param int $type 转换类型 + * @param bool $ucfirst 首字母是否大写(驼峰规则) + * @return string + */ + function parse_name(string $name, int $type = 0, bool $ucfirst = true): string + { + if ($type) { + $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) { + return strtoupper($match[1]); + }, $name); + + return $ucfirst ? ucfirst($name) : lcfirst($name); + } + + return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); + } +} + +if (!function_exists('redirect')) { + /** + * 获取\think\response\Redirect对象实例 + * @param string $url 重定向地址 + * @param int $code 状态码 + * @return \think\response\Redirect + */ + function redirect(string $url = '', int $code = 302): Redirect + { + return Response::create($url, 'redirect', $code); + } +} + +if (!function_exists('request')) { + /** + * 获取当前Request对象实例 + * @return Request + */ + function request(): \think\Request + { + return app('request'); + } +} + +if (!function_exists('response')) { + /** + * 创建普通 Response 对象实例 + * @param mixed $data 输出数据 + * @param int|string $code 状态码 + * @param array $header 头信息 + * @param string $type + * @return Response + */ + function response($data = '', $code = 200, $header = [], $type = 'html'): Response + { + return Response::create($data, $type, $code)->header($header); + } +} + +if (!function_exists('session')) { + /** + * Session管理 + * @param string $name session名称 + * @param mixed $value session值 + * @return mixed + */ + function session($name = '', $value = '') + { + if (is_null($name)) { + // 清除 + Session::clear(); + } elseif ('' === $name) { + return Session::all(); + } elseif (is_null($value)) { + // 删除 + Session::delete($name); + } elseif ('' === $value) { + // 判断或获取 + return 0 === strpos($name, '?') ? Session::has(substr($name, 1)) : Session::get($name); + } else { + // 设置 + Session::set($name, $value); + } + } +} + +if (!function_exists('token')) { + /** + * 获取Token令牌 + * @param string $name 令牌名称 + * @param mixed $type 令牌生成方法 + * @return string + */ + function token(string $name = '__token__', string $type = 'md5'): string + { + return Request::buildToken($name, $type); + } +} + +if (!function_exists('token_field')) { + /** + * 生成令牌隐藏表单 + * @param string $name 令牌名称 + * @param mixed $type 令牌生成方法 + * @return string + */ + function token_field(string $name = '__token__', string $type = 'md5'): string + { + $token = Request::buildToken($name, $type); + + return ''; + } +} + +if (!function_exists('token_meta')) { + /** + * 生成令牌meta + * @param string $name 令牌名称 + * @param mixed $type 令牌生成方法 + * @return string + */ + function token_meta(string $name = '__token__', string $type = 'md5'): string + { + $token = Request::buildToken($name, $type); + + return ''; + } +} + +if (!function_exists('trace')) { + /** + * 记录日志信息 + * @param mixed $log log信息 支持字符串和数组 + * @param string $level 日志级别 + * @return array|void + */ + function trace($log = '[think]', string $level = 'log') + { + if ('[think]' === $log) { + return Log::getLog(); + } + + Log::record($log, $level); + } +} + +if (!function_exists('url')) { + /** + * Url生成 + * @param string $url 路由地址 + * @param array $vars 变量 + * @param bool|string $suffix 生成的URL后缀 + * @param bool|string $domain 域名 + * @return UrlBuild + */ + function url(string $url = '', array $vars = [], $suffix = true, $domain = false): UrlBuild + { + return Route::buildUrl($url, $vars)->suffix($suffix)->domain($domain); + } +} + +if (!function_exists('validate')) { + /** + * 生成验证对象 + * @param string|array $validate 验证器类名或者验证规则数组 + * @param array $message 错误提示信息 + * @param bool $batch 是否批量验证 + * @param bool $failException 是否抛出异常 + * @return Validate + */ + function validate($validate = '', array $message = [], bool $batch = false, bool $failException = true): Validate + { + if (is_array($validate) || '' === $validate) { + $v = new Validate(); + if (is_array($validate)) { + $v->rule($validate); + } + } else { + if (strpos($validate, '.')) { + // 支持场景 + [$validate, $scene] = explode('.', $validate); + } + + $class = false !== strpos($validate, '\\') ? $validate : app()->parseClass('validate', $validate); + + $v = new $class(); + + if (!empty($scene)) { + $v->scene($scene); + } + } + + return $v->message($message)->batch($batch)->failException($failException); + } +} + +if (!function_exists('view')) { + /** + * 渲染模板输出 + * @param string $template 模板文件 + * @param array $vars 模板变量 + * @param int $code 状态码 + * @param callable $filter 内容过滤 + * @return \think\response\View + */ + function view(string $template = '', $vars = [], $code = 200, $filter = null): View + { + return Response::create($template, 'view', $code)->assign($vars)->filter($filter); + } +} + +if (!function_exists('display')) { + /** + * 渲染模板输出 + * @param string $content 渲染内容 + * @param array $vars 模板变量 + * @param int $code 状态码 + * @param callable $filter 内容过滤 + * @return \think\response\View + */ + function display(string $content, $vars = [], $code = 200, $filter = null): View + { + return Response::create($content, 'view', $code)->isContent(true)->assign($vars)->filter($filter); + } +} + +if (!function_exists('xml')) { + /** + * 获取\think\response\Xml对象实例 + * @param mixed $data 返回的数据 + * @param int $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Xml + */ + function xml($data = [], $code = 200, $header = [], $options = []): Xml + { + return Response::create($data, 'xml', $code)->header($header)->options($options); + } +} + +if (!function_exists('app_path')) { + /** + * 获取当前应用目录 + * + * @param string $path + * @return string + */ + function app_path($path = '') + { + return app()->getAppPath() . ($path ? $path . DIRECTORY_SEPARATOR : $path); + } +} + +if (!function_exists('base_path')) { + /** + * 获取应用基础目录 + * + * @param string $path + * @return string + */ + function base_path($path = '') + { + return app()->getBasePath() . ($path ? $path . DIRECTORY_SEPARATOR : $path); + } +} + +if (!function_exists('config_path')) { + /** + * 获取应用配置目录 + * + * @param string $path + * @return string + */ + function config_path($path = '') + { + return app()->getConfigPath() . ($path ? $path . DIRECTORY_SEPARATOR : $path); + } +} + +if (!function_exists('public_path')) { + /** + * 获取web根目录 + * + * @param string $path + * @return string + */ + function public_path($path = '') + { + return app()->getRootPath() . ($path ? ltrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $path); + } +} + +if (!function_exists('runtime_path')) { + /** + * 获取应用运行时目录 + * + * @param string $path + * @return string + */ + function runtime_path($path = '') + { + return app()->getRuntimePath() . ($path ? $path . DIRECTORY_SEPARATOR : $path); + } +} + +if (!function_exists('root_path')) { + /** + * 获取项目根目录 + * + * @param string $path + * @return string + */ + function root_path($path = '') + { + return app()->getRootPath() . ($path ? $path . DIRECTORY_SEPARATOR : $path); + } +} diff --git a/vendor/topthink/framework/src/lang/zh-cn.php b/vendor/topthink/framework/src/lang/zh-cn.php new file mode 100644 index 0000000..83d8a1e --- /dev/null +++ b/vendor/topthink/framework/src/lang/zh-cn.php @@ -0,0 +1,148 @@ + +// +---------------------------------------------------------------------- + +// 核心中文语言包 +return [ + // 系统错误提示 + 'Undefined variable' => '未定义变量', + 'Undefined index' => '未定义数组索引', + 'Undefined offset' => '未定义数组下标', + 'Parse error' => '语法解析错误', + 'Type error' => '类型错误', + 'Fatal error' => '致命错误', + 'syntax error' => '语法错误', + + // 框架核心错误提示 + 'dispatch type not support' => '不支持的调度类型', + 'method param miss' => '方法参数错误', + 'method not exists' => '方法不存在', + 'function not exists' => '函数不存在', + 'app not exists' => '应用不存在', + 'controller not exists' => '控制器不存在', + 'class not exists' => '类不存在', + 'property not exists' => '类的属性不存在', + 'template not exists' => '模板文件不存在', + 'illegal controller name' => '非法的控制器名称', + 'illegal action name' => '非法的操作名称', + 'url suffix deny' => '禁止的URL后缀访问', + 'Undefined cache config' => '缓存配置未定义', + 'Route Not Found' => '当前访问路由未定义或不匹配', + 'Undefined db config' => '数据库配置未定义', + 'Undefined log config' => '日志配置未定义', + 'Undefined db type' => '未定义数据库类型', + 'variable type error' => '变量类型错误', + 'PSR-4 error' => 'PSR-4 规范错误', + 'not support type' => '不支持的分页索引字段类型', + 'not support total' => '简洁模式下不能获取数据总数', + 'not support last' => '简洁模式下不能获取最后一页', + 'error session handler' => '错误的SESSION处理器类', + 'not allow php tag' => '模板不允许使用PHP语法', + 'not support' => '不支持', + 'database config error' => '数据库配置信息错误', + 'redisd master' => 'Redisd 主服务器错误', + 'redisd slave' => 'Redisd 从服务器错误', + 'must run at sae' => '必须在SAE运行', + 'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务', + 'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务', + 'fields not exists' => '数据表字段不存在', + 'where express error' => '查询表达式错误', + 'no data to update' => '没有任何数据需要更新', + 'miss data to insert' => '缺少需要写入的数据', + 'miss complex primary data' => '缺少复合主键数据', + 'miss update condition' => '缺少更新条件', + 'model data Not Found' => '模型数据不存在', + 'table data not Found' => '表数据不存在', + 'delete without condition' => '没有条件不会执行删除操作', + 'miss relation data' => '缺少关联表数据', + 'tag attr must' => '模板标签属性必须', + 'tag error' => '模板标签错误', + 'cache write error' => '缓存写入失败', + 'sae mc write error' => 'SAE mc 写入错误', + 'route name not exists' => '路由标识不存在(或参数不够)', + 'invalid request' => '非法请求', + 'bind attr has exists' => '模型的属性已经存在', + 'relation data not exists' => '关联数据不存在', + 'relation not support' => '关联不支持', + 'chunk not support order' => 'Chunk不支持调用order方法', + 'route pattern error' => '路由变量规则定义错误', + 'route behavior will not support' => '路由行为废弃(使用中间件替代)', + 'closure not support cache(true)' => '使用闭包查询不支持cache(true),请指定缓存Key', + + // 上传错误信息 + 'unknown upload error' => '未知上传错误!', + 'file write error' => '文件写入失败!', + 'upload temp dir not found' => '找不到临时文件夹!', + 'no file to uploaded' => '没有文件被上传!', + 'only the portion of file is uploaded' => '文件只有部分被上传!', + 'upload File size exceeds the maximum value' => '上传文件大小超过了最大值!', + 'upload write error' => '文件上传保存错误!', + 'has the same filename: {:filename}' => '存在同名文件:{:filename}', + 'upload illegal files' => '非法上传文件', + 'illegal image files' => '非法图片文件', + 'extensions to upload is not allowed' => '上传文件后缀不允许', + 'mimetype to upload is not allowed' => '上传文件MIME类型不允许!', + 'filesize not match' => '上传文件大小不符!', + 'directory {:path} creation failed' => '目录 {:path} 创建失败!', + + 'The middleware must return Response instance' => '中间件方法必须返回Response对象实例', + 'The queue was exhausted, with no response returned' => '中间件队列为空', + // Validate Error Message + ':attribute require' => ':attribute不能为空', + ':attribute must' => ':attribute必须', + ':attribute must be numeric' => ':attribute必须是数字', + ':attribute must be integer' => ':attribute必须是整数', + ':attribute must be float' => ':attribute必须是浮点数', + ':attribute must be bool' => ':attribute必须是布尔值', + ':attribute not a valid email address' => ':attribute格式不符', + ':attribute not a valid mobile' => ':attribute格式不符', + ':attribute must be a array' => ':attribute必须是数组', + ':attribute must be yes,on or 1' => ':attribute必须是yes、on或者1', + ':attribute not a valid datetime' => ':attribute不是一个有效的日期或时间格式', + ':attribute not a valid file' => ':attribute不是有效的上传文件', + ':attribute not a valid image' => ':attribute不是有效的图像文件', + ':attribute must be alpha' => ':attribute只能是字母', + ':attribute must be alpha-numeric' => ':attribute只能是字母和数字', + ':attribute must be alpha-numeric, dash, underscore' => ':attribute只能是字母、数字和下划线_及破折号-', + ':attribute not a valid domain or ip' => ':attribute不是有效的域名或者IP', + ':attribute must be chinese' => ':attribute只能是汉字', + ':attribute must be chinese or alpha' => ':attribute只能是汉字、字母', + ':attribute must be chinese,alpha-numeric' => ':attribute只能是汉字、字母和数字', + ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', + ':attribute not a valid url' => ':attribute不是有效的URL地址', + ':attribute not a valid ip' => ':attribute不是有效的IP地址', + ':attribute must be dateFormat of :rule' => ':attribute必须使用日期格式 :rule', + ':attribute must be in :rule' => ':attribute必须在 :rule 范围内', + ':attribute be notin :rule' => ':attribute不能在 :rule 范围内', + ':attribute must between :1 - :2' => ':attribute只能在 :1 - :2 之间', + ':attribute not between :1 - :2' => ':attribute不能在 :1 - :2 之间', + 'size of :attribute must be :rule' => ':attribute长度不符合要求 :rule', + 'max size of :attribute must be :rule' => ':attribute长度不能超过 :rule', + 'min size of :attribute must be :rule' => ':attribute长度不能小于 :rule', + ':attribute cannot be less than :rule' => ':attribute日期不能小于 :rule', + ':attribute cannot exceed :rule' => ':attribute日期不能超过 :rule', + ':attribute not within :rule' => '不在有效期内 :rule', + 'access IP is not allowed' => '不允许的IP访问', + 'access IP denied' => '禁止的IP访问', + ':attribute out of accord with :2' => ':attribute和确认字段:2不一致', + ':attribute cannot be same with :2' => ':attribute和比较字段:2不能相同', + ':attribute must greater than or equal :rule' => ':attribute必须大于等于 :rule', + ':attribute must greater than :rule' => ':attribute必须大于 :rule', + ':attribute must less than or equal :rule' => ':attribute必须小于等于 :rule', + ':attribute must less than :rule' => ':attribute必须小于 :rule', + ':attribute must equal :rule' => ':attribute必须等于 :rule', + ':attribute has exists' => ':attribute已存在', + ':attribute not conform to the rules' => ':attribute不符合指定规则', + 'invalid Request method' => '无效的请求类型', + 'invalid token' => '令牌数据无效', + 'not conform to the rules' => '规则错误', + + 'record has update' => '记录已经被更新了', +]; diff --git a/vendor/topthink/framework/src/think/App.php b/vendor/topthink/framework/src/think/App.php new file mode 100644 index 0000000..24c03f3 --- /dev/null +++ b/vendor/topthink/framework/src/think/App.php @@ -0,0 +1,610 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use think\event\AppInit; +use think\helper\Str; +use think\initializer\BootService; +use think\initializer\Error; +use think\initializer\RegisterService; + +/** + * App 基础类 + * @property Route $route + * @property Config $config + * @property Cache $cache + * @property Request $request + * @property Http $http + * @property Console $console + * @property Env $env + * @property Event $event + * @property Middleware $middleware + * @property Log $log + * @property Lang $lang + * @property Db $db + * @property Cookie $cookie + * @property Session $session + * @property Validate $validate + * @property Filesystem $filesystem + */ +class App extends Container +{ + const VERSION = '6.0.2'; + + /** + * 应用调试模式 + * @var bool + */ + protected $appDebug = false; + + /** + * 应用开始时间 + * @var float + */ + protected $beginTime; + + /** + * 应用内存初始占用 + * @var integer + */ + protected $beginMem; + + /** + * 当前应用类库命名空间 + * @var string + */ + protected $namespace = 'app'; + + /** + * 应用根目录 + * @var string + */ + protected $rootPath = ''; + + /** + * 框架目录 + * @var string + */ + protected $thinkPath = ''; + + /** + * 应用目录 + * @var string + */ + protected $appPath = ''; + + /** + * Runtime目录 + * @var string + */ + protected $runtimePath = ''; + + /** + * 路由定义目录 + * @var string + */ + protected $routePath = ''; + + /** + * 配置后缀 + * @var string + */ + protected $configExt = '.php'; + + /** + * 应用初始化器 + * @var array + */ + protected $initializers = [ + Error::class, + RegisterService::class, + BootService::class, + ]; + + /** + * 注册的系统服务 + * @var array + */ + protected $services = []; + + /** + * 初始化 + * @var bool + */ + protected $initialized = false; + + /** + * 容器绑定标识 + * @var array + */ + protected $bind = [ + 'app' => App::class, + 'cache' => Cache::class, + 'config' => Config::class, + 'console' => Console::class, + 'cookie' => Cookie::class, + 'db' => Db::class, + 'env' => Env::class, + 'event' => Event::class, + 'http' => Http::class, + 'lang' => Lang::class, + 'log' => Log::class, + 'middleware' => Middleware::class, + 'request' => Request::class, + 'response' => Response::class, + 'route' => Route::class, + 'session' => Session::class, + 'validate' => Validate::class, + 'view' => View::class, + 'filesystem' => Filesystem::class, + 'think\DbManager' => Db::class, + 'think\LogManager' => Log::class, + 'think\CacheManager' => Cache::class, + + // 接口依赖注入 + 'Psr\Log\LoggerInterface' => Log::class, + ]; + + /** + * 架构方法 + * @access public + * @param string $rootPath 应用根目录 + */ + public function __construct(string $rootPath = '') + { + $this->thinkPath = dirname(__DIR__) . DIRECTORY_SEPARATOR; + $this->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath(); + $this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR; + $this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR; + + if (is_file($this->appPath . 'provider.php')) { + $this->bind(include $this->appPath . 'provider.php'); + } + + static::setInstance($this); + + $this->instance('app', $this); + $this->instance('think\Container', $this); + } + + /** + * 注册服务 + * @access public + * @param Service|string $service 服务 + * @param bool $force 强制重新注册 + * @return Service|null + */ + public function register($service, bool $force = false) + { + $registered = $this->getService($service); + + if ($registered && !$force) { + return $registered; + } + + if (is_string($service)) { + $service = new $service($this); + } + + if (method_exists($service, 'register')) { + $service->register(); + } + + if (property_exists($service, 'bind')) { + $this->bind($service->bind); + } + + $this->services[] = $service; + } + + /** + * 执行服务 + * @access public + * @param Service $service 服务 + * @return mixed + */ + public function bootService($service) + { + if (method_exists($service, 'boot')) { + return $this->invoke([$service, 'boot']); + } + } + + /** + * 获取服务 + * @param string|Service $service + * @return Service|null + */ + public function getService($service) + { + $name = is_string($service) ? $service : get_class($service); + return array_values(array_filter($this->services, function ($value) use ($name) { + return $value instanceof $name; + }, ARRAY_FILTER_USE_BOTH))[0] ?? null; + } + + /** + * 开启应用调试模式 + * @access public + * @param bool $debug 开启应用调试模式 + * @return $this + */ + public function debug(bool $debug = true) + { + $this->appDebug = $debug; + return $this; + } + + /** + * 是否为调试模式 + * @access public + * @return bool + */ + public function isDebug(): bool + { + return $this->appDebug; + } + + /** + * 设置应用命名空间 + * @access public + * @param string $namespace 应用命名空间 + * @return $this + */ + public function setNamespace(string $namespace) + { + $this->namespace = $namespace; + return $this; + } + + /** + * 获取应用类库命名空间 + * @access public + * @return string + */ + public function getNamespace(): string + { + return $this->namespace; + } + + /** + * 获取框架版本 + * @access public + * @return string + */ + public function version(): string + { + return static::VERSION; + } + + /** + * 获取应用根目录 + * @access public + * @return string + */ + public function getRootPath(): string + { + return $this->rootPath; + } + + /** + * 获取应用基础目录 + * @access public + * @return string + */ + public function getBasePath(): string + { + return $this->rootPath . 'app' . DIRECTORY_SEPARATOR; + } + + /** + * 获取当前应用目录 + * @access public + * @return string + */ + public function getAppPath(): string + { + return $this->appPath; + } + + /** + * 设置应用目录 + * @param string $path 应用目录 + */ + public function setAppPath(string $path) + { + $this->appPath = $path; + } + + /** + * 获取应用运行时目录 + * @access public + * @return string + */ + public function getRuntimePath(): string + { + return $this->runtimePath; + } + + /** + * 设置runtime目录 + * @param string $path 定义目录 + */ + public function setRuntimePath(string $path): void + { + $this->runtimePath = $path; + } + + /** + * 获取核心框架目录 + * @access public + * @return string + */ + public function getThinkPath(): string + { + return $this->thinkPath; + } + + /** + * 获取应用配置目录 + * @access public + * @return string + */ + public function getConfigPath(): string + { + return $this->rootPath . 'config' . DIRECTORY_SEPARATOR; + } + + /** + * 获取配置后缀 + * @access public + * @return string + */ + public function getConfigExt(): string + { + return $this->configExt; + } + + /** + * 获取应用开启时间 + * @access public + * @return float + */ + public function getBeginTime(): float + { + return $this->beginTime; + } + + /** + * 获取应用初始内存占用 + * @access public + * @return integer + */ + public function getBeginMem(): int + { + return $this->beginMem; + } + + /** + * 初始化应用 + * @access public + * @return $this + */ + public function initialize() + { + $this->initialized = true; + + $this->beginTime = microtime(true); + $this->beginMem = memory_get_usage(); + + // 加载环境变量 + if (is_file($this->rootPath . '.env')) { + $this->env->load($this->rootPath . '.env'); + } + + $this->configExt = $this->env->get('config_ext', '.php'); + + $this->debugModeInit(); + + // 加载全局初始化文件 + $this->load(); + + // 加载框架默认语言包 + $langSet = $this->lang->defaultLangSet(); + + $this->lang->load($this->thinkPath . 'lang' . DIRECTORY_SEPARATOR . $langSet . '.php'); + + // 加载应用默认语言包 + $this->loadLangPack($langSet); + + // 监听AppInit + $this->event->trigger(AppInit::class); + + date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai')); + + // 初始化 + foreach ($this->initializers as $initializer) { + $this->make($initializer)->init($this); + } + + return $this; + } + + /** + * 是否初始化过 + * @return bool + */ + public function initialized() + { + return $this->initialized; + } + + /** + * 加载语言包 + * @param string $langset 语言 + * @return void + */ + public function loadLangPack($langset) + { + if (empty($langset)) { + return; + } + + // 加载系统语言包 + $files = glob($this->appPath . 'lang' . DIRECTORY_SEPARATOR . $langset . '.*'); + $this->lang->load($files); + + // 加载扩展(自定义)语言包 + $list = $this->config->get('lang.extend_list', []); + + if (isset($list[$langset])) { + $this->lang->load($list[$langset]); + } + } + + /** + * 引导应用 + * @access public + * @return void + */ + public function boot(): void + { + array_walk($this->services, function ($service) { + $this->bootService($service); + }); + } + + /** + * 加载应用文件和配置 + * @access protected + * @return void + */ + protected function load(): void + { + $appPath = $this->getAppPath(); + + if (is_file($appPath . 'common.php')) { + include_once $appPath . 'common.php'; + } + + include_once $this->thinkPath . 'helper.php'; + + $configPath = $this->getConfigPath(); + + $files = []; + + if (is_dir($configPath)) { + $files = glob($configPath . '*' . $this->configExt); + } + + foreach ($files as $file) { + $this->config->load($file, pathinfo($file, PATHINFO_FILENAME)); + } + + if (is_file($appPath . 'event.php')) { + $this->loadEvent(include $appPath . 'event.php'); + } + + if (is_file($appPath . 'service.php')) { + $services = include $appPath . 'service.php'; + foreach ($services as $service) { + $this->register($service); + } + } + } + + /** + * 调试模式设置 + * @access protected + * @return void + */ + protected function debugModeInit(): void + { + // 应用调试模式 + if (!$this->appDebug) { + $this->appDebug = $this->env->get('app_debug') ? true : false; + ini_set('display_errors', 'Off'); + } + + if (!$this->runningInConsole()) { + //重新申请一块比较大的buffer + if (ob_get_level() > 0) { + $output = ob_get_clean(); + } + ob_start(); + if (!empty($output)) { + echo $output; + } + } + } + + /** + * 注册应用事件 + * @access protected + * @param array $event 事件数据 + * @return void + */ + public function loadEvent(array $event): void + { + if (isset($event['bind'])) { + $this->event->bind($event['bind']); + } + + if (isset($event['listen'])) { + $this->event->listenEvents($event['listen']); + } + + if (isset($event['subscribe'])) { + $this->event->subscribe($event['subscribe']); + } + } + + /** + * 解析应用类的类名 + * @access public + * @param string $layer 层名 controller model ... + * @param string $name 类名 + * @return string + */ + public function parseClass(string $layer, string $name): string + { + $name = str_replace(['/', '.'], '\\', $name); + $array = explode('\\', $name); + $class = Str::studly(array_pop($array)); + $path = $array ? implode('\\', $array) . '\\' : ''; + + return $this->namespace . '\\' . $layer . '\\' . $path . $class; + } + + /** + * 是否运行在命令行下 + * @return bool + */ + public function runningInConsole() + { + return php_sapi_name() === 'cli' || php_sapi_name() === 'phpdbg'; + } + + /** + * 获取应用根目录 + * @access protected + * @return string + */ + protected function getDefaultRootPath(): string + { + $path = dirname(dirname(dirname(dirname($this->thinkPath)))); + + return $path . DIRECTORY_SEPARATOR; + } + +} diff --git a/vendor/topthink/framework/src/think/Cache.php b/vendor/topthink/framework/src/think/Cache.php new file mode 100644 index 0000000..4bc99c2 --- /dev/null +++ b/vendor/topthink/framework/src/think/Cache.php @@ -0,0 +1,197 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use Psr\SimpleCache\CacheInterface; +use think\cache\Driver; +use think\cache\TagSet; +use think\exception\InvalidArgumentException; +use think\helper\Arr; + +/** + * 缓存管理类 + * @mixin Driver + * @mixin \think\cache\driver\File + */ +class Cache extends Manager implements CacheInterface +{ + + protected $namespace = '\\think\\cache\\driver\\'; + + /** + * 默认驱动 + * @return string|null + */ + public function getDefaultDriver() + { + return $this->getConfig('default'); + } + + /** + * 获取缓存配置 + * @access public + * @param null|string $name 名称 + * @param mixed $default 默认值 + * @return mixed + */ + public function getConfig(string $name = null, $default = null) + { + if (!is_null($name)) { + return $this->app->config->get('cache.' . $name, $default); + } + + return $this->app->config->get('cache'); + } + + /** + * 获取驱动配置 + * @param string $store + * @param string $name + * @param null $default + * @return array + */ + public function getStoreConfig(string $store, string $name = null, $default = null) + { + if ($config = $this->getConfig("stores.{$store}")) { + return Arr::get($config, $name, $default); + } + + throw new \InvalidArgumentException("Store [$store] not found."); + } + + protected function resolveType(string $name) + { + return $this->getStoreConfig($name, 'type', 'file'); + } + + protected function resolveConfig(string $name) + { + return $this->getStoreConfig($name); + } + + /** + * 连接或者切换缓存 + * @access public + * @param string $name 连接配置名 + * @return Driver + */ + public function store(string $name = null) + { + return $this->driver($name); + } + + /** + * 清空缓冲池 + * @access public + * @return bool + */ + public function clear(): bool + { + return $this->store()->clear(); + } + + /** + * 读取缓存 + * @access public + * @param string $key 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($key, $default = null) + { + return $this->store()->get($key, $default); + } + + /** + * 写入缓存 + * @access public + * @param string $key 缓存变量名 + * @param mixed $value 存储数据 + * @param int|\DateTime $ttl 有效时间 0为永久 + * @return bool + */ + public function set($key, $value, $ttl = null): bool + { + return $this->store()->set($key, $value, $ttl); + } + + /** + * 删除缓存 + * @access public + * @param string $key 缓存变量名 + * @return bool + */ + public function delete($key): bool + { + return $this->store()->delete($key); + } + + /** + * 读取缓存 + * @access public + * @param iterable $keys 缓存变量名 + * @param mixed $default 默认值 + * @return iterable + * @throws InvalidArgumentException + */ + public function getMultiple($keys, $default = null): iterable + { + return $this->store()->getMultiple($keys, $default); + } + + /** + * 写入缓存 + * @access public + * @param iterable $values 缓存数据 + * @param null|int|\DateInterval $ttl 有效时间 0为永久 + * @return bool + */ + public function setMultiple($values, $ttl = null): bool + { + return $this->store()->setMultiple($values, $ttl); + } + + /** + * 删除缓存 + * @access public + * @param iterable $keys 缓存变量名 + * @return bool + * @throws InvalidArgumentException + */ + public function deleteMultiple($keys): bool + { + return $this->store()->deleteMultiple($keys); + } + + /** + * 判断缓存是否存在 + * @access public + * @param string $key 缓存变量名 + * @return bool + */ + public function has($key): bool + { + return $this->store()->has($key); + } + + /** + * 缓存标签 + * @access public + * @param string|array $name 标签名 + * @return TagSet + */ + public function tag($name): TagSet + { + return $this->store()->tag($name); + } +} diff --git a/vendor/topthink/framework/src/think/Config.php b/vendor/topthink/framework/src/think/Config.php new file mode 100644 index 0000000..78933ad --- /dev/null +++ b/vendor/topthink/framework/src/think/Config.php @@ -0,0 +1,193 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +/** + * 配置管理类 + * @package think + */ +class Config +{ + /** + * 配置参数 + * @var array + */ + protected $config = []; + + /** + * 配置文件目录 + * @var string + */ + protected $path; + + /** + * 配置文件后缀 + * @var string + */ + protected $ext; + + /** + * 构造方法 + * @access public + */ + public function __construct(string $path = null, string $ext = '.php') + { + $this->path = $path ?: ''; + $this->ext = $ext; + } + + public static function __make(App $app) + { + $path = $app->getConfigPath(); + $ext = $app->getConfigExt(); + + return new static($path, $ext); + } + + /** + * 加载配置文件(多种格式) + * @access public + * @param string $file 配置文件名 + * @param string $name 一级配置名 + * @return array + */ + public function load(string $file, string $name = ''): array + { + if (is_file($file)) { + $filename = $file; + } elseif (is_file($this->path . $file . $this->ext)) { + $filename = $this->path . $file . $this->ext; + } + + if (isset($filename)) { + return $this->parse($filename, $name); + } + + return $this->config; + } + + /** + * 解析配置文件 + * @access public + * @param string $file 配置文件名 + * @param string $name 一级配置名 + * @return array + */ + protected function parse(string $file, string $name): array + { + $type = pathinfo($file, PATHINFO_EXTENSION); + $config = []; + switch ($type) { + case 'php': + $config = include $file; + break; + case 'yml': + case 'yaml': + if (function_exists('yaml_parse_file')) { + $config = yaml_parse_file($file); + } + break; + case 'ini': + $config = parse_ini_file($file, true, INI_SCANNER_TYPED) ?: []; + break; + case 'json': + $config = json_decode(file_get_contents($file), true); + break; + } + + return is_array($config) ? $this->set($config, strtolower($name)) : []; + } + + /** + * 检测配置是否存在 + * @access public + * @param string $name 配置参数名(支持多级配置 .号分割) + * @return bool + */ + public function has(string $name): bool + { + return !is_null($this->get($name)); + } + + /** + * 获取一级配置 + * @access protected + * @param string $name 一级配置名 + * @return array + */ + protected function pull(string $name): array + { + $name = strtolower($name); + + return $this->config[$name] ?? []; + } + + /** + * 获取配置参数 为空则获取所有配置 + * @access public + * @param string $name 配置参数名(支持多级配置 .号分割) + * @param mixed $default 默认值 + * @return mixed + */ + public function get(string $name = null, $default = null) + { + // 无参数时获取所有 + if (empty($name)) { + return $this->config; + } + + if (false === strpos($name, '.')) { + return $this->pull($name); + } + + $name = explode('.', $name); + $name[0] = strtolower($name[0]); + $config = $this->config; + + // 按.拆分成多维数组进行判断 + foreach ($name as $val) { + if (isset($config[$val])) { + $config = $config[$val]; + } else { + return $default; + } + } + + return $config; + } + + /** + * 设置配置参数 name为数组则为批量设置 + * @access public + * @param array $config 配置参数 + * @param string $name 配置名 + * @return array + */ + public function set(array $config, string $name = null): array + { + if (!empty($name)) { + if (isset($this->config[$name])) { + $result = array_merge($this->config[$name], $config); + } else { + $result = $config; + } + + $this->config[$name] = $result; + } else { + $result = $this->config = array_merge($this->config, array_change_key_case($config)); + } + + return $result; + } + +} diff --git a/vendor/topthink/framework/src/think/Console.php b/vendor/topthink/framework/src/think/Console.php new file mode 100644 index 0000000..a1398d5 --- /dev/null +++ b/vendor/topthink/framework/src/think/Console.php @@ -0,0 +1,732 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use Closure; +use InvalidArgumentException; +use LogicException; +use think\console\Command; +use think\console\command\Clear; +use think\console\command\Help; +use think\console\command\Help as HelpCommand; +use think\console\command\Lists; +use think\console\command\make\Command as MakeCommand; +use think\console\command\make\Controller; +use think\console\command\make\Event; +use think\console\command\make\Listener; +use think\console\command\make\Middleware; +use think\console\command\make\Model; +use think\console\command\make\Service; +use think\console\command\make\Subscribe; +use think\console\command\make\Validate; +use think\console\command\optimize\Route; +use think\console\command\optimize\Schema; +use think\console\command\RouteList; +use think\console\command\RunServer; +use think\console\command\ServiceDiscover; +use think\console\command\VendorPublish; +use think\console\command\Version; +use think\console\Input; +use think\console\input\Argument as InputArgument; +use think\console\input\Definition as InputDefinition; +use think\console\input\Option as InputOption; +use think\console\Output; +use think\console\output\driver\Buffer; + +/** + * 控制台应用管理类 + */ +class Console +{ + + protected $app; + + /** @var Command[] */ + protected $commands = []; + + protected $wantHelps = false; + + protected $catchExceptions = true; + protected $autoExit = true; + protected $definition; + protected $defaultCommand = 'list'; + + protected $defaultCommands = [ + 'help' => Help::class, + 'list' => Lists::class, + 'clear' => Clear::class, + 'make:command' => MakeCommand::class, + 'make:controller' => Controller::class, + 'make:model' => Model::class, + 'make:middleware' => Middleware::class, + 'make:validate' => Validate::class, + 'make:event' => Event::class, + 'make:listener' => Listener::class, + 'make:service' => Service::class, + 'make:subscribe' => Subscribe::class, + 'optimize:route' => Route::class, + 'optimize:schema' => Schema::class, + 'run' => RunServer::class, + 'version' => Version::class, + 'route:list' => RouteList::class, + 'service:discover' => ServiceDiscover::class, + 'vendor:publish' => VendorPublish::class, + ]; + + /** + * 启动器 + * @var array + */ + protected static $startCallbacks = []; + + public function __construct(App $app) + { + $this->app = $app; + + if (!$this->app->initialized()) { + $this->app->initialize(); + } + + $this->definition = $this->getDefaultInputDefinition(); + + //加载指令 + $this->loadCommands(); + + $this->start(); + } + + /** + * 添加初始化器 + * @param Closure $callback + */ + public static function starting(Closure $callback): void + { + static::$startCallbacks[] = $callback; + } + + /** + * 清空启动器 + */ + public static function flushStartCallbacks(): void + { + static::$startCallbacks = []; + } + + /** + * 设置执行用户 + * @param $user + */ + public static function setUser(string $user): void + { + if (extension_loaded('posix')) { + $user = posix_getpwnam($user); + + if (!empty($user)) { + posix_setgid($user['gid']); + posix_setuid($user['uid']); + } + } + } + + /** + * 启动 + */ + protected function start(): void + { + foreach (static::$startCallbacks as $callback) { + $callback($this); + } + } + + /** + * 加载指令 + * @access protected + */ + protected function loadCommands(): void + { + $commands = $this->app->config->get('console.commands', []); + $commands = array_merge($this->defaultCommands, $commands); + + $this->addCommands($commands); + } + + /** + * @access public + * @param string $command + * @param array $parameters + * @param string $driver + * @return Output|Buffer + */ + public function call(string $command, array $parameters = [], string $driver = 'buffer') + { + array_unshift($parameters, $command); + + $input = new Input($parameters); + $output = new Output($driver); + + $this->setCatchExceptions(false); + $this->find($command)->run($input, $output); + + return $output; + } + + /** + * 执行当前的指令 + * @access public + * @return int + * @throws \Exception + * @api + */ + public function run() + { + $input = new Input(); + $output = new Output(); + + $this->configureIO($input, $output); + + try { + $exitCode = $this->doRun($input, $output); + } catch (\Exception $e) { + if (!$this->catchExceptions) { + throw $e; + } + + $output->renderException($e); + + $exitCode = $e->getCode(); + if (is_numeric($exitCode)) { + $exitCode = (int) $exitCode; + if (0 === $exitCode) { + $exitCode = 1; + } + } else { + $exitCode = 1; + } + } + + if ($this->autoExit) { + if ($exitCode > 255) { + $exitCode = 255; + } + + exit($exitCode); + } + + return $exitCode; + } + + /** + * 执行指令 + * @access public + * @param Input $input + * @param Output $output + * @return int + */ + public function doRun(Input $input, Output $output) + { + if (true === $input->hasParameterOption(['--version', '-V'])) { + $output->writeln($this->getLongVersion()); + + return 0; + } + + $name = $this->getCommandName($input); + + if (true === $input->hasParameterOption(['--help', '-h'])) { + if (!$name) { + $name = 'help'; + $input = new Input(['help']); + } else { + $this->wantHelps = true; + } + } + + if (!$name) { + $name = $this->defaultCommand; + $input = new Input([$this->defaultCommand]); + } + + $command = $this->find($name); + + return $this->doRunCommand($command, $input, $output); + } + + /** + * 设置输入参数定义 + * @access public + * @param InputDefinition $definition + */ + public function setDefinition(InputDefinition $definition): void + { + $this->definition = $definition; + } + + /** + * 获取输入参数定义 + * @access public + * @return InputDefinition The InputDefinition instance + */ + public function getDefinition(): InputDefinition + { + return $this->definition; + } + + /** + * Gets the help message. + * @access public + * @return string A help message. + */ + public function getHelp(): string + { + return $this->getLongVersion(); + } + + /** + * 是否捕获异常 + * @access public + * @param bool $boolean + * @api + */ + public function setCatchExceptions(bool $boolean): void + { + $this->catchExceptions = $boolean; + } + + /** + * 是否自动退出 + * @access public + * @param bool $boolean + * @api + */ + public function setAutoExit(bool $boolean): void + { + $this->autoExit = $boolean; + } + + /** + * 获取完整的版本号 + * @access public + * @return string + */ + public function getLongVersion(): string + { + if ($this->app->version()) { + return sprintf('version %s', $this->app->version()); + } + + return 'Console Tool'; + } + + /** + * 添加指令集 + * @access public + * @param array $commands + */ + public function addCommands(array $commands): void + { + foreach ($commands as $key => $command) { + if (is_subclass_of($command, Command::class)) { + // 注册指令 + $this->addCommand($command, is_numeric($key) ? '' : $key); + } + } + } + + /** + * 添加一个指令 + * @access public + * @param string|Command $command 指令对象或者指令类名 + * @param string $name 指令名 留空则自动获取 + * @return Command|void + */ + public function addCommand($command, string $name = '') + { + if ($name) { + $this->commands[$name] = $command; + return; + } + + if (is_string($command)) { + $command = $this->app->invokeClass($command); + } + + $command->setConsole($this); + + if (!$command->isEnabled()) { + $command->setConsole(null); + return; + } + + $command->setApp($this->app); + + if (null === $command->getDefinition()) { + throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))); + } + + $this->commands[$command->getName()] = $command; + + foreach ($command->getAliases() as $alias) { + $this->commands[$alias] = $command; + } + + return $command; + } + + /** + * 获取指令 + * @access public + * @param string $name 指令名称 + * @return Command + * @throws InvalidArgumentException + */ + public function getCommand(string $name): Command + { + if (!isset($this->commands[$name])) { + throw new InvalidArgumentException(sprintf('The command "%s" does not exist.', $name)); + } + + $command = $this->commands[$name]; + + if (is_string($command)) { + $command = $this->app->invokeClass($command); + /** @var Command $command */ + $command->setConsole($this); + $command->setApp($this->app); + } + + if ($this->wantHelps) { + $this->wantHelps = false; + + /** @var HelpCommand $helpCommand */ + $helpCommand = $this->getCommand('help'); + $helpCommand->setCommand($command); + + return $helpCommand; + } + + return $command; + } + + /** + * 某个指令是否存在 + * @access public + * @param string $name 指令名称 + * @return bool + */ + public function hasCommand(string $name): bool + { + return isset($this->commands[$name]); + } + + /** + * 获取所有的命名空间 + * @access public + * @return array + */ + public function getNamespaces(): array + { + $namespaces = []; + foreach ($this->commands as $key => $command) { + if (is_string($command)) { + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($key)); + } else { + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName())); + + foreach ($command->getAliases() as $alias) { + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias)); + } + } + } + + return array_values(array_unique(array_filter($namespaces))); + } + + /** + * 查找注册命名空间中的名称或缩写。 + * @access public + * @param string $namespace + * @return string + * @throws InvalidArgumentException + */ + public function findNamespace(string $namespace): string + { + $allNamespaces = $this->getNamespaces(); + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { + return preg_quote($matches[1]) . '[^:]*'; + }, $namespace); + $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); + + if (empty($namespaces)) { + $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); + + if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { + if (1 == count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + + $message .= implode("\n ", $alternatives); + } + + throw new InvalidArgumentException($message); + } + + $exact = in_array($namespace, $namespaces, true); + if (count($namespaces) > 1 && !$exact) { + throw new InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces)))); + } + + return $exact ? $namespace : reset($namespaces); + } + + /** + * 查找指令 + * @access public + * @param string $name 名称或者别名 + * @return Command + * @throws InvalidArgumentException + */ + public function find(string $name): Command + { + $allCommands = array_keys($this->commands); + + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { + return preg_quote($matches[1]) . '[^:]*'; + }, $name); + + $commands = preg_grep('{^' . $expr . '}', $allCommands); + + if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) { + if (false !== $pos = strrpos($name, ':')) { + $this->findNamespace(substr($name, 0, $pos)); + } + + $message = sprintf('Command "%s" is not defined.', $name); + + if ($alternatives = $this->findAlternatives($name, $allCommands)) { + if (1 == count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + $message .= implode("\n ", $alternatives); + } + + throw new InvalidArgumentException($message); + } + + $exact = in_array($name, $commands, true); + if (count($commands) > 1 && !$exact) { + $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); + + throw new InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); + } + + return $this->getCommand($exact ? $name : reset($commands)); + } + + /** + * 获取所有的指令 + * @access public + * @param string $namespace 命名空间 + * @return Command[] + * @api + */ + public function all(string $namespace = null): array + { + if (null === $namespace) { + return $this->commands; + } + + $commands = []; + foreach ($this->commands as $name => $command) { + if ($this->extractNamespace($name, substr_count($namespace, ':') + 1) === $namespace) { + $commands[$name] = $command; + } + } + + return $commands; + } + + /** + * 配置基于用户的参数和选项的输入和输出实例。 + * @access protected + * @param Input $input 输入实例 + * @param Output $output 输出实例 + */ + protected function configureIO(Input $input, Output $output): void + { + if (true === $input->hasParameterOption(['--ansi'])) { + $output->setDecorated(true); + } elseif (true === $input->hasParameterOption(['--no-ansi'])) { + $output->setDecorated(false); + } + + if (true === $input->hasParameterOption(['--no-interaction', '-n'])) { + $input->setInteractive(false); + } + + if (true === $input->hasParameterOption(['--quiet', '-q'])) { + $output->setVerbosity(Output::VERBOSITY_QUIET); + } elseif ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) { + $output->setVerbosity(Output::VERBOSITY_DEBUG); + } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) { + $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE); + } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) { + $output->setVerbosity(Output::VERBOSITY_VERBOSE); + } + } + + /** + * 执行指令 + * @access protected + * @param Command $command 指令实例 + * @param Input $input 输入实例 + * @param Output $output 输出实例 + * @return int + * @throws \Exception + */ + protected function doRunCommand(Command $command, Input $input, Output $output) + { + return $command->run($input, $output); + } + + /** + * 获取指令的基础名称 + * @access protected + * @param Input $input + * @return string + */ + protected function getCommandName(Input $input): string + { + return $input->getFirstArgument() ?: ''; + } + + /** + * 获取默认输入定义 + * @access protected + * @return InputDefinition + */ + protected function getDefaultInputDefinition(): InputDefinition + { + return new InputDefinition([ + new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), + new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'), + new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this console version'), + new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'), + new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), + new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'), + new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'), + new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'), + ]); + } + + /** + * 获取可能的建议 + * @access private + * @param array $abbrevs + * @return string + */ + private function getAbbreviationSuggestions(array $abbrevs): string + { + return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : ''); + } + + /** + * 返回命名空间部分 + * @access public + * @param string $name 指令 + * @param int $limit 部分的命名空间的最大数量 + * @return string + */ + public function extractNamespace(string $name, int $limit = 0): string + { + $parts = explode(':', $name); + array_pop($parts); + + return implode(':', 0 === $limit ? $parts : array_slice($parts, 0, $limit)); + } + + /** + * 查找可替代的建议 + * @access private + * @param string $name + * @param array|\Traversable $collection + * @return array + */ + private function findAlternatives(string $name, $collection): array + { + $threshold = 1e3; + $alternatives = []; + + $collectionParts = []; + foreach ($collection as $item) { + $collectionParts[$item] = explode(':', $item); + } + + foreach (explode(':', $name) as $i => $subname) { + foreach ($collectionParts as $collectionName => $parts) { + $exists = isset($alternatives[$collectionName]); + if (!isset($parts[$i]) && $exists) { + $alternatives[$collectionName] += $threshold; + continue; + } elseif (!isset($parts[$i])) { + continue; + } + + $lev = levenshtein($subname, $parts[$i]); + if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) { + $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; + } elseif ($exists) { + $alternatives[$collectionName] += $threshold; + } + } + } + + foreach ($collection as $item) { + $lev = levenshtein($name, $item); + if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { + $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; + } + } + + $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { + return $lev < 2 * $threshold; + }); + asort($alternatives); + + return array_keys($alternatives); + } + + /** + * 返回所有的命名空间 + * @access private + * @param string $name + * @return array + */ + private function extractAllNamespaces(string $name): array + { + $parts = explode(':', $name, -1); + $namespaces = []; + + foreach ($parts as $part) { + if (count($namespaces)) { + $namespaces[] = end($namespaces) . ':' . $part; + } else { + $namespaces[] = $part; + } + } + + return $namespaces; + } + +} diff --git a/vendor/topthink/framework/src/think/Container.php b/vendor/topthink/framework/src/think/Container.php new file mode 100644 index 0000000..215524f --- /dev/null +++ b/vendor/topthink/framework/src/think/Container.php @@ -0,0 +1,551 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use ArrayAccess; +use ArrayIterator; +use Closure; +use Countable; +use InvalidArgumentException; +use IteratorAggregate; +use Psr\Container\ContainerInterface; +use ReflectionClass; +use ReflectionException; +use ReflectionFunction; +use ReflectionFunctionAbstract; +use ReflectionMethod; +use think\exception\ClassNotFoundException; +use think\exception\FuncNotFoundException; +use think\helper\Str; + +/** + * 容器管理类 支持PSR-11 + */ +class Container implements ContainerInterface, ArrayAccess, IteratorAggregate, Countable +{ + /** + * 容器对象实例 + * @var Container|Closure + */ + protected static $instance; + + /** + * 容器中的对象实例 + * @var array + */ + protected $instances = []; + + /** + * 容器绑定标识 + * @var array + */ + protected $bind = []; + + /** + * 容器回调 + * @var array + */ + protected $invokeCallback = []; + + /** + * 获取当前容器的实例(单例) + * @access public + * @return static + */ + public static function getInstance() + { + if (is_null(static::$instance)) { + static::$instance = new static; + } + + if (static::$instance instanceof Closure) { + return (static::$instance)(); + } + + return static::$instance; + } + + /** + * 设置当前容器的实例 + * @access public + * @param object|Closure $instance + * @return void + */ + public static function setInstance($instance): void + { + static::$instance = $instance; + } + + /** + * 注册一个容器对象回调 + * + * @param string|Closure $abstract + * @param Closure|null $callback + * @return void + */ + public function resolving($abstract, Closure $callback = null): void + { + if ($abstract instanceof Closure) { + $this->invokeCallback['*'][] = $abstract; + return; + } + + $abstract = $this->getAlias($abstract); + + $this->invokeCallback[$abstract][] = $callback; + } + + /** + * 获取容器中的对象实例 不存在则创建 + * @access public + * @param string $abstract 类名或者标识 + * @param array|true $vars 变量 + * @param bool $newInstance 是否每次创建新的实例 + * @return object + */ + public static function pull(string $abstract, array $vars = [], bool $newInstance = false) + { + return static::getInstance()->make($abstract, $vars, $newInstance); + } + + /** + * 获取容器中的对象实例 + * @access public + * @param string $abstract 类名或者标识 + * @return object + */ + public function get($abstract) + { + if ($this->has($abstract)) { + return $this->make($abstract); + } + + throw new ClassNotFoundException('class not exists: ' . $abstract, $abstract); + } + + /** + * 绑定一个类、闭包、实例、接口实现到容器 + * @access public + * @param string|array $abstract 类标识、接口 + * @param mixed $concrete 要绑定的类、闭包或者实例 + * @return $this + */ + public function bind($abstract, $concrete = null) + { + if (is_array($abstract)) { + foreach ($abstract as $key => $val) { + $this->bind($key, $val); + } + } elseif ($concrete instanceof Closure) { + $this->bind[$abstract] = $concrete; + } elseif (is_object($concrete)) { + $this->instance($abstract, $concrete); + } else { + $abstract = $this->getAlias($abstract); + + $this->bind[$abstract] = $concrete; + } + + return $this; + } + + /** + * 根据别名获取真实类名 + * @param string $abstract + * @return string + */ + public function getAlias(string $abstract): string + { + if (isset($this->bind[$abstract])) { + $bind = $this->bind[$abstract]; + + if (is_string($bind)) { + return $this->getAlias($bind); + } + } + + return $abstract; + } + + /** + * 绑定一个类实例到容器 + * @access public + * @param string $abstract 类名或者标识 + * @param object $instance 类的实例 + * @return $this + */ + public function instance(string $abstract, $instance) + { + $abstract = $this->getAlias($abstract); + + $this->instances[$abstract] = $instance; + + return $this; + } + + /** + * 判断容器中是否存在类及标识 + * @access public + * @param string $abstract 类名或者标识 + * @return bool + */ + public function bound(string $abstract): bool + { + return isset($this->bind[$abstract]) || isset($this->instances[$abstract]); + } + + /** + * 判断容器中是否存在类及标识 + * @access public + * @param string $name 类名或者标识 + * @return bool + */ + public function has($name): bool + { + return $this->bound($name); + } + + /** + * 判断容器中是否存在对象实例 + * @access public + * @param string $abstract 类名或者标识 + * @return bool + */ + public function exists(string $abstract): bool + { + $abstract = $this->getAlias($abstract); + + return isset($this->instances[$abstract]); + } + + /** + * 创建类的实例 已经存在则直接获取 + * @access public + * @param string $abstract 类名或者标识 + * @param array $vars 变量 + * @param bool $newInstance 是否每次创建新的实例 + * @return mixed + */ + public function make(string $abstract, array $vars = [], bool $newInstance = false) + { + $abstract = $this->getAlias($abstract); + + if (isset($this->instances[$abstract]) && !$newInstance) { + return $this->instances[$abstract]; + } + + if (isset($this->bind[$abstract]) && $this->bind[$abstract] instanceof Closure) { + $object = $this->invokeFunction($this->bind[$abstract], $vars); + } else { + $object = $this->invokeClass($abstract, $vars); + } + + if (!$newInstance) { + $this->instances[$abstract] = $object; + } + + return $object; + } + + /** + * 删除容器中的对象实例 + * @access public + * @param string $name 类名或者标识 + * @return void + */ + public function delete($name) + { + $name = $this->getAlias($name); + + if (isset($this->instances[$name])) { + unset($this->instances[$name]); + } + } + + /** + * 执行函数或者闭包方法 支持参数调用 + * @access public + * @param string|Closure $function 函数或者闭包 + * @param array $vars 参数 + * @return mixed + */ + public function invokeFunction($function, array $vars = []) + { + try { + $reflect = new ReflectionFunction($function); + } catch (ReflectionException $e) { + throw new FuncNotFoundException("function not exists: {$function}()", $function, $e); + } + + $args = $this->bindParams($reflect, $vars); + + return $function(...$args); + } + + /** + * 调用反射执行类的方法 支持参数绑定 + * @access public + * @param mixed $method 方法 + * @param array $vars 参数 + * @param bool $accessible 设置是否可访问 + * @return mixed + */ + public function invokeMethod($method, array $vars = [], bool $accessible = false) + { + if (is_array($method)) { + [$class, $method] = $method; + + $class = is_object($class) ? $class : $this->invokeClass($class); + } else { + // 静态方法 + [$class, $method] = explode('::', $method); + } + + try { + $reflect = new ReflectionMethod($class, $method); + } catch (ReflectionException $e) { + $class = is_object($class) ? get_class($class) : $class; + throw new FuncNotFoundException('method not exists: ' . $class . '::' . $method . '()', "{$class}::{$method}", $e); + } + + $args = $this->bindParams($reflect, $vars); + + if ($accessible) { + $reflect->setAccessible($accessible); + } + + return $reflect->invokeArgs(is_object($class) ? $class : null, $args); + } + + /** + * 调用反射执行类的方法 支持参数绑定 + * @access public + * @param object $instance 对象实例 + * @param mixed $reflect 反射类 + * @param array $vars 参数 + * @return mixed + */ + public function invokeReflectMethod($instance, $reflect, array $vars = []) + { + $args = $this->bindParams($reflect, $vars); + + return $reflect->invokeArgs($instance, $args); + } + + /** + * 调用反射执行callable 支持参数绑定 + * @access public + * @param mixed $callable + * @param array $vars 参数 + * @param bool $accessible 设置是否可访问 + * @return mixed + */ + public function invoke($callable, array $vars = [], bool $accessible = false) + { + if ($callable instanceof Closure) { + return $this->invokeFunction($callable, $vars); + } elseif (is_string($callable) && false === strpos($callable, '::')) { + return $this->invokeFunction($callable, $vars); + } else { + return $this->invokeMethod($callable, $vars, $accessible); + } + } + + /** + * 调用反射执行类的实例化 支持依赖注入 + * @access public + * @param string $class 类名 + * @param array $vars 参数 + * @return mixed + */ + public function invokeClass(string $class, array $vars = []) + { + try { + $reflect = new ReflectionClass($class); + } catch (ReflectionException $e) { + throw new ClassNotFoundException('class not exists: ' . $class, $class, $e); + } + + if ($reflect->hasMethod('__make')) { + $method = $reflect->getMethod('__make'); + if ($method->isPublic() && $method->isStatic()) { + $args = $this->bindParams($method, $vars); + return $method->invokeArgs(null, $args); + } + } + + $constructor = $reflect->getConstructor(); + + $args = $constructor ? $this->bindParams($constructor, $vars) : []; + + $object = $reflect->newInstanceArgs($args); + + $this->invokeAfter($class, $object); + + return $object; + } + + /** + * 执行invokeClass回调 + * @access protected + * @param string $class 对象类名 + * @param object $object 容器对象实例 + * @return void + */ + protected function invokeAfter(string $class, $object): void + { + if (isset($this->invokeCallback['*'])) { + foreach ($this->invokeCallback['*'] as $callback) { + $callback($object, $this); + } + } + + if (isset($this->invokeCallback[$class])) { + foreach ($this->invokeCallback[$class] as $callback) { + $callback($object, $this); + } + } + } + + /** + * 绑定参数 + * @access protected + * @param ReflectionFunctionAbstract $reflect 反射类 + * @param array $vars 参数 + * @return array + */ + protected function bindParams(ReflectionFunctionAbstract $reflect, array $vars = []): array + { + if ($reflect->getNumberOfParameters() == 0) { + return []; + } + + // 判断数组类型 数字数组时按顺序绑定参数 + reset($vars); + $type = key($vars) === 0 ? 1 : 0; + $params = $reflect->getParameters(); + $args = []; + + foreach ($params as $param) { + $name = $param->getName(); + $lowerName = Str::snake($name); + $class = $param->getClass(); + + if ($class) { + $args[] = $this->getObjectParam($class->getName(), $vars); + } elseif (1 == $type && !empty($vars)) { + $args[] = array_shift($vars); + } elseif (0 == $type && isset($vars[$name])) { + $args[] = $vars[$name]; + } elseif (0 == $type && isset($vars[$lowerName])) { + $args[] = $vars[$lowerName]; + } elseif ($param->isDefaultValueAvailable()) { + $args[] = $param->getDefaultValue(); + } else { + throw new InvalidArgumentException('method param miss:' . $name); + } + } + + return $args; + } + + /** + * 创建工厂对象实例 + * @param string $name 工厂类名 + * @param string $namespace 默认命名空间 + * @param array $args + * @return mixed + * @deprecated + * @access public + */ + public static function factory(string $name, string $namespace = '', ...$args) + { + $class = false !== strpos($name, '\\') ? $name : $namespace . ucwords($name); + + return Container::getInstance()->invokeClass($class, $args); + } + + /** + * 获取对象类型的参数值 + * @access protected + * @param string $className 类名 + * @param array $vars 参数 + * @return mixed + */ + protected function getObjectParam(string $className, array &$vars) + { + $array = $vars; + $value = array_shift($array); + + if ($value instanceof $className) { + $result = $value; + array_shift($vars); + } else { + $result = $this->make($className); + } + + return $result; + } + + public function __set($name, $value) + { + $this->bind($name, $value); + } + + public function __get($name) + { + return $this->get($name); + } + + public function __isset($name): bool + { + return $this->exists($name); + } + + public function __unset($name) + { + $this->delete($name); + } + + public function offsetExists($key) + { + return $this->exists($key); + } + + public function offsetGet($key) + { + return $this->make($key); + } + + public function offsetSet($key, $value) + { + $this->bind($key, $value); + } + + public function offsetUnset($key) + { + $this->delete($key); + } + + //Countable + public function count() + { + return count($this->instances); + } + + //IteratorAggregate + public function getIterator() + { + return new ArrayIterator($this->instances); + } +} diff --git a/vendor/topthink/framework/src/think/Cookie.php b/vendor/topthink/framework/src/think/Cookie.php new file mode 100644 index 0000000..6eb85b6 --- /dev/null +++ b/vendor/topthink/framework/src/think/Cookie.php @@ -0,0 +1,230 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use DateTimeInterface; + +/** + * Cookie管理类 + * @package think + */ +class Cookie +{ + /** + * 配置参数 + * @var array + */ + protected $config = [ + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => false, + // samesite 设置,支持 'strict' 'lax' + 'samesite' => '', + ]; + + /** + * Cookie写入数据 + * @var array + */ + protected $cookie = []; + + /** + * 当前Request对象 + * @var Request + */ + protected $request; + + /** + * 构造方法 + * @access public + */ + public function __construct(Request $request, array $config = []) + { + $this->request = $request; + $this->config = array_merge($this->config, array_change_key_case($config)); + } + + public static function __make(Request $request, Config $config) + { + return new static($request, $config->get('cookie')); + } + + /** + * 获取cookie + * @access public + * @param mixed $name 数据名称 + * @param string $default 默认值 + * @return mixed + */ + public function get(string $name = '', $default = null) + { + return $this->request->cookie($name, $default); + } + + /** + * 是否存在Cookie参数 + * @access public + * @param string $name 变量名 + * @return bool + */ + public function has(string $name): bool + { + return $this->request->has($name, 'cookie'); + } + + /** + * Cookie 设置 + * + * @access public + * @param string $name cookie名称 + * @param string $value cookie值 + * @param mixed $option 可选参数 + * @return void + */ + public function set(string $name, string $value, $option = null): void + { + // 参数设置(会覆盖黙认设置) + if (!is_null($option)) { + if (is_numeric($option) || $option instanceof DateTimeInterface) { + $option = ['expire' => $option]; + } + + $config = array_merge($this->config, array_change_key_case($option)); + } else { + $config = $this->config; + } + + if ($config['expire'] instanceof DateTimeInterface) { + $expire = $config['expire']->getTimestamp(); + } else { + $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0; + } + + $this->setCookie($name, $value, $expire, $config); + } + + /** + * Cookie 保存 + * + * @access public + * @param string $name cookie名称 + * @param string $value cookie值 + * @param int $expire 有效期 + * @param array $option 可选参数 + * @return void + */ + protected function setCookie(string $name, string $value, int $expire, array $option = []): void + { + $this->cookie[$name] = [$value, $expire, $option]; + } + + /** + * 永久保存Cookie数据 + * @access public + * @param string $name cookie名称 + * @param string $value cookie值 + * @param mixed $option 可选参数 可能会是 null|integer|string + * @return void + */ + public function forever(string $name, string $value = '', $option = null): void + { + if (is_null($option) || is_numeric($option)) { + $option = []; + } + + $option['expire'] = 315360000; + + $this->set($name, $value, $option); + } + + /** + * Cookie删除 + * @access public + * @param string $name cookie名称 + * @return void + */ + public function delete(string $name): void + { + $this->setCookie($name, '', time() - 3600, $this->config); + } + + /** + * 获取cookie保存数据 + * @access public + * @return array + */ + public function getCookie(): array + { + return $this->cookie; + } + + /** + * 保存Cookie + * @access public + * @return void + */ + public function save(): void + { + foreach ($this->cookie as $name => $val) { + [$value, $expire, $option] = $val; + + $this->saveCookie( + $name, + $value, + $expire, + $option['path'], + $option['domain'], + $option['secure'] ? true : false, + $option['httponly'] ? true : false, + $option['samesite'] + ); + } + } + + /** + * 保存Cookie + * @access public + * @param string $name cookie名称 + * @param string $value cookie值 + * @param int $expire cookie过期时间 + * @param string $path 有效的服务器路径 + * @param string $domain 有效域名/子域名 + * @param bool $secure 是否仅仅通过HTTPS + * @param bool $httponly 仅可通过HTTP访问 + * @param string $samesite 防止CSRF攻击和用户追踪 + * @return void + */ + protected function saveCookie(string $name, string $value, int $expire, string $path, string $domain, bool $secure, bool $httponly, string $samesite): void + { + if (version_compare(PHP_VERSION, '7.3.0', '>=')) { + setcookie($name, $value, [ + 'expires' => $expire, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure, + 'httponly' => $httponly, + 'samesite' => $samesite, + ]); + } else { + setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); + } + } + +} diff --git a/vendor/topthink/framework/src/think/Db.php b/vendor/topthink/framework/src/think/Db.php new file mode 100644 index 0000000..06b7ff2 --- /dev/null +++ b/vendor/topthink/framework/src/think/Db.php @@ -0,0 +1,114 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +/** + * 数据库管理类 + * @package think + */ +class Db extends DbManager +{ + /** + * @param Event $event + * @param Config $config + * @param Log $log + * @param Cache $cache + * @return Db + * @codeCoverageIgnore + */ + public static function __make(Event $event, Config $config, Log $log, Cache $cache) + { + $db = new static(); + $db->setConfig($config); + $db->setEvent($event); + $db->setLog($log); + $db->setCache($cache); + $db->triggerSql(); + + return $db; + } + + /** + * 注入模型对象 + * @access public + * @return void + */ + protected function modelMaker() + { + } + + /** + * 设置配置对象 + * @access public + * @param Config $config 配置对象 + * @return void + */ + public function setConfig($config): void + { + $this->config = $config; + } + + /** + * 获取配置参数 + * @access public + * @param string $name 配置参数 + * @param mixed $default 默认值 + * @return mixed + */ + public function getConfig(string $name = '', $default = null) + { + if ('' !== $name) { + return $this->config->get('database.' . $name, $default); + } + + return $this->config->get('database', []); + } + + /** + * 设置Event对象 + * @param Event $event + */ + public function setEvent(Event $event): void + { + $this->event = $event; + } + + /** + * 注册回调方法 + * @access public + * @param string $event 事件名 + * @param callable $callback 回调方法 + * @return void + */ + public function event(string $event, callable $callback): void + { + if ($this->event) { + $this->event->listen('db.' . $event, $callback); + } + } + + /** + * 触发事件 + * @access public + * @param string $event 事件名 + * @param mixed $params 传入参数 + * @param bool $once + * @return mixed + */ + public function trigger(string $event, $params = null, bool $once = false) + { + if ($this->event) { + return $this->event->trigger('db.' . $event, $params, $once); + } + } +} diff --git a/vendor/topthink/framework/src/think/Env.php b/vendor/topthink/framework/src/think/Env.php new file mode 100644 index 0000000..05228aa --- /dev/null +++ b/vendor/topthink/framework/src/think/Env.php @@ -0,0 +1,181 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use ArrayAccess; + +/** + * Env管理类 + * @package think + */ +class Env implements ArrayAccess +{ + /** + * 环境变量数据 + * @var array + */ + protected $data = []; + + public function __construct() + { + $this->data = $_ENV; + } + + /** + * 读取环境变量定义文件 + * @access public + * @param string $file 环境变量定义文件 + * @return void + */ + public function load(string $file): void + { + $env = parse_ini_file($file, true) ?: []; + $this->set($env); + } + + /** + * 获取环境变量值 + * @access public + * @param string $name 环境变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get(string $name = null, $default = null) + { + if (is_null($name)) { + return $this->data; + } + + $name = strtoupper(str_replace('.', '_', $name)); + + if (isset($this->data[$name])) { + return $this->data[$name]; + } + + return $this->getEnv($name, $default); + } + + protected function getEnv(string $name, $default = null) + { + $result = getenv('PHP_' . $name); + + if (false === $result) { + return $default; + } + + if ('false' === $result) { + $result = false; + } elseif ('true' === $result) { + $result = true; + } + + if (!isset($this->data[$name])) { + $this->data[$name] = $result; + } + + return $result; + } + + /** + * 设置环境变量值 + * @access public + * @param string|array $env 环境变量 + * @param mixed $value 值 + * @return void + */ + public function set($env, $value = null): void + { + if (is_array($env)) { + $env = array_change_key_case($env, CASE_UPPER); + + foreach ($env as $key => $val) { + if (is_array($val)) { + foreach ($val as $k => $v) { + $this->data[$key . '_' . strtoupper($k)] = $v; + } + } else { + $this->data[$key] = $val; + } + } + } else { + $name = strtoupper(str_replace('.', '_', $env)); + + $this->data[$name] = $value; + } + } + + /** + * 检测是否存在环境变量 + * @access public + * @param string $name 参数名 + * @return bool + */ + public function has(string $name): bool + { + return !is_null($this->get($name)); + } + + /** + * 设置环境变量 + * @access public + * @param string $name 参数名 + * @param mixed $value 值 + */ + public function __set(string $name, $value): void + { + $this->set($name, $value); + } + + /** + * 获取环境变量 + * @access public + * @param string $name 参数名 + * @return mixed + */ + public function __get(string $name) + { + return $this->get($name); + } + + /** + * 检测是否存在环境变量 + * @access public + * @param string $name 参数名 + * @return bool + */ + public function __isset(string $name): bool + { + return $this->has($name); + } + + // ArrayAccess + public function offsetSet($name, $value): void + { + $this->set($name, $value); + } + + public function offsetExists($name): bool + { + return $this->__isset($name); + } + + public function offsetUnset($name) + { + throw new Exception('not support: unset'); + } + + public function offsetGet($name) + { + return $this->get($name); + } +} diff --git a/vendor/topthink/framework/src/think/Event.php b/vendor/topthink/framework/src/think/Event.php new file mode 100644 index 0000000..ecb9912 --- /dev/null +++ b/vendor/topthink/framework/src/think/Event.php @@ -0,0 +1,301 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use ReflectionClass; +use ReflectionMethod; + +/** + * 事件管理类 + * @package think + */ +class Event +{ + /** + * 监听者 + * @var array + */ + protected $listener = []; + + /** + * 事件别名 + * @var array + */ + protected $bind = [ + 'AppInit' => event\AppInit::class, + 'HttpRun' => event\HttpRun::class, + 'HttpEnd' => event\HttpEnd::class, + 'RouteLoaded' => event\RouteLoaded::class, + 'LogWrite' => event\LogWrite::class, + ]; + + /** + * 是否需要事件响应 + * @var bool + */ + protected $withEvent = true; + + /** + * 应用对象 + * @var App + */ + protected $app; + + public function __construct(App $app) + { + $this->app = $app; + } + + /** + * 设置是否开启事件响应 + * @access protected + * @param bool $event 是否需要事件响应 + * @return $this + */ + public function withEvent(bool $event) + { + $this->withEvent = $event; + return $this; + } + + /** + * 批量注册事件监听 + * @access public + * @param array $events 事件定义 + * @return $this + */ + public function listenEvents(array $events) + { + if (!$this->withEvent) { + return $this; + } + + foreach ($events as $event => $listeners) { + if (isset($this->bind[$event])) { + $event = $this->bind[$event]; + } + + $this->listener[$event] = array_merge($this->listener[$event] ?? [], $listeners); + } + + return $this; + } + + /** + * 注册事件监听 + * @access public + * @param string $event 事件名称 + * @param mixed $listener 监听操作(或者类名) + * @param bool $first 是否优先执行 + * @return $this + */ + public function listen(string $event, $listener, bool $first = false) + { + if (!$this->withEvent) { + return $this; + } + + if (isset($this->bind[$event])) { + $event = $this->bind[$event]; + } + + if ($first && isset($this->listener[$event])) { + array_unshift($this->listener[$event], $listener); + } else { + $this->listener[$event][] = $listener; + } + + return $this; + } + + /** + * 是否存在事件监听 + * @access public + * @param string $event 事件名称 + * @return bool + */ + public function hasListener(string $event): bool + { + if (isset($this->bind[$event])) { + $event = $this->bind[$event]; + } + + return isset($this->listener[$event]); + } + + /** + * 移除事件监听 + * @access public + * @param string $event 事件名称 + * @return void + */ + public function remove(string $event): void + { + if (isset($this->bind[$event])) { + $event = $this->bind[$event]; + } + + unset($this->listener[$event]); + } + + /** + * 指定事件别名标识 便于调用 + * @access public + * @param array $events 事件别名 + * @return $this + */ + public function bind(array $events) + { + $this->bind = array_merge($this->bind, $events); + + return $this; + } + + /** + * 注册事件订阅者 + * @access public + * @param mixed $subscriber 订阅者 + * @return $this + */ + public function subscribe($subscriber) + { + if (!$this->withEvent) { + return $this; + } + + $subscribers = (array) $subscriber; + + foreach ($subscribers as $subscriber) { + if (is_string($subscriber)) { + $subscriber = $this->app->make($subscriber); + } + + if (method_exists($subscriber, 'subscribe')) { + // 手动订阅 + $subscriber->subscribe($this); + } else { + // 智能订阅 + $this->observe($subscriber); + } + } + + return $this; + } + + /** + * 自动注册事件观察者 + * @access public + * @param string|object $observer 观察者 + * @param null|string $prefix 事件名前缀 + * @return $this + */ + public function observe($observer, string $prefix = '') + { + if (!$this->withEvent) { + return $this; + } + + if (is_string($observer)) { + $observer = $this->app->make($observer); + } + + $reflect = new ReflectionClass($observer); + $methods = $reflect->getMethods(ReflectionMethod::IS_PUBLIC); + + if (empty($prefix) && $reflect->hasProperty('eventPrefix')) { + $reflectProperty = $reflect->getProperty('eventPrefix'); + $reflectProperty->setAccessible(true); + $prefix = $reflectProperty->getValue($observer); + } + + foreach ($methods as $method) { + $name = $method->getName(); + if (0 === strpos($name, 'on')) { + $this->listen($prefix . substr($name, 2), [$observer, $name]); + } + } + + return $this; + } + + /** + * 触发事件 + * @access public + * @param string|object $event 事件名称 + * @param mixed $params 传入参数 + * @param bool $once 只获取一个有效返回值 + * @return mixed + */ + public function trigger($event, $params = null, bool $once = false) + { + if (!$this->withEvent) { + return; + } + + if (is_object($event)) { + $params = $event; + $event = get_class($event); + } + + if (isset($this->bind[$event])) { + $event = $this->bind[$event]; + } + + $result = []; + $listeners = $this->listener[$event] ?? []; + $listeners = array_unique($listeners, SORT_REGULAR); + + foreach ($listeners as $key => $listener) { + $result[$key] = $this->dispatch($listener, $params); + + if (false === $result[$key] || (!is_null($result[$key]) && $once)) { + break; + } + } + + return $once ? end($result) : $result; + } + + /** + * 触发事件(只获取一个有效返回值) + * @param $event + * @param null $params + * @return mixed + */ + public function until($event, $params = null) + { + return $this->trigger($event, $params, true); + } + + /** + * 执行事件调度 + * @access protected + * @param mixed $event 事件方法 + * @param mixed $params 参数 + * @return mixed + */ + protected function dispatch($event, $params = null) + { + if (!is_string($event)) { + $call = $event; + } elseif (strpos($event, '::')) { + $call = $event; + } else { + $obj = $this->app->make($event); + $call = [$obj, 'handle']; + } + + return $this->app->invoke($call, [$params]); + } + +} diff --git a/vendor/topthink/framework/src/think/Exception.php b/vendor/topthink/framework/src/think/Exception.php new file mode 100644 index 0000000..468e29d --- /dev/null +++ b/vendor/topthink/framework/src/think/Exception.php @@ -0,0 +1,60 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +/** + * 异常基础类 + * @package think + */ +class Exception extends \Exception +{ + /** + * 保存异常页面显示的额外Debug数据 + * @var array + */ + protected $data = []; + + /** + * 设置异常额外的Debug数据 + * 数据将会显示为下面的格式 + * + * Exception Data + * -------------------------------------------------- + * Label 1 + * key1 value1 + * key2 value2 + * Label 2 + * key1 value1 + * key2 value2 + * + * @access protected + * @param string $label 数据分类,用于异常页面显示 + * @param array $data 需要显示的数据,必须为关联数组 + */ + final protected function setData(string $label, array $data) + { + $this->data[$label] = $data; + } + + /** + * 获取异常额外Debug数据 + * 主要用于输出到异常页面便于调试 + * @access public + * @return array 由setData设置的Debug数据 + */ + final public function getData() + { + return $this->data; + } + +} diff --git a/vendor/topthink/framework/src/think/Facade.php b/vendor/topthink/framework/src/think/Facade.php new file mode 100644 index 0000000..7921298 --- /dev/null +++ b/vendor/topthink/framework/src/think/Facade.php @@ -0,0 +1,98 @@ + +// +---------------------------------------------------------------------- +namespace think; + +/** + * Facade管理类 + */ +class Facade +{ + /** + * 始终创建新的对象实例 + * @var bool + */ + protected static $alwaysNewInstance; + + /** + * 创建Facade实例 + * @static + * @access protected + * @param string $class 类名或标识 + * @param array $args 变量 + * @param bool $newInstance 是否每次创建新的实例 + * @return object + */ + protected static function createFacade(string $class = '', array $args = [], bool $newInstance = false) + { + $class = $class ?: static::class; + + $facadeClass = static::getFacadeClass(); + + if ($facadeClass) { + $class = $facadeClass; + } + + if (static::$alwaysNewInstance) { + $newInstance = true; + } + + return Container::getInstance()->make($class, $args, $newInstance); + } + + /** + * 获取当前Facade对应类名 + * @access protected + * @return string + */ + protected static function getFacadeClass() + {} + + /** + * 带参数实例化当前Facade类 + * @access public + * @return object + */ + public static function instance(...$args) + { + if (__CLASS__ != static::class) { + return self::createFacade('', $args); + } + } + + /** + * 调用类的实例 + * @access public + * @param string $class 类名或者标识 + * @param array|true $args 变量 + * @param bool $newInstance 是否每次创建新的实例 + * @return object + */ + public static function make(string $class, $args = [], $newInstance = false) + { + if (__CLASS__ != static::class) { + return self::__callStatic('make', func_get_args()); + } + + if (true === $args) { + // 总是创建新的实例化对象 + $newInstance = true; + $args = []; + } + + return self::createFacade($class, $args, $newInstance); + } + + // 调用实际类的方法 + public static function __callStatic($method, $params) + { + return call_user_func_array([static::createFacade(), $method], $params); + } +} diff --git a/vendor/topthink/framework/src/think/File.php b/vendor/topthink/framework/src/think/File.php new file mode 100644 index 0000000..cb4cca0 --- /dev/null +++ b/vendor/topthink/framework/src/think/File.php @@ -0,0 +1,187 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use SplFileInfo; +use think\exception\FileException; + +/** + * 文件上传类 + * @package think + */ +class File extends SplFileInfo +{ + + /** + * 文件hash规则 + * @var array + */ + protected $hash = []; + + protected $hashName; + + public function __construct(string $path, bool $checkPath = true) + { + if ($checkPath && !is_file($path)) { + throw new FileException(sprintf('The file "%s" does not exist', $path)); + } + + parent::__construct($path); + } + + /** + * 获取文件的哈希散列值 + * @access public + * @param string $type + * @return string + */ + public function hash(string $type = 'sha1'): string + { + if (!isset($this->hash[$type])) { + $this->hash[$type] = hash_file($type, $this->getPathname()); + } + + return $this->hash[$type]; + } + + /** + * 获取文件的MD5值 + * @access public + * @return string + */ + public function md5(): string + { + return $this->hash('md5'); + } + + /** + * 获取文件的SHA1值 + * @access public + * @return string + */ + public function sha1(): string + { + return $this->hash('sha1'); + } + + /** + * 获取文件类型信息 + * @access public + * @return string + */ + public function getMime(): string + { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + + return finfo_file($finfo, $this->getPathname()); + } + + /** + * 移动文件 + * @access public + * @param string $directory 保存路径 + * @param string|null $name 保存的文件名 + * @return File + */ + public function move(string $directory, string $name = null): File + { + $target = $this->getTargetFile($directory, $name); + + set_error_handler(function ($type, $msg) use (&$error) { + $error = $msg; + }); + $renamed = rename($this->getPathname(), (string) $target); + restore_error_handler(); + if (!$renamed) { + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error))); + } + + @chmod((string) $target, 0666 & ~umask()); + + return $target; + } + + /** + * 实例化一个新文件 + * @param string $directory + * @param null|string $name + * @return File + */ + protected function getTargetFile(string $directory, string $name = null): File + { + if (!is_dir($directory)) { + if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) { + throw new FileException(sprintf('Unable to create the "%s" directory', $directory)); + } + } elseif (!is_writable($directory)) { + throw new FileException(sprintf('Unable to write in the "%s" directory', $directory)); + } + + $target = rtrim($directory, '/\\') . \DIRECTORY_SEPARATOR . (null === $name ? $this->getBasename() : $this->getName($name)); + + return new self($target, false); + } + + /** + * 获取文件名 + * @param string $name + * @return string + */ + protected function getName(string $name): string + { + $originalName = str_replace('\\', '/', $name); + $pos = strrpos($originalName, '/'); + $originalName = false === $pos ? $originalName : substr($originalName, $pos + 1); + + return $originalName; + } + + /** + * 文件扩展名 + * @return string + */ + public function extension(): string + { + return $this->getExtension(); + } + + /** + * 自动生成文件名 + * @access protected + * @param string|\Closure $rule + * @return string + */ + public function hashName($rule = 'date'): string + { + if (!$this->hashName) { + if ($rule instanceof \Closure) { + $this->hashName = call_user_func_array($rule, [$this]); + } else { + switch (true) { + case in_array($rule, hash_algos()): + $hash = $this->hash($rule); + $this->hashName = substr($hash, 0, 2) . DIRECTORY_SEPARATOR . substr($hash, 2); + break; + case is_callable($rule): + $this->hashName = call_user_func($rule); + break; + default: + $this->hashName = date('Ymd') . DIRECTORY_SEPARATOR . md5((string) microtime(true)); + break; + } + } + } + + return $this->hashName . '.' . $this->extension(); + } +} diff --git a/vendor/topthink/framework/src/think/Filesystem.php b/vendor/topthink/framework/src/think/Filesystem.php new file mode 100644 index 0000000..a443f74 --- /dev/null +++ b/vendor/topthink/framework/src/think/Filesystem.php @@ -0,0 +1,89 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use InvalidArgumentException; +use think\filesystem\Driver; +use think\filesystem\driver\Local; +use think\helper\Arr; + +/** + * Class Filesystem + * @package think + * @mixin Driver + * @mixin Local + */ +class Filesystem extends Manager +{ + protected $namespace = '\\think\\filesystem\\driver\\'; + + /** + * @param null|string $name + * @return Driver + */ + public function disk(string $name = null): Driver + { + return $this->driver($name); + } + + protected function resolveType(string $name) + { + return $this->getDiskConfig($name, 'type', 'local'); + } + + protected function resolveConfig(string $name) + { + return $this->getDiskConfig($name); + } + + /** + * 获取缓存配置 + * @access public + * @param null|string $name 名称 + * @param mixed $default 默认值 + * @return mixed + */ + public function getConfig(string $name = null, $default = null) + { + if (!is_null($name)) { + return $this->app->config->get('filesystem.' . $name, $default); + } + + return $this->app->config->get('filesystem'); + } + + /** + * 获取磁盘配置 + * @param string $disk + * @param null $name + * @param null $default + * @return array + */ + public function getDiskConfig($disk, $name = null, $default = null) + { + if ($config = $this->getConfig("disks.{$disk}")) { + return Arr::get($config, $name, $default); + } + + throw new InvalidArgumentException("Disk [$disk] not found."); + } + + /** + * 默认驱动 + * @return string|null + */ + public function getDefaultDriver() + { + return $this->getConfig('default'); + } +} diff --git a/vendor/topthink/framework/src/think/Http.php b/vendor/topthink/framework/src/think/Http.php new file mode 100644 index 0000000..a78b8b4 --- /dev/null +++ b/vendor/topthink/framework/src/think/Http.php @@ -0,0 +1,285 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use think\event\HttpEnd; +use think\event\HttpRun; +use think\event\RouteLoaded; +use think\exception\Handle; +use Throwable; + +/** + * Web应用管理类 + * @package think + */ +class Http +{ + + /** + * @var App + */ + protected $app; + + /** + * 应用名称 + * @var string + */ + protected $name; + + /** + * 应用路径 + * @var string + */ + protected $path; + + /** + * 是否绑定应用 + * @var bool + */ + protected $isBind = false; + + public function __construct(App $app) + { + $this->app = $app; + + $this->routePath = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR; + } + + /** + * 设置应用名称 + * @access public + * @param string $name 应用名称 + * @return $this + */ + public function name(string $name) + { + $this->name = $name; + return $this; + } + + /** + * 获取应用名称 + * @access public + * @return string + */ + public function getName(): string + { + return $this->name ?: ''; + } + + /** + * 设置应用目录 + * @access public + * @param string $path 应用目录 + * @return $this + */ + public function path(string $path) + { + if (substr($path, -1) != DIRECTORY_SEPARATOR) { + $path .= DIRECTORY_SEPARATOR; + } + + $this->path = $path; + return $this; + } + + /** + * 获取应用路径 + * @access public + * @return string + */ + public function getPath(): string + { + return $this->path ?: ''; + } + + /** + * 获取路由目录 + * @access public + * @return string + */ + public function getRoutePath(): string + { + return $this->routePath; + } + + /** + * 设置路由目录 + * @access public + * @param string $path 路由定义目录 + * @return string + */ + public function setRoutePath(string $path): void + { + $this->routePath = $path; + } + + /** + * 设置应用绑定 + * @access public + * @param bool $bind 是否绑定 + * @return $this + */ + public function setBind(bool $bind = true) + { + $this->isBind = $bind; + return $this; + } + + /** + * 是否绑定应用 + * @access public + * @return bool + */ + public function isBind(): bool + { + return $this->isBind; + } + + /** + * 执行应用程序 + * @access public + * @param Request|null $request + * @return Response + */ + public function run(Request $request = null): Response + { + //自动创建request对象 + $request = $request ?? $this->app->make('request', [], true); + $this->app->instance('request', $request); + + try { + $response = $this->runWithRequest($request); + } catch (Throwable $e) { + $this->reportException($e); + + $response = $this->renderException($request, $e); + } + + return $response; + } + + /** + * 初始化 + */ + protected function initialize() + { + if (!$this->app->initialized()) { + $this->app->initialize(); + } + } + + /** + * 执行应用程序 + * @param Request $request + * @return mixed + */ + protected function runWithRequest(Request $request) + { + $this->initialize(); + + // 加载全局中间件 + $this->loadMiddleware(); + + // 设置开启事件机制 + $this->app->event->withEvent($this->app->config->get('app.with_event', true)); + + // 监听HttpRun + $this->app->event->trigger(HttpRun::class); + + return $this->app->middleware->pipeline() + ->send($request) + ->then(function ($request) { + return $this->dispatchToRoute($request); + }); + } + + protected function dispatchToRoute($request) + { + $withRoute = $this->app->config->get('app.with_route', true) ? function () { + $this->loadRoutes(); + } : null; + + return $this->app->route->dispatch($request, $withRoute); + } + + /** + * 加载全局中间件 + */ + protected function loadMiddleware(): void + { + if (is_file($this->app->getBasePath() . 'middleware.php')) { + $this->app->middleware->import(include $this->app->getBasePath() . 'middleware.php'); + } + } + + /** + * 加载路由 + * @access protected + * @return void + */ + protected function loadRoutes(): void + { + // 加载路由定义 + $routePath = $this->getRoutePath(); + + if (is_dir($routePath)) { + $files = glob($routePath . '*.php'); + foreach ($files as $file) { + include $file; + } + } + + $this->app->event->trigger(RouteLoaded::class); + } + + /** + * Report the exception to the exception handler. + * + * @param Throwable $e + * @return void + */ + protected function reportException(Throwable $e) + { + $this->app->make(Handle::class)->report($e); + } + + /** + * Render the exception to a response. + * + * @param Request $request + * @param Throwable $e + * @return Response + */ + protected function renderException($request, Throwable $e) + { + return $this->app->make(Handle::class)->render($request, $e); + } + + /** + * HttpEnd + * @param Response $response + * @return void + */ + public function end(Response $response): void + { + $this->app->event->trigger(HttpEnd::class, $response); + + //执行中间件 + $this->app->middleware->end($response); + + // 写入日志 + $this->app->log->save(); + } + +} diff --git a/vendor/topthink/framework/src/think/Lang.php b/vendor/topthink/framework/src/think/Lang.php new file mode 100644 index 0000000..aed43fd --- /dev/null +++ b/vendor/topthink/framework/src/think/Lang.php @@ -0,0 +1,277 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +/** + * 多语言管理类 + * @package think + */ +class Lang +{ + /** + * 配置参数 + * @var array + */ + protected $config = [ + // 默认语言 + 'default_lang' => 'zh-cn', + // 允许的语言列表 + 'allow_lang_list' => [], + // 是否使用Cookie记录 + 'use_cookie' => true, + // 扩展语言包 + 'extend_list' => [], + // 多语言cookie变量 + 'cookie_var' => 'think_lang', + // 多语言自动侦测变量名 + 'detect_var' => 'lang', + // Accept-Language转义为对应语言包名称 + 'accept_language' => [ + 'zh-hans-cn' => 'zh-cn', + ], + // 是否支持语言分组 + 'allow_group' => false, + ]; + + /** + * 多语言信息 + * @var array + */ + private $lang = []; + + /** + * 当前语言 + * @var string + */ + private $range = 'zh-cn'; + + /** + * 构造方法 + * @access public + * @param array $config + */ + public function __construct(array $config = []) + { + $this->config = array_merge($this->config, array_change_key_case($config)); + $this->range = $this->config['default_lang']; + } + + public static function __make(Config $config) + { + return new static($config->get('lang')); + } + + /** + * 设置当前语言 + * @access public + * @param string $lang 语言 + * @return void + */ + public function setLangSet(string $lang): void + { + $this->range = $lang; + } + + /** + * 获取当前语言 + * @access public + * @return string + */ + public function getLangSet(): string + { + return $this->range; + } + + /** + * 获取默认语言 + * @access public + * @return string + */ + public function defaultLangSet() + { + return $this->config['default_lang']; + } + + /** + * 加载语言定义(不区分大小写) + * @access public + * @param string|array $file 语言文件 + * @param string $range 语言作用域 + * @return array + */ + public function load($file, $range = ''): array + { + $range = $range ?: $this->range; + if (!isset($this->lang[$range])) { + $this->lang[$range] = []; + } + + $lang = []; + + foreach ((array) $file as $_file) { + if (is_file($_file)) { + $result = $this->parse($_file); + $lang = array_change_key_case($result) + $lang; + } + } + + if (!empty($lang)) { + $this->lang[$range] = $lang + $this->lang[$range]; + } + + return $this->lang[$range]; + } + + /** + * 解析语言文件 + * @access protected + * @param string $file 语言文件名 + * @return array + */ + protected function parse(string $file): array + { + $type = pathinfo($file, PATHINFO_EXTENSION); + + switch ($type) { + case 'php': + $result = include $file; + break; + case 'yml': + case 'yaml': + if (function_exists('yaml_parse_file')) { + $result = yaml_parse_file($file); + } + break; + } + + return isset($result) && is_array($result) ? $result : []; + } + + /** + * 判断是否存在语言定义(不区分大小写) + * @access public + * @param string|null $name 语言变量 + * @param string $range 语言作用域 + * @return bool + */ + public function has(string $name, string $range = ''): bool + { + $range = $range ?: $this->range; + + if ($this->config['allow_group'] && strpos($name, '.')) { + [$name1, $name2] = explode('.', $name, 2); + return isset($this->lang[$range][strtolower($name1)][$name2]); + } + + return isset($this->lang[$range][strtolower($name)]); + } + + /** + * 获取语言定义(不区分大小写) + * @access public + * @param string|null $name 语言变量 + * @param array $vars 变量替换 + * @param string $range 语言作用域 + * @return mixed + */ + public function get(string $name = null, array $vars = [], string $range = '') + { + $range = $range ?: $this->range; + + // 空参数返回所有定义 + if (is_null($name)) { + return $this->lang[$range] ?? []; + } + + if ($this->config['allow_group'] && strpos($name, '.')) { + [$name1, $name2] = explode('.', $name, 2); + + $value = $this->lang[$range][strtolower($name1)][$name2] ?? $name; + } else { + $value = $this->lang[$range][strtolower($name)] ?? $name; + } + + // 变量解析 + if (!empty($vars) && is_array($vars)) { + /** + * Notes: + * 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0 + * 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数 + */ + if (key($vars) === 0) { + // 数字索引解析 + array_unshift($vars, $value); + $value = call_user_func_array('sprintf', $vars); + } else { + // 关联索引解析 + $replace = array_keys($vars); + foreach ($replace as &$v) { + $v = "{:{$v}}"; + } + $value = str_replace($replace, $vars, $value); + } + } + + return $value; + } + + /** + * 自动侦测设置获取语言选择 + * @access public + * @param Request $request + * @return string + */ + public function detect(Request $request): string + { + // 自动侦测设置获取语言选择 + $langSet = ''; + + if ($request->get($this->config['detect_var'])) { + // url中设置了语言变量 + $langSet = strtolower($request->get($this->config['detect_var'])); + } elseif ($request->cookie($this->config['cookie_var'])) { + // Cookie中设置了语言变量 + $langSet = strtolower($request->cookie($this->config['cookie_var'])); + } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) { + // 自动侦测浏览器语言 + $match = preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches); + if ($match) { + $langSet = strtolower($matches[1]); + if (isset($this->config['accept_language'][$langSet])) { + $langSet = $this->config['accept_language'][$langSet]; + } + } + } + + if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) { + // 合法的语言 + $this->range = $langSet; + } + + return $this->range; + } + + /** + * 保存当前语言到Cookie + * @access public + * @param Cookie $cookie Cookie对象 + * @return void + */ + public function saveToCookie(Cookie $cookie) + { + if ($this->config['use_cookie']) { + $cookie->set($this->config['cookie_var'], $this->range); + } + } + +} diff --git a/vendor/topthink/framework/src/think/Log.php b/vendor/topthink/framework/src/think/Log.php new file mode 100644 index 0000000..e9031c7 --- /dev/null +++ b/vendor/topthink/framework/src/think/Log.php @@ -0,0 +1,342 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use InvalidArgumentException; +use Psr\Log\LoggerInterface; +use think\event\LogWrite; +use think\helper\Arr; +use think\log\Channel; +use think\log\ChannelSet; + +/** + * 日志管理类 + * @package think + * @mixin Channel + */ +class Log extends Manager implements LoggerInterface +{ + const EMERGENCY = 'emergency'; + const ALERT = 'alert'; + const CRITICAL = 'critical'; + const ERROR = 'error'; + const WARNING = 'warning'; + const NOTICE = 'notice'; + const INFO = 'info'; + const DEBUG = 'debug'; + const SQL = 'sql'; + + protected $namespace = '\\think\\log\\driver\\'; + + /** + * 默认驱动 + * @return string|null + */ + public function getDefaultDriver() + { + return $this->getConfig('default'); + } + + /** + * 获取日志配置 + * @access public + * @param null|string $name 名称 + * @param mixed $default 默认值 + * @return mixed + */ + public function getConfig(string $name = null, $default = null) + { + if (!is_null($name)) { + return $this->app->config->get('log.' . $name, $default); + } + + return $this->app->config->get('log'); + } + + /** + * 获取渠道配置 + * @param string $channel + * @param null $name + * @param null $default + * @return array + */ + public function getChannelConfig($channel, $name = null, $default = null) + { + if ($config = $this->getConfig("channels.{$channel}")) { + return Arr::get($config, $name, $default); + } + + throw new InvalidArgumentException("Channel [$channel] not found."); + } + + /** + * driver()的别名 + * @param string|array $name 渠道名 + * @return Channel|ChannelSet + */ + public function channel($name = null) + { + if (is_array($name)) { + return new ChannelSet($this, $name); + } + + return $this->driver($name); + } + + protected function resolveType(string $name) + { + return $this->getChannelConfig($name, 'type', 'file'); + } + + public function createDriver(string $name) + { + $driver = parent::createDriver($name); + + $lazy = !$this->getChannelConfig($name, "realtime_write", false) && !$this->app->runningInConsole(); + $allow = array_merge($this->getConfig("level", []), $this->getChannelConfig($name, "level", [])); + + return new Channel($name, $driver, $allow, $lazy, $this->app->event); + } + + protected function resolveConfig(string $name) + { + return $this->getChannelConfig($name); + } + + /** + * 清空日志信息 + * @access public + * @param string|array $channel 日志通道名 + * @return $this + */ + public function clear($channel = '*') + { + if ('*' == $channel) { + $channel = array_keys($this->drivers); + } + + $this->channel($channel)->clear(); + + return $this; + } + + /** + * 关闭本次请求日志写入 + * @access public + * @param string|array $channel 日志通道名 + * @return $this + */ + public function close($channel = '*') + { + if ('*' == $channel) { + $channel = array_keys($this->drivers); + } + + $this->channel($channel)->close(); + + return $this; + } + + /** + * 获取日志信息 + * @access public + * @param string $channel 日志通道名 + * @return array + */ + public function getLog(string $channel = null): array + { + return $this->channel($channel)->getLog(); + } + + /** + * 保存日志信息 + * @access public + * @return bool + */ + public function save(): bool + { + /** @var Channel $channel */ + foreach ($this->drivers as $channel) { + $channel->save(); + } + + return true; + } + + /** + * 记录日志信息 + * @access public + * @param mixed $msg 日志信息 + * @param string $type 日志级别 + * @param array $context 替换内容 + * @param bool $lazy + * @return $this + */ + public function record($msg, string $type = 'info', array $context = [], bool $lazy = true) + { + $channel = $this->getConfig('type_channel.' . $type); + + $this->channel($channel)->record($msg, $type, $context, $lazy); + + return $this; + } + + /** + * 实时写入日志信息 + * @access public + * @param mixed $msg 调试信息 + * @param string $type 日志级别 + * @param array $context 替换内容 + * @return $this + */ + public function write($msg, string $type = 'info', array $context = []) + { + return $this->record($msg, $type, $context, false); + } + + /** + * 注册日志写入事件监听 + * @param $listener + * @return Event + */ + public function listen($listener) + { + return $this->app->event->listen(LogWrite::class, $listener); + } + + /** + * 记录日志信息 + * @access public + * @param string $level 日志级别 + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function log($level, $message, array $context = []): void + { + $this->record($message, $level, $context); + } + + /** + * 记录emergency信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function emergency($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录警报信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function alert($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录紧急情况 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function critical($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录错误信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function error($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录warning信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function warning($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录notice信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function notice($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录一般信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function info($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录调试信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function debug($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * 记录sql信息 + * @access public + * @param mixed $message 日志信息 + * @param array $context 替换内容 + * @return void + */ + public function sql($message, array $context = []): void + { + $this->log(__FUNCTION__, $message, $context); + } + + public function __call($method, $parameters) + { + $this->log($method, ...$parameters); + } +} diff --git a/vendor/topthink/framework/src/think/Manager.php b/vendor/topthink/framework/src/think/Manager.php new file mode 100644 index 0000000..7845e46 --- /dev/null +++ b/vendor/topthink/framework/src/think/Manager.php @@ -0,0 +1,176 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use InvalidArgumentException; +use think\helper\Str; + +abstract class Manager +{ + /** @var App */ + protected $app; + + /** + * 驱动 + * @var array + */ + protected $drivers = []; + + /** + * 驱动的命名空间 + * @var string + */ + protected $namespace = null; + + public function __construct(App $app) + { + $this->app = $app; + } + + /** + * 获取驱动实例 + * @param null|string $name + * @return mixed + */ + protected function driver(string $name = null) + { + $name = $name ?: $this->getDefaultDriver(); + + if (is_null($name)) { + throw new InvalidArgumentException(sprintf( + 'Unable to resolve NULL driver for [%s].', static::class + )); + } + + return $this->drivers[$name] = $this->getDriver($name); + } + + /** + * 获取驱动实例 + * @param string $name + * @return mixed + */ + protected function getDriver(string $name) + { + return $this->drivers[$name] ?? $this->createDriver($name); + } + + /** + * 获取驱动类型 + * @param string $name + * @return mixed + */ + protected function resolveType(string $name) + { + return $name; + } + + /** + * 获取驱动配置 + * @param string $name + * @return mixed + */ + protected function resolveConfig(string $name) + { + return $name; + } + + /** + * 获取驱动类 + * @param string $type + * @return string + */ + protected function resolveClass(string $type): string + { + if ($this->namespace || false !== strpos($type, '\\')) { + $class = false !== strpos($type, '\\') ? $type : $this->namespace . Str::studly($type); + + if (class_exists($class)) { + return $class; + } + } + + throw new InvalidArgumentException("Driver [$type] not supported."); + } + + /** + * 获取驱动参数 + * @param $name + * @return array + */ + protected function resolveParams($name): array + { + $config = $this->resolveConfig($name); + return [$config]; + } + + /** + * 创建驱动 + * + * @param string $name + * @return mixed + * + */ + protected function createDriver(string $name) + { + $type = $this->resolveType($name); + + $method = 'create' . Str::studly($type) . 'Driver'; + + $params = $this->resolveParams($name); + + if (method_exists($this, $method)) { + return $this->$method(...$params); + } + + $class = $this->resolveClass($type); + + return $this->app->invokeClass($class, $params); + } + + /** + * 移除一个驱动实例 + * + * @param array|string|null $name + * @return $this + */ + public function forgetDriver($name = null) + { + $name = $name ?? $this->getDefaultDriver(); + + foreach ((array) $name as $cacheName) { + if (isset($this->drivers[$cacheName])) { + unset($this->drivers[$cacheName]); + } + } + + return $this; + } + + /** + * 默认驱动 + * @return string|null + */ + abstract public function getDefaultDriver(); + + /** + * 动态调用 + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return $this->driver()->$method(...$parameters); + } +} diff --git a/vendor/topthink/framework/src/think/Middleware.php b/vendor/topthink/framework/src/think/Middleware.php new file mode 100644 index 0000000..0868fb2 --- /dev/null +++ b/vendor/topthink/framework/src/think/Middleware.php @@ -0,0 +1,257 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use Closure; +use InvalidArgumentException; +use LogicException; +use think\exception\Handle; +use Throwable; + +/** + * 中间件管理类 + * @package think + */ +class Middleware +{ + /** + * 中间件执行队列 + * @var array + */ + protected $queue = []; + + /** + * 应用对象 + * @var App + */ + protected $app; + + public function __construct(App $app) + { + $this->app = $app; + } + + /** + * 导入中间件 + * @access public + * @param array $middlewares + * @param string $type 中间件类型 + * @return void + */ + public function import(array $middlewares = [], string $type = 'global'): void + { + foreach ($middlewares as $middleware) { + $this->add($middleware, $type); + } + } + + /** + * 注册中间件 + * @access public + * @param mixed $middleware + * @param string $type 中间件类型 + * @return void + */ + public function add($middleware, string $type = 'global'): void + { + $middleware = $this->buildMiddleware($middleware, $type); + + if (!empty($middleware)) { + $this->queue[$type][] = $middleware; + $this->queue[$type] = array_unique($this->queue[$type], SORT_REGULAR); + } + } + + /** + * 注册路由中间件 + * @access public + * @param mixed $middleware + * @return void + */ + public function route($middleware): void + { + $this->add($middleware, 'route'); + } + + /** + * 注册控制器中间件 + * @access public + * @param mixed $middleware + * @return void + */ + public function controller($middleware): void + { + $this->add($middleware, 'controller'); + } + + /** + * 注册中间件到开始位置 + * @access public + * @param mixed $middleware + * @param string $type 中间件类型 + */ + public function unshift($middleware, string $type = 'global') + { + $middleware = $this->buildMiddleware($middleware, $type); + + if (!empty($middleware)) { + if (!isset($this->queue[$type])) { + $this->queue[$type] = []; + } + + array_unshift($this->queue[$type], $middleware); + } + } + + /** + * 获取注册的中间件 + * @access public + * @param string $type 中间件类型 + * @return array + */ + public function all(string $type = 'global'): array + { + return $this->queue[$type] ?? []; + } + + /** + * 调度管道 + * @access public + * @param string $type 中间件类型 + * @return Pipeline + */ + public function pipeline(string $type = 'global') + { + return (new Pipeline()) + ->through(array_map(function ($middleware) { + return function ($request, $next) use ($middleware) { + [$call, $params] = $middleware; + if (is_array($call) && is_string($call[0])) { + $call = [$this->app->make($call[0]), $call[1]]; + } + $response = call_user_func($call, $request, $next, ...$params); + + if (!$response instanceof Response) { + throw new LogicException('The middleware must return Response instance'); + } + return $response; + }; + }, $this->sortMiddleware($this->queue[$type] ?? []))) + ->whenException([$this, 'handleException']); + } + + /** + * 结束调度 + * @param Response $response + */ + public function end(Response $response) + { + foreach ($this->queue as $queue) { + foreach ($queue as $middleware) { + [$call] = $middleware; + if (is_array($call) && is_string($call[0])) { + $instance = $this->app->make($call[0]); + if (method_exists($instance, 'end')) { + $instance->end($response); + } + } + } + } + } + + /** + * 异常处理 + * @param Request $passable + * @param Throwable $e + * @return Response + */ + public function handleException($passable, Throwable $e) + { + /** @var Handle $handler */ + $handler = $this->app->make(Handle::class); + + $handler->report($e); + + return $handler->render($passable, $e); + } + + /** + * 解析中间件 + * @access protected + * @param mixed $middleware + * @param string $type 中间件类型 + * @return array + */ + protected function buildMiddleware($middleware, string $type): array + { + if (is_array($middleware)) { + [$middleware, $params] = $middleware; + } + + if ($middleware instanceof Closure) { + return [$middleware, $params ?? []]; + } + + if (!is_string($middleware)) { + throw new InvalidArgumentException('The middleware is invalid'); + } + + //中间件别名检查 + $alias = $this->app->config->get('middleware.alias', []); + + if (isset($alias[$middleware])) { + $middleware = $alias[$middleware]; + } + + if (is_array($middleware)) { + $this->import($middleware, $type); + return []; + } + + return [[$middleware, 'handle'], $params ?? []]; + } + + /** + * 中间件排序 + * @param array $middlewares + * @return array + */ + protected function sortMiddleware(array $middlewares) + { + $priority = $this->app->config->get('middleware.priority', []); + uasort($middlewares, function ($a, $b) use ($priority) { + $aPriority = $this->getMiddlewarePriority($priority, $a); + $bPriority = $this->getMiddlewarePriority($priority, $b); + return $bPriority - $aPriority; + }); + + return $middlewares; + } + + /** + * 获取中间件优先级 + * @param $priority + * @param $middleware + * @return int + */ + protected function getMiddlewarePriority($priority, $middleware) + { + [$call] = $middleware; + if (is_array($call) && is_string($call[0])) { + $index = array_search($call[0], array_reverse($priority)); + return false === $index ? -1 : $index; + } + return -1; + } + +} diff --git a/vendor/topthink/framework/src/think/Pipeline.php b/vendor/topthink/framework/src/think/Pipeline.php new file mode 100644 index 0000000..24c5122 --- /dev/null +++ b/vendor/topthink/framework/src/think/Pipeline.php @@ -0,0 +1,106 @@ + +// +---------------------------------------------------------------------- +namespace think; + +use Closure; +use Exception; +use Throwable; + +class Pipeline +{ + protected $passable; + + protected $pipes = []; + + protected $exceptionHandler; + + /** + * 初始数据 + * @param $passable + * @return $this + */ + public function send($passable) + { + $this->passable = $passable; + return $this; + } + + /** + * 调用栈 + * @param $pipes + * @return $this + */ + public function through($pipes) + { + $this->pipes = is_array($pipes) ? $pipes : func_get_args(); + return $this; + } + + /** + * 执行 + * @param Closure $destination + * @return mixed + */ + public function then(Closure $destination) + { + $pipeline = array_reduce( + array_reverse($this->pipes), + $this->carry(), + function ($passable) use ($destination) { + try { + return $destination($passable); + } catch (Throwable | Exception $e) { + return $this->handleException($passable, $e); + } + }); + + return $pipeline($this->passable); + } + + /** + * 设置异常处理器 + * @param callable $handler + * @return $this + */ + public function whenException($handler) + { + $this->exceptionHandler = $handler; + return $this; + } + + protected function carry() + { + return function ($stack, $pipe) { + return function ($passable) use ($stack, $pipe) { + try { + return $pipe($passable, $stack); + } catch (Throwable | Exception $e) { + return $this->handleException($passable, $e); + } + }; + }; + } + + /** + * 异常处理 + * @param $passable + * @param $e + * @return mixed + */ + protected function handleException($passable, Throwable $e) + { + if ($this->exceptionHandler) { + return call_user_func($this->exceptionHandler, $passable, $e); + } + throw $e; + } + +} diff --git a/vendor/topthink/framework/src/think/Request.php b/vendor/topthink/framework/src/think/Request.php new file mode 100644 index 0000000..0053c0b --- /dev/null +++ b/vendor/topthink/framework/src/think/Request.php @@ -0,0 +1,2129 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use think\file\UploadedFile; +use think\route\Rule; + +/** + * 请求管理类 + * @package think + */ +class Request +{ + /** + * 兼容PATH_INFO获取 + * @var array + */ + protected $pathinfoFetch = ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL']; + + /** + * PATHINFO变量名 用于兼容模式 + * @var string + */ + protected $varPathinfo = 's'; + + /** + * 请求类型 + * @var string + */ + protected $varMethod = '_method'; + + /** + * 表单ajax伪装变量 + * @var string + */ + protected $varAjax = '_ajax'; + + /** + * 表单pjax伪装变量 + * @var string + */ + protected $varPjax = '_pjax'; + + /** + * 域名根 + * @var string + */ + protected $rootDomain = ''; + + /** + * HTTPS代理标识 + * @var string + */ + protected $httpsAgentName = ''; + + /** + * 前端代理服务器IP + * @var array + */ + protected $proxyServerIp = []; + + /** + * 前端代理服务器真实IP头 + * @var array + */ + protected $proxyServerIpHeader = ['HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP']; + + /** + * 请求类型 + * @var string + */ + protected $method; + + /** + * 域名(含协议及端口) + * @var string + */ + protected $domain; + + /** + * HOST(含端口) + * @var string + */ + protected $host; + + /** + * 子域名 + * @var string + */ + protected $subDomain; + + /** + * 泛域名 + * @var string + */ + protected $panDomain; + + /** + * 当前URL地址 + * @var string + */ + protected $url; + + /** + * 基础URL + * @var string + */ + protected $baseUrl; + + /** + * 当前执行的文件 + * @var string + */ + protected $baseFile; + + /** + * 访问的ROOT地址 + * @var string + */ + protected $root; + + /** + * pathinfo + * @var string + */ + protected $pathinfo; + + /** + * pathinfo(不含后缀) + * @var string + */ + protected $path; + + /** + * 当前请求的IP地址 + * @var string + */ + protected $realIP; + + /** + * 当前控制器名 + * @var string + */ + protected $controller; + + /** + * 当前操作名 + * @var string + */ + protected $action; + + /** + * 当前请求参数 + * @var array + */ + protected $param = []; + + /** + * 当前GET参数 + * @var array + */ + protected $get = []; + + /** + * 当前POST参数 + * @var array + */ + protected $post = []; + + /** + * 当前REQUEST参数 + * @var array + */ + protected $request = []; + + /** + * 当前路由对象 + * @var Rule + */ + protected $rule; + + /** + * 当前ROUTE参数 + * @var array + */ + protected $route = []; + + /** + * 中间件传递的参数 + * @var array + */ + protected $middleware = []; + + /** + * 当前PUT参数 + * @var array + */ + protected $put; + + /** + * SESSION对象 + * @var Session + */ + protected $session; + + /** + * COOKIE数据 + * @var array + */ + protected $cookie = []; + + /** + * ENV对象 + * @var Env + */ + protected $env; + + /** + * 当前SERVER参数 + * @var array + */ + protected $server = []; + + /** + * 当前FILE参数 + * @var array + */ + protected $file = []; + + /** + * 当前HEADER参数 + * @var array + */ + protected $header = []; + + /** + * 资源类型定义 + * @var array + */ + protected $mimeType = [ + 'xml' => 'application/xml,text/xml,application/x-xml', + 'json' => 'application/json,text/x-json,application/jsonrequest,text/json', + 'js' => 'text/javascript,application/javascript,application/x-javascript', + 'css' => 'text/css', + 'rss' => 'application/rss+xml', + 'yaml' => 'application/x-yaml,text/yaml', + 'atom' => 'application/atom+xml', + 'pdf' => 'application/pdf', + 'text' => 'text/plain', + 'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*', + 'csv' => 'text/csv', + 'html' => 'text/html,application/xhtml+xml,*/*', + ]; + + /** + * 当前请求内容 + * @var string + */ + protected $content; + + /** + * 全局过滤规则 + * @var array + */ + protected $filter; + + /** + * php://input内容 + * @var string + */ + // php://input + protected $input; + + /** + * 请求安全Key + * @var string + */ + protected $secureKey; + + /** + * 是否合并Param + * @var bool + */ + protected $mergeParam = false; + + /** + * 架构函数 + * @access public + */ + public function __construct() + { + // 保存 php://input + $this->input = file_get_contents('php://input'); + } + + public static function __make(App $app) + { + $request = new static(); + + if (function_exists('apache_request_headers') && $result = apache_request_headers()) { + $header = $result; + } else { + $header = []; + $server = $_SERVER; + foreach ($server as $key => $val) { + if (0 === strpos($key, 'HTTP_')) { + $key = str_replace('_', '-', strtolower(substr($key, 5))); + $header[$key] = $val; + } + } + if (isset($server['CONTENT_TYPE'])) { + $header['content-type'] = $server['CONTENT_TYPE']; + } + if (isset($server['CONTENT_LENGTH'])) { + $header['content-length'] = $server['CONTENT_LENGTH']; + } + } + + $request->header = array_change_key_case($header); + $request->server = $_SERVER; + $request->env = $app->env; + + $inputData = $request->getInputData($request->input); + + $request->get = $_GET; + $request->post = $_POST ?: $inputData; + $request->put = $inputData; + $request->request = $_REQUEST; + $request->cookie = $_COOKIE; + $request->file = $_FILES ?? []; + + return $request; + } + + /** + * 设置当前包含协议的域名 + * @access public + * @param string $domain 域名 + * @return $this + */ + public function setDomain(string $domain) + { + $this->domain = $domain; + return $this; + } + + /** + * 获取当前包含协议的域名 + * @access public + * @param bool $port 是否需要去除端口号 + * @return string + */ + public function domain(bool $port = false): string + { + return $this->scheme() . '://' . $this->host($port); + } + + /** + * 获取当前根域名 + * @access public + * @return string + */ + public function rootDomain(): string + { + $root = $this->rootDomain; + + if (!$root) { + $item = explode('.', $this->host()); + $count = count($item); + $root = $count > 1 ? $item[$count - 2] . '.' . $item[$count - 1] : $item[0]; + } + + return $root; + } + + /** + * 设置当前泛域名的值 + * @access public + * @param string $domain 域名 + * @return $this + */ + public function setSubDomain(string $domain) + { + $this->subDomain = $domain; + return $this; + } + + /** + * 获取当前子域名 + * @access public + * @return string + */ + public function subDomain(): string + { + if (is_null($this->subDomain)) { + // 获取当前主域名 + $rootDomain = $this->rootDomain(); + + if ($rootDomain) { + $this->subDomain = rtrim(stristr($this->host(), $rootDomain, true), '.'); + } else { + $this->subDomain = ''; + } + } + + return $this->subDomain; + } + + /** + * 设置当前泛域名的值 + * @access public + * @param string $domain 域名 + * @return $this + */ + public function setPanDomain(string $domain) + { + $this->panDomain = $domain; + return $this; + } + + /** + * 获取当前泛域名的值 + * @access public + * @return string + */ + public function panDomain(): string + { + return $this->panDomain ?: ''; + } + + /** + * 设置当前完整URL 包括QUERY_STRING + * @access public + * @param string $url URL地址 + * @return $this + */ + public function setUrl(string $url) + { + $this->url = $url; + return $this; + } + + /** + * 获取当前完整URL 包括QUERY_STRING + * @access public + * @param bool $complete 是否包含完整域名 + * @return string + */ + public function url(bool $complete = false): string + { + if ($this->url) { + $url = $this->url; + } elseif ($this->server('HTTP_X_REWRITE_URL')) { + $url = $this->server('HTTP_X_REWRITE_URL'); + } elseif ($this->server('REQUEST_URI')) { + $url = $this->server('REQUEST_URI'); + } elseif ($this->server('ORIG_PATH_INFO')) { + $url = $this->server('ORIG_PATH_INFO') . (!empty($this->server('QUERY_STRING')) ? '?' . $this->server('QUERY_STRING') : ''); + } elseif (isset($_SERVER['argv'][1])) { + $url = $_SERVER['argv'][1]; + } else { + $url = ''; + } + + return $complete ? $this->domain() . $url : $url; + } + + /** + * 设置当前URL 不含QUERY_STRING + * @access public + * @param string $url URL地址 + * @return $this + */ + public function setBaseUrl(string $url) + { + $this->baseUrl = $url; + return $this; + } + + /** + * 获取当前URL 不含QUERY_STRING + * @access public + * @param bool $complete 是否包含完整域名 + * @return string + */ + public function baseUrl(bool $complete = false): string + { + if (!$this->baseUrl) { + $str = $this->url(); + $this->baseUrl = strpos($str, '?') ? strstr($str, '?', true) : $str; + } + + return $complete ? $this->domain() . $this->baseUrl : $this->baseUrl; + } + + /** + * 获取当前执行的文件 SCRIPT_NAME + * @access public + * @param bool $complete 是否包含完整域名 + * @return string + */ + public function baseFile(bool $complete = false): string + { + if (!$this->baseFile) { + $url = ''; + if (!$this->isCli()) { + $script_name = basename($this->server('SCRIPT_FILENAME')); + if (basename($this->server('SCRIPT_NAME')) === $script_name) { + $url = $this->server('SCRIPT_NAME'); + } elseif (basename($this->server('PHP_SELF')) === $script_name) { + $url = $this->server('PHP_SELF'); + } elseif (basename($this->server('ORIG_SCRIPT_NAME')) === $script_name) { + $url = $this->server('ORIG_SCRIPT_NAME'); + } elseif (($pos = strpos($this->server('PHP_SELF'), '/' . $script_name)) !== false) { + $url = substr($this->server('SCRIPT_NAME'), 0, $pos) . '/' . $script_name; + } elseif ($this->server('DOCUMENT_ROOT') && strpos($this->server('SCRIPT_FILENAME'), $this->server('DOCUMENT_ROOT')) === 0) { + $url = str_replace('\\', '/', str_replace($this->server('DOCUMENT_ROOT'), '', $this->server('SCRIPT_FILENAME'))); + } + } + $this->baseFile = $url; + } + + return $complete ? $this->domain() . $this->baseFile : $this->baseFile; + } + + /** + * 设置URL访问根地址 + * @access public + * @param string $url URL地址 + * @return $this + */ + public function setRoot(string $url) + { + $this->root = $url; + return $this; + } + + /** + * 获取URL访问根地址 + * @access public + * @param bool $complete 是否包含完整域名 + * @return string + */ + public function root(bool $complete = false): string + { + if (!$this->root) { + $file = $this->baseFile(); + if ($file && 0 !== strpos($this->url(), $file)) { + $file = str_replace('\\', '/', dirname($file)); + } + $this->root = rtrim($file, '/'); + } + + return $complete ? $this->domain() . $this->root : $this->root; + } + + /** + * 获取URL访问根目录 + * @access public + * @return string + */ + public function rootUrl(): string + { + $base = $this->root(); + $root = strpos($base, '.') ? ltrim(dirname($base), DIRECTORY_SEPARATOR) : $base; + + if ('' != $root) { + $root = '/' . ltrim($root, '/'); + } + + return $root; + } + + /** + * 设置当前请求的pathinfo + * @access public + * @param string $pathinfo + * @return $this + */ + public function setPathinfo(string $pathinfo) + { + $this->pathinfo = $pathinfo; + return $this; + } + + /** + * 获取当前请求URL的pathinfo信息(含URL后缀) + * @access public + * @return string + */ + public function pathinfo(): string + { + if (is_null($this->pathinfo)) { + if (isset($_GET[$this->varPathinfo])) { + // 判断URL里面是否有兼容模式参数 + $pathinfo = $_GET[$this->varPathinfo]; + unset($_GET[$this->varPathinfo]); + unset($this->get[$this->varPathinfo]); + } elseif ($this->server('PATH_INFO')) { + $pathinfo = $this->server('PATH_INFO'); + } elseif (false !== strpos(PHP_SAPI, 'cli')) { + $pathinfo = strpos($this->server('REQUEST_URI'), '?') ? strstr($this->server('REQUEST_URI'), '?', true) : $this->server('REQUEST_URI'); + } + + // 分析PATHINFO信息 + if (!isset($pathinfo)) { + foreach ($this->pathinfoFetch as $type) { + if ($this->server($type)) { + $pathinfo = (0 === strpos($this->server($type), $this->server('SCRIPT_NAME'))) ? + substr($this->server($type), strlen($this->server('SCRIPT_NAME'))) : $this->server($type); + break; + } + } + } + + if (!empty($pathinfo)) { + unset($this->get[$pathinfo], $this->request[$pathinfo]); + } + + $this->pathinfo = empty($pathinfo) || '/' == $pathinfo ? '' : ltrim($pathinfo, '/'); + } + + return $this->pathinfo; + } + + /** + * 当前URL的访问后缀 + * @access public + * @return string + */ + public function ext(): string + { + return pathinfo($this->pathinfo(), PATHINFO_EXTENSION); + } + + /** + * 获取当前请求的时间 + * @access public + * @param bool $float 是否使用浮点类型 + * @return integer|float + */ + public function time(bool $float = false) + { + return $float ? $this->server('REQUEST_TIME_FLOAT') : $this->server('REQUEST_TIME'); + } + + /** + * 当前请求的资源类型 + * @access public + * @return string + */ + public function type(): string + { + $accept = $this->server('HTTP_ACCEPT'); + + if (empty($accept)) { + return ''; + } + + foreach ($this->mimeType as $key => $val) { + $array = explode(',', $val); + foreach ($array as $k => $v) { + if (stristr($accept, $v)) { + return $key; + } + } + } + + return ''; + } + + /** + * 设置资源类型 + * @access public + * @param string|array $type 资源类型名 + * @param string $val 资源类型 + * @return void + */ + public function mimeType($type, $val = ''): void + { + if (is_array($type)) { + $this->mimeType = array_merge($this->mimeType, $type); + } else { + $this->mimeType[$type] = $val; + } + } + + /** + * 设置请求类型 + * @access public + * @param string $method 请求类型 + * @return $this + */ + public function setMethod(string $method) + { + $this->method = strtoupper($method); + return $this; + } + + /** + * 当前的请求类型 + * @access public + * @param bool $origin 是否获取原始请求类型 + * @return string + */ + public function method(bool $origin = false): string + { + if ($origin) { + // 获取原始请求类型 + return $this->server('REQUEST_METHOD') ?: 'GET'; + } elseif (!$this->method) { + if (isset($this->post[$this->varMethod])) { + $method = strtolower($this->post[$this->varMethod]); + if (in_array($method, ['get', 'post', 'put', 'patch', 'delete'])) { + $this->method = strtoupper($method); + $this->{$method} = $this->post; + } else { + $this->method = 'POST'; + } + unset($this->post[$this->varMethod]); + } elseif ($this->server('HTTP_X_HTTP_METHOD_OVERRIDE')) { + $this->method = strtoupper($this->server('HTTP_X_HTTP_METHOD_OVERRIDE')); + } else { + $this->method = $this->server('REQUEST_METHOD') ?: 'GET'; + } + } + + return $this->method; + } + + /** + * 是否为GET请求 + * @access public + * @return bool + */ + public function isGet(): bool + { + return $this->method() == 'GET'; + } + + /** + * 是否为POST请求 + * @access public + * @return bool + */ + public function isPost(): bool + { + return $this->method() == 'POST'; + } + + /** + * 是否为PUT请求 + * @access public + * @return bool + */ + public function isPut(): bool + { + return $this->method() == 'PUT'; + } + + /** + * 是否为DELTE请求 + * @access public + * @return bool + */ + public function isDelete(): bool + { + return $this->method() == 'DELETE'; + } + + /** + * 是否为HEAD请求 + * @access public + * @return bool + */ + public function isHead(): bool + { + return $this->method() == 'HEAD'; + } + + /** + * 是否为PATCH请求 + * @access public + * @return bool + */ + public function isPatch(): bool + { + return $this->method() == 'PATCH'; + } + + /** + * 是否为OPTIONS请求 + * @access public + * @return bool + */ + public function isOptions(): bool + { + return $this->method() == 'OPTIONS'; + } + + /** + * 是否为cli + * @access public + * @return bool + */ + public function isCli(): bool + { + return PHP_SAPI == 'cli'; + } + + /** + * 是否为cgi + * @access public + * @return bool + */ + public function isCgi(): bool + { + return strpos(PHP_SAPI, 'cgi') === 0; + } + + /** + * 获取当前请求的参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function param($name = '', $default = null, $filter = '') + { + if (empty($this->mergeParam)) { + $method = $this->method(true); + + // 自动获取请求变量 + switch ($method) { + case 'POST': + $vars = $this->post(false); + break; + case 'PUT': + case 'DELETE': + case 'PATCH': + $vars = $this->put(false); + break; + default: + $vars = []; + } + + // 当前请求参数和URL地址中的参数合并 + $this->param = array_merge($this->param, $this->get(false), $vars, $this->route(false)); + + $this->mergeParam = true; + } + + if (is_array($name)) { + return $this->only($name, $this->param, $filter); + } + + return $this->input($this->param, $name, $default, $filter); + } + + /** + * 设置路由变量 + * @access public + * @param Rule $rule 路由对象 + * @return $this + */ + public function setRule(Rule $rule) + { + $this->rule = $rule; + return $this; + } + + /** + * 获取当前路由对象 + * @access public + * @return Rule|null + */ + public function rule() + { + return $this->rule; + } + + /** + * 设置路由变量 + * @access public + * @param array $route 路由变量 + * @return $this + */ + public function setRoute(array $route) + { + $this->route = array_merge($this->route, $route); + return $this; + } + + /** + * 获取路由参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function route($name = '', $default = null, $filter = '') + { + if (is_array($name)) { + return $this->only($name, $this->route, $filter); + } + + return $this->input($this->route, $name, $default, $filter); + } + + /** + * 获取GET参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function get($name = '', $default = null, $filter = '') + { + if (is_array($name)) { + return $this->only($name, $this->get, $filter); + } + + return $this->input($this->get, $name, $default, $filter); + } + + /** + * 获取中间件传递的参数 + * @access public + * @param mixed $name 变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function middleware($name, $default = null) + { + return $this->middleware[$name] ?? $default; + } + + /** + * 获取POST参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function post($name = '', $default = null, $filter = '') + { + if (is_array($name)) { + return $this->only($name, $this->post, $filter); + } + + return $this->input($this->post, $name, $default, $filter); + } + + /** + * 获取PUT参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function put($name = '', $default = null, $filter = '') + { + if (is_array($name)) { + return $this->only($name, $this->put, $filter); + } + + return $this->input($this->put, $name, $default, $filter); + } + + protected function getInputData($content): array + { + $contentType = $this->contentType(); + if ($contentType == 'application/x-www-form-urlencoded') { + parse_str($content, $data); + return $data; + } elseif (false !== strpos($contentType, 'json')) { + return (array) json_decode($content, true); + } + + return []; + } + + /** + * 设置获取DELETE参数 + * @access public + * @param mixed $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function delete($name = '', $default = null, $filter = '') + { + return $this->put($name, $default, $filter); + } + + /** + * 设置获取PATCH参数 + * @access public + * @param mixed $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function patch($name = '', $default = null, $filter = '') + { + return $this->put($name, $default, $filter); + } + + /** + * 获取request变量 + * @access public + * @param string|array $name 数据名称 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function request($name = '', $default = null, $filter = '') + { + if (is_array($name)) { + return $this->only($name, $this->request, $filter); + } + + return $this->input($this->request, $name, $default, $filter); + } + + /** + * 获取环境变量 + * @access public + * @param string $name 数据名称 + * @param string $default 默认值 + * @return mixed + */ + public function env(string $name = '', string $default = null) + { + if (empty($name)) { + return $this->env->get(); + } else { + $name = strtoupper($name); + } + + return $this->env->get($name, $default); + } + + /** + * 获取session数据 + * @access public + * @param string $name 数据名称 + * @param string $default 默认值 + * @return mixed + */ + public function session(string $name = '', $default = null) + { + if ('' === $name) { + return $this->session->all(); + } + return $this->session->get($name, $default); + } + + /** + * 获取cookie参数 + * @access public + * @param mixed $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function cookie(string $name = '', $default = null, $filter = '') + { + if (!empty($name)) { + $data = $this->getData($this->cookie, $name, $default); + } else { + $data = $this->cookie; + } + + // 解析过滤器 + $filter = $this->getFilter($filter, $default); + + if (is_array($data)) { + array_walk_recursive($data, [$this, 'filterValue'], $filter); + } else { + $this->filterValue($data, $name, $filter); + } + + return $data; + } + + /** + * 获取server参数 + * @access public + * @param string $name 数据名称 + * @param string $default 默认值 + * @return mixed + */ + public function server(string $name = '', string $default = '') + { + if (empty($name)) { + return $this->server; + } else { + $name = strtoupper($name); + } + + return $this->server[$name] ?? $default; + } + + /** + * 获取上传的文件信息 + * @access public + * @param string $name 名称 + * @return null|array|UploadedFile + */ + public function file(string $name = '') + { + $files = $this->file; + if (!empty($files)) { + + if (strpos($name, '.')) { + [$name, $sub] = explode('.', $name); + } + + // 处理上传文件 + $array = $this->dealUploadFile($files, $name); + + if ('' === $name) { + // 获取全部文件 + return $array; + } elseif (isset($sub) && isset($array[$name][$sub])) { + return $array[$name][$sub]; + } elseif (isset($array[$name])) { + return $array[$name]; + } + } + } + + protected function dealUploadFile(array $files, string $name): array + { + $array = []; + foreach ($files as $key => $file) { + if (is_array($file['name'])) { + $item = []; + $keys = array_keys($file); + $count = count($file['name']); + + for ($i = 0; $i < $count; $i++) { + if ($file['error'][$i] > 0) { + if ($name == $key) { + $this->throwUploadFileError($file['error'][$i]); + } else { + continue; + } + } + + $temp['key'] = $key; + + foreach ($keys as $_key) { + $temp[$_key] = $file[$_key][$i]; + } + + $item[] = new UploadedFile($temp['tmp_name'], $temp['name'], $temp['type'], $temp['error']); + } + + $array[$key] = $item; + } else { + if ($file instanceof File) { + $array[$key] = $file; + } else { + if ($file['error'] > 0) { + if ($key == $name) { + $this->throwUploadFileError($file['error']); + } else { + continue; + } + } + + $array[$key] = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error']); + } + } + } + + return $array; + } + + protected function throwUploadFileError($error) + { + static $fileUploadErrors = [ + 1 => 'upload File size exceeds the maximum value', + 2 => 'upload File size exceeds the maximum value', + 3 => 'only the portion of file is uploaded', + 4 => 'no file to uploaded', + 6 => 'upload temp dir not found', + 7 => 'file write error', + ]; + + $msg = $fileUploadErrors[$error]; + throw new Exception($msg, $error); + } + + /** + * 设置或者获取当前的Header + * @access public + * @param string $name header名称 + * @param string $default 默认值 + * @return string|array + */ + public function header(string $name = '', string $default = null) + { + if ('' === $name) { + return $this->header; + } + + $name = str_replace('_', '-', strtolower($name)); + + return $this->header[$name] ?? $default; + } + + /** + * 获取变量 支持过滤和默认值 + * @access public + * @param array $data 数据源 + * @param string|false $name 字段名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤函数 + * @return mixed + */ + public function input(array $data = [], $name = '', $default = null, $filter = '') + { + if (false === $name) { + // 获取原始数据 + return $data; + } + + $name = (string) $name; + if ('' != $name) { + // 解析name + if (strpos($name, '/')) { + [$name, $type] = explode('/', $name); + } + + $data = $this->getData($data, $name); + + if (is_null($data)) { + return $default; + } + + if (is_object($data)) { + return $data; + } + } + + $data = $this->filterData($data, $filter, $name, $default); + + if (isset($type) && $data !== $default) { + // 强制类型转换 + $this->typeCast($data, $type); + } + + return $data; + } + + protected function filterData($data, $filter, $name, $default) + { + // 解析过滤器 + $filter = $this->getFilter($filter, $default); + + if (is_array($data)) { + array_walk_recursive($data, [$this, 'filterValue'], $filter); + } else { + $this->filterValue($data, $name, $filter); + } + + return $data; + } + + /** + * 强制类型转换 + * @access public + * @param mixed $data + * @param string $type + * @return mixed + */ + private function typeCast(&$data, string $type) + { + switch (strtolower($type)) { + // 数组 + case 'a': + $data = (array) $data; + break; + // 数字 + case 'd': + $data = (int) $data; + break; + // 浮点 + case 'f': + $data = (float) $data; + break; + // 布尔 + case 'b': + $data = (boolean) $data; + break; + // 字符串 + case 's': + if (is_scalar($data)) { + $data = (string) $data; + } else { + throw new \InvalidArgumentException('variable type error:' . gettype($data)); + } + break; + } + } + + /** + * 获取数据 + * @access public + * @param array $data 数据源 + * @param string $name 字段名 + * @param mixed $default 默认值 + * @return mixed + */ + protected function getData(array $data, string $name, $default = null) + { + foreach (explode('.', $name) as $val) { + if (isset($data[$val])) { + $data = $data[$val]; + } else { + return $default; + } + } + + return $data; + } + + /** + * 设置或获取当前的过滤规则 + * @access public + * @param mixed $filter 过滤规则 + * @return mixed + */ + public function filter($filter = null) + { + if (is_null($filter)) { + return $this->filter; + } + + $this->filter = $filter; + + return $this; + } + + protected function getFilter($filter, $default): array + { + if (is_null($filter)) { + $filter = []; + } else { + $filter = $filter ?: $this->filter; + if (is_string($filter) && false === strpos($filter, '/')) { + $filter = explode(',', $filter); + } else { + $filter = (array) $filter; + } + } + + $filter[] = $default; + + return $filter; + } + + /** + * 递归过滤给定的值 + * @access public + * @param mixed $value 键值 + * @param mixed $key 键名 + * @param array $filters 过滤方法+默认值 + * @return mixed + */ + public function filterValue(&$value, $key, $filters) + { + $default = array_pop($filters); + + foreach ($filters as $filter) { + if (is_callable($filter)) { + // 调用函数或者方法过滤 + $value = call_user_func($filter, $value); + } elseif (is_scalar($value)) { + if (is_string($filter) && false !== strpos($filter, '/')) { + // 正则过滤 + if (!preg_match($filter, $value)) { + // 匹配不成功返回默认值 + $value = $default; + break; + } + } elseif (!empty($filter)) { + // filter函数不存在时, 则使用filter_var进行过滤 + // filter为非整形值时, 调用filter_id取得过滤id + $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter)); + if (false === $value) { + $value = $default; + break; + } + } + } + } + + return $value; + } + + /** + * 是否存在某个请求参数 + * @access public + * @param string $name 变量名 + * @param string $type 变量类型 + * @param bool $checkEmpty 是否检测空值 + * @return bool + */ + public function has(string $name, string $type = 'param', bool $checkEmpty = false): bool + { + if (!in_array($type, ['param', 'get', 'post', 'put', 'patch', 'route', 'delete', 'cookie', 'session', 'env', 'request', 'server', 'header', 'file'])) { + return false; + } + + $param = empty($this->$type) ? $this->$type() : $this->$type; + + if (is_object($param)) { + return $param->has($name); + } + + // 按.拆分成多维数组进行判断 + foreach (explode('.', $name) as $val) { + if (isset($param[$val])) { + $param = $param[$val]; + } else { + return false; + } + } + + return ($checkEmpty && '' === $param) ? false : true; + } + + /** + * 获取指定的参数 + * @access public + * @param array $name 变量名 + * @param mixed $data 数据或者变量类型 + * @param string|array $filter 过滤方法 + * @return array + */ + public function only(array $name, $data = 'param', $filter = ''): array + { + $data = is_array($data) ? $data : $this->$data(); + + $item = []; + foreach ($name as $key => $val) { + + if (is_int($key)) { + $default = null; + $key = $val; + if (!isset($data[$key])) { + continue; + } + } else { + $default = $val; + } + + $item[$key] = $this->filterData($data[$key] ?? $default, $filter, $key, $default); + } + + return $item; + } + + /** + * 排除指定参数获取 + * @access public + * @param array $name 变量名 + * @param string $type 变量类型 + * @return mixed + */ + public function except(array $name, string $type = 'param'): array + { + $param = $this->$type(); + + foreach ($name as $key) { + if (isset($param[$key])) { + unset($param[$key]); + } + } + + return $param; + } + + /** + * 当前是否ssl + * @access public + * @return bool + */ + public function isSsl(): bool + { + if ($this->server('HTTPS') && ('1' == $this->server('HTTPS') || 'on' == strtolower($this->server('HTTPS')))) { + return true; + } elseif ('https' == $this->server('REQUEST_SCHEME')) { + return true; + } elseif ('443' == $this->server('SERVER_PORT')) { + return true; + } elseif ('https' == $this->server('HTTP_X_FORWARDED_PROTO')) { + return true; + } elseif ($this->httpsAgentName && $this->server($this->httpsAgentName)) { + return true; + } + + return false; + } + + /** + * 当前是否JSON请求 + * @access public + * @return bool + */ + public function isJson(): bool + { + $acceptType = $this->type(); + + return false !== strpos($acceptType, 'json'); + } + + /** + * 当前是否Ajax请求 + * @access public + * @param bool $ajax true 获取原始ajax请求 + * @return bool + */ + public function isAjax(bool $ajax = false): bool + { + $value = $this->server('HTTP_X_REQUESTED_WITH'); + $result = $value && 'xmlhttprequest' == strtolower($value) ? true : false; + + if (true === $ajax) { + return $result; + } + + return $this->param($this->varAjax) ? true : $result; + } + + /** + * 当前是否Pjax请求 + * @access public + * @param bool $pjax true 获取原始pjax请求 + * @return bool + */ + public function isPjax(bool $pjax = false): bool + { + $result = !empty($this->server('HTTP_X_PJAX')) ? true : false; + + if (true === $pjax) { + return $result; + } + + return $this->param($this->varPjax) ? true : $result; + } + + /** + * 获取客户端IP地址 + * @access public + * @return string + */ + public function ip(): string + { + if (!empty($this->realIP)) { + return $this->realIP; + } + + $this->realIP = $this->server('REMOTE_ADDR', ''); + + // 如果指定了前端代理服务器IP以及其会发送的IP头 + // 则尝试获取前端代理服务器发送过来的真实IP + $proxyIp = $this->proxyServerIp; + $proxyIpHeader = $this->proxyServerIpHeader; + + if (count($proxyIp) > 0 && count($proxyIpHeader) > 0) { + // 从指定的HTTP头中依次尝试获取IP地址 + // 直到获取到一个合法的IP地址 + foreach ($proxyIpHeader as $header) { + $tempIP = $this->server($header); + + if (empty($tempIP)) { + continue; + } + + $tempIP = trim(explode(',', $tempIP)[0]); + + if (!$this->isValidIP($tempIP)) { + $tempIP = null; + } else { + break; + } + } + + // tempIP不为空,说明获取到了一个IP地址 + // 这时我们检查 REMOTE_ADDR 是不是指定的前端代理服务器之一 + // 如果是的话说明该 IP头 是由前端代理服务器设置的 + // 否则则是伪装的 + if (!empty($tempIP)) { + $realIPBin = $this->ip2bin($this->realIP); + + foreach ($proxyIp as $ip) { + $serverIPElements = explode('/', $ip); + $serverIP = $serverIPElements[0]; + $serverIPPrefix = $serverIPElements[1] ?? 128; + $serverIPBin = $this->ip2bin($serverIP); + + // IP类型不符 + if (strlen($realIPBin) !== strlen($serverIPBin)) { + continue; + } + + if (strncmp($realIPBin, $serverIPBin, (int) $serverIPPrefix) === 0) { + $this->realIP = $tempIP; + break; + } + } + } + } + + if (!$this->isValidIP($this->realIP)) { + $this->realIP = '0.0.0.0'; + } + + return $this->realIP; + } + + /** + * 检测是否是合法的IP地址 + * + * @param string $ip IP地址 + * @param string $type IP地址类型 (ipv4, ipv6) + * + * @return boolean + */ + public function isValidIP(string $ip, string $type = ''): bool + { + switch (strtolower($type)) { + case 'ipv4': + $flag = FILTER_FLAG_IPV4; + break; + case 'ipv6': + $flag = FILTER_FLAG_IPV6; + break; + default: + $flag = null; + break; + } + + return boolval(filter_var($ip, FILTER_VALIDATE_IP, $flag)); + } + + /** + * 将IP地址转换为二进制字符串 + * + * @param string $ip + * + * @return string + */ + public function ip2bin(string $ip): string + { + if ($this->isValidIP($ip, 'ipv6')) { + $IPHex = str_split(bin2hex(inet_pton($ip)), 4); + foreach ($IPHex as $key => $value) { + $IPHex[$key] = intval($value, 16); + } + $IPBin = vsprintf('%016b%016b%016b%016b%016b%016b%016b%016b', $IPHex); + } else { + $IPHex = str_split(bin2hex(inet_pton($ip)), 2); + foreach ($IPHex as $key => $value) { + $IPHex[$key] = intval($value, 16); + } + $IPBin = vsprintf('%08b%08b%08b%08b', $IPHex); + } + + return $IPBin; + } + + /** + * 检测是否使用手机访问 + * @access public + * @return bool + */ + public function isMobile(): bool + { + if ($this->server('HTTP_VIA') && stristr($this->server('HTTP_VIA'), "wap")) { + return true; + } elseif ($this->server('HTTP_ACCEPT') && strpos(strtoupper($this->server('HTTP_ACCEPT')), "VND.WAP.WML")) { + return true; + } elseif ($this->server('HTTP_X_WAP_PROFILE') || $this->server('HTTP_PROFILE')) { + return true; + } elseif ($this->server('HTTP_USER_AGENT') && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $this->server('HTTP_USER_AGENT'))) { + return true; + } + + return false; + } + + /** + * 当前URL地址中的scheme参数 + * @access public + * @return string + */ + public function scheme(): string + { + return $this->isSsl() ? 'https' : 'http'; + } + + /** + * 当前请求URL地址中的query参数 + * @access public + * @return string + */ + public function query(): string + { + return $this->server('QUERY_STRING', ''); + } + + /** + * 设置当前请求的host(包含端口) + * @access public + * @param string $host 主机名(含端口) + * @return $this + */ + public function setHost(string $host) + { + $this->host = $host; + + return $this; + } + + /** + * 当前请求的host + * @access public + * @param bool $strict true 仅仅获取HOST + * @return string + */ + public function host(bool $strict = false): string + { + if ($this->host) { + $host = $this->host; + } else { + $host = strval($this->server('HTTP_X_REAL_HOST') ?: $this->server('HTTP_HOST')); + } + + return true === $strict && strpos($host, ':') ? strstr($host, ':', true) : $host; + } + + /** + * 当前请求URL地址中的port参数 + * @access public + * @return int + */ + public function port(): int + { + return (int) $this->server('SERVER_PORT', ''); + } + + /** + * 当前请求 SERVER_PROTOCOL + * @access public + * @return string + */ + public function protocol(): string + { + return $this->server('SERVER_PROTOCOL', ''); + } + + /** + * 当前请求 REMOTE_PORT + * @access public + * @return int + */ + public function remotePort(): int + { + return (int) $this->server('REMOTE_PORT', ''); + } + + /** + * 当前请求 HTTP_CONTENT_TYPE + * @access public + * @return string + */ + public function contentType(): string + { + $contentType = $this->header('Content-Type'); + + if ($contentType) { + if (strpos($contentType, ';')) { + [$type] = explode(';', $contentType); + } else { + $type = $contentType; + } + return trim($type); + } + + return ''; + } + + /** + * 获取当前请求的安全Key + * @access public + * @return string + */ + public function secureKey(): string + { + if (is_null($this->secureKey)) { + $this->secureKey = uniqid('', true); + } + + return $this->secureKey; + } + + /** + * 设置当前的控制器名 + * @access public + * @param string $controller 控制器名 + * @return $this + */ + public function setController(string $controller) + { + $this->controller = $controller; + return $this; + } + + /** + * 设置当前的操作名 + * @access public + * @param string $action 操作名 + * @return $this + */ + public function setAction(string $action) + { + $this->action = $action; + return $this; + } + + /** + * 获取当前的控制器名 + * @access public + * @param bool $convert 转换为小写 + * @return string + */ + public function controller(bool $convert = false): string + { + $name = $this->controller ?: ''; + return $convert ? strtolower($name) : $name; + } + + /** + * 获取当前的操作名 + * @access public + * @param bool $convert 转换为小写 + * @return string + */ + public function action(bool $convert = false): string + { + $name = $this->action ?: ''; + return $convert ? strtolower($name) : $name; + } + + /** + * 设置或者获取当前请求的content + * @access public + * @return string + */ + public function getContent(): string + { + if (is_null($this->content)) { + $this->content = $this->input; + } + + return $this->content; + } + + /** + * 获取当前请求的php://input + * @access public + * @return string + */ + public function getInput(): string + { + return $this->input; + } + + /** + * 生成请求令牌 + * @access public + * @param string $name 令牌名称 + * @param mixed $type 令牌生成方法 + * @return string + */ + public function buildToken(string $name = '__token__', $type = 'md5'): string + { + $type = is_callable($type) ? $type : 'md5'; + $token = call_user_func($type, $this->server('REQUEST_TIME_FLOAT')); + + $this->session->set($name, $token); + + return $token; + } + + /** + * 检查请求令牌 + * @access public + * @param string $token 令牌名称 + * @param array $data 表单数据 + * @return bool + */ + public function checkToken(string $token = '__token__', array $data = []): bool + { + if (in_array($this->method(), ['GET', 'HEAD', 'OPTIONS'], true)) { + return true; + } + + if (!$this->session->has($token)) { + // 令牌数据无效 + return false; + } + + // Header验证 + if ($this->header('X-CSRF-TOKEN') && $this->session->get($token) === $this->header('X-CSRF-TOKEN')) { + // 防止重复提交 + $this->session->delete($token); // 验证完成销毁session + return true; + } + + if (empty($data)) { + $data = $this->post(); + } + + // 令牌验证 + if (isset($data[$token]) && $this->session->get($token) === $data[$token]) { + // 防止重复提交 + $this->session->delete($token); // 验证完成销毁session + return true; + } + + // 开启TOKEN重置 + $this->session->delete($token); + return false; + } + + /** + * 设置在中间件传递的数据 + * @access public + * @param array $middleware 数据 + * @return $this + */ + public function withMiddleware(array $middleware) + { + $this->middleware = array_merge($this->middleware, $middleware); + return $this; + } + + /** + * 设置GET数据 + * @access public + * @param array $get 数据 + * @return $this + */ + public function withGet(array $get) + { + $this->get = $get; + return $this; + } + + /** + * 设置POST数据 + * @access public + * @param array $post 数据 + * @return $this + */ + public function withPost(array $post) + { + $this->post = $post; + return $this; + } + + /** + * 设置COOKIE数据 + * @access public + * @param array $cookie 数据 + * @return $this + */ + public function withCookie(array $cookie) + { + $this->cookie = $cookie; + return $this; + } + + /** + * 设置SESSION数据 + * @access public + * @param Session $session 数据 + * @return $this + */ + public function withSession(Session $session) + { + $this->session = $session; + return $this; + } + + /** + * 设置SERVER数据 + * @access public + * @param array $server 数据 + * @return $this + */ + public function withServer(array $server) + { + $this->server = array_change_key_case($server, CASE_UPPER); + return $this; + } + + /** + * 设置HEADER数据 + * @access public + * @param array $header 数据 + * @return $this + */ + public function withHeader(array $header) + { + $this->header = array_change_key_case($header); + return $this; + } + + /** + * 设置ENV数据 + * @access public + * @param Env $env 数据 + * @return $this + */ + public function withEnv(Env $env) + { + $this->env = $env; + return $this; + } + + /** + * 设置php://input数据 + * @access public + * @param string $input RAW数据 + * @return $this + */ + public function withInput(string $input) + { + $this->input = $input; + if (!empty($input)) { + $inputData = $this->getInputData($input); + if (!empty($inputData)) { + $this->post = $inputData; + $this->put = $inputData; + } + } + return $this; + } + + /** + * 设置文件上传数据 + * @access public + * @param array $files 上传信息 + * @return $this + */ + public function withFiles(array $files) + { + $this->file = $files; + return $this; + } + + /** + * 设置ROUTE变量 + * @access public + * @param array $route 数据 + * @return $this + */ + public function withRoute(array $route) + { + $this->route = $route; + return $this; + } + + /** + * 设置中间传递数据 + * @access public + * @param string $name 参数名 + * @param mixed $value 值 + */ + public function __set(string $name, $value) + { + $this->middleware[$name] = $value; + } + + /** + * 获取中间传递数据的值 + * @access public + * @param string $name 名称 + * @return mixed + */ + public function __get(string $name) + { + return $this->middleware($name); + } + + /** + * 检测中间传递数据的值 + * @access public + * @param string $name 名称 + * @return boolean + */ + public function __isset(string $name): bool + { + return isset($this->middleware[$name]); + } +} diff --git a/vendor/topthink/framework/src/think/Response.php b/vendor/topthink/framework/src/think/Response.php new file mode 100644 index 0000000..556696a --- /dev/null +++ b/vendor/topthink/framework/src/think/Response.php @@ -0,0 +1,410 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +/** + * 响应输出基础类 + * @package think + */ +abstract class Response +{ + /** + * 原始数据 + * @var mixed + */ + protected $data; + + /** + * 当前contentType + * @var string + */ + protected $contentType = 'text/html'; + + /** + * 字符集 + * @var string + */ + protected $charset = 'utf-8'; + + /** + * 状态码 + * @var integer + */ + protected $code = 200; + + /** + * 是否允许请求缓存 + * @var bool + */ + protected $allowCache = true; + + /** + * 输出参数 + * @var array + */ + protected $options = []; + + /** + * header参数 + * @var array + */ + protected $header = []; + + /** + * 输出内容 + * @var string + */ + protected $content = null; + + /** + * Cookie对象 + * @var Cookie + */ + protected $cookie; + + /** + * Session对象 + * @var Session + */ + protected $session; + + /** + * 初始化 + * @access protected + * @param mixed $data 输出数据 + * @param int $code 状态码 + */ + protected function init($data = '', int $code = 200) + { + $this->data($data); + $this->code = $code; + + $this->contentType($this->contentType, $this->charset); + } + + /** + * 创建Response对象 + * @access public + * @param mixed $data 输出数据 + * @param string $type 输出类型 + * @param int $code 状态码 + * @return Response + */ + public static function create($data = '', string $type = 'html', int $code = 200): Response + { + $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst(strtolower($type)); + + return Container::getInstance()->invokeClass($class, [$data, $code]); + } + + /** + * 设置Session对象 + * @access public + * @param Session $session Session对象 + * @return $this + */ + public function setSession(Session $session) + { + $this->session = $session; + return $this; + } + + /** + * 发送数据到客户端 + * @access public + * @return void + * @throws \InvalidArgumentException + */ + public function send(): void + { + // 处理输出数据 + $data = $this->getContent(); + + if (!headers_sent() && !empty($this->header)) { + // 发送状态码 + http_response_code($this->code); + // 发送头部信息 + foreach ($this->header as $name => $val) { + header($name . (!is_null($val) ? ':' . $val : '')); + } + } + if ($this->cookie) { + $this->cookie->save(); + } + + $this->sendData($data); + + if (function_exists('fastcgi_finish_request')) { + // 提高页面响应 + fastcgi_finish_request(); + } + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + return $data; + } + + /** + * 输出数据 + * @access protected + * @param string $data 要处理的数据 + * @return void + */ + protected function sendData(string $data): void + { + echo $data; + } + + /** + * 输出的参数 + * @access public + * @param mixed $options 输出参数 + * @return $this + */ + public function options(array $options = []) + { + $this->options = array_merge($this->options, $options); + + return $this; + } + + /** + * 输出数据设置 + * @access public + * @param mixed $data 输出数据 + * @return $this + */ + public function data($data) + { + $this->data = $data; + + return $this; + } + + /** + * 是否允许请求缓存 + * @access public + * @param bool $cache 允许请求缓存 + * @return $this + */ + public function allowCache(bool $cache) + { + $this->allowCache = $cache; + + return $this; + } + + /** + * 是否允许请求缓存 + * @access public + * @return $this + */ + public function isAllowCache() + { + return $this->allowCache; + } + + /** + * 设置Cookie + * @access public + * @param string $name cookie名称 + * @param string $value cookie值 + * @param mixed $option 可选参数 + * @return $this + */ + public function cookie(string $name, string $value, $option = null) + { + $this->cookie->set($name, $value, $option); + + return $this; + } + + /** + * 设置响应头 + * @access public + * @param array $header 参数 + * @return $this + */ + public function header(array $header = []) + { + $this->header = array_merge($this->header, $header); + + return $this; + } + + /** + * 设置页面输出内容 + * @access public + * @param mixed $content + * @return $this + */ + public function content($content) + { + if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ + $content, + '__toString', + ]) + ) { + throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); + } + + $this->content = (string) $content; + + return $this; + } + + /** + * 发送HTTP状态 + * @access public + * @param integer $code 状态码 + * @return $this + */ + public function code(int $code) + { + $this->code = $code; + + return $this; + } + + /** + * LastModified + * @access public + * @param string $time + * @return $this + */ + public function lastModified(string $time) + { + $this->header['Last-Modified'] = $time; + + return $this; + } + + /** + * Expires + * @access public + * @param string $time + * @return $this + */ + public function expires(string $time) + { + $this->header['Expires'] = $time; + + return $this; + } + + /** + * ETag + * @access public + * @param string $eTag + * @return $this + */ + public function eTag(string $eTag) + { + $this->header['ETag'] = $eTag; + + return $this; + } + + /** + * 页面缓存控制 + * @access public + * @param string $cache 状态码 + * @return $this + */ + public function cacheControl(string $cache) + { + $this->header['Cache-control'] = $cache; + + return $this; + } + + /** + * 页面输出类型 + * @access public + * @param string $contentType 输出类型 + * @param string $charset 输出编码 + * @return $this + */ + public function contentType(string $contentType, string $charset = 'utf-8') + { + $this->header['Content-Type'] = $contentType . '; charset=' . $charset; + + return $this; + } + + /** + * 获取头部信息 + * @access public + * @param string $name 头部名称 + * @return mixed + */ + public function getHeader(string $name = '') + { + if (!empty($name)) { + return $this->header[$name] ?? null; + } + + return $this->header; + } + + /** + * 获取原始数据 + * @access public + * @return mixed + */ + public function getData() + { + return $this->data; + } + + /** + * 获取输出数据 + * @access public + * @return string + */ + public function getContent(): string + { + if (null == $this->content) { + $content = $this->output($this->data); + + if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ + $content, + '__toString', + ]) + ) { + throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); + } + + $this->content = (string) $content; + } + + return $this->content; + } + + /** + * 获取状态码 + * @access public + * @return integer + */ + public function getCode(): int + { + return $this->code; + } +} diff --git a/vendor/topthink/framework/src/think/Route.php b/vendor/topthink/framework/src/think/Route.php new file mode 100644 index 0000000..6bf7c80 --- /dev/null +++ b/vendor/topthink/framework/src/think/Route.php @@ -0,0 +1,894 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use Closure; +use think\exception\RouteNotFoundException; +use think\route\Dispatch; +use think\route\dispatch\Url as UrlDispatch; +use think\route\Domain; +use think\route\Resource; +use think\route\Rule; +use think\route\RuleGroup; +use think\route\RuleItem; +use think\route\RuleName; +use think\route\Url as UrlBuild; + +/** + * 路由管理类 + * @package think + */ +class Route +{ + /** + * REST定义 + * @var array + */ + protected $rest = [ + 'index' => ['get', '', 'index'], + 'create' => ['get', '/create', 'create'], + 'edit' => ['get', '//edit', 'edit'], + 'read' => ['get', '/', 'read'], + 'save' => ['post', '', 'save'], + 'update' => ['put', '/', 'update'], + 'delete' => ['delete', '/', 'delete'], + ]; + + /** + * 配置参数 + * @var array + */ + protected $config = [ + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // 是否开启路由延迟解析 + 'url_lazy_route' => false, + // 是否强制使用路由 + 'url_route_must' => false, + // 合并路由规则 + 'route_rule_merge' => false, + // 路由是否完全匹配 + 'route_complete_match' => false, + // 去除斜杠 + 'remove_slash' => false, + // 使用注解路由 + 'route_annotation' => false, + // 默认的路由变量规则 + 'default_route_pattern' => '[\w\.]+', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // 访问控制器层名称 + 'controller_layer' => 'controller', + // 空控制器名 + 'empty_controller' => 'Error', + // 是否使用控制器后缀 + 'controller_suffix' => false, + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 操作方法后缀 + 'action_suffix' => '', + // 非路由变量是否使用普通参数方式(用于URL生成) + 'url_common_param' => true, + ]; + + /** + * 当前应用 + * @var App + */ + protected $app; + + /** + * 请求对象 + * @var Request + */ + protected $request; + + /** + * @var RuleName + */ + protected $ruleName; + + /** + * 当前HOST + * @var string + */ + protected $host; + + /** + * 当前分组对象 + * @var RuleGroup + */ + protected $group; + + /** + * 路由绑定 + * @var array + */ + protected $bind = []; + + /** + * 域名对象 + * @var array + */ + protected $domains = []; + + /** + * 跨域路由规则 + * @var RuleGroup + */ + protected $cross; + + /** + * 路由是否延迟解析 + * @var bool + */ + protected $lazy = true; + + /** + * 路由是否测试模式 + * @var bool + */ + protected $isTest = false; + + /** + * (分组)路由规则是否合并解析 + * @var bool + */ + protected $mergeRuleRegex = false; + + /** + * 是否去除URL最后的斜线 + * @var bool + */ + protected $removeSlash = false; + + public function __construct(App $app) + { + $this->app = $app; + $this->ruleName = new RuleName(); + $this->setDefaultDomain(); + + if (is_file($this->app->getRuntimePath() . 'route.php')) { + // 读取路由映射文件 + $this->import(include $this->app->getRuntimePath() . 'route.php'); + } + } + + protected function init() + { + $this->config = array_merge($this->config, $this->app->config->get('route')); + + if (!empty($this->config['middleware'])) { + $this->app->middleware->import($this->config['middleware'], 'route'); + } + + $this->lazy($this->config['url_lazy_route']); + $this->mergeRuleRegex = $this->config['route_rule_merge']; + $this->removeSlash = $this->config['remove_slash']; + + $this->group->removeSlash($this->removeSlash); + } + + public function config(string $name = null) + { + if (is_null($name)) { + return $this->config; + } + + return $this->config[$name] ?? null; + } + + /** + * 设置路由域名及分组(包括资源路由)是否延迟解析 + * @access public + * @param bool $lazy 路由是否延迟解析 + * @return $this + */ + public function lazy(bool $lazy = true) + { + $this->lazy = $lazy; + return $this; + } + + /** + * 设置路由为测试模式 + * @access public + * @param bool $test 路由是否测试模式 + * @return void + */ + public function setTestMode(bool $test): void + { + $this->isTest = $test; + } + + /** + * 检查路由是否为测试模式 + * @access public + * @return bool + */ + public function isTest(): bool + { + return $this->isTest; + } + + /** + * 设置路由域名及分组(包括资源路由)是否合并解析 + * @access public + * @param bool $merge 路由是否合并解析 + * @return $this + */ + public function mergeRuleRegex(bool $merge = true) + { + $this->mergeRuleRegex = $merge; + $this->group->mergeRuleRegex($merge); + + return $this; + } + + /** + * 初始化默认域名 + * @access protected + * @return void + */ + protected function setDefaultDomain(): void + { + // 注册默认域名 + $domain = new Domain($this); + + $this->domains['-'] = $domain; + + // 默认分组 + $this->group = $domain; + } + + /** + * 设置当前分组 + * @access public + * @param RuleGroup $group 域名 + * @return void + */ + public function setGroup(RuleGroup $group): void + { + $this->group = $group; + } + + /** + * 获取指定标识的路由分组 不指定则获取当前分组 + * @access public + * @param string $name 分组标识 + * @return RuleGroup + */ + public function getGroup(string $name = null) + { + return $name ? $this->ruleName->getGroup($name) : $this->group; + } + + /** + * 注册变量规则 + * @access public + * @param array $pattern 变量规则 + * @return $this + */ + public function pattern(array $pattern) + { + $this->group->pattern($pattern); + + return $this; + } + + /** + * 注册路由参数 + * @access public + * @param array $option 参数 + * @return $this + */ + public function option(array $option) + { + $this->group->option($option); + + return $this; + } + + /** + * 注册域名路由 + * @access public + * @param string|array $name 子域名 + * @param mixed $rule 路由规则 + * @return Domain + */ + public function domain($name, $rule = null): Domain + { + // 支持多个域名使用相同路由规则 + $domainName = is_array($name) ? array_shift($name) : $name; + + if (!isset($this->domains[$domainName])) { + $domain = (new Domain($this, $domainName, $rule)) + ->lazy($this->lazy) + ->removeSlash($this->removeSlash) + ->mergeRuleRegex($this->mergeRuleRegex); + + $this->domains[$domainName] = $domain; + } else { + $domain = $this->domains[$domainName]; + $domain->parseGroupRule($rule); + } + + if (is_array($name) && !empty($name)) { + foreach ($name as $item) { + $this->domains[$item] = $domainName; + } + } + + // 返回域名对象 + return $domain; + } + + /** + * 获取域名 + * @access public + * @return array + */ + public function getDomains(): array + { + return $this->domains; + } + + /** + * 获取RuleName对象 + * @access public + * @return RuleName + */ + public function getRuleName(): RuleName + { + return $this->ruleName; + } + + /** + * 设置路由绑定 + * @access public + * @param string $bind 绑定信息 + * @param string $domain 域名 + * @return $this + */ + public function bind(string $bind, string $domain = null) + { + $domain = is_null($domain) ? '-' : $domain; + + $this->bind[$domain] = $bind; + + return $this; + } + + /** + * 读取路由绑定信息 + * @access public + * @return array + */ + public function getBind(): array + { + return $this->bind; + } + + /** + * 读取路由绑定 + * @access public + * @param string $domain 域名 + * @return string|null + */ + public function getDomainBind(string $domain = null) + { + if (is_null($domain)) { + $domain = $this->host; + } elseif (false === strpos($domain, '.') && $this->request) { + $domain .= '.' . $this->request->rootDomain(); + } + + if ($this->request) { + $subDomain = $this->request->subDomain(); + + if (strpos($subDomain, '.')) { + $name = '*' . strstr($subDomain, '.'); + } + } + + if (isset($this->bind[$domain])) { + $result = $this->bind[$domain]; + } elseif (isset($name) && isset($this->bind[$name])) { + $result = $this->bind[$name]; + } elseif (!empty($subDomain) && isset($this->bind['*'])) { + $result = $this->bind['*']; + } else { + $result = null; + } + + return $result; + } + + /** + * 读取路由标识 + * @access public + * @param string $name 路由标识 + * @param string $domain 域名 + * @param string $method 请求类型 + * @return RuleItem[] + */ + public function getName(string $name = null, string $domain = null, string $method = '*'): array + { + return $this->ruleName->getName($name, $domain, $method); + } + + /** + * 批量导入路由标识 + * @access public + * @param array $name 路由标识 + * @return $this + */ + public function import(array $name): void + { + $this->ruleName->import($name); + } + + /** + * 注册路由标识 + * @access public + * @param string $name 路由标识 + * @param RuleItem $ruleItem 路由规则 + * @param bool $first 是否优先 + * @return void + */ + public function setName(string $name, RuleItem $ruleItem, bool $first = false): void + { + $this->ruleName->setName($name, $ruleItem, $first); + } + + /** + * 保存路由规则 + * @access public + * @param string $rule 路由规则 + * @param RuleItem $ruleItem RuleItem对象 + * @return void + */ + public function setRule(string $rule, RuleItem $ruleItem = null): void + { + $this->ruleName->setRule($rule, $ruleItem); + } + + /** + * 读取路由 + * @access public + * @param string $rule 路由规则 + * @return RuleItem[] + */ + public function getRule(string $rule): array + { + return $this->ruleName->getRule($rule); + } + + /** + * 读取路由列表 + * @access public + * @return array + */ + public function getRuleList(): array + { + return $this->ruleName->getRuleList(); + } + + /** + * 清空路由规则 + * @access public + * @return void + */ + public function clear(): void + { + $this->ruleName->clear(); + + if ($this->group) { + $this->group->clear(); + } + } + + /** + * 注册路由规则 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @param string $method 请求类型 + * @return RuleItem + */ + public function rule(string $rule, $route = null, string $method = '*'): RuleItem + { + return $this->group->addRule($rule, $route, $method); + } + + /** + * 设置跨域有效路由规则 + * @access public + * @param Rule $rule 路由规则 + * @param string $method 请求类型 + * @return $this + */ + public function setCrossDomainRule(Rule $rule, string $method = '*') + { + if (!isset($this->cross)) { + $this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex); + } + + $this->cross->addRuleItem($rule, $method); + + return $this; + } + + /** + * 注册路由分组 + * @access public + * @param string|\Closure $name 分组名称或者参数 + * @param mixed $route 分组路由 + * @return RuleGroup + */ + public function group($name, $route = null): RuleGroup + { + if ($name instanceof Closure) { + $route = $name; + $name = ''; + } + + return (new RuleGroup($this, $this->group, $name, $route)) + ->lazy($this->lazy) + ->removeSlash($this->removeSlash) + ->mergeRuleRegex($this->mergeRuleRegex); + } + + /** + * 注册路由 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @return RuleItem + */ + public function any(string $rule, $route): RuleItem + { + return $this->rule($rule, $route, '*'); + } + + /** + * 注册GET路由 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @return RuleItem + */ + public function get(string $rule, $route): RuleItem + { + return $this->rule($rule, $route, 'GET'); + } + + /** + * 注册POST路由 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @return RuleItem + */ + public function post(string $rule, $route): RuleItem + { + return $this->rule($rule, $route, 'POST'); + } + + /** + * 注册PUT路由 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @return RuleItem + */ + public function put(string $rule, $route): RuleItem + { + return $this->rule($rule, $route, 'PUT'); + } + + /** + * 注册DELETE路由 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @return RuleItem + */ + public function delete(string $rule, $route): RuleItem + { + return $this->rule($rule, $route, 'DELETE'); + } + + /** + * 注册PATCH路由 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @return RuleItem + */ + public function patch(string $rule, $route): RuleItem + { + return $this->rule($rule, $route, 'PATCH'); + } + + /** + * 注册OPTIONS路由 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @return RuleItem + */ + public function options(string $rule, $route): RuleItem + { + return $this->rule($rule, $route, 'OPTIONS'); + } + + /** + * 注册资源路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @return Resource + */ + public function resource(string $rule, string $route): Resource + { + return (new Resource($this, $this->group, $rule, $route, $this->rest)) + ->lazy($this->lazy); + } + + /** + * 注册视图路由 + * @access public + * @param string $rule 路由规则 + * @param string $template 路由模板地址 + * @param array $vars 模板变量 + * @return RuleItem + */ + public function view(string $rule, string $template = '', array $vars = []): RuleItem + { + return $this->rule($rule, $template, 'GET')->view($vars); + } + + /** + * 注册重定向路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param int $status 状态码 + * @return RuleItem + */ + public function redirect(string $rule, string $route = '', int $status = 301): RuleItem + { + return $this->rule($rule, $route, '*')->redirect()->status($status); + } + + /** + * rest方法定义和修改 + * @access public + * @param string|array $name 方法名称 + * @param array|bool $resource 资源 + * @return $this + */ + public function rest($name, $resource = []) + { + if (is_array($name)) { + $this->rest = $resource ? $name : array_merge($this->rest, $name); + } else { + $this->rest[$name] = $resource; + } + + return $this; + } + + /** + * 获取rest方法定义的参数 + * @access public + * @param string $name 方法名称 + * @return array|null + */ + public function getRest(string $name = null) + { + if (is_null($name)) { + return $this->rest; + } + + return $this->rest[$name] ?? null; + } + + /** + * 注册未匹配路由规则后的处理 + * @access public + * @param string|Closure $route 路由地址 + * @param string $method 请求类型 + * @return RuleItem + */ + public function miss($route, string $method = '*'): RuleItem + { + return $this->group->miss($route, $method); + } + + /** + * 路由调度 + * @param Request $request + * @param Closure $withRoute + * @return Response + */ + public function dispatch(Request $request, $withRoute = null) + { + $this->request = $request; + $this->host = $this->request->host(true); + $this->init(); + + if ($withRoute) { + //加载路由 + $withRoute(); + $dispatch = $this->check(); + } else { + $dispatch = $this->url($this->path()); + } + + $dispatch->init($this->app); + + return $this->app->middleware->pipeline('route') + ->send($request) + ->then(function () use ($dispatch) { + return $dispatch->run(); + }); + } + + /** + * 检测URL路由 + * @access public + * @return Dispatch + * @throws RouteNotFoundException + */ + public function check(): Dispatch + { + // 自动检测域名路由 + $url = str_replace($this->config['pathinfo_depr'], '|', $this->path()); + + $completeMatch = $this->config['route_complete_match']; + + $result = $this->checkDomain()->check($this->request, $url, $completeMatch); + + if (false === $result && !empty($this->cross)) { + // 检测跨域路由 + $result = $this->cross->check($this->request, $url, $completeMatch); + } + + if (false !== $result) { + return $result; + } elseif ($this->config['url_route_must']) { + throw new RouteNotFoundException(); + } + + return $this->url($url); + } + + /** + * 获取当前请求URL的pathinfo信息(不含URL后缀) + * @access protected + * @return string + */ + protected function path(): string + { + $suffix = $this->config['url_html_suffix']; + $pathinfo = $this->request->pathinfo(); + + if (false === $suffix) { + // 禁止伪静态访问 + $path = $pathinfo; + } elseif ($suffix) { + // 去除正常的URL后缀 + $path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo); + } else { + // 允许任何后缀访问 + $path = preg_replace('/\.' . $this->request->ext() . '$/i', '', $pathinfo); + } + + return $path; + } + + /** + * 默认URL解析 + * @access public + * @param string $url URL地址 + * @return Dispatch + */ + public function url(string $url): UrlDispatch + { + return new UrlDispatch($this->request, $this->group, $url); + } + + /** + * 检测域名的路由规则 + * @access protected + * @return Domain + */ + protected function checkDomain(): Domain + { + $item = false; + + if (count($this->domains) > 1) { + // 获取当前子域名 + $subDomain = $this->request->subDomain(); + + $domain = $subDomain ? explode('.', $subDomain) : []; + $domain2 = $domain ? array_pop($domain) : ''; + + if ($domain) { + // 存在三级域名 + $domain3 = array_pop($domain); + } + + if (isset($this->domains[$this->host])) { + // 子域名配置 + $item = $this->domains[$this->host]; + } elseif (isset($this->domains[$subDomain])) { + $item = $this->domains[$subDomain]; + } elseif (isset($this->domains['*.' . $domain2]) && !empty($domain3)) { + // 泛三级域名 + $item = $this->domains['*.' . $domain2]; + $panDomain = $domain3; + } elseif (isset($this->domains['*']) && !empty($domain2)) { + // 泛二级域名 + if ('www' != $domain2) { + $item = $this->domains['*']; + $panDomain = $domain2; + } + } + + if (isset($panDomain)) { + // 保存当前泛域名 + $this->request->setPanDomain($panDomain); + } + } + + if (false === $item) { + // 检测全局域名规则 + $item = $this->domains['-']; + } + + if (is_string($item)) { + $item = $this->domains[$item]; + } + + return $item; + } + + /** + * URL生成 支持路由反射 + * @access public + * @param string $url 路由地址 + * @param array $vars 参数 ['a'=>'val1', 'b'=>'val2'] + * @return UrlBuild + */ + public function buildUrl(string $url = '', array $vars = []): UrlBuild + { + return $this->app->make(UrlBuild::class, [$this, $this->app, $url, $vars], true); + } + + /** + * 设置全局的路由分组参数 + * @access public + * @param string $method 方法名 + * @param array $args 调用参数 + * @return RuleGroup + */ + public function __call($method, $args) + { + return call_user_func_array([$this->group, $method], $args); + } +} diff --git a/vendor/topthink/framework/src/think/Service.php b/vendor/topthink/framework/src/think/Service.php new file mode 100644 index 0000000..68c6789 --- /dev/null +++ b/vendor/topthink/framework/src/think/Service.php @@ -0,0 +1,66 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use Closure; +use think\event\RouteLoaded; + +/** + * 系统服务基础类 + * @method void register() + * @method void boot() + */ +abstract class Service +{ + protected $app; + + public function __construct(App $app) + { + $this->app = $app; + } + + /** + * 加载路由 + * @access protected + * @param string $path 路由路径 + */ + protected function loadRoutesFrom($path) + { + $this->registerRoutes(function () use ($path) { + include $path; + }); + } + + /** + * 注册路由 + * @param Closure $closure + */ + protected function registerRoutes(Closure $closure) + { + $this->app->event->listen(RouteLoaded::class, $closure); + } + + /** + * 添加指令 + * @access protected + * @param array|string $commands 指令 + */ + protected function commands($commands) + { + $commands = is_array($commands) ? $commands : func_get_args(); + + Console::starting(function (Console $console) use ($commands) { + $console->addCommands($commands); + }); + } +} diff --git a/vendor/topthink/framework/src/think/Session.php b/vendor/topthink/framework/src/think/Session.php new file mode 100644 index 0000000..c344f0b --- /dev/null +++ b/vendor/topthink/framework/src/think/Session.php @@ -0,0 +1,65 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use think\helper\Arr; +use think\session\Store; + +/** + * Session管理类 + * @package think + * @mixin Store + */ +class Session extends Manager +{ + protected $namespace = '\\think\\session\\driver\\'; + + protected function createDriver(string $name) + { + $handler = parent::createDriver($name); + + return new Store($this->getConfig('name') ?: 'PHPSESSID', $handler, $this->getConfig('serialize')); + } + + /** + * 获取Session配置 + * @access public + * @param null|string $name 名称 + * @param mixed $default 默认值 + * @return mixed + */ + public function getConfig(string $name = null, $default = null) + { + if (!is_null($name)) { + return $this->app->config->get('session.' . $name, $default); + } + + return $this->app->config->get('session'); + } + + protected function resolveConfig(string $name) + { + $config = $this->app->config->get('session', []); + Arr::forget($config, 'type'); + return $config; + } + + /** + * 默认驱动 + * @return string|null + */ + public function getDefaultDriver() + { + return $this->app->config->get('session.type', 'file'); + } +} diff --git a/vendor/topthink/framework/src/think/Validate.php b/vendor/topthink/framework/src/think/Validate.php new file mode 100644 index 0000000..1b6adbd --- /dev/null +++ b/vendor/topthink/framework/src/think/Validate.php @@ -0,0 +1,1677 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use Closure; +use think\exception\ValidateException; +use think\helper\Str; +use think\validate\ValidateRule; + +/** + * 数据验证类 + * @package think + */ +class Validate +{ + /** + * 自定义验证类型 + * @var array + */ + protected $type = []; + + /** + * 验证类型别名 + * @var array + */ + protected $alias = [ + '>' => 'gt', '>=' => 'egt', '<' => 'lt', '<=' => 'elt', '=' => 'eq', 'same' => 'eq', + ]; + + /** + * 当前验证规则 + * @var array + */ + protected $rule = []; + + /** + * 验证提示信息 + * @var array + */ + protected $message = []; + + /** + * 验证字段描述 + * @var array + */ + protected $field = []; + + /** + * 默认规则提示 + * @var array + */ + protected $typeMsg = [ + 'require' => ':attribute require', + 'must' => ':attribute must', + 'number' => ':attribute must be numeric', + 'integer' => ':attribute must be integer', + 'float' => ':attribute must be float', + 'boolean' => ':attribute must be bool', + 'email' => ':attribute not a valid email address', + 'mobile' => ':attribute not a valid mobile', + 'array' => ':attribute must be a array', + 'accepted' => ':attribute must be yes,on or 1', + 'date' => ':attribute not a valid datetime', + 'file' => ':attribute not a valid file', + 'image' => ':attribute not a valid image', + 'alpha' => ':attribute must be alpha', + 'alphaNum' => ':attribute must be alpha-numeric', + 'alphaDash' => ':attribute must be alpha-numeric, dash, underscore', + 'activeUrl' => ':attribute not a valid domain or ip', + 'chs' => ':attribute must be chinese', + 'chsAlpha' => ':attribute must be chinese or alpha', + 'chsAlphaNum' => ':attribute must be chinese,alpha-numeric', + 'chsDash' => ':attribute must be chinese,alpha-numeric,underscore, dash', + 'url' => ':attribute not a valid url', + 'ip' => ':attribute not a valid ip', + 'dateFormat' => ':attribute must be dateFormat of :rule', + 'in' => ':attribute must be in :rule', + 'notIn' => ':attribute be notin :rule', + 'between' => ':attribute must between :1 - :2', + 'notBetween' => ':attribute not between :1 - :2', + 'length' => 'size of :attribute must be :rule', + 'max' => 'max size of :attribute must be :rule', + 'min' => 'min size of :attribute must be :rule', + 'after' => ':attribute cannot be less than :rule', + 'before' => ':attribute cannot exceed :rule', + 'expire' => ':attribute not within :rule', + 'allowIp' => 'access IP is not allowed', + 'denyIp' => 'access IP denied', + 'confirm' => ':attribute out of accord with :2', + 'different' => ':attribute cannot be same with :2', + 'egt' => ':attribute must greater than or equal :rule', + 'gt' => ':attribute must greater than :rule', + 'elt' => ':attribute must less than or equal :rule', + 'lt' => ':attribute must less than :rule', + 'eq' => ':attribute must equal :rule', + 'unique' => ':attribute has exists', + 'regex' => ':attribute not conform to the rules', + 'method' => 'invalid Request method', + 'token' => 'invalid token', + 'fileSize' => 'filesize not match', + 'fileExt' => 'extensions to upload is not allowed', + 'fileMime' => 'mimetype to upload is not allowed', + ]; + + /** + * 当前验证场景 + * @var string + */ + protected $currentScene; + + /** + * 内置正则验证规则 + * @var array + */ + protected $defaultRegex = [ + 'alpha' => '/^[A-Za-z]+$/', + 'alphaNum' => '/^[A-Za-z0-9]+$/', + 'alphaDash' => '/^[A-Za-z0-9\-\_]+$/', + 'chs' => '/^[\x{4e00}-\x{9fa5}]+$/u', + 'chsAlpha' => '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u', + 'chsAlphaNum' => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]+$/u', + 'chsDash' => '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u', + 'mobile' => '/^1[3-9]\d{9}$/', + 'idCard' => '/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/', + 'zip' => '/\d{6}/', + ]; + + /** + * Filter_var 规则 + * @var array + */ + protected $filter = [ + 'email' => FILTER_VALIDATE_EMAIL, + 'ip' => [FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6], + 'integer' => FILTER_VALIDATE_INT, + 'url' => FILTER_VALIDATE_URL, + 'macAddr' => FILTER_VALIDATE_MAC, + 'float' => FILTER_VALIDATE_FLOAT, + ]; + + /** + * 验证场景定义 + * @var array + */ + protected $scene = []; + + /** + * 验证失败错误信息 + * @var string|array + */ + protected $error = []; + + /** + * 是否批量验证 + * @var bool + */ + protected $batch = false; + + /** + * 验证失败是否抛出异常 + * @var bool + */ + protected $failException = false; + + /** + * 场景需要验证的规则 + * @var array + */ + protected $only = []; + + /** + * 场景需要移除的验证规则 + * @var array + */ + protected $remove = []; + + /** + * 场景需要追加的验证规则 + * @var array + */ + protected $append = []; + + /** + * 验证正则定义 + * @var array + */ + protected $regex = []; + + /** + * Db对象 + * @var Db + */ + protected $db; + + /** + * 语言对象 + * @var Lang + */ + protected $lang; + + /** + * 请求对象 + * @var Request + */ + protected $request; + + /** + * @var Closure[] + */ + protected static $maker = []; + + /** + * 构造方法 + * @access public + */ + public function __construct() + { + if (!empty(static::$maker)) { + foreach (static::$maker as $maker) { + call_user_func($maker, $this); + } + } + } + + /** + * 设置服务注入 + * @access public + * @param Closure $maker + * @return void + */ + public static function maker(Closure $maker) + { + static::$maker[] = $maker; + } + + /** + * 设置Lang对象 + * @access public + * @param Lang $lang Lang对象 + * @return void + */ + public function setLang(Lang $lang) + { + $this->lang = $lang; + } + + /** + * 设置Db对象 + * @access public + * @param Db $db Db对象 + * @return void + */ + public function setDb(Db $db) + { + $this->db = $db; + } + + /** + * 设置Request对象 + * @access public + * @param Request $request Request对象 + * @return void + */ + public function setRequest(Request $request) + { + $this->request = $request; + } + + /** + * 添加字段验证规则 + * @access protected + * @param string|array $name 字段名称或者规则数组 + * @param mixed $rule 验证规则或者字段描述信息 + * @return $this + */ + public function rule($name, $rule = '') + { + if (is_array($name)) { + $this->rule = $name + $this->rule; + if (is_array($rule)) { + $this->field = array_merge($this->field, $rule); + } + } else { + $this->rule[$name] = $rule; + } + + return $this; + } + + /** + * 注册验证(类型)规则 + * @access public + * @param string $type 验证规则类型 + * @param callable $callback callback方法(或闭包) + * @param string $message 验证失败提示信息 + * @return $this + */ + public function extend(string $type, callable $callback = null, string $message = null) + { + $this->type[$type] = $callback; + + if ($message) { + $this->typeMsg[$type] = $message; + } + + return $this; + } + + /** + * 设置验证规则的默认提示信息 + * @access public + * @param string|array $type 验证规则类型名称或者数组 + * @param string $msg 验证提示信息 + * @return void + */ + public function setTypeMsg($type, string $msg = null): void + { + if (is_array($type)) { + $this->typeMsg = array_merge($this->typeMsg, $type); + } else { + $this->typeMsg[$type] = $msg; + } + } + + /** + * 设置提示信息 + * @access public + * @param array $message 错误信息 + * @return Validate + */ + public function message(array $message) + { + $this->message = array_merge($this->message, $message); + + return $this; + } + + /** + * 设置验证场景 + * @access public + * @param string $name 场景名 + * @return $this + */ + public function scene(string $name) + { + // 设置当前场景 + $this->currentScene = $name; + + return $this; + } + + /** + * 判断是否存在某个验证场景 + * @access public + * @param string $name 场景名 + * @return bool + */ + public function hasScene(string $name): bool + { + return isset($this->scene[$name]) || method_exists($this, 'scene' . $name); + } + + /** + * 设置批量验证 + * @access public + * @param bool $batch 是否批量验证 + * @return $this + */ + public function batch(bool $batch = true) + { + $this->batch = $batch; + + return $this; + } + + /** + * 设置验证失败后是否抛出异常 + * @access protected + * @param bool $fail 是否抛出异常 + * @return $this + */ + public function failException(bool $fail = true) + { + $this->failException = $fail; + + return $this; + } + + /** + * 指定需要验证的字段列表 + * @access public + * @param array $fields 字段名 + * @return $this + */ + public function only(array $fields) + { + $this->only = $fields; + + return $this; + } + + /** + * 移除某个字段的验证规则 + * @access public + * @param string|array $field 字段名 + * @param mixed $rule 验证规则 true 移除所有规则 + * @return $this + */ + public function remove($field, $rule = null) + { + if (is_array($field)) { + foreach ($field as $key => $rule) { + if (is_int($key)) { + $this->remove($rule); + } else { + $this->remove($key, $rule); + } + } + } else { + if (is_string($rule)) { + $rule = explode('|', $rule); + } + + $this->remove[$field] = $rule; + } + + return $this; + } + + /** + * 追加某个字段的验证规则 + * @access public + * @param string|array $field 字段名 + * @param mixed $rule 验证规则 + * @return $this + */ + public function append($field, $rule = null) + { + if (is_array($field)) { + foreach ($field as $key => $rule) { + $this->append($key, $rule); + } + } else { + if (is_string($rule)) { + $rule = explode('|', $rule); + } + + $this->append[$field] = $rule; + } + + return $this; + } + + /** + * 数据自动验证 + * @access public + * @param array $data 数据 + * @param array $rules 验证规则 + * @return bool + */ + public function check(array $data, array $rules = []): bool + { + $this->error = []; + + if (empty($rules)) { + // 读取验证规则 + $rules = $this->rule; + } + + if ($this->currentScene) { + $this->getScene($this->currentScene); + } + + foreach ($this->append as $key => $rule) { + if (!isset($rules[$key])) { + $rules[$key] = $rule; + } + } + + foreach ($rules as $key => $rule) { + // field => 'rule1|rule2...' field => ['rule1','rule2',...] + if (strpos($key, '|')) { + // 字段|描述 用于指定属性名称 + [$key, $title] = explode('|', $key); + } else { + $title = $this->field[$key] ?? $key; + } + + // 场景检测 + if (!empty($this->only) && !in_array($key, $this->only)) { + continue; + } + + // 获取数据 支持二维数组 + $value = $this->getDataValue($data, $key); + + // 字段验证 + if ($rule instanceof Closure) { + $result = call_user_func_array($rule, [$value, $data]); + } elseif ($rule instanceof ValidateRule) { + // 验证因子 + $result = $this->checkItem($key, $value, $rule->getRule(), $data, $rule->getTitle() ?: $title, $rule->getMsg()); + } else { + $result = $this->checkItem($key, $value, $rule, $data, $title); + } + + if (true !== $result) { + // 没有返回true 则表示验证失败 + if (!empty($this->batch)) { + // 批量验证 + $this->error[$key] = $result; + } elseif ($this->failException) { + throw new ValidateException($result); + } else { + $this->error = $result; + return false; + } + } + } + + if (!empty($this->error)) { + if ($this->failException) { + throw new ValidateException($this->error); + } + return false; + } + + return true; + } + + /** + * 根据验证规则验证数据 + * @access public + * @param mixed $value 字段值 + * @param mixed $rules 验证规则 + * @return bool + */ + public function checkRule($value, $rules): bool + { + if ($rules instanceof Closure) { + return call_user_func_array($rules, [$value]); + } elseif ($rules instanceof ValidateRule) { + $rules = $rules->getRule(); + } elseif (is_string($rules)) { + $rules = explode('|', $rules); + } + + foreach ($rules as $key => $rule) { + if ($rule instanceof Closure) { + $result = call_user_func_array($rule, [$value]); + } else { + // 判断验证类型 + [$type, $rule] = $this->getValidateType($key, $rule); + + $callback = $this->type[$type] ?? [$this, $type]; + + $result = call_user_func_array($callback, [$value, $rule]); + } + + if (true !== $result) { + if ($this->failException) { + throw new ValidateException($result); + } + + return $result; + } + } + + return true; + } + + /** + * 验证单个字段规则 + * @access protected + * @param string $field 字段名 + * @param mixed $value 字段值 + * @param mixed $rules 验证规则 + * @param array $data 数据 + * @param string $title 字段描述 + * @param array $msg 提示信息 + * @return mixed + */ + protected function checkItem(string $field, $value, $rules, $data, string $title = '', array $msg = []) + { + if (isset($this->remove[$field]) && true === $this->remove[$field] && empty($this->append[$field])) { + // 字段已经移除 无需验证 + return true; + } + + // 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...] + if (is_string($rules)) { + $rules = explode('|', $rules); + } + + if (isset($this->append[$field])) { + // 追加额外的验证规则 + $rules = array_unique(array_merge($rules, $this->append[$field]), SORT_REGULAR); + } + + $i = 0; + foreach ($rules as $key => $rule) { + if ($rule instanceof Closure) { + $result = call_user_func_array($rule, [$value, $data]); + $info = is_numeric($key) ? '' : $key; + } else { + // 判断验证类型 + [$type, $rule, $info] = $this->getValidateType($key, $rule); + + if (isset($this->append[$field]) && in_array($info, $this->append[$field])) { + + } elseif (isset($this->remove[$field]) && in_array($info, $this->remove[$field])) { + // 规则已经移除 + $i++; + continue; + } + + if (isset($this->type[$type])) { + $result = call_user_func_array($this->type[$type], [$value, $rule, $data, $field, $title]); + } elseif ('must' == $info || 0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) { + $result = call_user_func_array([$this, $type], [$value, $rule, $data, $field, $title]); + } else { + $result = true; + } + } + + if (false === $result) { + // 验证失败 返回错误信息 + if (!empty($msg[$i])) { + $message = $msg[$i]; + if (is_string($message) && strpos($message, '{%') === 0) { + $message = $this->lang->get(substr($message, 2, -1)); + } + } else { + $message = $this->getRuleMsg($field, $title, $info, $rule); + } + + return $message; + } elseif (true !== $result) { + // 返回自定义错误信息 + if (is_string($result) && false !== strpos($result, ':')) { + $result = str_replace(':attribute', $title, $result); + + if (strpos($result, ':rule') && is_scalar($rule)) { + $result = str_replace(':rule', (string) $rule, $result); + } + } + + return $result; + } + $i++; + } + + return $result; + } + + /** + * 获取当前验证类型及规则 + * @access public + * @param mixed $key + * @param mixed $rule + * @return array + */ + protected function getValidateType($key, $rule): array + { + // 判断验证类型 + if (!is_numeric($key)) { + if (isset($this->alias[$key])) { + // 判断别名 + $key = $this->alias[$key]; + } + return [$key, $rule, $key]; + } + + if (strpos($rule, ':')) { + [$type, $rule] = explode(':', $rule, 2); + if (isset($this->alias[$type])) { + // 判断别名 + $type = $this->alias[$type]; + } + $info = $type; + } elseif (method_exists($this, $rule)) { + $type = $rule; + $info = $rule; + $rule = ''; + } else { + $type = 'is'; + $info = $rule; + } + + return [$type, $rule, $info]; + } + + /** + * 验证是否和某个字段的值一致 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @param string $field 字段名 + * @return bool + */ + public function confirm($value, $rule, array $data = [], string $field = ''): bool + { + if ('' == $rule) { + if (strpos($field, '_confirm')) { + $rule = strstr($field, '_confirm', true); + } else { + $rule = $field . '_confirm'; + } + } + + return $this->getDataValue($data, $rule) === $value; + } + + /** + * 验证是否和某个字段的值是否不同 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function different($value, $rule, array $data = []): bool + { + return $this->getDataValue($data, $rule) != $value; + } + + /** + * 验证是否大于等于某个值 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function egt($value, $rule, array $data = []): bool + { + return $value >= $this->getDataValue($data, $rule); + } + + /** + * 验证是否大于某个值 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function gt($value, $rule, array $data = []): bool + { + return $value > $this->getDataValue($data, $rule); + } + + /** + * 验证是否小于等于某个值 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function elt($value, $rule, array $data = []): bool + { + return $value <= $this->getDataValue($data, $rule); + } + + /** + * 验证是否小于某个值 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function lt($value, $rule, array $data = []): bool + { + return $value < $this->getDataValue($data, $rule); + } + + /** + * 验证是否等于某个值 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function eq($value, $rule): bool + { + return $value == $rule; + } + + /** + * 必须验证 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function must($value, $rule = null): bool + { + return !empty($value) || '0' == $value; + } + + /** + * 验证字段值是否为有效格式 + * @access public + * @param mixed $value 字段值 + * @param string $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function is($value, string $rule, array $data = []): bool + { + switch (Str::camel($rule)) { + case 'require': + // 必须 + $result = !empty($value) || '0' == $value; + break; + case 'accepted': + // 接受 + $result = in_array($value, ['1', 'on', 'yes']); + break; + case 'date': + // 是否是一个有效日期 + $result = false !== strtotime($value); + break; + case 'activeUrl': + // 是否为有效的网址 + $result = checkdnsrr($value); + break; + case 'boolean': + case 'bool': + // 是否为布尔值 + $result = in_array($value, [true, false, 0, 1, '0', '1'], true); + break; + case 'number': + $result = ctype_digit((string) $value); + break; + case 'alphaNum': + $result = ctype_alnum($value); + break; + case 'array': + // 是否为数组 + $result = is_array($value); + break; + case 'file': + $result = $value instanceof File; + break; + case 'image': + $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]); + break; + case 'token': + $result = $this->token($value, '__token__', $data); + break; + default: + if (isset($this->type[$rule])) { + // 注册的验证规则 + $result = call_user_func_array($this->type[$rule], [$value]); + } elseif (function_exists('ctype_' . $rule)) { + // ctype验证规则 + $ctypeFun = 'ctype_' . $rule; + $result = $ctypeFun($value); + } elseif (isset($this->filter[$rule])) { + // Filter_var验证规则 + $result = $this->filter($value, $this->filter[$rule]); + } else { + // 正则验证 + $result = $this->regex($value, $rule); + } + } + + return $result; + } + + // 判断图像类型 + protected function getImageType($image) + { + if (function_exists('exif_imagetype')) { + return exif_imagetype($image); + } + + try { + $info = getimagesize($image); + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; + } + } + + /** + * 验证表单令牌 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function token($value, string $rule, array $data): bool + { + $rule = !empty($rule) ? $rule : '__token__'; + return $this->request->checkToken($rule, $data); + } + + /** + * 验证是否为合格的域名或者IP 支持A,MX,NS,SOA,PTR,CNAME,AAAA,A6, SRV,NAPTR,TXT 或者 ANY类型 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function activeUrl(string $value, string $rule = 'MX'): bool + { + if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) { + $rule = 'MX'; + } + + return checkdnsrr($value, $rule); + } + + /** + * 验证是否有效IP + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 ipv4 ipv6 + * @return bool + */ + public function ip($value, string $rule = 'ipv4'): bool + { + if (!in_array($rule, ['ipv4', 'ipv6'])) { + $rule = 'ipv4'; + } + + return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]); + } + + /** + * 检测上传文件后缀 + * @access public + * @param File $file + * @param array|string $ext 允许后缀 + * @return bool + */ + protected function checkExt(File $file, $ext): bool + { + if (is_string($ext)) { + $ext = explode(',', $ext); + } + + return in_array(strtolower($file->extension()), $ext); + } + + /** + * 检测上传文件大小 + * @access public + * @param File $file + * @param integer $size 最大大小 + * @return bool + */ + protected function checkSize(File $file, $size): bool + { + return $file->getSize() <= (int) $size; + } + + /** + * 检测上传文件类型 + * @access public + * @param File $file + * @param array|string $mime 允许类型 + * @return bool + */ + protected function checkMime(File $file, $mime): bool + { + if (is_string($mime)) { + $mime = explode(',', $mime); + } + + return in_array(strtolower($file->getMime()), $mime); + } + + /** + * 验证上传文件后缀 + * @access public + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + public function fileExt($file, $rule): bool + { + if (is_array($file)) { + foreach ($file as $item) { + if (!($item instanceof File) || !$this->checkExt($item, $rule)) { + return false; + } + } + return true; + } elseif ($file instanceof File) { + return $this->checkExt($file, $rule); + } + + return false; + } + + /** + * 验证上传文件类型 + * @access public + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + public function fileMime($file, $rule): bool + { + if (is_array($file)) { + foreach ($file as $item) { + if (!($item instanceof File) || !$this->checkMime($item, $rule)) { + return false; + } + } + return true; + } elseif ($file instanceof File) { + return $this->checkMime($file, $rule); + } + + return false; + } + + /** + * 验证上传文件大小 + * @access public + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + public function fileSize($file, $rule): bool + { + if (is_array($file)) { + foreach ($file as $item) { + if (!($item instanceof File) || !$this->checkSize($item, $rule)) { + return false; + } + } + return true; + } elseif ($file instanceof File) { + return $this->checkSize($file, $rule); + } + + return false; + } + + /** + * 验证图片的宽高及类型 + * @access public + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + public function image($file, $rule): bool + { + if (!($file instanceof File)) { + return false; + } + + if ($rule) { + $rule = explode(',', $rule); + + [$width, $height, $type] = getimagesize($file->getRealPath()); + + if (isset($rule[2])) { + $imageType = strtolower($rule[2]); + + if ('jpg' == $imageType) { + $imageType = 'jpeg'; + } + + if (image_type_to_extension($type, false) != $imageType) { + return false; + } + } + + [$w, $h] = $rule; + + return $w == $width && $h == $height; + } + + return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]); + } + + /** + * 验证时间和日期是否符合指定格式 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function dateFormat($value, $rule): bool + { + $info = date_parse_from_format($rule, $value); + return 0 == $info['warning_count'] && 0 == $info['error_count']; + } + + /** + * 验证是否唯一 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 格式:数据表,字段名,排除ID,主键名 + * @param array $data 数据 + * @param string $field 验证字段名 + * @return bool + */ + public function unique($value, $rule, array $data = [], string $field = ''): bool + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + + if (false !== strpos($rule[0], '\\')) { + // 指定模型类 + $db = new $rule[0]; + } else { + $db = $this->db->name($rule[0]); + } + + $key = $rule[1] ?? $field; + $map = []; + + if (strpos($key, '^')) { + // 支持多个字段验证 + $fields = explode('^', $key); + foreach ($fields as $key) { + if (isset($data[$key])) { + $map[] = [$key, '=', $data[$key]]; + } + } + } elseif (isset($data[$field])) { + $map[] = [$key, '=', $data[$field]]; + } else { + $map = []; + } + + $pk = !empty($rule[3]) ? $rule[3] : $db->getPk(); + + if (is_string($pk)) { + if (isset($rule[2])) { + $map[] = [$pk, '<>', $rule[2]]; + } elseif (isset($data[$pk])) { + $map[] = [$pk, '<>', $data[$pk]]; + } + } + + if ($db->where($map)->field($pk)->find()) { + return false; + } + + return true; + } + + /** + * 使用filter_var方式验证 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function filter($value, $rule): bool + { + if (is_string($rule) && strpos($rule, ',')) { + [$rule, $param] = explode(',', $rule); + } elseif (is_array($rule)) { + $param = $rule[1] ?? null; + $rule = $rule[0]; + } else { + $param = null; + } + + return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param); + } + + /** + * 验证某个字段等于某个值的时候必须 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function requireIf($value, $rule, array $data = []): bool + { + [$field, $val] = explode(',', $rule); + + if ($this->getDataValue($data, $field) == $val) { + return !empty($value) || '0' == $value; + } + + return true; + } + + /** + * 通过回调方法验证某个字段是否必须 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function requireCallback($value, $rule, array $data = []): bool + { + $result = call_user_func_array([$this, $rule], [$value, $data]); + + if ($result) { + return !empty($value) || '0' == $value; + } + + return true; + } + + /** + * 验证某个字段有值的情况下必须 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function requireWith($value, $rule, array $data = []): bool + { + $val = $this->getDataValue($data, $rule); + + if (!empty($val)) { + return !empty($value) || '0' == $value; + } + + return true; + } + + /** + * 验证某个字段没有值的情况下必须 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function requireWithout($value, $rule, array $data = []): bool + { + $val = $this->getDataValue($data, $rule); + + if (empty($val)) { + return !empty($value) || '0' == $value; + } + + return true; + } + + /** + * 验证是否在范围内 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function in($value, $rule): bool + { + return in_array($value, is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * 验证是否不在某个范围 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function notIn($value, $rule): bool + { + return !in_array($value, is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * between验证数据 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function between($value, $rule): bool + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + [$min, $max] = $rule; + + return $value >= $min && $value <= $max; + } + + /** + * 使用notbetween验证数据 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function notBetween($value, $rule): bool + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + [$min, $max] = $rule; + + return $value < $min || $value > $max; + } + + /** + * 验证数据长度 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function length($value, $rule): bool + { + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } + + if (is_string($rule) && strpos($rule, ',')) { + // 长度区间 + [$min, $max] = explode(',', $rule); + return $length >= $min && $length <= $max; + } + + // 指定长度 + return $length == $rule; + } + + /** + * 验证数据最大长度 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function max($value, $rule): bool + { + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } + + return $length <= $rule; + } + + /** + * 验证数据最小长度 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function min($value, $rule): bool + { + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } + + return $length >= $rule; + } + + /** + * 验证日期 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function after($value, $rule, array $data = []): bool + { + return strtotime($value) >= strtotime($rule); + } + + /** + * 验证日期 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function before($value, $rule, array $data = []): bool + { + return strtotime($value) <= strtotime($rule); + } + + /** + * 验证日期 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function afterWith($value, $rule, array $data = []): bool + { + $rule = $this->getDataValue($data, $rule); + return !is_null($rule) && strtotime($value) >= strtotime($rule); + } + + /** + * 验证日期 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + public function beforeWith($value, $rule, array $data = []): bool + { + $rule = $this->getDataValue($data, $rule); + return !is_null($rule) && strtotime($value) <= strtotime($rule); + } + + /** + * 验证有效期 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function expire($value, $rule): bool + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + + [$start, $end] = $rule; + + if (!is_numeric($start)) { + $start = strtotime($start); + } + + if (!is_numeric($end)) { + $end = strtotime($end); + } + + return time() >= $start && time() <= $end; + } + + /** + * 验证IP许可 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function allowIp($value, $rule): bool + { + return in_array($value, is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * 验证IP禁用 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + public function denyIp($value, $rule): bool + { + return !in_array($value, is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * 使用正则验证数据 + * @access public + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 正则规则或者预定义正则名 + * @return bool + */ + public function regex($value, $rule): bool + { + if (isset($this->regex[$rule])) { + $rule = $this->regex[$rule]; + } elseif (isset($this->defaultRegex[$rule])) { + $rule = $this->defaultRegex[$rule]; + } + + if (is_string($rule) && 0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) { + // 不是正则表达式则两端补上/ + $rule = '/^' . $rule . '$/'; + } + + return is_scalar($value) && 1 === preg_match($rule, (string) $value); + } + + /** + * 获取错误信息 + * @return array|string + */ + public function getError() + { + return $this->error; + } + + /** + * 获取数据值 + * @access protected + * @param array $data 数据 + * @param string $key 数据标识 支持二维 + * @return mixed + */ + protected function getDataValue(array $data, $key) + { + if (is_numeric($key)) { + $value = $key; + } elseif (is_string($key) && strpos($key, '.')) { + // 支持多维数组验证 + foreach (explode('.', $key) as $key) { + if (!isset($data[$key])) { + $value = null; + break; + } + $value = $data = $data[$key]; + } + } else { + $value = $data[$key] ?? null; + } + + return $value; + } + + /** + * 获取验证规则的错误提示信息 + * @access protected + * @param string $attribute 字段英文名 + * @param string $title 字段描述名 + * @param string $type 验证规则名称 + * @param mixed $rule 验证规则数据 + * @return string|array + */ + protected function getRuleMsg(string $attribute, string $title, string $type, $rule) + { + if (isset($this->message[$attribute . '.' . $type])) { + $msg = $this->message[$attribute . '.' . $type]; + } elseif (isset($this->message[$attribute][$type])) { + $msg = $this->message[$attribute][$type]; + } elseif (isset($this->message[$attribute])) { + $msg = $this->message[$attribute]; + } elseif (isset($this->typeMsg[$type])) { + $msg = $this->typeMsg[$type]; + } elseif (0 === strpos($type, 'require')) { + $msg = $this->typeMsg['require']; + } else { + $msg = $title . $this->lang->get('not conform to the rules'); + } + + if (is_array($msg)) { + return $this->errorMsgIsArray($msg, $rule, $title); + } + + return $this->parseErrorMsg($msg, $rule, $title); + } + + /** + * 获取验证规则的错误提示信息 + * @access protected + * @param string $msg 错误信息 + * @param mixed $rule 验证规则数据 + * @param string $title 字段描述名 + * @return string + */ + protected function parseErrorMsg(string $msg, $rule, string $title) + { + if (0 === strpos($msg, '{%')) { + $msg = $this->lang->get(substr($msg, 2, -1)); + } elseif ($this->lang->has($msg)) { + $msg = $this->lang->get($msg); + } + + if (is_array($msg)) { + return $this->errorMsgIsArray($msg, $rule, $title); + } + + if (is_scalar($rule) && false !== strpos($msg, ':')) { + // 变量替换 + if (is_string($rule) && strpos($rule, ',')) { + $array = array_pad(explode(',', $rule), 3, ''); + } else { + $array = array_pad([], 3, ''); + } + + $msg = str_replace( + [':attribute', ':1', ':2', ':3'], + [$title, $array[0], $array[1], $array[2]], + $msg); + + if (strpos($msg, ':rule')) { + $msg = str_replace(':rule', (string) $rule, $msg); + } + } + + return $msg; + } + + /** + * 错误信息数组处理 + * @access protected + * @param array $msg 错误信息 + * @param mixed $rule 验证规则数据 + * @param string $title 字段描述名 + * @return array + */ + protected function errorMsgIsArray(array $msg, $rule, string $title) + { + foreach ($msg as $key => $val) { + if (is_string($val)) { + $msg[$key] = $this->parseErrorMsg($val, $rule, $title); + } + } + return $msg; + } + + /** + * 获取数据验证的场景 + * @access protected + * @param string $scene 验证场景 + * @return void + */ + protected function getScene(string $scene): void + { + $this->only = $this->append = $this->remove = []; + + if (method_exists($this, 'scene' . $scene)) { + call_user_func([$this, 'scene' . $scene]); + } elseif (isset($this->scene[$scene])) { + // 如果设置了验证适用场景 + $this->only = $this->scene[$scene]; + } + } + + /** + * 动态方法 直接调用is方法进行验证 + * @access public + * @param string $method 方法名 + * @param array $args 调用参数 + * @return bool + */ + public function __call($method, $args) + { + if ('is' == strtolower(substr($method, 0, 2))) { + $method = substr($method, 2); + } + + array_push($args, lcfirst($method)); + + return call_user_func_array([$this, 'is'], $args); + } +} diff --git a/vendor/topthink/framework/src/think/View.php b/vendor/topthink/framework/src/think/View.php new file mode 100644 index 0000000..c2e7368 --- /dev/null +++ b/vendor/topthink/framework/src/think/View.php @@ -0,0 +1,187 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think; + +use think\helper\Arr; + +/** + * 视图类 + * @package think + */ +class View extends Manager +{ + + protected $namespace = '\\think\\view\\driver\\'; + + /** + * 模板变量 + * @var array + */ + protected $data = []; + + /** + * 内容过滤 + * @var mixed + */ + protected $filter; + + /** + * 获取模板引擎 + * @access public + * @param string $type 模板引擎类型 + * @return $this + */ + public function engine(string $type = null) + { + return $this->driver($type); + } + + /** + * 模板变量赋值 + * @access public + * @param string|array $name 模板变量 + * @param mixed $value 变量值 + * @return $this + */ + public function assign($name, $value = null) + { + if (is_array($name)) { + $this->data = array_merge($this->data, $name); + } else { + $this->data[$name] = $value; + } + + return $this; + } + + /** + * 视图过滤 + * @access public + * @param Callable $filter 过滤方法或闭包 + * @return $this + */ + public function filter(callable $filter = null) + { + $this->filter = $filter; + return $this; + } + + /** + * 解析和获取模板内容 用于输出 + * @access public + * @param string $template 模板文件名或者内容 + * @param array $vars 模板变量 + * @return string + * @throws \Exception + */ + public function fetch(string $template = '', array $vars = []): string + { + return $this->getContent(function () use ($vars, $template) { + $this->engine()->fetch($template, array_merge($this->data, $vars)); + }); + } + + /** + * 渲染内容输出 + * @access public + * @param string $content 内容 + * @param array $vars 模板变量 + * @return string + */ + public function display(string $content, array $vars = []): string + { + return $this->getContent(function () use ($vars, $content) { + $this->engine()->display($content, array_merge($this->data, $vars)); + }); + } + + /** + * 获取模板引擎渲染内容 + * @param $callback + * @return string + * @throws \Exception + */ + protected function getContent($callback): string + { + // 页面缓存 + ob_start(); + ob_implicit_flush(0); + + // 渲染输出 + try { + $callback(); + } catch (\Exception $e) { + ob_end_clean(); + throw $e; + } + + // 获取并清空缓存 + $content = ob_get_clean(); + + if ($this->filter) { + $content = call_user_func_array($this->filter, [$content]); + } + + return $content; + } + + /** + * 模板变量赋值 + * @access public + * @param string $name 变量名 + * @param mixed $value 变量值 + */ + public function __set($name, $value) + { + $this->data[$name] = $value; + } + + /** + * 取得模板显示变量的值 + * @access protected + * @param string $name 模板变量 + * @return mixed + */ + public function __get($name) + { + return $this->data[$name]; + } + + /** + * 检测模板变量是否设置 + * @access public + * @param string $name 模板变量名 + * @return bool + */ + public function __isset($name) + { + return isset($this->data[$name]); + } + + protected function resolveConfig(string $name) + { + $config = $this->app->config->get('view', []); + Arr::forget($config, 'type'); + return $config; + } + + /** + * 默认驱动 + * @return string|null + */ + public function getDefaultDriver() + { + return $this->app->config->get('view.type', 'php'); + } + +} diff --git a/vendor/topthink/framework/src/think/cache/Driver.php b/vendor/topthink/framework/src/think/cache/Driver.php new file mode 100644 index 0000000..f4198b4 --- /dev/null +++ b/vendor/topthink/framework/src/think/cache/Driver.php @@ -0,0 +1,347 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\cache; + +use Closure; +use DateInterval; +use DateTime; +use DateTimeInterface; +use Exception; +use Psr\SimpleCache\CacheInterface; +use think\Container; +use think\contract\CacheHandlerInterface; +use think\exception\InvalidArgumentException; +use throwable; + +/** + * 缓存基础类 + */ +abstract class Driver implements CacheInterface, CacheHandlerInterface +{ + /** + * 驱动句柄 + * @var object + */ + protected $handler = null; + + /** + * 缓存读取次数 + * @var integer + */ + protected $readTimes = 0; + + /** + * 缓存写入次数 + * @var integer + */ + protected $writeTimes = 0; + + /** + * 缓存参数 + * @var array + */ + protected $options = []; + + /** + * 缓存标签 + * @var array + */ + protected $tag = []; + + /** + * 获取有效期 + * @access protected + * @param integer|DateTimeInterface|DateInterval $expire 有效期 + * @return int + */ + protected function getExpireTime($expire): int + { + if ($expire instanceof DateTimeInterface) { + $expire = $expire->getTimestamp() - time(); + } elseif ($expire instanceof DateInterval) { + $expire = DateTime::createFromFormat('U', (string) time()) + ->add($expire) + ->format('U') - time(); + } + + return (int) $expire; + } + + /** + * 获取实际的缓存标识 + * @access public + * @param string $name 缓存名 + * @return string + */ + public function getCacheKey(string $name): string + { + return $this->options['prefix'] . $name; + } + + /** + * 读取缓存并删除 + * @access public + * @param string $name 缓存变量名 + * @return mixed + */ + public function pull(string $name) + { + $result = $this->get($name, false); + + if ($result) { + $this->delete($name); + return $result; + } + } + + /** + * 追加(数组)缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @return void + */ + public function push(string $name, $value): void + { + $item = $this->get($name, []); + + if (!is_array($item)) { + throw new InvalidArgumentException('only array cache can be push'); + } + + $item[] = $value; + + if (count($item) > 1000) { + array_shift($item); + } + + $item = array_unique($item); + + $this->set($name, $item); + } + + /** + * 如果不存在则写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int $expire 有效时间 0为永久 + * @return mixed + */ + public function remember(string $name, $value, $expire = null) + { + if ($this->has($name)) { + return $this->get($name); + } + + $time = time(); + + while ($time + 5 > time() && $this->has($name . '_lock')) { + // 存在锁定则等待 + usleep(200000); + } + + try { + // 锁定 + $this->set($name . '_lock', true); + + if ($value instanceof Closure) { + // 获取缓存数据 + $value = Container::getInstance()->invokeFunction($value); + } + + // 缓存数据 + $this->set($name, $value, $expire); + + // 解锁 + $this->delete($name . '_lock'); + } catch (Exception | throwable $e) { + $this->delete($name . '_lock'); + throw $e; + } + + return $value; + } + + /** + * 缓存标签 + * @access public + * @param string|array $name 标签名 + * @return TagSet + */ + public function tag($name): TagSet + { + $name = (array) $name; + $key = implode('-', $name); + + if (!isset($this->tag[$key])) { + $name = array_map(function ($val) { + return $this->getTagKey($val); + }, $name); + $this->tag[$key] = new TagSet($name, $this); + } + + return $this->tag[$key]; + } + + /** + * 获取标签包含的缓存标识 + * @access public + * @param string $tag 标签标识 + * @return array + */ + public function getTagItems(string $tag): array + { + return $this->get($tag, []); + } + + /** + * 获取实际标签名 + * @access public + * @param string $tag 标签名 + * @return string + */ + public function getTagKey(string $tag): string + { + return $this->options['tag_prefix'] . md5($tag); + } + + /** + * 序列化数据 + * @access protected + * @param mixed $data 缓存数据 + * @return string + */ + protected function serialize($data): string + { + if (is_numeric($data)) { + return (string) $data; + } + + $serialize = $this->options['serialize'][0] ?? "serialize"; + + return $serialize($data); + } + + /** + * 反序列化数据 + * @access protected + * @param string $data 缓存数据 + * @return mixed + */ + protected function unserialize(string $data) + { + if (is_numeric($data)) { + return $data; + } + + $unserialize = $this->options['serialize'][1] ?? "unserialize"; + + return $unserialize($data); + } + + /** + * 返回句柄对象,可执行其它高级方法 + * + * @access public + * @return object + */ + public function handler() + { + return $this->handler; + } + + /** + * 返回缓存读取次数 + * @access public + * @return int + */ + public function getReadTimes(): int + { + return $this->readTimes; + } + + /** + * 返回缓存写入次数 + * @access public + * @return int + */ + public function getWriteTimes(): int + { + return $this->writeTimes; + } + + /** + * 读取缓存 + * @access public + * @param iterable $keys 缓存变量名 + * @param mixed $default 默认值 + * @return iterable + * @throws InvalidArgumentException + */ + public function getMultiple($keys, $default = null): iterable + { + $result = []; + + foreach ($keys as $key) { + $result[$key] = $this->get($key, $default); + } + + return $result; + } + + /** + * 写入缓存 + * @access public + * @param iterable $values 缓存数据 + * @param null|int|\DateInterval $ttl 有效时间 0为永久 + * @return bool + */ + public function setMultiple($values, $ttl = null): bool + { + foreach ($values as $key => $val) { + $result = $this->set($key, $val, $ttl); + + if (false === $result) { + return false; + } + } + + return true; + } + + /** + * 删除缓存 + * @access public + * @param iterable $keys 缓存变量名 + * @return bool + * @throws InvalidArgumentException + */ + public function deleteMultiple($keys): bool + { + foreach ($keys as $key) { + $result = $this->delete($key); + + if (false === $result) { + return false; + } + } + + return true; + } + + public function __call($method, $args) + { + return call_user_func_array([$this->handler, $method], $args); + } +} diff --git a/vendor/topthink/framework/src/think/cache/TagSet.php b/vendor/topthink/framework/src/think/cache/TagSet.php new file mode 100644 index 0000000..d890c49 --- /dev/null +++ b/vendor/topthink/framework/src/think/cache/TagSet.php @@ -0,0 +1,130 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\cache; + +/** + * 标签集合 + */ +class TagSet +{ + /** + * 标签的缓存Key + * @var array + */ + protected $tag; + + /** + * 缓存句柄 + * @var Driver + */ + protected $handler; + + /** + * 架构函数 + * @access public + * @param array $tag 缓存标签 + * @param Driver $cache 缓存对象 + */ + public function __construct(array $tag, Driver $cache) + { + $this->tag = $tag; + $this->handler = $cache; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set(string $name, $value, $expire = null): bool + { + $this->handler->set($name, $value, $expire); + + $this->append($name); + + return true; + } + + /** + * 追加缓存标识到标签 + * @access public + * @param string $name 缓存变量名 + * @return void + */ + public function append(string $name): void + { + $name = $this->handler->getCacheKey($name); + + foreach ($this->tag as $tag) { + $this->handler->push($tag, $name); + } + } + + /** + * 写入缓存 + * @access public + * @param iterable $values 缓存数据 + * @param null|int|\DateInterval $ttl 有效时间 0为永久 + * @return bool + */ + public function setMultiple($values, $ttl = null): bool + { + foreach ($values as $key => $val) { + $result = $this->set($key, $val, $ttl); + + if (false === $result) { + return false; + } + } + + return true; + } + + /** + * 如果不存在则写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int $expire 有效时间 0为永久 + * @return mixed + */ + public function remember(string $name, $value, $expire = null) + { + $result = $this->handler->remember($name, $value, $expire); + + $this->append($name); + + return $result; + } + + /** + * 清除缓存 + * @access public + * @return bool + */ + public function clear(): bool + { + // 指定标签清除 + foreach ($this->tag as $tag) { + $names = $this->handler->getTagItems($tag); + + $this->handler->clearTag($names); + $this->handler->delete($tag); + } + + return true; + } +} diff --git a/vendor/topthink/framework/src/think/cache/driver/File.php b/vendor/topthink/framework/src/think/cache/driver/File.php new file mode 100644 index 0000000..f0122f5 --- /dev/null +++ b/vendor/topthink/framework/src/think/cache/driver/File.php @@ -0,0 +1,304 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\cache\driver; + +use FilesystemIterator; +use think\App; +use think\cache\Driver; + +/** + * 文件缓存类 + */ +class File extends Driver +{ + /** + * 配置参数 + * @var array + */ + protected $options = [ + 'expire' => 0, + 'cache_subdir' => true, + 'prefix' => '', + 'path' => '', + 'hash_type' => 'md5', + 'data_compress' => false, + 'tag_prefix' => 'tag:', + 'serialize' => [], + ]; + + /** + * 架构函数 + * @param App $app + * @param array $options 参数 + */ + public function __construct(App $app, array $options = []) + { + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + + if (empty($this->options['path'])) { + $this->options['path'] = $app->getRuntimePath() . 'cache'; + } + + if (substr($this->options['path'], -1) != DIRECTORY_SEPARATOR) { + $this->options['path'] .= DIRECTORY_SEPARATOR; + } + } + + /** + * 取得变量的存储文件名 + * @access public + * @param string $name 缓存变量名 + * @return string + */ + public function getCacheKey(string $name): string + { + $name = hash($this->options['hash_type'], $name); + + if ($this->options['cache_subdir']) { + // 使用子目录 + $name = substr($name, 0, 2) . DIRECTORY_SEPARATOR . substr($name, 2); + } + + if ($this->options['prefix']) { + $name = $this->options['prefix'] . DIRECTORY_SEPARATOR . $name; + } + + return $this->options['path'] . $name . '.php'; + } + + /** + * 获取缓存数据 + * @param string $name 缓存标识名 + * @return array|null + */ + protected function getRaw(string $name) + { + $filename = $this->getCacheKey($name); + + if (!is_file($filename)) { + return; + } + + $content = @file_get_contents($filename); + + if (false !== $content) { + $expire = (int) substr($content, 8, 12); + if (0 != $expire && time() - $expire > filemtime($filename)) { + //缓存过期删除缓存文件 + $this->unlink($filename); + return; + } + + $content = substr($content, 32); + + if ($this->options['data_compress'] && function_exists('gzcompress')) { + //启用数据压缩 + $content = gzuncompress($content); + } + + return ['content' => $content, 'expire' => $expire]; + } + } + + /** + * 判断缓存是否存在 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name): bool + { + return $this->getRaw($name) !== null; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = null) + { + $this->readTimes++; + + $raw = $this->getRaw($name); + + return is_null($raw) ? $default : $this->unserialize($raw['content']); + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int|\DateTime $expire 有效时间 0为永久 + * @return bool + */ + public function set($name, $value, $expire = null): bool + { + $this->writeTimes++; + + if (is_null($expire)) { + $expire = $this->options['expire']; + } + + $expire = $this->getExpireTime($expire); + $filename = $this->getCacheKey($name); + + $dir = dirname($filename); + + if (!is_dir($dir)) { + try { + mkdir($dir, 0755, true); + } catch (\Exception $e) { + // 创建失败 + } + } + + $data = $this->serialize($value); + + if ($this->options['data_compress'] && function_exists('gzcompress')) { + //数据压缩 + $data = gzcompress($data, 3); + } + + $data = "\n" . $data; + $result = file_put_contents($filename, $data); + + if ($result) { + clearstatcache(); + return true; + } + + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc(string $name, int $step = 1) + { + if ($raw = $this->getRaw($name)) { + $value = $this->unserialize($raw['content']) + $step; + $expire = $raw['expire']; + } else { + $value = $step; + $expire = 0; + } + + return $this->set($name, $value, $expire) ? $value : false; + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec(string $name, int $step = 1) + { + return $this->inc($name, -$step); + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function delete($name): bool + { + $this->writeTimes++; + + return $this->unlink($this->getCacheKey($name)); + } + + /** + * 清除缓存 + * @access public + * @return bool + */ + public function clear(): bool + { + $this->writeTimes++; + + $dirname = $this->options['path'] . $this->options['prefix']; + + $this->rmdir($dirname); + + return true; + } + + /** + * 删除缓存标签 + * @access public + * @param array $keys 缓存标识列表 + * @return void + */ + public function clearTag(array $keys): void + { + foreach ($keys as $key) { + $this->unlink($key); + } + } + + /** + * 判断文件是否存在后,删除 + * @access private + * @param string $path + * @return bool + */ + private function unlink(string $path): bool + { + try { + return is_file($path) && unlink($path); + } catch (\Exception $e) { + return false; + } + } + + /** + * 删除文件夹 + * @param $dirname + * @return bool + */ + private function rmdir($dirname) + { + if (!is_dir($dirname)) { + return false; + } + + $items = new FilesystemIterator($dirname); + + foreach ($items as $item) { + if ($item->isDir() && !$item->isLink()) { + $this->rmdir($item->getPathname()); + } else { + $this->unlink($item->getPathname()); + } + } + + @rmdir($dirname); + + return true; + } + +} diff --git a/vendor/topthink/framework/src/think/cache/driver/Memcache.php b/vendor/topthink/framework/src/think/cache/driver/Memcache.php new file mode 100644 index 0000000..81b988f --- /dev/null +++ b/vendor/topthink/framework/src/think/cache/driver/Memcache.php @@ -0,0 +1,209 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Memcache缓存类 + */ +class Memcache extends Driver +{ + /** + * 配置参数 + * @var array + */ + protected $options = [ + 'host' => '127.0.0.1', + 'port' => 11211, + 'expire' => 0, + 'timeout' => 0, // 超时时间(单位:毫秒) + 'persistent' => true, + 'prefix' => '', + 'tag_prefix' => 'tag:', + 'serialize' => [], + ]; + + /** + * 架构函数 + * @access public + * @param array $options 缓存参数 + * @throws \BadFunctionCallException + */ + public function __construct(array $options = []) + { + if (!extension_loaded('memcache')) { + throw new \BadFunctionCallException('not support: memcache'); + } + + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + + $this->handler = new \Memcache; + + // 支持集群 + $hosts = (array) $this->options['host']; + $ports = (array) $this->options['port']; + + if (empty($ports[0])) { + $ports[0] = 11211; + } + + // 建立连接 + foreach ($hosts as $i => $host) { + $port = $ports[$i] ?? $ports[0]; + $this->options['timeout'] > 0 ? + $this->handler->addServer($host, (int) $port, $this->options['persistent'], 1, (int) $this->options['timeout']) : + $this->handler->addServer($host, (int) $port, $this->options['persistent'], 1); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name): bool + { + $key = $this->getCacheKey($name); + + return false !== $this->handler->get($key); + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = null) + { + $this->readTimes++; + + $result = $this->handler->get($this->getCacheKey($name)); + + return false !== $result ? $this->unserialize($result) : $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null): bool + { + $this->writeTimes++; + + if (is_null($expire)) { + $expire = $this->options['expire']; + } + + $key = $this->getCacheKey($name); + $expire = $this->getExpireTime($expire); + $value = $this->serialize($value); + + if ($this->handler->set($key, $value, 0, $expire)) { + return true; + } + + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + if ($this->handler->get($key)) { + return $this->handler->increment($key, $step); + } + + return $this->handler->set($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + $value = $this->handler->get($key) - $step; + $res = $this->handler->set($key, $value); + + return !$res ? false : $value; + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @param bool|false $ttl + * @return bool + */ + public function delete($name, $ttl = false): bool + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + return false === $ttl ? + $this->handler->delete($key) : + $this->handler->delete($key, $ttl); + } + + /** + * 清除缓存 + * @access public + * @return bool + */ + public function clear(): bool + { + $this->writeTimes++; + + return $this->handler->flush(); + } + + /** + * 删除缓存标签 + * @access public + * @param array $keys 缓存标识列表 + * @return void + */ + public function clearTag(array $keys): void + { + foreach ($keys as $key) { + $this->handler->delete($key); + } + } + +} diff --git a/vendor/topthink/framework/src/think/cache/driver/Memcached.php b/vendor/topthink/framework/src/think/cache/driver/Memcached.php new file mode 100644 index 0000000..e6c5606 --- /dev/null +++ b/vendor/topthink/framework/src/think/cache/driver/Memcached.php @@ -0,0 +1,221 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Memcached缓存类 + */ +class Memcached extends Driver +{ + /** + * 配置参数 + * @var array + */ + protected $options = [ + 'host' => '127.0.0.1', + 'port' => 11211, + 'expire' => 0, + 'timeout' => 0, // 超时时间(单位:毫秒) + 'prefix' => '', + 'username' => '', //账号 + 'password' => '', //密码 + 'option' => [], + 'tag_prefix' => 'tag:', + 'serialize' => [], + ]; + + /** + * 架构函数 + * @access public + * @param array $options 缓存参数 + */ + public function __construct(array $options = []) + { + if (!extension_loaded('memcached')) { + throw new \BadFunctionCallException('not support: memcached'); + } + + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + + $this->handler = new \Memcached; + + if (!empty($this->options['option'])) { + $this->handler->setOptions($this->options['option']); + } + + // 设置连接超时时间(单位:毫秒) + if ($this->options['timeout'] > 0) { + $this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->options['timeout']); + } + + // 支持集群 + $hosts = (array) $this->options['host']; + $ports = (array) $this->options['port']; + if (empty($ports[0])) { + $ports[0] = 11211; + } + + // 建立连接 + $servers = []; + foreach ($hosts as $i => $host) { + $servers[] = [$host, $ports[$i] ?? $ports[0], 1]; + } + + $this->handler->addServers($servers); + + if ('' != $this->options['username']) { + $this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + $this->handler->setSaslAuthData($this->options['username'], $this->options['password']); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name): bool + { + $key = $this->getCacheKey($name); + + return $this->handler->get($key) ? true : false; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = null) + { + $this->readTimes++; + + $result = $this->handler->get($this->getCacheKey($name)); + + return false !== $result ? $this->unserialize($result) : $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null): bool + { + $this->writeTimes++; + + if (is_null($expire)) { + $expire = $this->options['expire']; + } + + $key = $this->getCacheKey($name); + $expire = $this->getExpireTime($expire); + $value = $this->serialize($value); + + if ($this->handler->set($key, $value, $expire)) { + return true; + } + + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + if ($this->handler->get($key)) { + return $this->handler->increment($key, $step); + } + + return $this->handler->set($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + $value = $this->handler->get($key) - $step; + $res = $this->handler->set($key, $value); + + return !$res ? false : $value; + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @param bool|false $ttl + * @return bool + */ + public function delete($name, $ttl = false): bool + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + return false === $ttl ? + $this->handler->delete($key) : + $this->handler->delete($key, $ttl); + } + + /** + * 清除缓存 + * @access public + * @return bool + */ + public function clear(): bool + { + $this->writeTimes++; + + return $this->handler->flush(); + } + + /** + * 删除缓存标签 + * @access public + * @param array $keys 缓存标识列表 + * @return void + */ + public function clearTag(array $keys): void + { + $this->handler->deleteMulti($keys); + } + +} diff --git a/vendor/topthink/framework/src/think/cache/driver/Redis.php b/vendor/topthink/framework/src/think/cache/driver/Redis.php new file mode 100644 index 0000000..487f66b --- /dev/null +++ b/vendor/topthink/framework/src/think/cache/driver/Redis.php @@ -0,0 +1,248 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Redis缓存驱动,适合单机部署、有前端代理实现高可用的场景,性能最好 + * 有需要在业务层实现读写分离、或者使用RedisCluster的需求,请使用Redisd驱动 + * + * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis + * @author 尘缘 <130775@qq.com> + */ +class Redis extends Driver +{ + /** @var \Predis\Client|\Redis */ + protected $handler; + + /** + * 配置参数 + * @var array + */ + protected $options = [ + 'host' => '127.0.0.1', + 'port' => 6379, + 'password' => '', + 'select' => 0, + 'timeout' => 0, + 'expire' => 0, + 'persistent' => false, + 'prefix' => '', + 'tag_prefix' => 'tag:', + 'serialize' => [], + ]; + + /** + * 架构函数 + * @access public + * @param array $options 缓存参数 + */ + public function __construct(array $options = []) + { + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + + if (extension_loaded('redis')) { + $this->handler = new \Redis; + + if ($this->options['persistent']) { + $this->handler->pconnect($this->options['host'], (int) $this->options['port'], (int) $this->options['timeout'], 'persistent_id_' . $this->options['select']); + } else { + $this->handler->connect($this->options['host'], (int) $this->options['port'], (int) $this->options['timeout']); + } + + if ('' != $this->options['password']) { + $this->handler->auth($this->options['password']); + } + } elseif (class_exists('\Predis\Client')) { + $params = []; + foreach ($this->options as $key => $val) { + if (in_array($key, ['aggregate', 'cluster', 'connections', 'exceptions', 'prefix', 'profile', 'replication', 'parameters'])) { + $params[$key] = $val; + unset($this->options[$key]); + } + } + + if ('' == $this->options['password']) { + unset($this->options['password']); + } + + $this->handler = new \Predis\Client($this->options, $params); + + $this->options['prefix'] = ''; + } else { + throw new \BadFunctionCallException('not support: redis'); + } + + if (0 != $this->options['select']) { + $this->handler->select($this->options['select']); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name): bool + { + return $this->handler->exists($this->getCacheKey($name)) ? true : false; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = null) + { + $this->readTimes++; + + $value = $this->handler->get($this->getCacheKey($name)); + + if (false === $value || is_null($value)) { + return $default; + } + + return $this->unserialize($value); + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null): bool + { + $this->writeTimes++; + + if (is_null($expire)) { + $expire = $this->options['expire']; + } + + $key = $this->getCacheKey($name); + $expire = $this->getExpireTime($expire); + $value = $this->serialize($value); + + if ($expire) { + $this->handler->setex($key, $expire, $value); + } else { + $this->handler->set($key, $value); + } + + return true; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + return $this->handler->incrby($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + return $this->handler->decrby($key, $step); + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function delete($name): bool + { + $this->writeTimes++; + + $result = $this->handler->del($this->getCacheKey($name)); + return $result > 0; + } + + /** + * 清除缓存 + * @access public + * @return bool + */ + public function clear(): bool + { + $this->writeTimes++; + + $this->handler->flushDB(); + return true; + } + + /** + * 删除缓存标签 + * @access public + * @param array $keys 缓存标识列表 + * @return void + */ + public function clearTag(array $keys): void + { + // 指定标签清除 + $this->handler->del($keys); + } + + /** + * 追加(数组)缓存数据 + * @access public + * @param string $name 缓存标识 + * @param mixed $value 数据 + * @return void + */ + public function push(string $name, $value): void + { + $this->handler->sAdd($name, $value); + } + + /** + * 获取标签包含的缓存标识 + * @access public + * @param string $tag 缓存标签 + * @return array + */ + public function getTagItems(string $tag): array + { + return $this->handler->sMembers($tag); + } + +} diff --git a/vendor/topthink/framework/src/think/cache/driver/Wincache.php b/vendor/topthink/framework/src/think/cache/driver/Wincache.php new file mode 100644 index 0000000..8b8e26d --- /dev/null +++ b/vendor/topthink/framework/src/think/cache/driver/Wincache.php @@ -0,0 +1,175 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Wincache缓存驱动 + */ +class Wincache extends Driver +{ + /** + * 配置参数 + * @var array + */ + protected $options = [ + 'prefix' => '', + 'expire' => 0, + 'tag_prefix' => 'tag:', + 'serialize' => [], + ]; + + /** + * 架构函数 + * @access public + * @param array $options 缓存参数 + * @throws \BadFunctionCallException + */ + public function __construct(array $options = []) + { + if (!function_exists('wincache_ucache_info')) { + throw new \BadFunctionCallException('not support: WinCache'); + } + + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name): bool + { + $this->readTimes++; + + $key = $this->getCacheKey($name); + + return wincache_ucache_exists($key); + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = null) + { + $this->readTimes++; + + $key = $this->getCacheKey($name); + + return wincache_ucache_exists($key) ? $this->unserialize(wincache_ucache_get($key)) : $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null): bool + { + $this->writeTimes++; + + if (is_null($expire)) { + $expire = $this->options['expire']; + } + + $key = $this->getCacheKey($name); + $expire = $this->getExpireTime($expire); + $value = $this->serialize($value); + + if (wincache_ucache_set($key, $value, $expire)) { + return true; + } + + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + return wincache_ucache_inc($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec(string $name, int $step = 1) + { + $this->writeTimes++; + + $key = $this->getCacheKey($name); + + return wincache_ucache_dec($key, $step); + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function delete($name): bool + { + $this->writeTimes++; + + return wincache_ucache_delete($this->getCacheKey($name)); + } + + /** + * 清除缓存 + * @access public + * @return bool + */ + public function clear(): bool + { + $this->writeTimes++; + return wincache_ucache_clear(); + } + + /** + * 删除缓存标签 + * @access public + * @param array $keys 缓存标识列表 + * @return void + */ + public function clearTag(array $keys): void + { + wincache_ucache_delete($keys); + } + +} diff --git a/vendor/topthink/framework/src/think/console/Command.php b/vendor/topthink/framework/src/think/console/Command.php new file mode 100644 index 0000000..bd3fb20 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/Command.php @@ -0,0 +1,504 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console; + +use Exception; +use InvalidArgumentException; +use LogicException; +use think\App; +use think\Console; +use think\console\input\Argument; +use think\console\input\Definition; +use think\console\input\Option; + +abstract class Command +{ + + /** @var Console */ + private $console; + private $name; + private $processTitle; + private $aliases = []; + private $definition; + private $help; + private $description; + private $ignoreValidationErrors = false; + private $consoleDefinitionMerged = false; + private $consoleDefinitionMergedWithArgs = false; + private $synopsis = []; + private $usages = []; + + /** @var Input */ + protected $input; + + /** @var Output */ + protected $output; + + /** @var App */ + protected $app; + + /** + * 构造方法 + * @throws LogicException + * @api + */ + public function __construct() + { + $this->definition = new Definition(); + + $this->configure(); + + if (!$this->name) { + throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this))); + } + } + + /** + * 忽略验证错误 + */ + public function ignoreValidationErrors(): void + { + $this->ignoreValidationErrors = true; + } + + /** + * 设置控制台 + * @param Console $console + */ + public function setConsole(Console $console = null): void + { + $this->console = $console; + } + + /** + * 获取控制台 + * @return Console + * @api + */ + public function getConsole(): Console + { + return $this->console; + } + + /** + * 设置app + * @param App $app + */ + public function setApp(App $app) + { + $this->app = $app; + } + + /** + * 获取app + * @return App + */ + public function getApp() + { + return $this->app; + } + + /** + * 是否有效 + * @return bool + */ + public function isEnabled(): bool + { + return true; + } + + /** + * 配置指令 + */ + protected function configure() + { + } + + /** + * 执行指令 + * @param Input $input + * @param Output $output + * @return null|int + * @throws LogicException + * @see setCode() + */ + protected function execute(Input $input, Output $output) + { + return $this->app->invoke([$this, 'handle']); + } + + /** + * 用户验证 + * @param Input $input + * @param Output $output + */ + protected function interact(Input $input, Output $output) + { + } + + /** + * 初始化 + * @param Input $input An InputInterface instance + * @param Output $output An OutputInterface instance + */ + protected function initialize(Input $input, Output $output) + { + } + + /** + * 执行 + * @param Input $input + * @param Output $output + * @return int + * @throws Exception + * @see setCode() + * @see execute() + */ + public function run(Input $input, Output $output): int + { + $this->input = $input; + $this->output = $output; + + $this->getSynopsis(true); + $this->getSynopsis(false); + + $this->mergeConsoleDefinition(); + + try { + $input->bind($this->definition); + } catch (Exception $e) { + if (!$this->ignoreValidationErrors) { + throw $e; + } + } + + $this->initialize($input, $output); + + if (null !== $this->processTitle) { + if (function_exists('cli_set_process_title')) { + if (false === @cli_set_process_title($this->processTitle)) { + if ('Darwin' === PHP_OS) { + $output->writeln('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.'); + } else { + $error = error_get_last(); + trigger_error($error['message'], E_USER_WARNING); + } + } + } elseif (function_exists('setproctitle')) { + setproctitle($this->processTitle); + } elseif (Output::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) { + $output->writeln('Install the proctitle PECL to be able to change the process title.'); + } + } + + if ($input->isInteractive()) { + $this->interact($input, $output); + } + + $input->validate(); + + $statusCode = $this->execute($input, $output); + + return is_numeric($statusCode) ? (int) $statusCode : 0; + } + + /** + * 合并参数定义 + * @param bool $mergeArgs + */ + public function mergeConsoleDefinition(bool $mergeArgs = true) + { + if (null === $this->console + || (true === $this->consoleDefinitionMerged + && ($this->consoleDefinitionMergedWithArgs || !$mergeArgs)) + ) { + return; + } + + if ($mergeArgs) { + $currentArguments = $this->definition->getArguments(); + $this->definition->setArguments($this->console->getDefinition()->getArguments()); + $this->definition->addArguments($currentArguments); + } + + $this->definition->addOptions($this->console->getDefinition()->getOptions()); + + $this->consoleDefinitionMerged = true; + if ($mergeArgs) { + $this->consoleDefinitionMergedWithArgs = true; + } + } + + /** + * 设置参数定义 + * @param array|Definition $definition + * @return Command + * @api + */ + public function setDefinition($definition) + { + if ($definition instanceof Definition) { + $this->definition = $definition; + } else { + $this->definition->setDefinition($definition); + } + + $this->consoleDefinitionMerged = false; + + return $this; + } + + /** + * 获取参数定义 + * @return Definition + * @api + */ + public function getDefinition(): Definition + { + return $this->definition; + } + + /** + * 获取当前指令的参数定义 + * @return Definition + */ + public function getNativeDefinition(): Definition + { + return $this->getDefinition(); + } + + /** + * 添加参数 + * @param string $name 名称 + * @param int $mode 类型 + * @param string $description 描述 + * @param mixed $default 默认值 + * @return Command + */ + public function addArgument(string $name, int $mode = null, string $description = '', $default = null) + { + $this->definition->addArgument(new Argument($name, $mode, $description, $default)); + + return $this; + } + + /** + * 添加选项 + * @param string $name 选项名称 + * @param string $shortcut 别名 + * @param int $mode 类型 + * @param string $description 描述 + * @param mixed $default 默认值 + * @return Command + */ + public function addOption(string $name, string $shortcut = null, int $mode = null, string $description = '', $default = null) + { + $this->definition->addOption(new Option($name, $shortcut, $mode, $description, $default)); + + return $this; + } + + /** + * 设置指令名称 + * @param string $name + * @return Command + * @throws InvalidArgumentException + */ + public function setName(string $name) + { + $this->validateName($name); + + $this->name = $name; + + return $this; + } + + /** + * 设置进程名称 + * + * PHP 5.5+ or the proctitle PECL library is required + * + * @param string $title The process title + * + * @return $this + */ + public function setProcessTitle($title) + { + $this->processTitle = $title; + + return $this; + } + + /** + * 获取指令名称 + * @return string + */ + public function getName(): string + { + return $this->name ?: ''; + } + + /** + * 设置描述 + * @param string $description + * @return Command + */ + public function setDescription(string $description) + { + $this->description = $description; + + return $this; + } + + /** + * 获取描述 + * @return string + */ + public function getDescription(): string + { + return $this->description ?: ''; + } + + /** + * 设置帮助信息 + * @param string $help + * @return Command + */ + public function setHelp(string $help) + { + $this->help = $help; + + return $this; + } + + /** + * 获取帮助信息 + * @return string + */ + public function getHelp(): string + { + return $this->help ?: ''; + } + + /** + * 描述信息 + * @return string + */ + public function getProcessedHelp(): string + { + $name = $this->name; + + $placeholders = [ + '%command.name%', + '%command.full_name%', + ]; + $replacements = [ + $name, + $_SERVER['PHP_SELF'] . ' ' . $name, + ]; + + return str_replace($placeholders, $replacements, $this->getHelp()); + } + + /** + * 设置别名 + * @param string[] $aliases + * @return Command + * @throws InvalidArgumentException + */ + public function setAliases(iterable $aliases) + { + foreach ($aliases as $alias) { + $this->validateName($alias); + } + + $this->aliases = $aliases; + + return $this; + } + + /** + * 获取别名 + * @return array + */ + public function getAliases(): array + { + return $this->aliases; + } + + /** + * 获取简介 + * @param bool $short 是否简单的 + * @return string + */ + public function getSynopsis(bool $short = false): string + { + $key = $short ? 'short' : 'long'; + + if (!isset($this->synopsis[$key])) { + $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short))); + } + + return $this->synopsis[$key]; + } + + /** + * 添加用法介绍 + * @param string $usage + * @return $this + */ + public function addUsage(string $usage) + { + if (0 !== strpos($usage, $this->name)) { + $usage = sprintf('%s %s', $this->name, $usage); + } + + $this->usages[] = $usage; + + return $this; + } + + /** + * 获取用法介绍 + * @return array + */ + public function getUsages(): array + { + return $this->usages; + } + + /** + * 验证指令名称 + * @param string $name + * @throws InvalidArgumentException + */ + private function validateName(string $name) + { + if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) { + throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); + } + } + + /** + * 输出表格 + * @param Table $table + * @return string + */ + protected function table(Table $table): string + { + $content = $table->render(); + $this->output->writeln($content); + return $content; + } + +} diff --git a/vendor/topthink/framework/src/think/console/Input.php b/vendor/topthink/framework/src/think/console/Input.php new file mode 100644 index 0000000..9ae9077 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/Input.php @@ -0,0 +1,465 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console; + +use think\console\input\Argument; +use think\console\input\Definition; +use think\console\input\Option; + +class Input +{ + + /** + * @var Definition + */ + protected $definition; + + /** + * @var Option[] + */ + protected $options = []; + + /** + * @var Argument[] + */ + protected $arguments = []; + + protected $interactive = true; + + private $tokens; + private $parsed; + + public function __construct($argv = null) + { + if (null === $argv) { + $argv = $_SERVER['argv']; + // 去除命令名 + array_shift($argv); + } + + $this->tokens = $argv; + + $this->definition = new Definition(); + } + + protected function setTokens(array $tokens) + { + $this->tokens = $tokens; + } + + /** + * 绑定实例 + * @param Definition $definition A InputDefinition instance + */ + public function bind(Definition $definition): void + { + $this->arguments = []; + $this->options = []; + $this->definition = $definition; + + $this->parse(); + } + + /** + * 解析参数 + */ + protected function parse(): void + { + $parseOptions = true; + $this->parsed = $this->tokens; + while (null !== $token = array_shift($this->parsed)) { + if ($parseOptions && '' == $token) { + $this->parseArgument($token); + } elseif ($parseOptions && '--' == $token) { + $parseOptions = false; + } elseif ($parseOptions && 0 === strpos($token, '--')) { + $this->parseLongOption($token); + } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { + $this->parseShortOption($token); + } else { + $this->parseArgument($token); + } + } + } + + /** + * 解析短选项 + * @param string $token 当前的指令. + */ + private function parseShortOption(string $token): void + { + $name = substr($token, 1); + + if (strlen($name) > 1) { + if ($this->definition->hasShortcut($name[0]) + && $this->definition->getOptionForShortcut($name[0])->acceptValue() + ) { + $this->addShortOption($name[0], substr($name, 1)); + } else { + $this->parseShortOptionSet($name); + } + } else { + $this->addShortOption($name, null); + } + } + + /** + * 解析短选项 + * @param string $name 当前指令 + * @throws \RuntimeException + */ + private function parseShortOptionSet(string $name): void + { + $len = strlen($name); + for ($i = 0; $i < $len; ++$i) { + if (!$this->definition->hasShortcut($name[$i])) { + throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i])); + } + + $option = $this->definition->getOptionForShortcut($name[$i]); + if ($option->acceptValue()) { + $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1)); + + break; + } else { + $this->addLongOption($option->getName(), null); + } + } + } + + /** + * 解析完整选项 + * @param string $token 当前指令 + */ + private function parseLongOption(string $token): void + { + $name = substr($token, 2); + + if (false !== $pos = strpos($name, '=')) { + $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1)); + } else { + $this->addLongOption($name, null); + } + } + + /** + * 解析参数 + * @param string $token 当前指令 + * @throws \RuntimeException + */ + private function parseArgument(string $token): void + { + $c = count($this->arguments); + + if ($this->definition->hasArgument($c)) { + $arg = $this->definition->getArgument($c); + + $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token; + + } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { + $arg = $this->definition->getArgument($c - 1); + + $this->arguments[$arg->getName()][] = $token; + } else { + throw new \RuntimeException('Too many arguments.'); + } + } + + /** + * 添加一个短选项的值 + * @param string $shortcut 短名称 + * @param mixed $value 值 + * @throws \RuntimeException + */ + private function addShortOption(string $shortcut, $value): void + { + if (!$this->definition->hasShortcut($shortcut)) { + throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); + } + + $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); + } + + /** + * 添加一个完整选项的值 + * @param string $name 选项名 + * @param mixed $value 值 + * @throws \RuntimeException + */ + private function addLongOption(string $name, $value): void + { + if (!$this->definition->hasOption($name)) { + throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name)); + } + + $option = $this->definition->getOption($name); + + if (false === $value) { + $value = null; + } + + if (null !== $value && !$option->acceptValue()) { + throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name, $value)); + } + + if (null === $value && $option->acceptValue() && count($this->parsed)) { + $next = array_shift($this->parsed); + if (isset($next[0]) && '-' !== $next[0]) { + $value = $next; + } elseif (empty($next)) { + $value = ''; + } else { + array_unshift($this->parsed, $next); + } + } + + if (null === $value) { + if ($option->isValueRequired()) { + throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name)); + } + + if (!$option->isArray()) { + $value = $option->isValueOptional() ? $option->getDefault() : true; + } + } + + if ($option->isArray()) { + $this->options[$name][] = $value; + } else { + $this->options[$name] = $value; + } + } + + /** + * 获取第一个参数 + * @return string|null + */ + public function getFirstArgument() + { + foreach ($this->tokens as $token) { + if ($token && '-' === $token[0]) { + continue; + } + + return $token; + } + return; + } + + /** + * 检查原始参数是否包含某个值 + * @param string|array $values 需要检查的值 + * @return bool + */ + public function hasParameterOption($values): bool + { + $values = (array) $values; + + foreach ($this->tokens as $token) { + foreach ($values as $value) { + if ($token === $value || 0 === strpos($token, $value . '=')) { + return true; + } + } + } + + return false; + } + + /** + * 获取原始选项的值 + * @param string|array $values 需要检查的值 + * @param mixed $default 默认值 + * @return mixed The option value + */ + public function getParameterOption($values, $default = false) + { + $values = (array) $values; + $tokens = $this->tokens; + + while (0 < count($tokens)) { + $token = array_shift($tokens); + + foreach ($values as $value) { + if ($token === $value || 0 === strpos($token, $value . '=')) { + if (false !== $pos = strpos($token, '=')) { + return substr($token, $pos + 1); + } + + return array_shift($tokens); + } + } + } + + return $default; + } + + /** + * 验证输入 + * @throws \RuntimeException + */ + public function validate() + { + if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) { + throw new \RuntimeException('Not enough arguments.'); + } + } + + /** + * 检查输入是否是交互的 + * @return bool + */ + public function isInteractive(): bool + { + return $this->interactive; + } + + /** + * 设置输入的交互 + * @param bool + */ + public function setInteractive(bool $interactive): void + { + $this->interactive = $interactive; + } + + /** + * 获取所有的参数 + * @return Argument[] + */ + public function getArguments(): array + { + return array_merge($this->definition->getArgumentDefaults(), $this->arguments); + } + + /** + * 根据名称获取参数 + * @param string $name 参数名 + * @return mixed + * @throws \InvalidArgumentException + */ + public function getArgument(string $name) + { + if (!$this->definition->hasArgument($name)) { + throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + return $this->arguments[$name] ?? $this->definition->getArgument($name) + ->getDefault(); + } + + /** + * 设置参数的值 + * @param string $name 参数名 + * @param string $value 值 + * @throws \InvalidArgumentException + */ + public function setArgument(string $name, $value) + { + if (!$this->definition->hasArgument($name)) { + throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + $this->arguments[$name] = $value; + } + + /** + * 检查是否存在某个参数 + * @param string|int $name 参数名或位置 + * @return bool + */ + public function hasArgument($name): bool + { + return $this->definition->hasArgument($name); + } + + /** + * 获取所有的选项 + * @return Option[] + */ + public function getOptions(): array + { + return array_merge($this->definition->getOptionDefaults(), $this->options); + } + + /** + * 获取选项值 + * @param string $name 选项名称 + * @return mixed + * @throws \InvalidArgumentException + */ + public function getOption(string $name) + { + if (!$this->definition->hasOption($name)) { + throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); + } + + return $this->options[$name] ?? $this->definition->getOption($name)->getDefault(); + } + + /** + * 设置选项值 + * @param string $name 选项名 + * @param string|bool $value 值 + * @throws \InvalidArgumentException + */ + public function setOption(string $name, $value): void + { + if (!$this->definition->hasOption($name)) { + throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); + } + + $this->options[$name] = $value; + } + + /** + * 是否有某个选项 + * @param string $name 选项名 + * @return bool + */ + public function hasOption(string $name): bool + { + return $this->definition->hasOption($name) && isset($this->options[$name]); + } + + /** + * 转义指令 + * @param string $token + * @return string + */ + public function escapeToken(string $token): string + { + return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token); + } + + /** + * 返回传递给命令的参数的字符串 + * @return string + */ + public function __toString() + { + $tokens = array_map(function ($token) { + if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) { + return $match[1] . $this->escapeToken($match[2]); + } + + if ($token && '-' !== $token[0]) { + return $this->escapeToken($token); + } + + return $token; + }, $this->tokens); + + return implode(' ', $tokens); + } +} diff --git a/vendor/topthink/framework/src/think/console/LICENSE b/vendor/topthink/framework/src/think/console/LICENSE new file mode 100644 index 0000000..0abe056 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2016 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/vendor/topthink/framework/src/think/console/Output.php b/vendor/topthink/framework/src/think/console/Output.php new file mode 100644 index 0000000..13837a7 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/Output.php @@ -0,0 +1,224 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console; + +use Exception; +use think\console\output\Ask; +use think\console\output\Descriptor; +use think\console\output\driver\Buffer; +use think\console\output\driver\Console; +use think\console\output\driver\Nothing; +use think\console\output\Question; +use think\console\output\question\Choice; +use think\console\output\question\Confirmation; +use Throwable; + +/** + * Class Output + * @package think\console + * + * @see \think\console\output\driver\Console::setDecorated + * @method void setDecorated($decorated) + * + * @see \think\console\output\driver\Buffer::fetch + * @method string fetch() + * + * @method void info($message) + * @method void error($message) + * @method void comment($message) + * @method void warning($message) + * @method void highlight($message) + * @method void question($message) + */ +class Output +{ + const VERBOSITY_QUIET = 0; + const VERBOSITY_NORMAL = 1; + const VERBOSITY_VERBOSE = 2; + const VERBOSITY_VERY_VERBOSE = 3; + const VERBOSITY_DEBUG = 4; + + const OUTPUT_NORMAL = 0; + const OUTPUT_RAW = 1; + const OUTPUT_PLAIN = 2; + + private $verbosity = self::VERBOSITY_NORMAL; + + /** @var Buffer|Console|Nothing */ + private $handle = null; + + protected $styles = [ + 'info', + 'error', + 'comment', + 'question', + 'highlight', + 'warning', + ]; + + public function __construct($driver = 'console') + { + $class = '\\think\\console\\output\\driver\\' . ucwords($driver); + + $this->handle = new $class($this); + } + + public function ask(Input $input, $question, $default = null, $validator = null) + { + $question = new Question($question, $default); + $question->setValidator($validator); + + return $this->askQuestion($input, $question); + } + + public function askHidden(Input $input, $question, $validator = null) + { + $question = new Question($question); + + $question->setHidden(true); + $question->setValidator($validator); + + return $this->askQuestion($input, $question); + } + + public function confirm(Input $input, $question, $default = true) + { + return $this->askQuestion($input, new Confirmation($question, $default)); + } + + /** + * {@inheritdoc} + */ + public function choice(Input $input, $question, array $choices, $default = null) + { + if (null !== $default) { + $values = array_flip($choices); + $default = $values[$default]; + } + + return $this->askQuestion($input, new Choice($question, $choices, $default)); + } + + protected function askQuestion(Input $input, Question $question) + { + $ask = new Ask($input, $this, $question); + $answer = $ask->run(); + + if ($input->isInteractive()) { + $this->newLine(); + } + + return $answer; + } + + protected function block(string $style, string $message): void + { + $this->writeln("<{$style}>{$message}"); + } + + /** + * 输出空行 + * @param int $count + */ + public function newLine(int $count = 1): void + { + $this->write(str_repeat(PHP_EOL, $count)); + } + + /** + * 输出信息并换行 + * @param string $messages + * @param int $type + */ + public function writeln(string $messages, int $type = 0): void + { + $this->write($messages, true, $type); + } + + /** + * 输出信息 + * @param string $messages + * @param bool $newline + * @param int $type + */ + public function write(string $messages, bool $newline = false, int $type = 0): void + { + $this->handle->write($messages, $newline, $type); + } + + public function renderException(Throwable $e): void + { + $this->handle->renderException($e); + } + + /** + * {@inheritdoc} + */ + public function setVerbosity(int $level) + { + $this->verbosity = $level; + } + + /** + * {@inheritdoc} + */ + public function getVerbosity(): int + { + return $this->verbosity; + } + + public function isQuiet(): bool + { + return self::VERBOSITY_QUIET === $this->verbosity; + } + + public function isVerbose(): bool + { + return self::VERBOSITY_VERBOSE <= $this->verbosity; + } + + public function isVeryVerbose(): bool + { + return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; + } + + public function isDebug(): bool + { + return self::VERBOSITY_DEBUG <= $this->verbosity; + } + + public function describe($object, array $options = []): void + { + $descriptor = new Descriptor(); + $options = array_merge([ + 'raw_text' => false, + ], $options); + + $descriptor->describe($this, $object, $options); + } + + public function __call($method, $args) + { + if (in_array($method, $this->styles)) { + array_unshift($args, $method); + return call_user_func_array([$this, 'block'], $args); + } + + if ($this->handle && method_exists($this->handle, $method)) { + return call_user_func_array([$this->handle, $method], $args); + } else { + throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + } + } + +} diff --git a/vendor/topthink/framework/src/think/console/Table.php b/vendor/topthink/framework/src/think/console/Table.php new file mode 100644 index 0000000..5a861d7 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/Table.php @@ -0,0 +1,300 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console; + +class Table +{ + const ALIGN_LEFT = 1; + const ALIGN_RIGHT = 0; + const ALIGN_CENTER = 2; + + /** + * 头信息数据 + * @var array + */ + protected $header = []; + + /** + * 头部对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER + * @var int + */ + protected $headerAlign = 1; + + /** + * 表格数据(二维数组) + * @var array + */ + protected $rows = []; + + /** + * 单元格对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER + * @var int + */ + protected $cellAlign = 1; + + /** + * 单元格宽度信息 + * @var array + */ + protected $colWidth = []; + + /** + * 表格输出样式 + * @var string + */ + protected $style = 'default'; + + /** + * 表格样式定义 + * @var array + */ + protected $format = [ + 'compact' => [], + 'default' => [ + 'top' => ['+', '-', '+', '+'], + 'cell' => ['|', ' ', '|', '|'], + 'middle' => ['+', '-', '+', '+'], + 'bottom' => ['+', '-', '+', '+'], + 'cross-top' => ['+', '-', '-', '+'], + 'cross-bottom' => ['+', '-', '-', '+'], + ], + 'markdown' => [ + 'top' => [' ', ' ', ' ', ' '], + 'cell' => ['|', ' ', '|', '|'], + 'middle' => ['|', '-', '|', '|'], + 'bottom' => [' ', ' ', ' ', ' '], + 'cross-top' => ['|', ' ', ' ', '|'], + 'cross-bottom' => ['|', ' ', ' ', '|'], + ], + 'borderless' => [ + 'top' => ['=', '=', ' ', '='], + 'cell' => [' ', ' ', ' ', ' '], + 'middle' => ['=', '=', ' ', '='], + 'bottom' => ['=', '=', ' ', '='], + 'cross-top' => ['=', '=', ' ', '='], + 'cross-bottom' => ['=', '=', ' ', '='], + ], + 'box' => [ + 'top' => ['┌', '─', '┬', '┐'], + 'cell' => ['│', ' ', '│', '│'], + 'middle' => ['├', '─', '┼', '┤'], + 'bottom' => ['└', '─', '┴', '┘'], + 'cross-top' => ['├', '─', '┴', '┤'], + 'cross-bottom' => ['├', '─', '┬', '┤'], + ], + 'box-double' => [ + 'top' => ['╔', '═', '╤', '╗'], + 'cell' => ['║', ' ', '│', '║'], + 'middle' => ['╠', '─', '╪', '╣'], + 'bottom' => ['╚', '═', '╧', '╝'], + 'cross-top' => ['╠', '═', '╧', '╣'], + 'cross-bottom' => ['╠', '═', '╤', '╣'], + ], + ]; + + /** + * 设置表格头信息 以及对齐方式 + * @access public + * @param array $header 要输出的Header信息 + * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER + * @return void + */ + public function setHeader(array $header, int $align = 1): void + { + $this->header = $header; + $this->headerAlign = $align; + + $this->checkColWidth($header); + } + + /** + * 设置输出表格数据 及对齐方式 + * @access public + * @param array $rows 要输出的表格数据(二维数组) + * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER + * @return void + */ + public function setRows(array $rows, int $align = 1): void + { + $this->rows = $rows; + $this->cellAlign = $align; + + foreach ($rows as $row) { + $this->checkColWidth($row); + } + } + + /** + * 设置全局单元格对齐方式 + * @param int $align 对齐方式 默认1 ALGIN_LEFT 0 ALIGN_RIGHT 2 ALIGN_CENTER + * @return $this + */ + public function setCellAlign(int $align = 1) + { + $this->cellAlign = $align; + return $this; + } + + /** + * 检查列数据的显示宽度 + * @access public + * @param mixed $row 行数据 + * @return void + */ + protected function checkColWidth($row): void + { + if (is_array($row)) { + foreach ($row as $key => $cell) { + $width = mb_strwidth((string) $cell); + if (!isset($this->colWidth[$key]) || $width > $this->colWidth[$key]) { + $this->colWidth[$key] = $width; + } + } + } + } + + /** + * 增加一行表格数据 + * @access public + * @param mixed $row 行数据 + * @param bool $first 是否在开头插入 + * @return void + */ + public function addRow($row, bool $first = false): void + { + if ($first) { + array_unshift($this->rows, $row); + } else { + $this->rows[] = $row; + } + + $this->checkColWidth($row); + } + + /** + * 设置输出表格的样式 + * @access public + * @param string $style 样式名 + * @return void + */ + public function setStyle(string $style): void + { + $this->style = isset($this->format[$style]) ? $style : 'default'; + } + + /** + * 输出分隔行 + * @access public + * @param string $pos 位置 + * @return string + */ + protected function renderSeparator(string $pos): string + { + $style = $this->getStyle($pos); + $array = []; + + foreach ($this->colWidth as $width) { + $array[] = str_repeat($style[1], $width + 2); + } + + return $style[0] . implode($style[2], $array) . $style[3] . PHP_EOL; + } + + /** + * 输出表格头部 + * @access public + * @return string + */ + protected function renderHeader(): string + { + $style = $this->getStyle('cell'); + $content = $this->renderSeparator('top'); + + foreach ($this->header as $key => $header) { + $array[] = ' ' . str_pad($header, $this->colWidth[$key], $style[1], $this->headerAlign); + } + + if (!empty($array)) { + $content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL; + + if (!empty($this->rows)) { + $content .= $this->renderSeparator('middle'); + } + } + + return $content; + } + + protected function getStyle(string $style): array + { + if ($this->format[$this->style]) { + $style = $this->format[$this->style][$style]; + } else { + $style = [' ', ' ', ' ', ' ']; + } + + return $style; + } + + /** + * 输出表格 + * @access public + * @param array $dataList 表格数据 + * @return string + */ + public function render(array $dataList = []): string + { + if (!empty($dataList)) { + $this->setRows($dataList); + } + + // 输出头部 + $content = $this->renderHeader(); + $style = $this->getStyle('cell'); + + if (!empty($this->rows)) { + foreach ($this->rows as $row) { + if (is_string($row) && '-' === $row) { + $content .= $this->renderSeparator('middle'); + } elseif (is_scalar($row)) { + $content .= $this->renderSeparator('cross-top'); + $width = 3 * (count($this->colWidth) - 1) + array_reduce($this->colWidth, function ($a, $b) { + return $a + $b; + }); + $array = str_pad($row, $width); + + $content .= $style[0] . ' ' . $array . ' ' . $style[3] . PHP_EOL; + $content .= $this->renderSeparator('cross-bottom'); + } else { + $array = []; + + foreach ($row as $key => $val) { + $width = $this->colWidth[$key]; + // form https://github.com/symfony/console/blob/20c9821c8d1c2189f287dcee709b2f86353ea08f/Helper/Table.php#L467 + // str_pad won't work properly with multi-byte strings, we need to fix the padding + if (false !== $encoding = mb_detect_encoding((string) $val, null, true)) { + $width += strlen((string) $val) - mb_strwidth((string) $val, $encoding); + } + $array[] = ' ' . str_pad((string) $val, $width, ' ', $this->cellAlign); + } + + $content .= $style[0] . implode(' ' . $style[2], $array) . ' ' . $style[3] . PHP_EOL; + } + } + } + + $content .= $this->renderSeparator('bottom'); + + return $content; + } +} diff --git a/vendor/topthink/framework/src/think/console/bin/README.md b/vendor/topthink/framework/src/think/console/bin/README.md new file mode 100644 index 0000000..9acc52f --- /dev/null +++ b/vendor/topthink/framework/src/think/console/bin/README.md @@ -0,0 +1 @@ +console 工具使用 hiddeninput.exe 在 windows 上隐藏密码输入,该二进制文件由第三方提供,相关源码和其他细节可以在 [Hidden Input](https://github.com/Seldaek/hidden-input) 找到。 diff --git a/vendor/topthink/framework/src/think/console/bin/hiddeninput.exe b/vendor/topthink/framework/src/think/console/bin/hiddeninput.exe new file mode 100644 index 0000000000000000000000000000000000000000..c8cf65e8d819e6e525121cf6b21f1c2429746038 GIT binary patch literal 9216 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 J0sQ~1{4brj`U(I5 literal 0 HcmV?d00001 diff --git a/vendor/topthink/framework/src/think/console/command/Clear.php b/vendor/topthink/framework/src/think/console/command/Clear.php new file mode 100644 index 0000000..81878c5 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/Clear.php @@ -0,0 +1,64 @@ + +// +---------------------------------------------------------------------- +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\input\Option; +use think\console\Output; + +class Clear extends Command +{ + protected function configure() + { + // 指令配置 + $this->setName('clear') + ->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null) + ->addOption('cache', 'c', Option::VALUE_NONE, 'clear cache file') + ->addOption('log', 'l', Option::VALUE_NONE, 'clear log file') + ->addOption('dir', 'r', Option::VALUE_NONE, 'clear empty dir') + ->setDescription('Clear runtime file'); + } + + protected function execute(Input $input, Output $output) + { + $runtimePath = $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR; + + if ($input->getOption('cache')) { + $path = $runtimePath . 'cache'; + } elseif ($input->getOption('log')) { + $path = $runtimePath . 'log'; + } else { + $path = $input->getOption('path') ?: $runtimePath; + } + + $rmdir = $input->getOption('dir') ? true : false; + $this->clear(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, $rmdir); + + $output->writeln("Clear Successed"); + } + + protected function clear(string $path, bool $rmdir): void + { + $files = is_dir($path) ? scandir($path) : []; + + foreach ($files as $file) { + if ('.' != $file && '..' != $file && is_dir($path . $file)) { + array_map('unlink', glob($path . $file . DIRECTORY_SEPARATOR . '*.*')); + if ($rmdir) { + rmdir($path . $file); + } + } elseif ('.gitignore' != $file && is_file($path . $file)) { + unlink($path . $file); + } + } + } +} diff --git a/vendor/topthink/framework/src/think/console/command/Help.php b/vendor/topthink/framework/src/think/console/command/Help.php new file mode 100644 index 0000000..d3833b8 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/Help.php @@ -0,0 +1,69 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\input\Argument as InputArgument; +use think\console\input\Option as InputOption; +use think\console\Output; + +class Help extends Command +{ + + private $command; + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this->ignoreValidationErrors(); + + $this->setName('help')->setDefinition([ + new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), + new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), + ])->setDescription('Displays help for a command')->setHelp(<<%command.name% command displays help for a given command: + + php %command.full_name% list + +To display the list of available commands, please use the list command. +EOF + ); + } + + /** + * Sets the command. + * @param Command $command The command to set + */ + public function setCommand(Command $command): void + { + $this->command = $command; + } + + /** + * {@inheritdoc} + */ + protected function execute(Input $input, Output $output) + { + if (null === $this->command) { + $this->command = $this->getConsole()->find($input->getArgument('command_name')); + } + + $output->describe($this->command, [ + 'raw_text' => $input->getOption('raw'), + ]); + + $this->command = null; + } +} diff --git a/vendor/topthink/framework/src/think/console/command/Lists.php b/vendor/topthink/framework/src/think/console/command/Lists.php new file mode 100644 index 0000000..278c2bd --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/Lists.php @@ -0,0 +1,73 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\input\Argument as InputArgument; +use think\console\input\Definition as InputDefinition; +use think\console\input\Option as InputOption; +use think\console\Output; + +class Lists extends Command +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + $this->setName('list')->setDefinition($this->createDefinition())->setDescription('Lists commands')->setHelp(<<%command.name% command lists all commands: + + php %command.full_name% + +You can also display the commands for a specific namespace: + + php %command.full_name% test + +It's also possible to get raw list of commands (useful for embedding command runner): + + php %command.full_name% --raw +EOF + ); + } + + /** + * {@inheritdoc} + */ + public function getNativeDefinition(): InputDefinition + { + return $this->createDefinition(); + } + + /** + * {@inheritdoc} + */ + protected function execute(Input $input, Output $output) + { + $output->describe($this->getConsole(), [ + 'raw_text' => $input->getOption('raw'), + 'namespace' => $input->getArgument('namespace'), + ]); + } + + /** + * {@inheritdoc} + */ + private function createDefinition(): InputDefinition + { + return new InputDefinition([ + new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), + new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), + ]); + } +} diff --git a/vendor/topthink/framework/src/think/console/command/Make.php b/vendor/topthink/framework/src/think/console/command/Make.php new file mode 100644 index 0000000..662b337 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/Make.php @@ -0,0 +1,99 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\input\Argument; +use think\console\Output; + +abstract class Make extends Command +{ + protected $type; + + abstract protected function getStub(); + + protected function configure() + { + $this->addArgument('name', Argument::REQUIRED, "The name of the class"); + } + + protected function execute(Input $input, Output $output) + { + $name = trim($input->getArgument('name')); + + $classname = $this->getClassName($name); + + $pathname = $this->getPathName($classname); + + if (is_file($pathname)) { + $output->writeln('' . $this->type . ':' . $classname . ' already exists!'); + return false; + } + + if (!is_dir(dirname($pathname))) { + mkdir(dirname($pathname), 0755, true); + } + + file_put_contents($pathname, $this->buildClass($classname)); + + $output->writeln('' . $this->type . ':' . $classname . ' created successfully.'); + } + + protected function buildClass(string $name) + { + $stub = file_get_contents($this->getStub()); + + $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\'); + + $class = str_replace($namespace . '\\', '', $name); + + return str_replace(['{%className%}', '{%actionSuffix%}', '{%namespace%}', '{%app_namespace%}'], [ + $class, + $this->app->config->get('route.action_suffix'), + $namespace, + $this->app->getNamespace(), + ], $stub); + } + + protected function getPathName(string $name): string + { + $name = str_replace('app\\', '', $name); + + return $this->app->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php'; + } + + protected function getClassName(string $name): string + { + if (strpos($name, '\\') !== false) { + return $name; + } + + if (strpos($name, '@')) { + [$app, $name] = explode('@', $name); + } else { + $app = ''; + } + + if (strpos($name, '/') !== false) { + $name = str_replace('/', '\\', $name); + } + + return $this->getNamespace($app) . '\\' . $name; + } + + protected function getNamespace(string $app): string + { + return 'app' . ($app ? '\\' . $app : ''); + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/RouteList.php b/vendor/topthink/framework/src/think/console/command/RouteList.php new file mode 100644 index 0000000..ed579b8 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/RouteList.php @@ -0,0 +1,129 @@ + +// +---------------------------------------------------------------------- +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\input\Argument; +use think\console\input\Option; +use think\console\Output; +use think\console\Table; +use think\event\RouteLoaded; + +class RouteList extends Command +{ + protected $sortBy = [ + 'rule' => 0, + 'route' => 1, + 'method' => 2, + 'name' => 3, + 'domain' => 4, + ]; + + protected function configure() + { + $this->setName('route:list') + ->addArgument('dir', Argument::OPTIONAL, 'dir name .') + ->addArgument('style', Argument::OPTIONAL, "the style of the table.", 'default') + ->addOption('sort', 's', Option::VALUE_OPTIONAL, 'order by rule name.', 0) + ->addOption('more', 'm', Option::VALUE_NONE, 'show route options.') + ->setDescription('show route list.'); + } + + protected function execute(Input $input, Output $output) + { + $dir = $input->getArgument('dir') ?: ''; + + $filename = $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . ($dir ? $dir . DIRECTORY_SEPARATOR : '') . 'route_list.php'; + + if (is_file($filename)) { + unlink($filename); + } elseif (!is_dir(dirname($filename))) { + mkdir(dirname($filename), 0755); + } + + $content = $this->getRouteList($dir); + file_put_contents($filename, 'Route List' . PHP_EOL . $content); + } + + protected function getRouteList(string $dir = null): string + { + $this->app->route->setTestMode(true); + $this->app->route->clear(); + + if ($dir) { + $path = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR; + } else { + $path = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR; + } + + $files = is_dir($path) ? scandir($path) : []; + + foreach ($files as $file) { + if (strpos($file, '.php')) { + include $path . $file; + } + } + + //触发路由载入完成事件 + $this->app->event->trigger(RouteLoaded::class); + + $table = new Table(); + + if ($this->input->hasOption('more')) { + $header = ['Rule', 'Route', 'Method', 'Name', 'Domain', 'Option', 'Pattern']; + } else { + $header = ['Rule', 'Route', 'Method', 'Name']; + } + + $table->setHeader($header); + + $routeList = $this->app->route->getRuleList(); + $rows = []; + + foreach ($routeList as $item) { + $item['route'] = $item['route'] instanceof \Closure ? '' : $item['route']; + + if ($this->input->hasOption('more')) { + $item = [$item['rule'], $item['route'], $item['method'], $item['name'], $item['domain'], json_encode($item['option']), json_encode($item['pattern'])]; + } else { + $item = [$item['rule'], $item['route'], $item['method'], $item['name']]; + } + + $rows[] = $item; + } + + if ($this->input->getOption('sort')) { + $sort = strtolower($this->input->getOption('sort')); + + if (isset($this->sortBy[$sort])) { + $sort = $this->sortBy[$sort]; + } + + uasort($rows, function ($a, $b) use ($sort) { + $itemA = $a[$sort] ?? null; + $itemB = $b[$sort] ?? null; + + return strcasecmp($itemA, $itemB); + }); + } + + $table->setRows($rows); + + if ($this->input->getArgument('style')) { + $style = $this->input->getArgument('style'); + $table->setStyle($style); + } + + return $this->table($table); + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/RunServer.php b/vendor/topthink/framework/src/think/console/command/RunServer.php new file mode 100644 index 0000000..82d2744 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/RunServer.php @@ -0,0 +1,57 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\input\Option; +use think\console\Output; + +class RunServer extends Command +{ + public function configure() + { + $this->setName('run') + ->addOption('host', 'H', Option::VALUE_OPTIONAL, + 'The host to server the application on', '0.0.0.0') + ->addOption('port', 'p', Option::VALUE_OPTIONAL, + 'The port to server the application on', 8000) + ->addOption('root', 'r', Option::VALUE_OPTIONAL, + 'The document root of the application', '') + ->setDescription('PHP Built-in Server for ThinkPHP'); + } + + public function execute(Input $input, Output $output) + { + $host = $input->getOption('host'); + $port = $input->getOption('port'); + $root = $input->getOption('root'); + if (empty($root)) { + $root = $this->app->getRootPath() . 'public'; + } + + $command = sprintf( + 'php -S %s:%d -t %s %s', + $host, + $port, + escapeshellarg($root), + escapeshellarg($root . DIRECTORY_SEPARATOR . 'router.php') + ); + + $output->writeln(sprintf('ThinkPHP Development server is started On ', '0.0.0.0' == $host ? '127.0.0.1' : $host, $port)); + $output->writeln(sprintf('You can exit with `CTRL-C`')); + $output->writeln(sprintf('Document root is: %s', $root)); + passthru($command); + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/ServiceDiscover.php b/vendor/topthink/framework/src/think/console/command/ServiceDiscover.php new file mode 100644 index 0000000..3aae1db --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/ServiceDiscover.php @@ -0,0 +1,48 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\Output; + +class ServiceDiscover extends Command +{ + public function configure() + { + $this->setName('service:discover') + ->setDescription('Discover Services for ThinkPHP'); + } + + public function execute(Input $input, Output $output) + { + if (is_file($path = $this->app->getRootPath() . 'vendor/composer/installed.json')) { + $packages = json_decode(@file_get_contents($path), true); + + $services = []; + foreach ($packages as $package) { + if (!empty($package['extra']['think']['services'])) { + $services = array_merge($services, (array) $package['extra']['think']['services']); + } + } + + $header = '// This file is automatically generated at:' . date('Y-m-d H:i:s') . PHP_EOL . 'declare (strict_types = 1);' . PHP_EOL; + + $content = 'app->getRootPath() . 'vendor/services.php', $content); + + $output->writeln('Succeed!'); + } + } +} diff --git a/vendor/topthink/framework/src/think/console/command/VendorPublish.php b/vendor/topthink/framework/src/think/console/command/VendorPublish.php new file mode 100644 index 0000000..7b43762 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/VendorPublish.php @@ -0,0 +1,66 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console\command; + +use think\console\Command; +use think\console\input\Option; + +class VendorPublish extends Command +{ + public function configure() + { + $this->setName('vendor:publish') + ->addOption('force', 'f', Option::VALUE_NONE, 'Overwrite any existing files') + ->setDescription('Publish any publishable assets from vendor packages'); + } + + public function handle() + { + + $force = $this->input->getOption('force'); + + if (is_file($path = $this->app->getRootPath() . 'vendor/composer/installed.json')) { + $packages = json_decode(@file_get_contents($path), true); + + foreach ($packages as $package) { + //配置 + $configDir = $this->app->getConfigPath(); + + if (!empty($package['extra']['think']['config'])) { + + $installPath = $this->app->getRootPath() . 'vendor/' . $package['name'] . DIRECTORY_SEPARATOR; + + foreach ((array) $package['extra']['think']['config'] as $name => $file) { + + $target = $configDir . $name . '.php'; + $source = $installPath . $file; + + if (is_file($target) && !$force) { + $this->output->info("File {$target} exist!"); + continue; + } + + if (!is_file($source)) { + $this->output->info("File {$source} not exist!"); + continue; + } + + copy($source, $target); + } + } + } + + $this->output->writeln('Succeed!'); + } + } +} diff --git a/vendor/topthink/framework/src/think/console/command/Version.php b/vendor/topthink/framework/src/think/console/command/Version.php new file mode 100644 index 0000000..beb49d2 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/Version.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\console\command; + +use think\console\Command; +use think\console\Input; +use think\console\Output; + +class Version extends Command +{ + protected function configure() + { + // 指令配置 + $this->setName('version') + ->setDescription('show thinkphp framework version'); + } + + protected function execute(Input $input, Output $output) + { + $output->writeln('v' . $this->app->version()); + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Command.php b/vendor/topthink/framework/src/think/console/command/make/Command.php new file mode 100644 index 0000000..88e665a --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Command.php @@ -0,0 +1,55 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command\make; + +use think\console\command\Make; +use think\console\input\Argument; + +class Command extends Make +{ + protected $type = "Command"; + + protected function configure() + { + parent::configure(); + $this->setName('make:command') + ->addArgument('commandName', Argument::OPTIONAL, "The name of the command") + ->setDescription('Create a new command class'); + } + + protected function buildClass(string $name): string + { + $commandName = $this->input->getArgument('commandName') ?: strtolower(basename($name)); + $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\'); + + $class = str_replace($namespace . '\\', '', $name); + $stub = file_get_contents($this->getStub()); + + return str_replace(['{%commandName%}', '{%className%}', '{%namespace%}', '{%app_namespace%}'], [ + $commandName, + $class, + $namespace, + $this->app->getNamespace(), + ], $stub); + } + + protected function getStub(): string + { + return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'command.stub'; + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\command'; + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Controller.php b/vendor/topthink/framework/src/think/console/command/make/Controller.php new file mode 100644 index 0000000..582cffb --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Controller.php @@ -0,0 +1,56 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command\make; + +use think\console\command\Make; +use think\console\input\Option; + +class Controller extends Make +{ + + protected $type = "Controller"; + + protected function configure() + { + parent::configure(); + $this->setName('make:controller') + ->addOption('api', null, Option::VALUE_NONE, 'Generate an api controller class.') + ->addOption('plain', null, Option::VALUE_NONE, 'Generate an empty controller class.') + ->setDescription('Create a new resource controller class'); + } + + protected function getStub(): string + { + $stubPath = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR; + + if ($this->input->getOption('api')) { + return $stubPath . 'controller.api.stub'; + } + + if ($this->input->getOption('plain')) { + return $stubPath . 'controller.plain.stub'; + } + + return $stubPath . 'controller.stub'; + } + + protected function getClassName(string $name): string + { + return parent::getClassName($name) . ($this->app->config->get('route.controller_suffix') ? 'Controller' : ''); + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\controller'; + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Event.php b/vendor/topthink/framework/src/think/console/command/make/Event.php new file mode 100644 index 0000000..a4676d8 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Event.php @@ -0,0 +1,35 @@ + +// +---------------------------------------------------------------------- +namespace think\console\command\make; + +use think\console\command\Make; + +class Event extends Make +{ + protected $type = "Event"; + + protected function configure() + { + parent::configure(); + $this->setName('make:event') + ->setDescription('Create a new event class'); + } + + protected function getStub(): string + { + return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'event.stub'; + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\event'; + } +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Listener.php b/vendor/topthink/framework/src/think/console/command/make/Listener.php new file mode 100644 index 0000000..bb29668 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Listener.php @@ -0,0 +1,35 @@ + +// +---------------------------------------------------------------------- +namespace think\console\command\make; + +use think\console\command\Make; + +class Listener extends Make +{ + protected $type = "Listener"; + + protected function configure() + { + parent::configure(); + $this->setName('make:listener') + ->setDescription('Create a new listener class'); + } + + protected function getStub(): string + { + return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'listener.stub'; + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\listener'; + } +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Middleware.php b/vendor/topthink/framework/src/think/console/command/make/Middleware.php new file mode 100644 index 0000000..80f4563 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Middleware.php @@ -0,0 +1,36 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command\make; + +use think\console\command\Make; + +class Middleware extends Make +{ + protected $type = "Middleware"; + + protected function configure() + { + parent::configure(); + $this->setName('make:middleware') + ->setDescription('Create a new middleware class'); + } + + protected function getStub(): string + { + return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'middleware.stub'; + } + + protected function getNamespace(string $app): string + { + return 'app\\middleware'; + } +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Model.php b/vendor/topthink/framework/src/think/console/command/make/Model.php new file mode 100644 index 0000000..acb37e7 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Model.php @@ -0,0 +1,36 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command\make; + +use think\console\command\Make; + +class Model extends Make +{ + protected $type = "Model"; + + protected function configure() + { + parent::configure(); + $this->setName('make:model') + ->setDescription('Create a new model class'); + } + + protected function getStub(): string + { + return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'model.stub'; + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\model'; + } +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Service.php b/vendor/topthink/framework/src/think/console/command/make/Service.php new file mode 100644 index 0000000..18bd54e --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Service.php @@ -0,0 +1,36 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command\make; + +use think\console\command\Make; + +class Service extends Make +{ + protected $type = "Service"; + + protected function configure() + { + parent::configure(); + $this->setName('make:service') + ->setDescription('Create a new Service class'); + } + + protected function getStub(): string + { + return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'service.stub'; + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\service'; + } +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Subscribe.php b/vendor/topthink/framework/src/think/console/command/make/Subscribe.php new file mode 100644 index 0000000..4203986 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Subscribe.php @@ -0,0 +1,35 @@ + +// +---------------------------------------------------------------------- +namespace think\console\command\make; + +use think\console\command\Make; + +class Subscribe extends Make +{ + protected $type = "Subscribe"; + + protected function configure() + { + parent::configure(); + $this->setName('make:subscribe') + ->setDescription('Create a new subscribe class'); + } + + protected function getStub(): string + { + return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'subscribe.stub'; + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\subscribe'; + } +} diff --git a/vendor/topthink/framework/src/think/console/command/make/Validate.php b/vendor/topthink/framework/src/think/console/command/make/Validate.php new file mode 100644 index 0000000..4926e20 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/Validate.php @@ -0,0 +1,39 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\command\make; + +use think\console\command\Make; + +class Validate extends Make +{ + protected $type = "Validate"; + + protected function configure() + { + parent::configure(); + $this->setName('make:validate') + ->setDescription('Create a validate class'); + } + + protected function getStub(): string + { + $stubPath = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR; + + return $stubPath . 'validate.stub'; + } + + protected function getNamespace(string $app): string + { + return parent::getNamespace($app) . '\\validate'; + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/make/stubs/command.stub b/vendor/topthink/framework/src/think/console/command/make/stubs/command.stub new file mode 100644 index 0000000..e9121cd --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/stubs/command.stub @@ -0,0 +1,26 @@ +setName('{%commandName%}') + ->setDescription('the {%commandName%} command'); + } + + protected function execute(Input $input, Output $output) + { + // 指令输出 + $output->writeln('{%commandName%}'); + } +} diff --git a/vendor/topthink/framework/src/think/console/command/make/stubs/controller.api.stub b/vendor/topthink/framework/src/think/console/command/make/stubs/controller.api.stub new file mode 100644 index 0000000..5d3383d --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/make/stubs/controller.api.stub @@ -0,0 +1,64 @@ + ['规则1','规则2'...] + * + * @var array + */ + protected $rule = []; + + /** + * 定义错误信息 + * 格式:'字段名.规则名' => '错误信息' + * + * @var array + */ + protected $message = []; +} diff --git a/vendor/topthink/framework/src/think/console/command/optimize/Route.php b/vendor/topthink/framework/src/think/console/command/optimize/Route.php new file mode 100644 index 0000000..bd4f79c --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/optimize/Route.php @@ -0,0 +1,67 @@ + +// +---------------------------------------------------------------------- +namespace think\console\command\optimize; + +use think\console\Command; +use think\console\Input; +use think\console\input\Argument; +use think\console\Output; +use think\event\RouteLoaded; + +class Route extends Command +{ + protected function configure() + { + $this->setName('optimize:route') + ->addArgument('dir', Argument::OPTIONAL, 'dir name .') + ->setDescription('Build app route cache.'); + } + + protected function execute(Input $input, Output $output) + { + $dir = $input->getArgument('dir') ?: ''; + + $path = $this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . ($dir ? $dir . DIRECTORY_SEPARATOR : ''); + + $filename = $path . 'route.php'; + if (is_file($filename)) { + unlink($filename); + } + + file_put_contents($filename, $this->buildRouteCache($dir)); + $output->writeln('Succeed!'); + } + + protected function buildRouteCache(string $dir = null): string + { + $this->app->route->clear(); + $this->app->route->lazy(false); + + // 路由检测 + $path = $this->app->getRootPath() . ($dir ? 'app' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR : '') . 'route' . DIRECTORY_SEPARATOR ; + + $files = is_dir($path) ? scandir($path) : []; + + foreach ($files as $file) { + if (strpos($file, '.php')) { + include $path . $file; + } + } + + //触发路由载入完成事件 + $this->app->event->trigger(RouteLoaded::class); + + $content = 'app->route->getName()) . '\');'; + return $content; + } + +} diff --git a/vendor/topthink/framework/src/think/console/command/optimize/Schema.php b/vendor/topthink/framework/src/think/console/command/optimize/Schema.php new file mode 100644 index 0000000..29f0bdb --- /dev/null +++ b/vendor/topthink/framework/src/think/console/command/optimize/Schema.php @@ -0,0 +1,116 @@ + +// +---------------------------------------------------------------------- +namespace think\console\command\optimize; + +use think\console\Command; +use think\console\Input; +use think\console\input\Argument; +use think\console\input\Option; +use think\console\Output; + +class Schema extends Command +{ + protected function configure() + { + $this->setName('optimize:schema') + ->addArgument('dir', Argument::OPTIONAL, 'dir name .') + ->addOption('db', null, Option::VALUE_REQUIRED, 'db name .') + ->addOption('table', null, Option::VALUE_REQUIRED, 'table name .') + ->setDescription('Build database schema cache.'); + } + + protected function execute(Input $input, Output $output) + { + $dir = $input->getArgument('dir') ?: ''; + + $schemaPath = $this->app->db->getConnection()->getConfig('schema_cache_path'); + + if (!is_dir($schemaPath)) { + mkdir($schemaPath, 0755, true); + } + + if ($input->hasOption('table')) { + $table = $input->getOption('table'); + if (false === strpos($table, '.')) { + $dbName = $this->app->db->getConnection()->getConfig('database'); + } + + $tables[] = $table; + } elseif ($input->hasOption('db')) { + $dbName = $input->getOption('db'); + $tables = $this->app->db->getConnection()->getTables($dbName); + } else { + if ($dir) { + $appPath = $this->app->getBasePath() . $dir . DIRECTORY_SEPARATOR; + $namespace = 'app\\' . $dir; + } else { + $appPath = $this->app->getBasePath(); + $namespace = 'app'; + } + + $path = $appPath . 'model'; + $list = is_dir($path) ? scandir($path) : []; + + foreach ($list as $file) { + if (0 === strpos($file, '.')) { + continue; + } + $class = '\\' . $namespace . '\\model\\' . pathinfo($file, PATHINFO_FILENAME); + $this->buildModelSchema($class); + } + + $output->writeln('Succeed!'); + return; + } + + $db = isset($dbName) ? $dbName . '.' : ''; + $this->buildDataBaseSchema($schemaPath, $tables, $db); + + $output->writeln('Succeed!'); + } + + protected function buildModelSchema(string $class): void + { + $reflect = new \ReflectionClass($class); + if (!$reflect->isAbstract() && $reflect->isSubclassOf('\think\Model')) { + /** @var \think\Model $model */ + $model = new $class; + + $table = $model->getTable(); + $dbName = $model->db()->getConnection()->getConfig('database'); + $path = $model->db()->getConnection()->getConfig('schema_cache_path'); + if (!is_dir($path)) { + mkdir($path, 0755, true); + } + $content = 'db()->getConnection()->getTableFieldsInfo($table); + $content .= var_export($info, true) . ';'; + + file_put_contents($path . $dbName . '.' . $table . '.php', $content); + } + } + + protected function buildDataBaseSchema(string $path, array $tables, string $db): void + { + if ('' == $db) { + $dbName = $this->app->db->getConnection()->getConfig('database') . '.'; + } else { + $dbName = $db; + } + + foreach ($tables as $table) { + $content = 'app->db->getConnection()->getTableFieldsInfo($db . $table); + $content .= var_export($info, true) . ';'; + file_put_contents($path . $dbName . $table . '.php', $content); + } + } +} diff --git a/vendor/topthink/framework/src/think/console/input/Argument.php b/vendor/topthink/framework/src/think/console/input/Argument.php new file mode 100644 index 0000000..4fa3e3c --- /dev/null +++ b/vendor/topthink/framework/src/think/console/input/Argument.php @@ -0,0 +1,115 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\input; + +class Argument +{ + + const REQUIRED = 1; + const OPTIONAL = 2; + const IS_ARRAY = 4; + + private $name; + private $mode; + private $default; + private $description; + + /** + * 构造方法 + * @param string $name 参数名 + * @param int $mode 参数类型: self::REQUIRED 或者 self::OPTIONAL + * @param string $description 描述 + * @param mixed $default 默认值 (仅 self::OPTIONAL 类型有效) + * @throws \InvalidArgumentException + */ + public function __construct(string $name, int $mode = null, string $description = '', $default = null) + { + if (null === $mode) { + $mode = self::OPTIONAL; + } elseif (!is_int($mode) || $mode > 7 || $mode < 1) { + throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode)); + } + + $this->name = $name; + $this->mode = $mode; + $this->description = $description; + + $this->setDefault($default); + } + + /** + * 获取参数名 + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * 是否必须 + * @return bool + */ + public function isRequired(): bool + { + return self::REQUIRED === (self::REQUIRED & $this->mode); + } + + /** + * 该参数是否接受数组 + * @return bool + */ + public function isArray(): bool + { + return self::IS_ARRAY === (self::IS_ARRAY & $this->mode); + } + + /** + * 设置默认值 + * @param mixed $default 默认值 + * @throws \LogicException + */ + public function setDefault($default = null): void + { + if (self::REQUIRED === $this->mode && null !== $default) { + throw new \LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); + } + + if ($this->isArray()) { + if (null === $default) { + $default = []; + } elseif (!is_array($default)) { + throw new \LogicException('A default value for an array argument must be an array.'); + } + } + + $this->default = $default; + } + + /** + * 获取默认值 + * @return mixed + */ + public function getDefault() + { + return $this->default; + } + + /** + * 获取描述 + * @return string + */ + public function getDescription(): string + { + return $this->description; + } +} diff --git a/vendor/topthink/framework/src/think/console/input/Definition.php b/vendor/topthink/framework/src/think/console/input/Definition.php new file mode 100644 index 0000000..ccf02a0 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/input/Definition.php @@ -0,0 +1,375 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\input; + +class Definition +{ + + /** + * @var Argument[] + */ + private $arguments; + + private $requiredCount; + private $hasAnArrayArgument = false; + private $hasOptional; + + /** + * @var Option[] + */ + private $options; + private $shortcuts; + + /** + * 构造方法 + * @param array $definition + * @api + */ + public function __construct(array $definition = []) + { + $this->setDefinition($definition); + } + + /** + * 设置指令的定义 + * @param array $definition 定义的数组 + */ + public function setDefinition(array $definition): void + { + $arguments = []; + $options = []; + foreach ($definition as $item) { + if ($item instanceof Option) { + $options[] = $item; + } else { + $arguments[] = $item; + } + } + + $this->setArguments($arguments); + $this->setOptions($options); + } + + /** + * 设置参数 + * @param Argument[] $arguments 参数数组 + */ + public function setArguments(array $arguments = []): void + { + $this->arguments = []; + $this->requiredCount = 0; + $this->hasOptional = false; + $this->hasAnArrayArgument = false; + $this->addArguments($arguments); + } + + /** + * 添加参数 + * @param Argument[] $arguments 参数数组 + * @api + */ + public function addArguments(array $arguments = []): void + { + if (null !== $arguments) { + foreach ($arguments as $argument) { + $this->addArgument($argument); + } + } + } + + /** + * 添加一个参数 + * @param Argument $argument 参数 + * @throws \LogicException + */ + public function addArgument(Argument $argument): void + { + if (isset($this->arguments[$argument->getName()])) { + throw new \LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName())); + } + + if ($this->hasAnArrayArgument) { + throw new \LogicException('Cannot add an argument after an array argument.'); + } + + if ($argument->isRequired() && $this->hasOptional) { + throw new \LogicException('Cannot add a required argument after an optional one.'); + } + + if ($argument->isArray()) { + $this->hasAnArrayArgument = true; + } + + if ($argument->isRequired()) { + ++$this->requiredCount; + } else { + $this->hasOptional = true; + } + + $this->arguments[$argument->getName()] = $argument; + } + + /** + * 根据名称或者位置获取参数 + * @param string|int $name 参数名或者位置 + * @return Argument 参数 + * @throws \InvalidArgumentException + */ + public function getArgument($name): Argument + { + if (!$this->hasArgument($name)) { + throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments; + + return $arguments[$name]; + } + + /** + * 根据名称或位置检查是否具有某个参数 + * @param string|int $name 参数名或者位置 + * @return bool + * @api + */ + public function hasArgument($name): bool + { + $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments; + + return isset($arguments[$name]); + } + + /** + * 获取所有的参数 + * @return Argument[] 参数数组 + */ + public function getArguments(): array + { + return $this->arguments; + } + + /** + * 获取参数数量 + * @return int + */ + public function getArgumentCount(): int + { + return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments); + } + + /** + * 获取必填的参数的数量 + * @return int + */ + public function getArgumentRequiredCount(): int + { + return $this->requiredCount; + } + + /** + * 获取参数默认值 + * @return array + */ + public function getArgumentDefaults(): array + { + $values = []; + foreach ($this->arguments as $argument) { + $values[$argument->getName()] = $argument->getDefault(); + } + + return $values; + } + + /** + * 设置选项 + * @param Option[] $options 选项数组 + */ + public function setOptions(array $options = []): void + { + $this->options = []; + $this->shortcuts = []; + $this->addOptions($options); + } + + /** + * 添加选项 + * @param Option[] $options 选项数组 + * @api + */ + public function addOptions(array $options = []): void + { + foreach ($options as $option) { + $this->addOption($option); + } + } + + /** + * 添加一个选项 + * @param Option $option 选项 + * @throws \LogicException + * @api + */ + public function addOption(Option $option): void + { + if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { + throw new \LogicException(sprintf('An option named "%s" already exists.', $option->getName())); + } + + if ($option->getShortcut()) { + foreach (explode('|', $option->getShortcut()) as $shortcut) { + if (isset($this->shortcuts[$shortcut]) + && !$option->equals($this->options[$this->shortcuts[$shortcut]]) + ) { + throw new \LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut)); + } + } + } + + $this->options[$option->getName()] = $option; + if ($option->getShortcut()) { + foreach (explode('|', $option->getShortcut()) as $shortcut) { + $this->shortcuts[$shortcut] = $option->getName(); + } + } + } + + /** + * 根据名称获取选项 + * @param string $name 选项名 + * @return Option + * @throws \InvalidArgumentException + * @api + */ + public function getOption(string $name): Option + { + if (!$this->hasOption($name)) { + throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name)); + } + + return $this->options[$name]; + } + + /** + * 根据名称检查是否有这个选项 + * @param string $name 选项名 + * @return bool + * @api + */ + public function hasOption(string $name): bool + { + return isset($this->options[$name]); + } + + /** + * 获取所有选项 + * @return Option[] + * @api + */ + public function getOptions(): array + { + return $this->options; + } + + /** + * 根据名称检查某个选项是否有短名称 + * @param string $name 短名称 + * @return bool + */ + public function hasShortcut(string $name): bool + { + return isset($this->shortcuts[$name]); + } + + /** + * 根据短名称获取选项 + * @param string $shortcut 短名称 + * @return Option + */ + public function getOptionForShortcut(string $shortcut): Option + { + return $this->getOption($this->shortcutToName($shortcut)); + } + + /** + * 获取所有选项的默认值 + * @return array + */ + public function getOptionDefaults(): array + { + $values = []; + foreach ($this->options as $option) { + $values[$option->getName()] = $option->getDefault(); + } + + return $values; + } + + /** + * 根据短名称获取选项名 + * @param string $shortcut 短名称 + * @return string + * @throws \InvalidArgumentException + */ + private function shortcutToName(string $shortcut): string + { + if (!isset($this->shortcuts[$shortcut])) { + throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut)); + } + + return $this->shortcuts[$shortcut]; + } + + /** + * 获取该指令的介绍 + * @param bool $short 是否简洁介绍 + * @return string + */ + public function getSynopsis(bool $short = false): string + { + $elements = []; + + if ($short && $this->getOptions()) { + $elements[] = '[options]'; + } elseif (!$short) { + foreach ($this->getOptions() as $option) { + $value = ''; + if ($option->acceptValue()) { + $value = sprintf(' %s%s%s', $option->isValueOptional() ? '[' : '', strtoupper($option->getName()), $option->isValueOptional() ? ']' : ''); + } + + $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : ''; + $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value); + } + } + + if (count($elements) && $this->getArguments()) { + $elements[] = '[--]'; + } + + foreach ($this->getArguments() as $argument) { + $element = '<' . $argument->getName() . '>'; + if (!$argument->isRequired()) { + $element = '[' . $element . ']'; + } elseif ($argument->isArray()) { + $element .= ' (' . $element . ')'; + } + + if ($argument->isArray()) { + $element .= '...'; + } + + $elements[] = $element; + } + + return implode(' ', $elements); + } +} diff --git a/vendor/topthink/framework/src/think/console/input/Option.php b/vendor/topthink/framework/src/think/console/input/Option.php new file mode 100644 index 0000000..e5707c9 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/input/Option.php @@ -0,0 +1,190 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\input; + +class Option +{ + + const VALUE_NONE = 1; + const VALUE_REQUIRED = 2; + const VALUE_OPTIONAL = 4; + const VALUE_IS_ARRAY = 8; + + private $name; + private $shortcut; + private $mode; + private $default; + private $description; + + /** + * 构造方法 + * @param string $name 选项名 + * @param string|array $shortcut 短名称,多个用|隔开或者使用数组 + * @param int $mode 选项类型(可选类型为 self::VALUE_*) + * @param string $description 描述 + * @param mixed $default 默认值 (类型为 self::VALUE_REQUIRED 或者 self::VALUE_NONE 的时候必须为null) + * @throws \InvalidArgumentException + */ + public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null) + { + if (0 === strpos($name, '--')) { + $name = substr($name, 2); + } + + if (empty($name)) { + throw new \InvalidArgumentException('An option name cannot be empty.'); + } + + if (empty($shortcut)) { + $shortcut = null; + } + + if (null !== $shortcut) { + if (is_array($shortcut)) { + $shortcut = implode('|', $shortcut); + } + $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-')); + $shortcuts = array_filter($shortcuts); + $shortcut = implode('|', $shortcuts); + + if (empty($shortcut)) { + throw new \InvalidArgumentException('An option shortcut cannot be empty.'); + } + } + + if (null === $mode) { + $mode = self::VALUE_NONE; + } elseif (!is_int($mode) || $mode > 15 || $mode < 1) { + throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode)); + } + + $this->name = $name; + $this->shortcut = $shortcut; + $this->mode = $mode; + $this->description = $description; + + if ($this->isArray() && !$this->acceptValue()) { + throw new \InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.'); + } + + $this->setDefault($default); + } + + /** + * 获取短名称 + * @return string + */ + public function getShortcut() + { + return $this->shortcut; + } + + /** + * 获取选项名 + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * 是否可以设置值 + * @return bool 类型不是 self::VALUE_NONE 的时候返回true,其他均返回false + */ + public function acceptValue() + { + return $this->isValueRequired() || $this->isValueOptional(); + } + + /** + * 是否必须 + * @return bool 类型是 self::VALUE_REQUIRED 的时候返回true,其他均返回false + */ + public function isValueRequired() + { + return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode); + } + + /** + * 是否可选 + * @return bool 类型是 self::VALUE_OPTIONAL 的时候返回true,其他均返回false + */ + public function isValueOptional() + { + return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode); + } + + /** + * 选项值是否接受数组 + * @return bool 类型是 self::VALUE_IS_ARRAY 的时候返回true,其他均返回false + */ + public function isArray() + { + return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); + } + + /** + * 设置默认值 + * @param mixed $default 默认值 + * @throws \LogicException + */ + public function setDefault($default = null) + { + if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { + throw new \LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); + } + + if ($this->isArray()) { + if (null === $default) { + $default = []; + } elseif (!is_array($default)) { + throw new \LogicException('A default value for an array option must be an array.'); + } + } + + $this->default = $this->acceptValue() ? $default : false; + } + + /** + * 获取默认值 + * @return mixed + */ + public function getDefault() + { + return $this->default; + } + + /** + * 获取描述文字 + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * 检查所给选项是否是当前这个 + * @param Option $option + * @return bool + */ + public function equals(Option $option) + { + return $option->getName() === $this->getName() + && $option->getShortcut() === $this->getShortcut() + && $option->getDefault() === $this->getDefault() + && $option->isArray() === $this->isArray() + && $option->isValueRequired() === $this->isValueRequired() + && $option->isValueOptional() === $this->isValueOptional(); + } +} diff --git a/vendor/topthink/framework/src/think/console/output/Ask.php b/vendor/topthink/framework/src/think/console/output/Ask.php new file mode 100644 index 0000000..56821c7 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/Ask.php @@ -0,0 +1,336 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output; + +use think\console\Input; +use think\console\Output; +use think\console\output\question\Choice; +use think\console\output\question\Confirmation; + +class Ask +{ + private static $stty; + + private static $shell; + + /** @var Input */ + protected $input; + + /** @var Output */ + protected $output; + + /** @var Question */ + protected $question; + + public function __construct(Input $input, Output $output, Question $question) + { + $this->input = $input; + $this->output = $output; + $this->question = $question; + } + + public function run() + { + if (!$this->input->isInteractive()) { + return $this->question->getDefault(); + } + + if (!$this->question->getValidator()) { + return $this->doAsk(); + } + + $that = $this; + + $interviewer = function () use ($that) { + return $that->doAsk(); + }; + + return $this->validateAttempts($interviewer); + } + + protected function doAsk() + { + $this->writePrompt(); + + $inputStream = STDIN; + $autocomplete = $this->question->getAutocompleterValues(); + + if (null === $autocomplete || !$this->hasSttyAvailable()) { + $ret = false; + if ($this->question->isHidden()) { + try { + $ret = trim($this->getHiddenResponse($inputStream)); + } catch (\RuntimeException $e) { + if (!$this->question->isHiddenFallback()) { + throw $e; + } + } + } + + if (false === $ret) { + $ret = fgets($inputStream, 4096); + if (false === $ret) { + throw new \RuntimeException('Aborted'); + } + $ret = trim($ret); + } + } else { + $ret = trim($this->autocomplete($inputStream)); + } + + $ret = strlen($ret) > 0 ? $ret : $this->question->getDefault(); + + if ($normalizer = $this->question->getNormalizer()) { + return $normalizer($ret); + } + + return $ret; + } + + private function autocomplete($inputStream) + { + $autocomplete = $this->question->getAutocompleterValues(); + $ret = ''; + + $i = 0; + $ofs = -1; + $matches = $autocomplete; + $numMatches = count($matches); + + $sttyMode = shell_exec('stty -g'); + + shell_exec('stty -icanon -echo'); + + while (!feof($inputStream)) { + $c = fread($inputStream, 1); + + if ("\177" === $c) { + if (0 === $numMatches && 0 !== $i) { + --$i; + $this->output->write("\033[1D"); + } + + if ($i === 0) { + $ofs = -1; + $matches = $autocomplete; + $numMatches = count($matches); + } else { + $numMatches = 0; + } + + $ret = substr($ret, 0, $i); + } elseif ("\033" === $c) { + $c .= fread($inputStream, 2); + + if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { + if ('A' === $c[2] && -1 === $ofs) { + $ofs = 0; + } + + if (0 === $numMatches) { + continue; + } + + $ofs += ('A' === $c[2]) ? -1 : 1; + $ofs = ($numMatches + $ofs) % $numMatches; + } + } elseif (ord($c) < 32) { + if ("\t" === $c || "\n" === $c) { + if ($numMatches > 0 && -1 !== $ofs) { + $ret = $matches[$ofs]; + $this->output->write(substr($ret, $i)); + $i = strlen($ret); + } + + if ("\n" === $c) { + $this->output->write($c); + break; + } + + $numMatches = 0; + } + + continue; + } else { + $this->output->write($c); + $ret .= $c; + ++$i; + + $numMatches = 0; + $ofs = 0; + + foreach ($autocomplete as $value) { + if (0 === strpos($value, $ret) && $i !== strlen($value)) { + $matches[$numMatches++] = $value; + } + } + } + + $this->output->write("\033[K"); + + if ($numMatches > 0 && -1 !== $ofs) { + $this->output->write("\0337"); + $this->output->highlight(substr($matches[$ofs], $i)); + $this->output->write("\0338"); + } + } + + shell_exec(sprintf('stty %s', $sttyMode)); + + return $ret; + } + + protected function getHiddenResponse($inputStream) + { + if ('\\' === DIRECTORY_SEPARATOR) { + $exe = __DIR__ . '/../bin/hiddeninput.exe'; + + $value = rtrim(shell_exec($exe)); + $this->output->writeln(''); + + return $value; + } + + if ($this->hasSttyAvailable()) { + $sttyMode = shell_exec('stty -g'); + + shell_exec('stty -echo'); + $value = fgets($inputStream, 4096); + shell_exec(sprintf('stty %s', $sttyMode)); + + if (false === $value) { + throw new \RuntimeException('Aborted'); + } + + $value = trim($value); + $this->output->writeln(''); + + return $value; + } + + if (false !== $shell = $this->getShell()) { + $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword'; + $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); + $value = rtrim(shell_exec($command)); + $this->output->writeln(''); + + return $value; + } + + throw new \RuntimeException('Unable to hide the response.'); + } + + protected function validateAttempts($interviewer) + { + /** @var \Exception $error */ + $error = null; + $attempts = $this->question->getMaxAttempts(); + while (null === $attempts || $attempts--) { + if (null !== $error) { + $this->output->error($error->getMessage()); + } + + try { + return call_user_func($this->question->getValidator(), $interviewer()); + } catch (\Exception $error) { + } + } + + throw $error; + } + + /** + * 显示问题的提示信息 + */ + protected function writePrompt() + { + $text = $this->question->getQuestion(); + $default = $this->question->getDefault(); + + switch (true) { + case null === $default: + $text = sprintf(' %s:', $text); + + break; + + case $this->question instanceof Confirmation: + $text = sprintf(' %s (yes/no) [%s]:', $text, $default ? 'yes' : 'no'); + + break; + + case $this->question instanceof Choice && $this->question->isMultiselect(): + $choices = $this->question->getChoices(); + $default = explode(',', $default); + + foreach ($default as $key => $value) { + $default[$key] = $choices[trim($value)]; + } + + $text = sprintf(' %s [%s]:', $text, implode(', ', $default)); + + break; + + case $this->question instanceof Choice: + $choices = $this->question->getChoices(); + $text = sprintf(' %s [%s]:', $text, $choices[$default]); + + break; + + default: + $text = sprintf(' %s [%s]:', $text, $default); + } + + $this->output->writeln($text); + + if ($this->question instanceof Choice) { + $width = max(array_map('strlen', array_keys($this->question->getChoices()))); + + foreach ($this->question->getChoices() as $key => $value) { + $this->output->writeln(sprintf(" [%-${width}s] %s", $key, $value)); + } + } + + $this->output->write(' > '); + } + + private function getShell() + { + if (null !== self::$shell) { + return self::$shell; + } + + self::$shell = false; + + if (file_exists('/usr/bin/env')) { + $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; + foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) { + if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { + self::$shell = $sh; + break; + } + } + } + + return self::$shell; + } + + private function hasSttyAvailable() + { + if (null !== self::$stty) { + return self::$stty; + } + + exec('stty 2>&1', $output, $exitcode); + + return self::$stty = $exitcode === 0; + } +} diff --git a/vendor/topthink/framework/src/think/console/output/Descriptor.php b/vendor/topthink/framework/src/think/console/output/Descriptor.php new file mode 100644 index 0000000..8582b59 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/Descriptor.php @@ -0,0 +1,319 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output; + +use think\Console; +use think\console\Command; +use think\console\input\Argument as InputArgument; +use think\console\input\Definition as InputDefinition; +use think\console\input\Option as InputOption; +use think\console\Output; +use think\console\output\descriptor\Console as ConsoleDescription; + +class Descriptor +{ + + /** + * @var Output + */ + protected $output; + + /** + * {@inheritdoc} + */ + public function describe(Output $output, $object, array $options = []) + { + $this->output = $output; + + switch (true) { + case $object instanceof InputArgument: + $this->describeInputArgument($object, $options); + break; + case $object instanceof InputOption: + $this->describeInputOption($object, $options); + break; + case $object instanceof InputDefinition: + $this->describeInputDefinition($object, $options); + break; + case $object instanceof Command: + $this->describeCommand($object, $options); + break; + case $object instanceof Console: + $this->describeConsole($object, $options); + break; + default: + throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object))); + } + } + + /** + * 输出内容 + * @param string $content + * @param bool $decorated + */ + protected function write($content, $decorated = false) + { + $this->output->write($content, false, $decorated ? Output::OUTPUT_NORMAL : Output::OUTPUT_RAW); + } + + /** + * 描述参数 + * @param InputArgument $argument + * @param array $options + * @return string|mixed + */ + protected function describeInputArgument(InputArgument $argument, array $options = []) + { + if (null !== $argument->getDefault() + && (!is_array($argument->getDefault()) + || count($argument->getDefault())) + ) { + $default = sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault())); + } else { + $default = ''; + } + + $totalWidth = $options['total_width'] ?? strlen($argument->getName()); + $spacingWidth = $totalWidth - strlen($argument->getName()) + 2; + + $this->writeText(sprintf(" %s%s%s%s", $argument->getName(), str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + + + 2 spaces + preg_replace('/\s*\R\s*/', PHP_EOL . str_repeat(' ', $totalWidth + 17), $argument->getDescription()), $default), $options); + } + + /** + * 描述选项 + * @param InputOption $option + * @param array $options + * @return string|mixed + */ + protected function describeInputOption(InputOption $option, array $options = []) + { + if ($option->acceptValue() && null !== $option->getDefault() + && (!is_array($option->getDefault()) + || count($option->getDefault())) + ) { + $default = sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault())); + } else { + $default = ''; + } + + $value = ''; + if ($option->acceptValue()) { + $value = '=' . strtoupper($option->getName()); + + if ($option->isValueOptional()) { + $value = '[' . $value . ']'; + } + } + + $totalWidth = $options['total_width'] ?? $this->calculateTotalWidthForOptions([$option]); + $synopsis = sprintf('%s%s', $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : ' ', sprintf('--%s%s', $option->getName(), $value)); + + $spacingWidth = $totalWidth - strlen($synopsis) + 2; + + $this->writeText(sprintf(" %s%s%s%s%s", $synopsis, str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + + + 2 spaces + preg_replace('/\s*\R\s*/', "\n" . str_repeat(' ', $totalWidth + 17), $option->getDescription()), $default, $option->isArray() ? ' (multiple values allowed)' : ''), $options); + } + + /** + * 描述输入 + * @param InputDefinition $definition + * @param array $options + * @return string|mixed + */ + protected function describeInputDefinition(InputDefinition $definition, array $options = []) + { + $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions()); + foreach ($definition->getArguments() as $argument) { + $totalWidth = max($totalWidth, strlen($argument->getName())); + } + + if ($definition->getArguments()) { + $this->writeText('Arguments:', $options); + $this->writeText("\n"); + foreach ($definition->getArguments() as $argument) { + $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth])); + $this->writeText("\n"); + } + } + + if ($definition->getArguments() && $definition->getOptions()) { + $this->writeText("\n"); + } + + if ($definition->getOptions()) { + $laterOptions = []; + + $this->writeText('Options:', $options); + foreach ($definition->getOptions() as $option) { + if (strlen($option->getShortcut()) > 1) { + $laterOptions[] = $option; + continue; + } + $this->writeText("\n"); + $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); + } + foreach ($laterOptions as $option) { + $this->writeText("\n"); + $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); + } + } + } + + /** + * 描述指令 + * @param Command $command + * @param array $options + * @return string|mixed + */ + protected function describeCommand(Command $command, array $options = []) + { + $command->getSynopsis(true); + $command->getSynopsis(false); + $command->mergeConsoleDefinition(false); + + $this->writeText('Usage:', $options); + foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) { + $this->writeText("\n"); + $this->writeText(' ' . $usage, $options); + } + $this->writeText("\n"); + + $definition = $command->getNativeDefinition(); + if ($definition->getOptions() || $definition->getArguments()) { + $this->writeText("\n"); + $this->describeInputDefinition($definition, $options); + $this->writeText("\n"); + } + + if ($help = $command->getProcessedHelp()) { + $this->writeText("\n"); + $this->writeText('Help:', $options); + $this->writeText("\n"); + $this->writeText(' ' . str_replace("\n", "\n ", $help), $options); + $this->writeText("\n"); + } + } + + /** + * 描述控制台 + * @param Console $console + * @param array $options + * @return string|mixed + */ + protected function describeConsole(Console $console, array $options = []) + { + $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; + $description = new ConsoleDescription($console, $describedNamespace); + + if (isset($options['raw_text']) && $options['raw_text']) { + $width = $this->getColumnWidth($description->getCommands()); + + foreach ($description->getCommands() as $command) { + $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options); + $this->writeText("\n"); + } + } else { + if ('' != $help = $console->getHelp()) { + $this->writeText("$help\n\n", $options); + } + + $this->writeText("Usage:\n", $options); + $this->writeText(" command [options] [arguments]\n\n", $options); + + $this->describeInputDefinition(new InputDefinition($console->getDefinition()->getOptions()), $options); + + $this->writeText("\n"); + $this->writeText("\n"); + + $width = $this->getColumnWidth($description->getCommands()); + + if ($describedNamespace) { + $this->writeText(sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options); + } else { + $this->writeText('Available commands:', $options); + } + + // add commands by namespace + foreach ($description->getNamespaces() as $namespace) { + if (!$describedNamespace && ConsoleDescription::GLOBAL_NAMESPACE !== $namespace['id']) { + $this->writeText("\n"); + $this->writeText(' ' . $namespace['id'] . '', $options); + } + + foreach ($namespace['commands'] as $name) { + $this->writeText("\n"); + $spacingWidth = $width - strlen($name); + $this->writeText(sprintf(" %s%s%s", $name, str_repeat(' ', $spacingWidth), $description->getCommand($name) + ->getDescription()), $options); + } + } + + $this->writeText("\n"); + } + } + + /** + * {@inheritdoc} + */ + private function writeText($content, array $options = []) + { + $this->write(isset($options['raw_text']) + && $options['raw_text'] ? strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : true); + } + + /** + * 格式化 + * @param mixed $default + * @return string + */ + private function formatDefaultValue($default) + { + return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + /** + * @param Command[] $commands + * @return int + */ + private function getColumnWidth(array $commands) + { + $width = 0; + foreach ($commands as $command) { + $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width; + } + + return $width + 2; + } + + /** + * @param InputOption[] $options + * @return int + */ + private function calculateTotalWidthForOptions($options) + { + $totalWidth = 0; + foreach ($options as $option) { + $nameLength = 4 + strlen($option->getName()) + 2; // - + shortcut + , + whitespace + name + -- + + if ($option->acceptValue()) { + $valueLength = 1 + strlen($option->getName()); // = + value + $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ] + + $nameLength += $valueLength; + } + $totalWidth = max($totalWidth, $nameLength); + } + + return $totalWidth; + } +} diff --git a/vendor/topthink/framework/src/think/console/output/Formatter.php b/vendor/topthink/framework/src/think/console/output/Formatter.php new file mode 100644 index 0000000..1b97ca3 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/Formatter.php @@ -0,0 +1,198 @@ + +// +---------------------------------------------------------------------- +namespace think\console\output; + +use think\console\output\formatter\Stack as StyleStack; +use think\console\output\formatter\Style; + +class Formatter +{ + + private $decorated = false; + private $styles = []; + private $styleStack; + + /** + * 转义 + * @param string $text + * @return string + */ + public static function escape($text) + { + return preg_replace('/([^\\\\]?)setStyle('error', new Style('white', 'red')); + $this->setStyle('info', new Style('green')); + $this->setStyle('comment', new Style('yellow')); + $this->setStyle('question', new Style('black', 'cyan')); + $this->setStyle('highlight', new Style('red')); + $this->setStyle('warning', new Style('black', 'yellow')); + + $this->styleStack = new StyleStack(); + } + + /** + * 设置外观标识 + * @param bool $decorated 是否美化文字 + */ + public function setDecorated($decorated) + { + $this->decorated = (bool) $decorated; + } + + /** + * 获取外观标识 + * @return bool + */ + public function isDecorated() + { + return $this->decorated; + } + + /** + * 添加一个新样式 + * @param string $name 样式名 + * @param Style $style 样式实例 + */ + public function setStyle($name, Style $style) + { + $this->styles[strtolower($name)] = $style; + } + + /** + * 是否有这个样式 + * @param string $name + * @return bool + */ + public function hasStyle($name) + { + return isset($this->styles[strtolower($name)]); + } + + /** + * 获取样式 + * @param string $name + * @return Style + * @throws \InvalidArgumentException + */ + public function getStyle($name) + { + if (!$this->hasStyle($name)) { + throw new \InvalidArgumentException(sprintf('Undefined style: %s', $name)); + } + + return $this->styles[strtolower($name)]; + } + + /** + * 使用所给的样式格式化文字 + * @param string $message 文字 + * @return string + */ + public function format($message) + { + $offset = 0; + $output = ''; + $tagRegex = '[a-z][a-z0-9_=;-]*'; + preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#isx", $message, $matches, PREG_OFFSET_CAPTURE); + foreach ($matches[0] as $i => $match) { + $pos = $match[1]; + $text = $match[0]; + + if (0 != $pos && '\\' == $message[$pos - 1]) { + continue; + } + + $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset)); + $offset = $pos + strlen($text); + + if ($open = '/' != $text[1]) { + $tag = $matches[1][$i][0]; + } else { + $tag = $matches[3][$i][0] ?? ''; + } + + if (!$open && !$tag) { + // + $this->styleStack->pop(); + } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) { + $output .= $this->applyCurrentStyle($text); + } elseif ($open) { + $this->styleStack->push($style); + } else { + $this->styleStack->pop($style); + } + } + + $output .= $this->applyCurrentStyle(substr($message, $offset)); + + return str_replace('\\<', '<', $output); + } + + /** + * @return StyleStack + */ + public function getStyleStack() + { + return $this->styleStack; + } + + /** + * 根据字符串创建新的样式实例 + * @param string $string + * @return Style|bool + */ + private function createStyleFromString($string) + { + if (isset($this->styles[$string])) { + return $this->styles[$string]; + } + + if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) { + return false; + } + + $style = new Style(); + foreach ($matches as $match) { + array_shift($match); + + if ('fg' == $match[0]) { + $style->setForeground($match[1]); + } elseif ('bg' == $match[0]) { + $style->setBackground($match[1]); + } else { + try { + $style->setOption($match[1]); + } catch (\InvalidArgumentException $e) { + return false; + } + } + } + + return $style; + } + + /** + * 从堆栈应用样式到文字 + * @param string $text 文字 + * @return string + */ + private function applyCurrentStyle($text) + { + return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text; + } +} diff --git a/vendor/topthink/framework/src/think/console/output/Question.php b/vendor/topthink/framework/src/think/console/output/Question.php new file mode 100644 index 0000000..03975f2 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/Question.php @@ -0,0 +1,211 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output; + +class Question +{ + + private $question; + private $attempts; + private $hidden = false; + private $hiddenFallback = true; + private $autocompleterValues; + private $validator; + private $default; + private $normalizer; + + /** + * 构造方法 + * @param string $question 问题 + * @param mixed $default 默认答案 + */ + public function __construct($question, $default = null) + { + $this->question = $question; + $this->default = $default; + } + + /** + * 获取问题 + * @return string + */ + public function getQuestion() + { + return $this->question; + } + + /** + * 获取默认答案 + * @return mixed + */ + public function getDefault() + { + return $this->default; + } + + /** + * 是否隐藏答案 + * @return bool + */ + public function isHidden() + { + return $this->hidden; + } + + /** + * 隐藏答案 + * @param bool $hidden + * @return Question + */ + public function setHidden($hidden) + { + if ($this->autocompleterValues) { + throw new \LogicException('A hidden question cannot use the autocompleter.'); + } + + $this->hidden = (bool) $hidden; + + return $this; + } + + /** + * 不能被隐藏是否撤销 + * @return bool + */ + public function isHiddenFallback() + { + return $this->hiddenFallback; + } + + /** + * 设置不能被隐藏的时候的操作 + * @param bool $fallback + * @return Question + */ + public function setHiddenFallback($fallback) + { + $this->hiddenFallback = (bool) $fallback; + + return $this; + } + + /** + * 获取自动完成 + * @return null|array|\Traversable + */ + public function getAutocompleterValues() + { + return $this->autocompleterValues; + } + + /** + * 设置自动完成的值 + * @param null|array|\Traversable $values + * @return Question + * @throws \InvalidArgumentException + * @throws \LogicException + */ + public function setAutocompleterValues($values) + { + if (is_array($values) && $this->isAssoc($values)) { + $values = array_merge(array_keys($values), array_values($values)); + } + + if (null !== $values && !is_array($values)) { + if (!$values instanceof \Traversable || $values instanceof \Countable) { + throw new \InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.'); + } + } + + if ($this->hidden) { + throw new \LogicException('A hidden question cannot use the autocompleter.'); + } + + $this->autocompleterValues = $values; + + return $this; + } + + /** + * 设置答案的验证器 + * @param null|callable $validator + * @return Question The current instance + */ + public function setValidator($validator) + { + $this->validator = $validator; + + return $this; + } + + /** + * 获取验证器 + * @return null|callable + */ + public function getValidator() + { + return $this->validator; + } + + /** + * 设置最大重试次数 + * @param null|int $attempts + * @return Question + * @throws \InvalidArgumentException + */ + public function setMaxAttempts($attempts) + { + if (null !== $attempts && $attempts < 1) { + throw new \InvalidArgumentException('Maximum number of attempts must be a positive value.'); + } + + $this->attempts = $attempts; + + return $this; + } + + /** + * 获取最大重试次数 + * @return null|int + */ + public function getMaxAttempts() + { + return $this->attempts; + } + + /** + * 设置响应的回调 + * @param string|\Closure $normalizer + * @return Question + */ + public function setNormalizer($normalizer) + { + $this->normalizer = $normalizer; + + return $this; + } + + /** + * 获取响应回调 + * The normalizer can ba a callable (a string), a closure or a class implementing __invoke. + * @return string|\Closure + */ + public function getNormalizer() + { + return $this->normalizer; + } + + protected function isAssoc($array) + { + return (bool) count(array_filter(array_keys($array), 'is_string')); + } +} diff --git a/vendor/topthink/framework/src/think/console/output/descriptor/Console.php b/vendor/topthink/framework/src/think/console/output/descriptor/Console.php new file mode 100644 index 0000000..ff9f464 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/descriptor/Console.php @@ -0,0 +1,153 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\descriptor; + +use think\Console as ThinkConsole; +use think\console\Command; + +class Console +{ + + const GLOBAL_NAMESPACE = '_global'; + + /** + * @var ThinkConsole + */ + private $console; + + /** + * @var null|string + */ + private $namespace; + + /** + * @var array + */ + private $namespaces; + + /** + * @var Command[] + */ + private $commands; + + /** + * @var Command[] + */ + private $aliases; + + /** + * 构造方法 + * @param ThinkConsole $console + * @param string|null $namespace + */ + public function __construct(ThinkConsole $console, $namespace = null) + { + $this->console = $console; + $this->namespace = $namespace; + } + + /** + * @return array + */ + public function getNamespaces(): array + { + if (null === $this->namespaces) { + $this->inspectConsole(); + } + + return $this->namespaces; + } + + /** + * @return Command[] + */ + public function getCommands(): array + { + if (null === $this->commands) { + $this->inspectConsole(); + } + + return $this->commands; + } + + /** + * @param string $name + * @return Command + * @throws \InvalidArgumentException + */ + public function getCommand(string $name): Command + { + if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) { + throw new \InvalidArgumentException(sprintf('Command %s does not exist.', $name)); + } + + return $this->commands[$name] ?? $this->aliases[$name]; + } + + private function inspectConsole(): void + { + $this->commands = []; + $this->namespaces = []; + + $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null); + foreach ($this->sortCommands($all) as $namespace => $commands) { + $names = []; + + /** @var Command $command */ + foreach ($commands as $name => $command) { + if (is_string($command)) { + $command = new $command(); + } + + if (!$command->getName()) { + continue; + } + + if ($command->getName() === $name) { + $this->commands[$name] = $command; + } else { + $this->aliases[$name] = $command; + } + + $names[] = $name; + } + + $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names]; + } + } + + /** + * @param array $commands + * @return array + */ + private function sortCommands(array $commands): array + { + $namespacedCommands = []; + foreach ($commands as $name => $command) { + $key = $this->console->extractNamespace($name, 1); + if (!$key) { + $key = self::GLOBAL_NAMESPACE; + } + + $namespacedCommands[$key][$name] = $command; + } + ksort($namespacedCommands); + + foreach ($namespacedCommands as &$commandsSet) { + ksort($commandsSet); + } + // unset reference to keep scope clear + unset($commandsSet); + + return $namespacedCommands; + } +} diff --git a/vendor/topthink/framework/src/think/console/output/driver/Buffer.php b/vendor/topthink/framework/src/think/console/output/driver/Buffer.php new file mode 100644 index 0000000..576f31a --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/driver/Buffer.php @@ -0,0 +1,52 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\driver; + +use think\console\Output; + +class Buffer +{ + /** + * @var string + */ + private $buffer = ''; + + public function __construct(Output $output) + { + // do nothing + } + + public function fetch() + { + $content = $this->buffer; + $this->buffer = ''; + return $content; + } + + public function write($messages, bool $newline = false, int $options = 0) + { + $messages = (array) $messages; + + foreach ($messages as $message) { + $this->buffer .= $message; + } + if ($newline) { + $this->buffer .= "\n"; + } + } + + public function renderException(\Throwable $e) + { + // do nothing + } + +} diff --git a/vendor/topthink/framework/src/think/console/output/driver/Console.php b/vendor/topthink/framework/src/think/console/output/driver/Console.php new file mode 100644 index 0000000..31bdf1f --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/driver/Console.php @@ -0,0 +1,368 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\driver; + +use think\console\Output; +use think\console\output\Formatter; + +class Console +{ + + /** @var Resource */ + private $stdout; + + /** @var Formatter */ + private $formatter; + + private $terminalDimensions; + + /** @var Output */ + private $output; + + public function __construct(Output $output) + { + $this->output = $output; + $this->formatter = new Formatter(); + $this->stdout = $this->openOutputStream(); + $decorated = $this->hasColorSupport($this->stdout); + $this->formatter->setDecorated($decorated); + } + + public function setDecorated($decorated) + { + $this->formatter->setDecorated($decorated); + } + + public function write($messages, bool $newline = false, int $type = 0, $stream = null) + { + if (Output::VERBOSITY_QUIET === $this->output->getVerbosity()) { + return; + } + + $messages = (array) $messages; + + foreach ($messages as $message) { + switch ($type) { + case Output::OUTPUT_NORMAL: + $message = $this->formatter->format($message); + break; + case Output::OUTPUT_RAW: + break; + case Output::OUTPUT_PLAIN: + $message = strip_tags($this->formatter->format($message)); + break; + default: + throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type)); + } + + $this->doWrite($message, $newline, $stream); + } + } + + public function renderException(\Throwable $e) + { + $stderr = $this->openErrorStream(); + $decorated = $this->hasColorSupport($stderr); + $this->formatter->setDecorated($decorated); + + do { + $title = sprintf(' [%s] ', get_class($e)); + + $len = $this->stringWidth($title); + + $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX; + + if (defined('HHVM_VERSION') && $width > 1 << 31) { + $width = 1 << 31; + } + $lines = []; + foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) { + foreach ($this->splitStringByWidth($line, $width - 4) as $line) { + + $lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $line)) + 4; + $lines[] = [$line, $lineLength]; + + $len = max($lineLength, $len); + } + } + + $messages = ['', '']; + $messages[] = $emptyLine = sprintf('%s', str_repeat(' ', $len)); + $messages[] = sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))); + foreach ($lines as $line) { + $messages[] = sprintf(' %s %s', $line[0], str_repeat(' ', $len - $line[1])); + } + $messages[] = $emptyLine; + $messages[] = ''; + $messages[] = ''; + + $this->write($messages, true, Output::OUTPUT_NORMAL, $stderr); + + if (Output::VERBOSITY_VERBOSE <= $this->output->getVerbosity()) { + $this->write('Exception trace:', true, Output::OUTPUT_NORMAL, $stderr); + + // exception related properties + $trace = $e->getTrace(); + array_unshift($trace, [ + 'function' => '', + 'file' => $e->getFile() !== null ? $e->getFile() : 'n/a', + 'line' => $e->getLine() !== null ? $e->getLine() : 'n/a', + 'args' => [], + ]); + + for ($i = 0, $count = count($trace); $i < $count; ++$i) { + $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : ''; + $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : ''; + $function = $trace[$i]['function']; + $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a'; + $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; + + $this->write(sprintf(' %s%s%s() at %s:%s', $class, $type, $function, $file, $line), true, Output::OUTPUT_NORMAL, $stderr); + } + + $this->write('', true, Output::OUTPUT_NORMAL, $stderr); + $this->write('', true, Output::OUTPUT_NORMAL, $stderr); + } + } while ($e = $e->getPrevious()); + + } + + /** + * 获取终端宽度 + * @return int|null + */ + protected function getTerminalWidth() + { + $dimensions = $this->getTerminalDimensions(); + + return $dimensions[0]; + } + + /** + * 获取终端高度 + * @return int|null + */ + protected function getTerminalHeight() + { + $dimensions = $this->getTerminalDimensions(); + + return $dimensions[1]; + } + + /** + * 获取当前终端的尺寸 + * @return array + */ + public function getTerminalDimensions(): array + { + if ($this->terminalDimensions) { + return $this->terminalDimensions; + } + + if ('\\' === DIRECTORY_SEPARATOR) { + if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) { + return [(int) $matches[1], (int) $matches[2]]; + } + if (preg_match('/^(\d+)x(\d+)$/', $this->getMode(), $matches)) { + return [(int) $matches[1], (int) $matches[2]]; + } + } + + if ($sttyString = $this->getSttyColumns()) { + if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { + return [(int) $matches[2], (int) $matches[1]]; + } + if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) { + return [(int) $matches[2], (int) $matches[1]]; + } + } + + return [null, null]; + } + + /** + * 获取stty列数 + * @return string + */ + private function getSttyColumns() + { + if (!function_exists('proc_open')) { + return; + } + + $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; + $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); + if (is_resource($process)) { + $info = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + + return $info; + } + return; + } + + /** + * 获取终端模式 + * @return string x 或 null + */ + private function getMode() + { + if (!function_exists('proc_open')) { + return; + } + + $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; + $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); + if (is_resource($process)) { + $info = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + + if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { + return $matches[2] . 'x' . $matches[1]; + } + } + return; + } + + private function stringWidth(string $string): int + { + if (!function_exists('mb_strwidth')) { + return strlen($string); + } + + if (false === $encoding = mb_detect_encoding($string)) { + return strlen($string); + } + + return mb_strwidth($string, $encoding); + } + + private function splitStringByWidth(string $string, int $width): array + { + if (!function_exists('mb_strwidth')) { + return str_split($string, $width); + } + + if (false === $encoding = mb_detect_encoding($string)) { + return str_split($string, $width); + } + + $utf8String = mb_convert_encoding($string, 'utf8', $encoding); + $lines = []; + $line = ''; + foreach (preg_split('//u', $utf8String) as $char) { + if (mb_strwidth($line . $char, 'utf8') <= $width) { + $line .= $char; + continue; + } + $lines[] = str_pad($line, $width); + $line = $char; + } + if (strlen($line)) { + $lines[] = count($lines) ? str_pad($line, $width) : $line; + } + + mb_convert_variables($encoding, 'utf8', $lines); + + return $lines; + } + + private function isRunningOS400(): bool + { + $checks = [ + function_exists('php_uname') ? php_uname('s') : '', + getenv('OSTYPE'), + PHP_OS, + ]; + return false !== stripos(implode(';', $checks), 'OS400'); + } + + /** + * 当前环境是否支持写入控制台输出到stdout. + * + * @return bool + */ + protected function hasStdoutSupport(): bool + { + return false === $this->isRunningOS400(); + } + + /** + * 当前环境是否支持写入控制台输出到stderr. + * + * @return bool + */ + protected function hasStderrSupport(): bool + { + return false === $this->isRunningOS400(); + } + + /** + * @return resource + */ + private function openOutputStream() + { + if (!$this->hasStdoutSupport()) { + return fopen('php://output', 'w'); + } + return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w'); + } + + /** + * @return resource + */ + private function openErrorStream() + { + return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w'); + } + + /** + * 将消息写入到输出。 + * @param string $message 消息 + * @param bool $newline 是否另起一行 + * @param null $stream + */ + protected function doWrite($message, $newline, $stream = null) + { + if (null === $stream) { + $stream = $this->stdout; + } + if (false === @fwrite($stream, $message . ($newline ? PHP_EOL : ''))) { + throw new \RuntimeException('Unable to write output.'); + } + + fflush($stream); + } + + /** + * 是否支持着色 + * @param $stream + * @return bool + */ + protected function hasColorSupport($stream): bool + { + if (DIRECTORY_SEPARATOR === '\\') { + return + '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR . '.' . PHP_WINDOWS_VERSION_MINOR . '.' . PHP_WINDOWS_VERSION_BUILD + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + } + + return function_exists('posix_isatty') && @posix_isatty($stream); + } + +} diff --git a/vendor/topthink/framework/src/think/console/output/driver/Nothing.php b/vendor/topthink/framework/src/think/console/output/driver/Nothing.php new file mode 100644 index 0000000..a7cc49e --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/driver/Nothing.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\driver; + +use think\console\Output; + +class Nothing +{ + + public function __construct(Output $output) + { + // do nothing + } + + public function write($messages, bool $newline = false, int $options = 0) + { + // do nothing + } + + public function renderException(\Throwable $e) + { + // do nothing + } +} diff --git a/vendor/topthink/framework/src/think/console/output/formatter/Stack.php b/vendor/topthink/framework/src/think/console/output/formatter/Stack.php new file mode 100644 index 0000000..5366259 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/formatter/Stack.php @@ -0,0 +1,116 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\formatter; + +class Stack +{ + + /** + * @var Style[] + */ + private $styles; + + /** + * @var Style + */ + private $emptyStyle; + + /** + * 构造方法 + * @param Style|null $emptyStyle + */ + public function __construct(Style $emptyStyle = null) + { + $this->emptyStyle = $emptyStyle ?: new Style(); + $this->reset(); + } + + /** + * 重置堆栈 + */ + public function reset(): void + { + $this->styles = []; + } + + /** + * 推一个样式进入堆栈 + * @param Style $style + */ + public function push(Style $style): void + { + $this->styles[] = $style; + } + + /** + * 从堆栈中弹出一个样式 + * @param Style|null $style + * @return Style + * @throws \InvalidArgumentException + */ + public function pop(Style $style = null): Style + { + if (empty($this->styles)) { + return $this->emptyStyle; + } + + if (null === $style) { + return array_pop($this->styles); + } + + /** + * @var int $index + * @var Style $stackedStyle + */ + foreach (array_reverse($this->styles, true) as $index => $stackedStyle) { + if ($style->apply('') === $stackedStyle->apply('')) { + $this->styles = array_slice($this->styles, 0, $index); + + return $stackedStyle; + } + } + + throw new \InvalidArgumentException('Incorrectly nested style tag found.'); + } + + /** + * 计算堆栈的当前样式。 + * @return Style + */ + public function getCurrent(): Style + { + if (empty($this->styles)) { + return $this->emptyStyle; + } + + return $this->styles[count($this->styles) - 1]; + } + + /** + * @param Style $emptyStyle + * @return Stack + */ + public function setEmptyStyle(Style $emptyStyle) + { + $this->emptyStyle = $emptyStyle; + + return $this; + } + + /** + * @return Style + */ + public function getEmptyStyle(): Style + { + return $this->emptyStyle; + } +} diff --git a/vendor/topthink/framework/src/think/console/output/formatter/Style.php b/vendor/topthink/framework/src/think/console/output/formatter/Style.php new file mode 100644 index 0000000..2aae768 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/formatter/Style.php @@ -0,0 +1,190 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\formatter; + +class Style +{ + protected static $availableForegroundColors = [ + 'black' => ['set' => 30, 'unset' => 39], + 'red' => ['set' => 31, 'unset' => 39], + 'green' => ['set' => 32, 'unset' => 39], + 'yellow' => ['set' => 33, 'unset' => 39], + 'blue' => ['set' => 34, 'unset' => 39], + 'magenta' => ['set' => 35, 'unset' => 39], + 'cyan' => ['set' => 36, 'unset' => 39], + 'white' => ['set' => 37, 'unset' => 39], + ]; + + protected static $availableBackgroundColors = [ + 'black' => ['set' => 40, 'unset' => 49], + 'red' => ['set' => 41, 'unset' => 49], + 'green' => ['set' => 42, 'unset' => 49], + 'yellow' => ['set' => 43, 'unset' => 49], + 'blue' => ['set' => 44, 'unset' => 49], + 'magenta' => ['set' => 45, 'unset' => 49], + 'cyan' => ['set' => 46, 'unset' => 49], + 'white' => ['set' => 47, 'unset' => 49], + ]; + + protected static $availableOptions = [ + 'bold' => ['set' => 1, 'unset' => 22], + 'underscore' => ['set' => 4, 'unset' => 24], + 'blink' => ['set' => 5, 'unset' => 25], + 'reverse' => ['set' => 7, 'unset' => 27], + 'conceal' => ['set' => 8, 'unset' => 28], + ]; + + private $foreground; + private $background; + private $options = []; + + /** + * 初始化输出的样式 + * @param string|null $foreground 字体颜色 + * @param string|null $background 背景色 + * @param array $options 格式 + * @api + */ + public function __construct($foreground = null, $background = null, array $options = []) + { + if (null !== $foreground) { + $this->setForeground($foreground); + } + if (null !== $background) { + $this->setBackground($background); + } + if (count($options)) { + $this->setOptions($options); + } + } + + /** + * 设置字体颜色 + * @param string|null $color 颜色名 + * @throws \InvalidArgumentException + * @api + */ + public function setForeground($color = null) + { + if (null === $color) { + $this->foreground = null; + + return; + } + + if (!isset(static::$availableForegroundColors[$color])) { + throw new \InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors)))); + } + + $this->foreground = static::$availableForegroundColors[$color]; + } + + /** + * 设置背景色 + * @param string|null $color 颜色名 + * @throws \InvalidArgumentException + * @api + */ + public function setBackground($color = null) + { + if (null === $color) { + $this->background = null; + + return; + } + + if (!isset(static::$availableBackgroundColors[$color])) { + throw new \InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors)))); + } + + $this->background = static::$availableBackgroundColors[$color]; + } + + /** + * 设置字体格式 + * @param string $option 格式名 + * @throws \InvalidArgumentException When the option name isn't defined + * @api + */ + public function setOption(string $option): void + { + if (!isset(static::$availableOptions[$option])) { + throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); + } + + if (!in_array(static::$availableOptions[$option], $this->options)) { + $this->options[] = static::$availableOptions[$option]; + } + } + + /** + * 重置字体格式 + * @param string $option 格式名 + * @throws \InvalidArgumentException + */ + public function unsetOption(string $option): void + { + if (!isset(static::$availableOptions[$option])) { + throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); + } + + $pos = array_search(static::$availableOptions[$option], $this->options); + if (false !== $pos) { + unset($this->options[$pos]); + } + } + + /** + * 批量设置字体格式 + * @param array $options + */ + public function setOptions(array $options) + { + $this->options = []; + + foreach ($options as $option) { + $this->setOption($option); + } + } + + /** + * 应用样式到文字 + * @param string $text 文字 + * @return string + */ + public function apply(string $text): string + { + $setCodes = []; + $unsetCodes = []; + + if (null !== $this->foreground) { + $setCodes[] = $this->foreground['set']; + $unsetCodes[] = $this->foreground['unset']; + } + if (null !== $this->background) { + $setCodes[] = $this->background['set']; + $unsetCodes[] = $this->background['unset']; + } + if (count($this->options)) { + foreach ($this->options as $option) { + $setCodes[] = $option['set']; + $unsetCodes[] = $option['unset']; + } + } + + if (0 === count($setCodes)) { + return $text; + } + + return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes)); + } +} diff --git a/vendor/topthink/framework/src/think/console/output/question/Choice.php b/vendor/topthink/framework/src/think/console/output/question/Choice.php new file mode 100644 index 0000000..1da1750 --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/question/Choice.php @@ -0,0 +1,163 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\question; + +use think\console\output\Question; + +class Choice extends Question +{ + + private $choices; + private $multiselect = false; + private $prompt = ' > '; + private $errorMessage = 'Value "%s" is invalid'; + + /** + * 构造方法 + * @param string $question 问题 + * @param array $choices 选项 + * @param mixed $default 默认答案 + */ + public function __construct($question, array $choices, $default = null) + { + parent::__construct($question, $default); + + $this->choices = $choices; + $this->setValidator($this->getDefaultValidator()); + $this->setAutocompleterValues($choices); + } + + /** + * 可选项 + * @return array + */ + public function getChoices(): array + { + return $this->choices; + } + + /** + * 设置可否多选 + * @param bool $multiselect + * @return self + */ + public function setMultiselect(bool $multiselect) + { + $this->multiselect = $multiselect; + $this->setValidator($this->getDefaultValidator()); + + return $this; + } + + public function isMultiselect(): bool + { + return $this->multiselect; + } + + /** + * 获取提示 + * @return string + */ + public function getPrompt(): string + { + return $this->prompt; + } + + /** + * 设置提示 + * @param string $prompt + * @return self + */ + public function setPrompt(string $prompt) + { + $this->prompt = $prompt; + + return $this; + } + + /** + * 设置错误提示信息 + * @param string $errorMessage + * @return self + */ + public function setErrorMessage(string $errorMessage) + { + $this->errorMessage = $errorMessage; + $this->setValidator($this->getDefaultValidator()); + + return $this; + } + + /** + * 获取默认的验证方法 + * @return callable + */ + private function getDefaultValidator() + { + $choices = $this->choices; + $errorMessage = $this->errorMessage; + $multiselect = $this->multiselect; + $isAssoc = $this->isAssoc($choices); + + return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) { + // Collapse all spaces. + $selectedChoices = str_replace(' ', '', $selected); + + if ($multiselect) { + // Check for a separated comma values + if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) { + throw new \InvalidArgumentException(sprintf($errorMessage, $selected)); + } + $selectedChoices = explode(',', $selectedChoices); + } else { + $selectedChoices = [$selected]; + } + + $multiselectChoices = []; + foreach ($selectedChoices as $value) { + $results = []; + foreach ($choices as $key => $choice) { + if ($choice === $value) { + $results[] = $key; + } + } + + if (count($results) > 1) { + throw new \InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results))); + } + + $result = array_search($value, $choices); + + if (!$isAssoc) { + if (!empty($result)) { + $result = $choices[$result]; + } elseif (isset($choices[$value])) { + $result = $choices[$value]; + } + } elseif (empty($result) && array_key_exists($value, $choices)) { + $result = $value; + } + + if (false === $result) { + throw new \InvalidArgumentException(sprintf($errorMessage, $value)); + } + array_push($multiselectChoices, $result); + } + + if ($multiselect) { + return $multiselectChoices; + } + + return current($multiselectChoices); + }; + } +} diff --git a/vendor/topthink/framework/src/think/console/output/question/Confirmation.php b/vendor/topthink/framework/src/think/console/output/question/Confirmation.php new file mode 100644 index 0000000..bf71b5d --- /dev/null +++ b/vendor/topthink/framework/src/think/console/output/question/Confirmation.php @@ -0,0 +1,57 @@ + +// +---------------------------------------------------------------------- + +namespace think\console\output\question; + +use think\console\output\Question; + +class Confirmation extends Question +{ + + private $trueAnswerRegex; + + /** + * 构造方法 + * @param string $question 问题 + * @param bool $default 默认答案 + * @param string $trueAnswerRegex 验证正则 + */ + public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i') + { + parent::__construct($question, (bool) $default); + + $this->trueAnswerRegex = $trueAnswerRegex; + $this->setNormalizer($this->getDefaultNormalizer()); + } + + /** + * 获取默认的答案回调 + * @return callable + */ + private function getDefaultNormalizer() + { + $default = $this->getDefault(); + $regex = $this->trueAnswerRegex; + + return function ($answer) use ($default, $regex) { + if (is_bool($answer)) { + return $answer; + } + + $answerIsTrue = (bool) preg_match($regex, $answer); + if (false === $default) { + return $answer && $answerIsTrue; + } + + return !$answer || $answerIsTrue; + }; + } +} diff --git a/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php b/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php new file mode 100644 index 0000000..e953f66 --- /dev/null +++ b/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php @@ -0,0 +1,88 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\contract; + +/** + * 缓存驱动接口 + */ +interface CacheHandlerInterface +{ + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name); + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = null); + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null); + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc(string $name, int $step = 1); + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec(string $name, int $step = 1); + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function delete($name); + + /** + * 清除缓存 + * @access public + * @return bool + */ + public function clear(); + + /** + * 删除缓存标签 + * @access public + * @param array $keys 缓存标识列表 + * @return void + */ + public function clearTag(array $keys); + +} diff --git a/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php b/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php new file mode 100644 index 0000000..896ac29 --- /dev/null +++ b/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php @@ -0,0 +1,28 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\contract; + +/** + * 日志驱动接口 + */ +interface LogHandlerInterface +{ + /** + * 日志写入接口 + * @access public + * @param array $log 日志信息 + * @return bool + */ + public function save(array $log): bool; + +} diff --git a/vendor/topthink/framework/src/think/contract/ModelRelationInterface.php b/vendor/topthink/framework/src/think/contract/ModelRelationInterface.php new file mode 100644 index 0000000..49cfa75 --- /dev/null +++ b/vendor/topthink/framework/src/think/contract/ModelRelationInterface.php @@ -0,0 +1,99 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\contract; + +use Closure; +use think\Collection; +use think\db\Query; +use think\Model; + +/** + * 模型关联接口 + */ +interface ModelRelationInterface +{ + /** + * 延迟获取关联数据 + * @access public + * @param array $subRelation 子关联 + * @param Closure $closure 闭包查询条件 + * @return Collection + */ + public function getRelation(array $subRelation = [], Closure $closure = null): Collection; + + /** + * 预载入关联查询 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param array $subRelation 子关联名 + * @param Closure $closure 闭包条件 + * @return void + */ + public function eagerlyResultSet(array &$resultSet, string $relation, array $subRelation, Closure $closure = null): void; + + /** + * 预载入关联查询 + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param array $subRelation 子关联名 + * @param Closure $closure 闭包条件 + * @return void + */ + public function eagerlyResult(Model $result, string $relation, array $subRelation = [], Closure $closure = null): void; + + /** + * 关联统计 + * @access public + * @param Model $result 模型对象 + * @param Closure $closure 闭包 + * @param string $aggregate 聚合查询方法 + * @param string $field 字段 + * @param string $name 统计字段别名 + * @return integer + */ + public function relationCount(Model $result, Closure $closure, string $aggregate = 'count', string $field = '*', string &$name = null); + + /** + * 创建关联统计子查询 + * @access public + * @param Closure $closure 闭包 + * @param string $aggregate 聚合查询方法 + * @param string $field 字段 + * @param string $name 统计字段别名 + * @return string + */ + public function getRelationCountQuery(Closure $closure = null, string $aggregate = 'count', string $field = '*', string &$name = null): string; + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function has(string $operator = '>=', int $count = 1, string $id = '*', string $joinType = 'INNER'): Query; + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @param mixed $fields 字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function hasWhere($where = [], $fields = null, string $joinType = ''): Query; +} diff --git a/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php b/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php new file mode 100644 index 0000000..caed322 --- /dev/null +++ b/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php @@ -0,0 +1,23 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\contract; + +/** + * Session驱动接口 + */ +interface SessionHandlerInterface +{ + public function read(string $sessionId): string; + public function delete(string $sessionId): bool; + public function write(string $sessionId, string $data): bool; +} diff --git a/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php b/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php new file mode 100644 index 0000000..f01820d --- /dev/null +++ b/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php @@ -0,0 +1,61 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\contract; + +/** + * 视图驱动接口 + */ +interface TemplateHandlerInterface +{ + /** + * 检测是否存在模板文件 + * @access public + * @param string $template 模板文件或者模板规则 + * @return bool + */ + public function exists(string $template): bool; + + /** + * 渲染模板文件 + * @access public + * @param string $template 模板文件 + * @param array $data 模板变量 + * @return void + */ + public function fetch(string $template, array $data = []): void; + + /** + * 渲染模板内容 + * @access public + * @param string $content 模板内容 + * @param array $data 模板变量 + * @return void + */ + public function display(string $content, array $data = []): void; + + /** + * 配置模板引擎 + * @access private + * @param array $config 参数 + * @return void + */ + public function config(array $config): void; + + /** + * 获取模板引擎配置 + * @access public + * @param string $name 参数名 + * @return void + */ + public function getConfig(string $name); +} diff --git a/vendor/topthink/framework/src/think/event/AppInit.php b/vendor/topthink/framework/src/think/event/AppInit.php new file mode 100644 index 0000000..83d75e7 --- /dev/null +++ b/vendor/topthink/framework/src/think/event/AppInit.php @@ -0,0 +1,19 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\event; + +/** + * AppInit事件类 + */ +class AppInit +{} diff --git a/vendor/topthink/framework/src/think/event/HttpEnd.php b/vendor/topthink/framework/src/think/event/HttpEnd.php new file mode 100644 index 0000000..5296ef1 --- /dev/null +++ b/vendor/topthink/framework/src/think/event/HttpEnd.php @@ -0,0 +1,19 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\event; + +/** + * HttpEnd事件类 + */ +class HttpEnd +{} diff --git a/vendor/topthink/framework/src/think/event/HttpRun.php b/vendor/topthink/framework/src/think/event/HttpRun.php new file mode 100644 index 0000000..a9cd7c3 --- /dev/null +++ b/vendor/topthink/framework/src/think/event/HttpRun.php @@ -0,0 +1,19 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\event; + +/** + * HttpRun事件类 + */ +class HttpRun +{} diff --git a/vendor/topthink/framework/src/think/event/LogWrite.php b/vendor/topthink/framework/src/think/event/LogWrite.php new file mode 100644 index 0000000..470e119 --- /dev/null +++ b/vendor/topthink/framework/src/think/event/LogWrite.php @@ -0,0 +1,31 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\event; + +/** + * LogWrite事件类 + */ +class LogWrite +{ + /** @var string */ + public $channel; + + /** @var array */ + public $log; + + public function __construct($channel, $log) + { + $this->channel = $channel; + $this->log = $log; + } +} diff --git a/vendor/topthink/framework/src/think/event/RouteLoaded.php b/vendor/topthink/framework/src/think/event/RouteLoaded.php new file mode 100644 index 0000000..eee1f3e --- /dev/null +++ b/vendor/topthink/framework/src/think/event/RouteLoaded.php @@ -0,0 +1,21 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\event; + +/** + * 路由加载完成事件 + */ +class RouteLoaded +{ + +} diff --git a/vendor/topthink/framework/src/think/exception/ClassNotFoundException.php b/vendor/topthink/framework/src/think/exception/ClassNotFoundException.php new file mode 100644 index 0000000..2fa1f58 --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/ClassNotFoundException.php @@ -0,0 +1,39 @@ + +// +---------------------------------------------------------------------- + +namespace think\exception; + +use Psr\Container\NotFoundExceptionInterface; +use RuntimeException; +use Throwable; + +class ClassNotFoundException extends RuntimeException implements NotFoundExceptionInterface +{ + protected $class; + + public function __construct(string $message, string $class = '', Throwable $previous = null) + { + $this->message = $message; + $this->class = $class; + + parent::__construct($message, 0, $previous); + } + + /** + * 获取类名 + * @access public + * @return string + */ + public function getClass() + { + return $this->class; + } +} diff --git a/vendor/topthink/framework/src/think/exception/ErrorException.php b/vendor/topthink/framework/src/think/exception/ErrorException.php new file mode 100644 index 0000000..54de0fe --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/ErrorException.php @@ -0,0 +1,57 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\exception; + +use think\Exception; + +/** + * ThinkPHP错误异常 + * 主要用于封装 set_error_handler 和 register_shutdown_function 得到的错误 + * 除开从 think\Exception 继承的功能 + * 其他和PHP系统\ErrorException功能基本一样 + */ +class ErrorException extends Exception +{ + /** + * 用于保存错误级别 + * @var integer + */ + protected $severity; + + /** + * 错误异常构造函数 + * @access public + * @param integer $severity 错误级别 + * @param string $message 错误详细信息 + * @param string $file 出错文件路径 + * @param integer $line 出错行号 + */ + public function __construct(int $severity, string $message, string $file, int $line) + { + $this->severity = $severity; + $this->message = $message; + $this->file = $file; + $this->line = $line; + $this->code = 0; + } + + /** + * 获取错误级别 + * @access public + * @return integer 错误级别 + */ + final public function getSeverity() + { + return $this->severity; + } +} diff --git a/vendor/topthink/framework/src/think/exception/FileException.php b/vendor/topthink/framework/src/think/exception/FileException.php new file mode 100644 index 0000000..2254472 --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/FileException.php @@ -0,0 +1,17 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\exception; + +class FileException extends \RuntimeException +{ +} diff --git a/vendor/topthink/framework/src/think/exception/FuncNotFoundException.php b/vendor/topthink/framework/src/think/exception/FuncNotFoundException.php new file mode 100644 index 0000000..ee2bcad --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/FuncNotFoundException.php @@ -0,0 +1,30 @@ +message = $message; + $this->func = $func; + + parent::__construct($message, 0, $previous); + } + + /** + * 获取方法名 + * @access public + * @return string + */ + public function getFunc() + { + return $this->func; + } +} diff --git a/vendor/topthink/framework/src/think/exception/Handle.php b/vendor/topthink/framework/src/think/exception/Handle.php new file mode 100644 index 0000000..9f92054 --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/Handle.php @@ -0,0 +1,334 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\exception; + +use Exception; +use think\App; +use think\console\Output; +use think\db\exception\DataNotFoundException; +use think\db\exception\ModelNotFoundException; +use think\Request; +use think\Response; +use Throwable; + +/** + * 系统异常处理类 + */ +class Handle +{ + /** @var App */ + protected $app; + + protected $ignoreReport = [ + HttpException::class, + HttpResponseException::class, + ModelNotFoundException::class, + DataNotFoundException::class, + ValidateException::class, + ]; + + protected $isJson = false; + + public function __construct(App $app) + { + $this->app = $app; + } + + /** + * Report or log an exception. + * + * @access public + * @param Throwable $exception + * @return void + */ + public function report(Throwable $exception): void + { + if (!$this->isIgnoreReport($exception)) { + // 收集异常数据 + if ($this->app->isDebug()) { + $data = [ + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'message' => $this->getMessage($exception), + 'code' => $this->getCode($exception), + ]; + $log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]"; + } else { + $data = [ + 'code' => $this->getCode($exception), + 'message' => $this->getMessage($exception), + ]; + $log = "[{$data['code']}]{$data['message']}"; + } + + if ($this->app->config->get('log.record_trace')) { + $log .= PHP_EOL . $exception->getTraceAsString(); + } + + try { + $this->app->log->record($log, 'error'); + } catch (Exception $e){} + } + } + + protected function isIgnoreReport(Throwable $exception): bool + { + foreach ($this->ignoreReport as $class) { + if ($exception instanceof $class) { + return true; + } + } + + return false; + } + + /** + * Render an exception into an HTTP response. + * + * @access public + * @param Request $request + * @param Throwable $e + * @return Response + */ + public function render($request, Throwable $e): Response + { + $this->isJson = $request->isJson(); + if ($e instanceof HttpResponseException) { + return $e->getResponse(); + } elseif ($e instanceof HttpException) { + return $this->renderHttpException($e); + } else { + return $this->convertExceptionToResponse($e); + } + } + + /** + * @access public + * @param Output $output + * @param Throwable $e + */ + public function renderForConsole(Output $output, Throwable $e): void + { + if ($this->app->isDebug()) { + $output->setVerbosity(Output::VERBOSITY_DEBUG); + } + + $output->renderException($e); + } + + /** + * @access protected + * @param HttpException $e + * @return Response + */ + protected function renderHttpException(HttpException $e): Response + { + $status = $e->getStatusCode(); + $template = $this->app->config->get('app.http_exception_template'); + + if (!$this->app->isDebug() && !empty($template[$status])) { + return Response::create($template[$status], 'view', $status)->assign(['e' => $e]); + } else { + return $this->convertExceptionToResponse($e); + } + } + + /** + * 收集异常数据 + * @param Throwable $exception + * @return array + */ + protected function convertExceptionToArray(Throwable $exception): array + { + if ($this->app->isDebug()) { + // 调试模式,获取详细的错误信息 + $traces = []; + $nextException = $exception; + do { + $traces[] = [ + 'name' => get_class($nextException), + 'file' => $nextException->getFile(), + 'line' => $nextException->getLine(), + 'code' => $this->getCode($nextException), + 'message' => $this->getMessage($nextException), + 'trace' => $nextException->getTrace(), + 'source' => $this->getSourceCode($nextException), + ]; + } while ($nextException = $nextException->getPrevious()); + $data = [ + 'code' => $this->getCode($exception), + 'message' => $this->getMessage($exception), + 'traces' => $traces, + 'datas' => $this->getExtendData($exception), + 'tables' => [ + 'GET Data' => $this->app->request->get(), + 'POST Data' => $this->app->request->post(), + 'Files' => $this->app->request->file(), + 'Cookies' => $this->app->request->cookie(), + 'Session' => $this->app->session->all(), + 'Server/Request Data' => $this->app->request->server(), + 'Environment Variables' => $this->app->request->env(), + 'ThinkPHP Constants' => $this->getConst(), + ], + ]; + } else { + // 部署模式仅显示 Code 和 Message + $data = [ + 'code' => $this->getCode($exception), + 'message' => $this->getMessage($exception), + ]; + + if (!$this->app->config->get('app.show_error_msg')) { + // 不显示详细错误信息 + $data['message'] = $this->app->config->get('app.error_message'); + } + } + + return $data; + } + + /** + * @access protected + * @param Throwable $exception + * @return Response + */ + protected function convertExceptionToResponse(Throwable $exception): Response + { + if (!$this->isJson) { + $response = Response::create($this->renderExceptionContent($exception)); + } else { + $response = Response::create($this->convertExceptionToArray($exception), 'json'); + } + + if ($exception instanceof HttpException) { + $statusCode = $exception->getStatusCode(); + $response->header($exception->getHeaders()); + } + + return $response->code($statusCode ?? 500); + } + + protected function renderExceptionContent(Throwable $exception): string + { + ob_start(); + $data = $this->convertExceptionToArray($exception); + extract($data); + include $this->app->config->get('app.exception_tmpl') ?: __DIR__ . '/../../tpl/think_exception.tpl'; + + return ob_get_clean(); + } + + /** + * 获取错误编码 + * ErrorException则使用错误级别作为错误编码 + * @access protected + * @param Throwable $exception + * @return integer 错误编码 + */ + protected function getCode(Throwable $exception) + { + $code = $exception->getCode(); + + if (!$code && $exception instanceof ErrorException) { + $code = $exception->getSeverity(); + } + + return $code; + } + + /** + * 获取错误信息 + * ErrorException则使用错误级别作为错误编码 + * @access protected + * @param Throwable $exception + * @return string 错误信息 + */ + protected function getMessage(Throwable $exception): string + { + $message = $exception->getMessage(); + + if ($this->app->runningInConsole()) { + return $message; + } + + $lang = $this->app->lang; + + if (strpos($message, ':')) { + $name = strstr($message, ':', true); + $message = $lang->has($name) ? $lang->get($name) . strstr($message, ':') : $message; + } elseif (strpos($message, ',')) { + $name = strstr($message, ',', true); + $message = $lang->has($name) ? $lang->get($name) . ':' . substr(strstr($message, ','), 1) : $message; + } elseif ($lang->has($message)) { + $message = $lang->get($message); + } + + return $message; + } + + /** + * 获取出错文件内容 + * 获取错误的前9行和后9行 + * @access protected + * @param Throwable $exception + * @return array 错误文件内容 + */ + protected function getSourceCode(Throwable $exception): array + { + // 读取前9行和后9行 + $line = $exception->getLine(); + $first = ($line - 9 > 0) ? $line - 9 : 1; + + try { + $contents = file($exception->getFile()) ?: []; + $source = [ + 'first' => $first, + 'source' => array_slice($contents, $first - 1, 19), + ]; + } catch (Exception $e) { + $source = []; + } + + return $source; + } + + /** + * 获取异常扩展信息 + * 用于非调试模式html返回类型显示 + * @access protected + * @param Throwable $exception + * @return array 异常类定义的扩展数据 + */ + protected function getExtendData(Throwable $exception): array + { + $data = []; + + if ($exception instanceof \think\Exception) { + $data = $exception->getData(); + } + + return $data; + } + + /** + * 获取常量列表 + * @access protected + * @return array 常量列表 + */ + protected function getConst(): array + { + $const = get_defined_constants(true); + + return $const['user'] ?? []; + } +} diff --git a/vendor/topthink/framework/src/think/exception/HttpException.php b/vendor/topthink/framework/src/think/exception/HttpException.php new file mode 100644 index 0000000..74fabfc --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/HttpException.php @@ -0,0 +1,42 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\exception; + +use Exception; + +/** + * HTTP异常 + */ +class HttpException extends \RuntimeException +{ + private $statusCode; + private $headers; + + public function __construct(int $statusCode, string $message = '', Exception $previous = null, array $headers = [], $code = 0) + { + $this->statusCode = $statusCode; + $this->headers = $headers; + + parent::__construct($message, $code, $previous); + } + + public function getStatusCode() + { + return $this->statusCode; + } + + public function getHeaders() + { + return $this->headers; + } +} diff --git a/vendor/topthink/framework/src/think/exception/HttpResponseException.php b/vendor/topthink/framework/src/think/exception/HttpResponseException.php new file mode 100644 index 0000000..759254c --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/HttpResponseException.php @@ -0,0 +1,37 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\exception; + +use think\Response; + +/** + * HTTP响应异常 + */ +class HttpResponseException extends \RuntimeException +{ + /** + * @var Response + */ + protected $response; + + public function __construct(Response $response) + { + $this->response = $response; + } + + public function getResponse() + { + return $this->response; + } + +} diff --git a/vendor/topthink/framework/src/think/exception/InvalidArgumentException.php b/vendor/topthink/framework/src/think/exception/InvalidArgumentException.php new file mode 100644 index 0000000..d317278 --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/InvalidArgumentException.php @@ -0,0 +1,22 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); +namespace think\exception; + +use Psr\Cache\InvalidArgumentException as Psr6CacheInvalidArgumentInterface; +use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInvalidArgumentInterface; + +/** + * 非法数据异常 + */ +class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInvalidArgumentInterface, SimpleCacheInvalidArgumentInterface +{ +} diff --git a/vendor/topthink/framework/src/think/exception/RouteNotFoundException.php b/vendor/topthink/framework/src/think/exception/RouteNotFoundException.php new file mode 100644 index 0000000..f50dff6 --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/RouteNotFoundException.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\exception; + +/** + * 路由未定义异常 + */ +class RouteNotFoundException extends HttpException +{ + + public function __construct() + { + parent::__construct(404, 'Route Not Found'); + } + +} diff --git a/vendor/topthink/framework/src/think/exception/ValidateException.php b/vendor/topthink/framework/src/think/exception/ValidateException.php new file mode 100644 index 0000000..cc79e19 --- /dev/null +++ b/vendor/topthink/framework/src/think/exception/ValidateException.php @@ -0,0 +1,37 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\exception; + +/** + * 数据验证异常 + */ +class ValidateException extends \RuntimeException +{ + protected $error; + + public function __construct($error) + { + $this->error = $error; + $this->message = is_array($error) ? implode(PHP_EOL, $error) : $error; + } + + /** + * 获取验证错误信息 + * @access public + * @return array|string + */ + public function getError() + { + return $this->error; + } +} diff --git a/vendor/topthink/framework/src/think/facade/App.php b/vendor/topthink/framework/src/think/facade/App.php new file mode 100644 index 0000000..4f64d96 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/App.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\App + * @package think\facade + * @mixin \think\App + */ +class App extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'app'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Cache.php b/vendor/topthink/framework/src/think/facade/Cache.php new file mode 100644 index 0000000..62391b7 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Cache.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Cache + * @package think\facade + * @mixin \think\Cache + */ +class Cache extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'cache'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Config.php b/vendor/topthink/framework/src/think/facade/Config.php new file mode 100644 index 0000000..93916e4 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Config.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Config + * @package think\facade + * @mixin \think\Config + */ +class Config extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'config'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Console.php b/vendor/topthink/framework/src/think/facade/Console.php new file mode 100644 index 0000000..f3f9239 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Console.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * Class Console + * @package think\facade + * @mixin \think\Console + */ +class Console extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'console'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Cookie.php b/vendor/topthink/framework/src/think/facade/Cookie.php new file mode 100644 index 0000000..98aa6c2 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Cookie.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Cookie + * @package think\facade + * @mixin \think\Cookie + */ +class Cookie extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'cookie'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Env.php b/vendor/topthink/framework/src/think/facade/Env.php new file mode 100644 index 0000000..5452e90 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Env.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Env + * @package think\facade + * @mixin \think\Env + */ +class Env extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'env'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Event.php b/vendor/topthink/framework/src/think/facade/Event.php new file mode 100644 index 0000000..0934452 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Event.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Event + * @package think\facade + * @mixin \think\Event + */ +class Event extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'event'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Filesystem.php b/vendor/topthink/framework/src/think/facade/Filesystem.php new file mode 100644 index 0000000..6fe4d5a --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Filesystem.php @@ -0,0 +1,28 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * Class Filesystem + * @package think\facade + * @mixin \think\Filesystem + */ +class Filesystem extends Facade +{ + protected static function getFacadeClass() + { + return 'filesystem'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Lang.php b/vendor/topthink/framework/src/think/facade/Lang.php new file mode 100644 index 0000000..1085c15 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Lang.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Lang + * @package think\facade + * @mixin \think\Lang + */ +class Lang extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'lang'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Log.php b/vendor/topthink/framework/src/think/facade/Log.php new file mode 100644 index 0000000..e92a5dc --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Log.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Log + * @package think\facade + * @mixin \think\Log + */ +class Log extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'log'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Middleware.php b/vendor/topthink/framework/src/think/facade/Middleware.php new file mode 100644 index 0000000..8a9cc36 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Middleware.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Middleware + * @package think\facade + * @mixin \think\Middleware + */ +class Middleware extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'middleware'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Request.php b/vendor/topthink/framework/src/think/facade/Request.php new file mode 100644 index 0000000..8bf5fc2 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Request.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Request + * @package think\facade + * @mixin \think\Request + */ +class Request extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'request'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Route.php b/vendor/topthink/framework/src/think/facade/Route.php new file mode 100644 index 0000000..5fd5e40 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Route.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Route + * @package think\facade + * @mixin \think\Route + */ +class Route extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'route'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Session.php b/vendor/topthink/framework/src/think/facade/Session.php new file mode 100644 index 0000000..4bcb6e8 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Session.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Session + * @package think\facade + * @mixin \think\Session + */ +class Session extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'session'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/Validate.php b/vendor/topthink/framework/src/think/facade/Validate.php new file mode 100644 index 0000000..0d6a34e --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/Validate.php @@ -0,0 +1,39 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\Validate + * @package think\facade + * @mixin \think\Validate + */ +class Validate extends Facade +{ + /** + * 始终创建新的对象实例 + * @var bool + */ + protected static $alwaysNewInstance = true; + + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'validate'; + } +} diff --git a/vendor/topthink/framework/src/think/facade/View.php b/vendor/topthink/framework/src/think/facade/View.php new file mode 100644 index 0000000..0fecb15 --- /dev/null +++ b/vendor/topthink/framework/src/think/facade/View.php @@ -0,0 +1,33 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\facade; + +use think\Facade; + +/** + * @see \think\View + * @package think\facade + * @mixin \think\View + */ +class View extends Facade +{ + /** + * 获取当前Facade对应类名(或者已经绑定的容器对象标识) + * @access protected + * @return string + */ + protected static function getFacadeClass() + { + return 'view'; + } +} diff --git a/vendor/topthink/framework/src/think/file/UploadedFile.php b/vendor/topthink/framework/src/think/file/UploadedFile.php new file mode 100644 index 0000000..7810eac --- /dev/null +++ b/vendor/topthink/framework/src/think/file/UploadedFile.php @@ -0,0 +1,143 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\file; + +use think\exception\FileException; +use think\File; + +class UploadedFile extends File +{ + + private $test = false; + private $originalName; + private $mimeType; + private $error; + + public function __construct(string $path, string $originalName, string $mimeType = null, int $error = null, bool $test = false) + { + $this->originalName = $originalName; + $this->mimeType = $mimeType ?: 'application/octet-stream'; + $this->test = $test; + $this->error = $error ?: UPLOAD_ERR_OK; + + parent::__construct($path, UPLOAD_ERR_OK === $this->error); + } + + public function isValid(): bool + { + $isOk = UPLOAD_ERR_OK === $this->error; + + return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname()); + } + + /** + * 上传文件 + * @access public + * @param string $directory 保存路径 + * @param string|null $name 保存的文件名 + * @return File + */ + public function move(string $directory, string $name = null): File + { + if ($this->isValid()) { + if ($this->test) { + return parent::move($directory, $name); + } + + $target = $this->getTargetFile($directory, $name); + + set_error_handler(function ($type, $msg) use (&$error) { + $error = $msg; + }); + + $moved = move_uploaded_file($this->getPathname(), $target); + restore_error_handler(); + if (!$moved) { + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error))); + } + + @chmod($target, 0666 & ~umask()); + + return $target; + } + + throw new FileException($this->getErrorMessage()); + } + + /** + * 获取错误信息 + * @access public + * @return string + */ + protected function getErrorMessage(): string + { + switch ($this->error) { + case 1: + case 2: + $message = 'upload File size exceeds the maximum value'; + break; + case 3: + $message = 'only the portion of file is uploaded'; + break; + case 4: + $message = 'no file to uploaded'; + break; + case 6: + $message = 'upload temp dir not found'; + break; + case 7: + $message = 'file write error'; + break; + default: + $message = 'unknown upload error'; + } + + return $message; + } + + /** + * 获取上传文件类型信息 + * @return string + */ + public function getOriginalMime(): string + { + return $this->mimeType; + } + + /** + * 上传文件名 + * @return string + */ + public function getOriginalName(): string + { + return $this->originalName; + } + + /** + * 获取上传文件扩展名 + * @return string + */ + public function getOriginalExtension(): string + { + return pathinfo($this->originalName, PATHINFO_EXTENSION); + } + + /** + * 获取文件扩展名 + * @return string + */ + public function extension(): string + { + return $this->getOriginalExtension(); + } +} diff --git a/vendor/topthink/framework/src/think/filesystem/CacheStore.php b/vendor/topthink/framework/src/think/filesystem/CacheStore.php new file mode 100644 index 0000000..46659ba --- /dev/null +++ b/vendor/topthink/framework/src/think/filesystem/CacheStore.php @@ -0,0 +1,54 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\filesystem; + +use League\Flysystem\Cached\Storage\AbstractCache; +use Psr\SimpleCache\CacheInterface; + +class CacheStore extends AbstractCache +{ + protected $store; + + protected $key; + + protected $expire; + + public function __construct(CacheInterface $store, $key = 'flysystem', $expire = null) + { + $this->key = $key; + $this->store = $store; + $this->expire = $expire; + } + + /** + * Store the cache. + */ + public function save() + { + $contents = $this->getForStorage(); + + $this->store->set($this->key, $contents, $this->expire); + } + + /** + * Load the cache. + */ + public function load() + { + $contents = $this->store->get($this->key); + + if (!is_null($contents)) { + $this->setFromStorage($contents); + } + } +} diff --git a/vendor/topthink/framework/src/think/filesystem/Driver.php b/vendor/topthink/framework/src/think/filesystem/Driver.php new file mode 100644 index 0000000..26826ad --- /dev/null +++ b/vendor/topthink/framework/src/think/filesystem/Driver.php @@ -0,0 +1,133 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\filesystem; + +use League\Flysystem\AdapterInterface; +use League\Flysystem\Adapter\AbstractAdapter; +use League\Flysystem\Cached\CachedAdapter; +use League\Flysystem\Cached\Storage\Memory as MemoryStore; +use League\Flysystem\Filesystem; +use think\Cache; +use think\File; + +/** + * Class Driver + * @package think\filesystem + * @mixin Filesystem + */ +abstract class Driver +{ + + /** @var Cache */ + protected $cache; + + /** @var Filesystem */ + protected $filesystem; + + /** + * 配置参数 + * @var array + */ + protected $config = []; + + public function __construct(Cache $cache, array $config) + { + $this->cache = $cache; + $this->config = array_merge($this->config, $config); + + $adapter = $this->createAdapter(); + $this->filesystem = $this->createFilesystem($adapter); + } + + protected function createCacheStore($config) + { + if (true === $config) { + return new MemoryStore; + } + + return new CacheStore( + $this->cache->store($config['store']), + $config['prefix'] ?? 'flysystem', + $config['expire'] ?? null + ); + } + + abstract protected function createAdapter(): AdapterInterface; + + protected function createFilesystem(AdapterInterface $adapter): Filesystem + { + if (!empty($this->config['cache'])) { + $adapter = new CachedAdapter($adapter, $this->createCacheStore($this->config['cache'])); + } + + $config = array_intersect_key($this->config, array_flip(['visibility', 'disable_asserts', 'url'])); + + return new Filesystem($adapter, count($config) > 0 ? $config : null); + } + + /** + * 获取文件完整路径 + * @param string $path + * @return string + */ + public function path(string $path): string + { + $adapter = $this->filesystem->getAdapter(); + + if ($adapter instanceof AbstractAdapter) { + return $adapter->applyPathPrefix($path); + } + + return $path; + } + + /** + * 保存文件 + * @param string $path 路径 + * @param File $file 文件 + * @param null|string|\Closure $rule 文件名规则 + * @param array $options 参数 + * @return bool|string + */ + public function putFile(string $path, File $file, $rule = null, array $options = []) + { + return $this->putFileAs($path, $file, $file->hashName($rule), $options); + } + + /** + * 指定文件名保存文件 + * @param string $path 路径 + * @param File $file 文件 + * @param string $name 文件名 + * @param array $options 参数 + * @return bool|string + */ + public function putFileAs(string $path, File $file, string $name, array $options = []) + { + $stream = fopen($file->getRealPath(), 'r'); + $path = trim($path . '/' . $name, '/'); + + $result = $this->putStream($path, $stream, $options); + + if (is_resource($stream)) { + fclose($stream); + } + + return $result ? $path : false; + } + + public function __call($method, $parameters) + { + return $this->filesystem->$method(...$parameters); + } +} diff --git a/vendor/topthink/framework/src/think/filesystem/driver/Local.php b/vendor/topthink/framework/src/think/filesystem/driver/Local.php new file mode 100644 index 0000000..60aa71c --- /dev/null +++ b/vendor/topthink/framework/src/think/filesystem/driver/Local.php @@ -0,0 +1,41 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\filesystem\driver; + +use League\Flysystem\AdapterInterface; +use League\Flysystem\Adapter\Local as LocalAdapter; +use think\filesystem\Driver; + +class Local extends Driver +{ + /** + * 配置参数 + * @var array + */ + protected $config = [ + 'root' => '', + ]; + + protected function createAdapter(): AdapterInterface + { + $permissions = $this->config['permissions'] ?? []; + + $links = ($this->config['links'] ?? null) === 'skip' + ? LocalAdapter::SKIP_LINKS + : LocalAdapter::DISALLOW_LINKS; + + return new LocalAdapter( + $this->config['root'], LOCK_EX, $links, $permissions + ); + } +} diff --git a/vendor/topthink/framework/src/think/initializer/BootService.php b/vendor/topthink/framework/src/think/initializer/BootService.php new file mode 100644 index 0000000..ef9b25e --- /dev/null +++ b/vendor/topthink/framework/src/think/initializer/BootService.php @@ -0,0 +1,26 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\initializer; + +use think\App; + +/** + * 启动系统服务 + */ +class BootService +{ + public function init(App $app) + { + $app->boot(); + } +} diff --git a/vendor/topthink/framework/src/think/initializer/Error.php b/vendor/topthink/framework/src/think/initializer/Error.php new file mode 100644 index 0000000..27fef64 --- /dev/null +++ b/vendor/topthink/framework/src/think/initializer/Error.php @@ -0,0 +1,117 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\initializer; + +use think\App; +use think\console\Output as ConsoleOutput; +use think\exception\ErrorException; +use think\exception\Handle; +use Throwable; + +/** + * 错误和异常处理 + */ +class Error +{ + /** @var App */ + protected $app; + + /** + * 注册异常处理 + * @access public + * @param App $app + * @return void + */ + public function init(App $app) + { + $this->app = $app; + error_reporting(E_ALL); + set_error_handler([$this, 'appError']); + set_exception_handler([$this, 'appException']); + register_shutdown_function([$this, 'appShutdown']); + } + + /** + * Exception Handler + * @access public + * @param \Throwable $e + */ + public function appException(Throwable $e): void + { + $handler = $this->getExceptionHandler(); + + $handler->report($e); + + if ($this->app->runningInConsole()) { + $handler->renderForConsole(new ConsoleOutput, $e); + } else { + $handler->render($this->app->request, $e)->send(); + } + } + + /** + * Error Handler + * @access public + * @param integer $errno 错误编号 + * @param string $errstr 详细错误信息 + * @param string $errfile 出错的文件 + * @param integer $errline 出错行号 + * @throws ErrorException + */ + public function appError(int $errno, string $errstr, string $errfile = '', int $errline = 0): void + { + $exception = new ErrorException($errno, $errstr, $errfile, $errline); + + if (error_reporting() & $errno) { + // 将错误信息托管至 think\exception\ErrorException + throw $exception; + } + } + + /** + * Shutdown Handler + * @access public + */ + public function appShutdown(): void + { + if (!is_null($error = error_get_last()) && $this->isFatal($error['type'])) { + // 将错误信息托管至think\ErrorException + $exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']); + + $this->appException($exception); + } + } + + /** + * 确定错误类型是否致命 + * + * @access protected + * @param int $type + * @return bool + */ + protected function isFatal(int $type): bool + { + return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]); + } + + /** + * Get an instance of the exception handler. + * + * @access protected + * @return Handle + */ + protected function getExceptionHandler() + { + return $this->app->make(Handle::class); + } +} diff --git a/vendor/topthink/framework/src/think/initializer/RegisterService.php b/vendor/topthink/framework/src/think/initializer/RegisterService.php new file mode 100644 index 0000000..c63ab35 --- /dev/null +++ b/vendor/topthink/framework/src/think/initializer/RegisterService.php @@ -0,0 +1,48 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\initializer; + +use think\App; +use think\service\ModelService; +use think\service\PaginatorService; +use think\service\ValidateService; + +/** + * 注册系统服务 + */ +class RegisterService +{ + + protected $services = [ + PaginatorService::class, + ValidateService::class, + ModelService::class, + ]; + + public function init(App $app) + { + $file = $app->getRootPath() . 'vendor/services.php'; + + $services = $this->services; + + if (is_file($file)) { + $services = array_merge($services, include $file); + } + + foreach ($services as $service) { + if (class_exists($service)) { + $app->register($service); + } + } + } +} diff --git a/vendor/topthink/framework/src/think/log/Channel.php b/vendor/topthink/framework/src/think/log/Channel.php new file mode 100644 index 0000000..2660a60 --- /dev/null +++ b/vendor/topthink/framework/src/think/log/Channel.php @@ -0,0 +1,282 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\log; + +use Psr\Log\LoggerInterface; +use think\contract\LogHandlerInterface; +use think\Event; +use think\event\LogWrite; + +class Channel implements LoggerInterface +{ + protected $name; + protected $logger; + protected $event; + + protected $lazy = true; + /** + * 日志信息 + * @var array + */ + protected $log = []; + + /** + * 关闭日志 + * @var array + */ + protected $close = false; + + /** + * 允许写入类型 + * @var array + */ + protected $allow = []; + + public function __construct(string $name, LogHandlerInterface $logger, array $allow, bool $lazy = true, Event $event = null) + { + $this->name = $name; + $this->logger = $logger; + $this->allow = $allow; + $this->lazy = $lazy; + $this->event = $event; + } + + /** + * 关闭通道 + */ + public function close() + { + $this->clear(); + $this->close = true; + } + + /** + * 清空日志 + */ + public function clear() + { + $this->log = []; + } + + /** + * 记录日志信息 + * @access public + * @param mixed $msg 日志信息 + * @param string $type 日志级别 + * @param array $context 替换内容 + * @param bool $lazy + * @return $this + */ + public function record($msg, string $type = 'info', array $context = [], bool $lazy = true) + { + if ($this->close || (!empty($this->allow) && !in_array($type, $this->allow))) { + return $this; + } + + if (is_string($msg) && !empty($context)) { + $replace = []; + foreach ($context as $key => $val) { + $replace['{' . $key . '}'] = $val; + } + + $msg = strtr($msg, $replace); + } + + if (!empty($msg) || 0 === $msg) { + $this->log[$type][] = $msg; + } + + if (!$this->lazy || !$lazy) { + $this->save(); + } + + return $this; + } + + /** + * 实时写入日志信息 + * @access public + * @param mixed $msg 调试信息 + * @param string $type 日志级别 + * @param array $context 替换内容 + * @return $this + */ + public function write($msg, string $type = 'info', array $context = []) + { + return $this->record($msg, $type, $context, false); + } + + /** + * 获取日志信息 + * @return array + */ + public function getLog(): array + { + return $this->log; + } + + /** + * 保存日志 + * @return bool + */ + public function save(): bool + { + $log = $this->log; + if ($this->event) { + $event = new LogWrite($this->name, $log); + $this->event->trigger($event); + $log = $event->log; + } + + if ($this->logger->save($log)) { + $this->clear(); + return true; + } + + return false; + } + + /** + * System is unusable. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function emergency($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = []) + { + $this->log(__FUNCTION__, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + */ + public function log($level, $message, array $context = []) + { + $this->record($message, $level, $context); + } + + public function __call($method, $parameters) + { + $this->log($method, ...$parameters); + } +} diff --git a/vendor/topthink/framework/src/think/log/ChannelSet.php b/vendor/topthink/framework/src/think/log/ChannelSet.php new file mode 100644 index 0000000..e38811c --- /dev/null +++ b/vendor/topthink/framework/src/think/log/ChannelSet.php @@ -0,0 +1,39 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\log; + +use think\Log; + +/** + * Class ChannelSet + * @package think\log + * @mixin Channel + */ +class ChannelSet +{ + protected $log; + protected $channels; + + public function __construct(Log $log, array $channels) + { + $this->log = $log; + $this->channels = $channels; + } + + public function __call($method, $arguments) + { + foreach ($this->channels as $channel) { + $this->log->channel($channel)->{$method}(...$arguments); + } + } +} diff --git a/vendor/topthink/framework/src/think/log/driver/File.php b/vendor/topthink/framework/src/think/log/driver/File.php new file mode 100644 index 0000000..1b6314d --- /dev/null +++ b/vendor/topthink/framework/src/think/log/driver/File.php @@ -0,0 +1,205 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\log\driver; + +use think\App; +use think\contract\LogHandlerInterface; + +/** + * 本地化调试输出到文件 + */ +class File implements LogHandlerInterface +{ + /** + * 配置参数 + * @var array + */ + protected $config = [ + 'time_format' => 'c', + 'single' => false, + 'file_size' => 2097152, + 'path' => '', + 'apart_level' => [], + 'max_files' => 0, + 'json' => false, + 'json_options' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, + 'format' => '[%s][%s] %s', + ]; + + // 实例化并传入参数 + public function __construct(App $app, $config = []) + { + if (is_array($config)) { + $this->config = array_merge($this->config, $config); + } + + if (empty($this->config['format'])) { + $this->config['format'] = '[%s][%s] %s'; + } + + if (empty($this->config['path'])) { + $this->config['path'] = $app->getRuntimePath() . 'log'; + } + + if (substr($this->config['path'], -1) != DIRECTORY_SEPARATOR) { + $this->config['path'] .= DIRECTORY_SEPARATOR; + } + } + + /** + * 日志写入接口 + * @access public + * @param array $log 日志信息 + * @return bool + */ + public function save(array $log): bool + { + $destination = $this->getMasterLogFile(); + + $path = dirname($destination); + !is_dir($path) && mkdir($path, 0755, true); + + $info = []; + + // 日志信息封装 + $time = date($this->config['time_format']); + + foreach ($log as $type => $val) { + $message = []; + foreach ($val as $msg) { + if (!is_string($msg)) { + $msg = var_export($msg, true); + } + + $message[] = $this->config['json'] ? + json_encode(['time' => $time, 'type' => $type, 'msg' => $msg], $this->config['json_options']) : + sprintf($this->config['format'], $time, $type, $msg); + } + + if (true === $this->config['apart_level'] || in_array($type, $this->config['apart_level'])) { + // 独立记录的日志级别 + $filename = $this->getApartLevelFile($path, $type); + $this->write($message, $filename); + continue; + } + + $info[$type] = $message; + } + + if ($info) { + return $this->write($info, $destination); + } + + return true; + } + + /** + * 日志写入 + * @access protected + * @param array $message 日志信息 + * @param string $destination 日志文件 + * @return bool + */ + protected function write(array $message, string $destination): bool + { + // 检测日志文件大小,超过配置大小则备份日志文件重新生成 + $this->checkLogSize($destination); + + $info = []; + + foreach ($message as $type => $msg) { + $info[$type] = is_array($msg) ? implode(PHP_EOL, $msg) : $msg; + } + + $message = implode(PHP_EOL, $info) . PHP_EOL; + + return error_log($message, 3, $destination); + } + + /** + * 获取主日志文件名 + * @access public + * @return string + */ + protected function getMasterLogFile(): string + { + + if ($this->config['max_files']) { + $files = glob($this->config['path'] . '*.log'); + + try { + if (count($files) > $this->config['max_files']) { + unlink($files[0]); + } + } catch (\Exception $e) { + // + } + } + + if ($this->config['single']) { + $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; + $destination = $this->config['path'] . $name . '.log'; + } else { + + if ($this->config['max_files']) { + $filename = date('Ymd') . '.log'; + } else { + $filename = date('Ym') . DIRECTORY_SEPARATOR . date('d') . '.log'; + } + + $destination = $this->config['path'] . $filename; + } + + return $destination; + } + + /** + * 获取独立日志文件名 + * @access public + * @param string $path 日志目录 + * @param string $type 日志类型 + * @return string + */ + protected function getApartLevelFile(string $path, string $type): string + { + + if ($this->config['single']) { + $name = is_string($this->config['single']) ? $this->config['single'] : 'single'; + + $name .= '_' . $type; + } elseif ($this->config['max_files']) { + $name = date('Ymd') . '_' . $type; + } else { + $name = date('d') . '_' . $type; + } + + return $path . DIRECTORY_SEPARATOR . $name . '.log'; + } + + /** + * 检查日志文件大小并自动生成备份文件 + * @access protected + * @param string $destination 日志文件 + * @return void + */ + protected function checkLogSize(string $destination): void + { + if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) { + try { + rename($destination, dirname($destination) . DIRECTORY_SEPARATOR . time() . '-' . basename($destination)); + } catch (\Exception $e) { + // + } + } + } +} diff --git a/vendor/topthink/framework/src/think/log/driver/Socket.php b/vendor/topthink/framework/src/think/log/driver/Socket.php new file mode 100644 index 0000000..fc74258 --- /dev/null +++ b/vendor/topthink/framework/src/think/log/driver/Socket.php @@ -0,0 +1,306 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\log\driver; + +use Psr\Container\NotFoundExceptionInterface; +use think\App; +use think\contract\LogHandlerInterface; + +/** + * github: https://github.com/luofei614/SocketLog + * @author luofei614 + */ +class Socket implements LogHandlerInterface +{ + protected $app; + + protected $config = [ + // socket服务器地址 + 'host' => 'localhost', + // socket服务器端口 + 'port' => 1116, + // 是否显示加载的文件列表 + 'show_included_files' => false, + // 日志强制记录到配置的client_id + 'force_client_ids' => [], + // 限制允许读取日志的client_id + 'allow_client_ids' => [], + // 调试开关 + 'debug' => false, + // 输出到浏览器时默认展开的日志级别 + 'expand_level' => ['debug'], + // 日志头渲染回调 + 'format_head' => null, + ]; + + protected $css = [ + 'sql' => 'color:#009bb4;', + 'sql_warn' => 'color:#009bb4;font-size:14px;', + 'error' => 'color:#f4006b;font-size:14px;', + 'page' => 'color:#40e2ff;background:#171717;', + 'big' => 'font-size:20px;color:red;', + ]; + + protected $allowForceClientIds = []; //配置强制推送且被授权的client_id + + protected $clientArg = []; + + /** + * 架构函数 + * @access public + * @param App $app + * @param array $config 缓存参数 + */ + public function __construct(App $app, array $config = []) + { + $this->app = $app; + + if (!empty($config)) { + $this->config = array_merge($this->config, $config); + } + + if (!isset($config['debug'])) { + $this->config['debug'] = $app->isDebug(); + } + } + + /** + * 调试输出接口 + * @access public + * @param array $log 日志信息 + * @return bool + */ + public function save(array $log = []): bool + { + if (!$this->check()) { + return false; + } + + $trace = []; + + if ($this->config['debug']) { + if ($this->app->exists('request')) { + $current_uri = $this->app->request->url(true); + } else { + $current_uri = 'cmd:' . implode(' ', $_SERVER['argv'] ?? []); + } + + if (!empty($this->config['format_head'])) { + try { + $current_uri = $this->app->invoke($this->config['format_head'], [$current_uri]); + } catch (NotFoundExceptionInterface $notFoundException) { + // Ignore exception + } + } + + // 基本信息 + $trace[] = [ + 'type' => 'group', + 'msg' => $current_uri, + 'css' => $this->css['page'], + ]; + } + + $expand_level = array_flip($this->config['expand_level']); + + foreach ($log as $type => $val) { + $trace[] = [ + 'type' => isset($expand_level[$type]) ? 'group' : 'groupCollapsed', + 'msg' => '[ ' . $type . ' ]', + 'css' => $this->css[$type] ?? '', + ]; + + foreach ($val as $msg) { + if (!is_string($msg)) { + $msg = var_export($msg, true); + } + $trace[] = [ + 'type' => 'log', + 'msg' => $msg, + 'css' => '', + ]; + } + + $trace[] = [ + 'type' => 'groupEnd', + 'msg' => '', + 'css' => '', + ]; + } + + if ($this->config['show_included_files']) { + $trace[] = [ + 'type' => 'groupCollapsed', + 'msg' => '[ file ]', + 'css' => '', + ]; + + $trace[] = [ + 'type' => 'log', + 'msg' => implode("\n", get_included_files()), + 'css' => '', + ]; + + $trace[] = [ + 'type' => 'groupEnd', + 'msg' => '', + 'css' => '', + ]; + } + + $trace[] = [ + 'type' => 'groupEnd', + 'msg' => '', + 'css' => '', + ]; + + $tabid = $this->getClientArg('tabid'); + + if (!$client_id = $this->getClientArg('client_id')) { + $client_id = ''; + } + + if (!empty($this->allowForceClientIds)) { + //强制推送到多个client_id + foreach ($this->allowForceClientIds as $force_client_id) { + $client_id = $force_client_id; + $this->sendToClient($tabid, $client_id, $trace, $force_client_id); + } + } else { + $this->sendToClient($tabid, $client_id, $trace, ''); + } + + return true; + } + + /** + * 发送给指定客户端 + * @access protected + * @author Zjmainstay + * @param $tabid + * @param $client_id + * @param $logs + * @param $force_client_id + */ + protected function sendToClient($tabid, $client_id, $logs, $force_client_id) + { + $logs = [ + 'tabid' => $tabid, + 'client_id' => $client_id, + 'logs' => $logs, + 'force_client_id' => $force_client_id, + ]; + + $msg = json_encode($logs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR); + $address = '/' . $client_id; //将client_id作为地址, server端通过地址判断将日志发布给谁 + + $this->send($this->config['host'], $this->config['port'], $msg, $address); + } + + /** + * 检测客户授权 + * @access protected + * @return bool + */ + protected function check() + { + $tabid = $this->getClientArg('tabid'); + + //是否记录日志的检查 + if (!$tabid && !$this->config['force_client_ids']) { + return false; + } + + //用户认证 + $allow_client_ids = $this->config['allow_client_ids']; + + if (!empty($allow_client_ids)) { + //通过数组交集得出授权强制推送的client_id + $this->allowForceClientIds = array_intersect($allow_client_ids, $this->config['force_client_ids']); + if (!$tabid && count($this->allowForceClientIds)) { + return true; + } + + $client_id = $this->getClientArg('client_id'); + if (!in_array($client_id, $allow_client_ids)) { + return false; + } + } else { + $this->allowForceClientIds = $this->config['force_client_ids']; + } + + return true; + } + + /** + * 获取客户参数 + * @access protected + * @param string $name + * @return string + */ + protected function getClientArg(string $name) + { + if (!$this->app->exists('request')) { + return ''; + } + + if (empty($this->clientArg)) { + if (empty($socketLog = $this->app->request->header('socketlog'))) { + if (empty($socketLog = $this->app->request->header('User-Agent'))) { + return ''; + } + } + + if (!preg_match('/SocketLog\((.*?)\)/', $socketLog, $match)) { + $this->clientArg = ['tabid' => null, 'client_id' => null]; + return ''; + } + parse_str($match[1] ?? '', $this->clientArg); + } + + if (isset($this->clientArg[$name])) { + return $this->clientArg[$name]; + } + + return ''; + } + + /** + * @access protected + * @param string $host - $host of socket server + * @param int $port - $port of socket server + * @param string $message - 发送的消息 + * @param string $address - 地址 + * @return bool + */ + protected function send($host, $port, $message = '', $address = '/') + { + $url = 'http://' . $host . ':' . $port . $address; + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $message); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + + $headers = [ + "Content-Type: application/json;charset=UTF-8", + ]; + + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //设置header + + return curl_exec($ch); + } +} diff --git a/vendor/topthink/framework/src/think/middleware/AllowCrossDomain.php b/vendor/topthink/framework/src/think/middleware/AllowCrossDomain.php new file mode 100644 index 0000000..1c1d4c7 --- /dev/null +++ b/vendor/topthink/framework/src/think/middleware/AllowCrossDomain.php @@ -0,0 +1,66 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\middleware; + +use Closure; +use think\Config; +use think\Request; +use think\Response; + +/** + * 跨域请求支持 + */ +class AllowCrossDomain +{ + protected $cookieDomain; + + protected $header = [ + 'Access-Control-Allow-Credentials' => 'true', + 'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With', + ]; + + public function __construct(Config $config) + { + $this->cookieDomain = $config->get('cookie.domain', ''); + } + + /** + * 允许跨域请求 + * @access public + * @param Request $request + * @param Closure $next + * @param array $header + * @return Response + */ + public function handle($request, Closure $next, ?array $header = []) + { + $header = !empty($header) ? array_merge($this->header, $header) : $this->header; + + if (!isset($header['Access-Control-Allow-Origin'])) { + $origin = $request->header('origin'); + + if ($origin && ('' == $this->cookieDomain || strpos($origin, $this->cookieDomain))) { + $header['Access-Control-Allow-Origin'] = $origin; + } else { + $header['Access-Control-Allow-Origin'] = '*'; + } + } + + if ($request->method(true) == 'OPTIONS') { + return Response::create()->code(204)->header($header); + } + + return $next($request)->header($header); + } +} diff --git a/vendor/topthink/framework/src/think/middleware/CheckRequestCache.php b/vendor/topthink/framework/src/think/middleware/CheckRequestCache.php new file mode 100644 index 0000000..f2d8a62 --- /dev/null +++ b/vendor/topthink/framework/src/think/middleware/CheckRequestCache.php @@ -0,0 +1,163 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\middleware; + +use Closure; +use think\Cache; +use think\Config; +use think\Request; +use think\Response; + +/** + * 请求缓存处理 + */ +class CheckRequestCache +{ + /** + * 缓存对象 + * @var Cache + */ + protected $cache; + + /** + * 配置参数 + * @var array + */ + protected $config = [ + // 请求缓存规则 true为自动规则 + 'request_cache_key' => true, + // 请求缓存有效期 + 'request_cache_expire' => null, + // 全局请求缓存排除规则 + 'request_cache_except' => [], + // 请求缓存的Tag + 'request_cache_tag' => '', + ]; + + public function __construct(Cache $cache, Config $config) + { + $this->cache = $cache; + $this->config = array_merge($this->config, $config->get('route')); + } + + /** + * 设置当前地址的请求缓存 + * @access public + * @param Request $request + * @param Closure $next + * @param mixed $cache + * @return Response + */ + public function handle($request, Closure $next, $cache = null) + { + if ($request->isGet() && false !== $cache) { + $cache = $cache ?: $this->getRequestCache($request); + + if ($cache) { + if (is_array($cache)) { + [$key, $expire, $tag] = $cache; + } else { + $key = str_replace('|', '/', $request->url()); + $expire = $cache; + $tag = null; + } + + if (strtotime($request->server('HTTP_IF_MODIFIED_SINCE', '')) + $expire > $request->server('REQUEST_TIME')) { + // 读取缓存 + return Response::create()->code(304); + } elseif (($hit = $this->cache->get($key)) !== null) { + [$content, $header, $when] = $hit; + if (null === $expire || $when + $expire > $request->server('REQUEST_TIME')) { + return Response::create($content)->header($header); + } + } + } + } + + $response = $next($request); + + if (isset($key) && 200 == $response->getCode() && $response->isAllowCache()) { + $header = $response->getHeader(); + $header['Cache-Control'] = 'max-age=' . $expire . ',must-revalidate'; + $header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT'; + $header['Expires'] = gmdate('D, d M Y H:i:s', time() + $expire) . ' GMT'; + + $this->cache->tag($tag)->set($key, [$response->getContent(), $header, time()], $expire); + } + + return $response; + } + + /** + * 读取当前地址的请求缓存信息 + * @access protected + * @param Request $request + * @return mixed + */ + protected function getRequestCache($request) + { + $key = $this->config['request_cache_key']; + $expire = $this->config['request_cache_expire']; + $except = $this->config['request_cache_except']; + $tag = $this->config['request_cache_tag']; + + if ($key instanceof \Closure) { + $key = call_user_func($key, $request); + } + + if (false === $key) { + // 关闭当前缓存 + return; + } + + foreach ($except as $rule) { + if (0 === stripos($request->url(), $rule)) { + return; + } + } + + if (true === $key) { + // 自动缓存功能 + $key = '__URL__'; + } elseif (strpos($key, '|')) { + [$key, $fun] = explode('|', $key); + } + + // 特殊规则替换 + if (false !== strpos($key, '__')) { + $key = str_replace(['__CONTROLLER__', '__ACTION__', '__URL__'], [$request->controller(), $request->action(), md5($request->url(true))], $key); + } + + if (false !== strpos($key, ':')) { + $param = $request->param(); + foreach ($param as $item => $val) { + if (is_string($val) && false !== strpos($key, ':' . $item)) { + $key = str_replace(':' . $item, $val, $key); + } + } + } elseif (strpos($key, ']')) { + if ('[' . $request->ext() . ']' == $key) { + // 缓存某个后缀的请求 + $key = md5($request->url()); + } else { + return; + } + } + + if (isset($fun)) { + $key = $fun($key); + } + + return [$key, $expire, $tag]; + } +} diff --git a/vendor/topthink/framework/src/think/middleware/FormTokenCheck.php b/vendor/topthink/framework/src/think/middleware/FormTokenCheck.php new file mode 100644 index 0000000..f507903 --- /dev/null +++ b/vendor/topthink/framework/src/think/middleware/FormTokenCheck.php @@ -0,0 +1,45 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\middleware; + +use Closure; +use think\exception\ValidateException; +use think\Request; +use think\Response; + +/** + * 表单令牌支持 + */ +class FormTokenCheck +{ + + /** + * 表单令牌检测 + * @access public + * @param Request $request + * @param Closure $next + * @param string $token 表单令牌Token名称 + * @return Response + */ + public function handle(Request $request, Closure $next, string $token = null) + { + $check = $request->checkToken($token ?: '__token__'); + + if (false === $check) { + throw new ValidateException('invalid token'); + } + + return $next($request); + } + +} diff --git a/vendor/topthink/framework/src/think/middleware/LoadLangPack.php b/vendor/topthink/framework/src/think/middleware/LoadLangPack.php new file mode 100644 index 0000000..c9e7a9d --- /dev/null +++ b/vendor/topthink/framework/src/think/middleware/LoadLangPack.php @@ -0,0 +1,61 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\middleware; + +use Closure; +use think\App; +use think\Lang; +use think\Request; +use think\Response; + +/** + * 多语言加载 + */ +class LoadLangPack +{ + protected $app; + + protected $lang; + + public function __construct(App $app, Lang $lang) + { + $this->app = $app; + $this->lang = $lang; + } + + /** + * 路由初始化(路由规则注册) + * @access public + * @param Request $request + * @param Closure $next + * @return Response + */ + public function handle($request, Closure $next) + { + // 自动侦测当前语言 + $langset = $this->lang->detect($request); + + if ($this->lang->defaultLangSet() != $langset) { + // 加载系统语言包 + $this->lang->load([ + $this->app->getThinkPath() . 'lang' . DIRECTORY_SEPARATOR . $langset . '.php', + ]); + + $this->app->LoadLangPack($langset); + } + + $this->lang->saveToCookie($this->app->cookie); + + return $next($request); + } +} diff --git a/vendor/topthink/framework/src/think/middleware/SessionInit.php b/vendor/topthink/framework/src/think/middleware/SessionInit.php new file mode 100644 index 0000000..8c2a7b4 --- /dev/null +++ b/vendor/topthink/framework/src/think/middleware/SessionInit.php @@ -0,0 +1,80 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\middleware; + +use Closure; +use think\App; +use think\Request; +use think\Response; +use think\Session; + +/** + * Session初始化 + */ +class SessionInit +{ + + /** @var App */ + protected $app; + + /** @var Session */ + protected $session; + + public function __construct(App $app, Session $session) + { + $this->app = $app; + $this->session = $session; + } + + /** + * Session初始化 + * @access public + * @param Request $request + * @param Closure $next + * @return Response + */ + public function handle($request, Closure $next) + { + // Session初始化 + $varSessionId = $this->app->config->get('session.var_session_id'); + $cookieName = $this->session->getName(); + + if ($varSessionId && $request->request($varSessionId)) { + $sessionId = $request->request($varSessionId); + } else { + $sessionId = $request->cookie($cookieName); + } + + if ($sessionId) { + $this->session->setId($sessionId); + } + + $this->session->init(); + + $request->withSession($this->session); + + /** @var Response $response */ + $response = $next($request); + + $response->setSession($this->session); + + $this->app->cookie->set($cookieName, $this->session->getId()); + + return $response; + } + + public function end(Response $response) + { + $this->session->save(); + } +} diff --git a/vendor/topthink/framework/src/think/response/File.php b/vendor/topthink/framework/src/think/response/File.php new file mode 100644 index 0000000..ce000ab --- /dev/null +++ b/vendor/topthink/framework/src/think/response/File.php @@ -0,0 +1,145 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\response; + +use think\Exception; +use think\Response; + +/** + * File Response + */ +class File extends Response +{ + protected $expire = 360; + protected $name; + protected $mimeType; + protected $isContent = false; + + public function __construct($data = '', int $code = 200) + { + $this->init($data, $code); + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + * @throws \Exception + */ + protected function output($data) + { + if (!$this->isContent && !is_file($data)) { + throw new Exception('file not exists:' . $data); + } + + ob_end_clean(); + + if (!empty($this->name)) { + $name = $this->name; + } else { + $name = !$this->isContent ? pathinfo($data, PATHINFO_BASENAME) : ''; + } + + if ($this->isContent) { + $mimeType = $this->mimeType; + $size = strlen($data); + } else { + $mimeType = $this->getMimeType($data); + $size = filesize($data); + } + + $this->header['Pragma'] = 'public'; + $this->header['Content-Type'] = $mimeType ?: 'application/octet-stream'; + $this->header['Cache-control'] = 'max-age=' . $this->expire; + $this->header['Content-Disposition'] = 'attachment; filename="' . $name . '"'; + $this->header['Content-Length'] = $size; + $this->header['Content-Transfer-Encoding'] = 'binary'; + $this->header['Expires'] = gmdate("D, d M Y H:i:s", time() + $this->expire) . ' GMT'; + + $this->lastModified(gmdate('D, d M Y H:i:s', time()) . ' GMT'); + + return $this->isContent ? $data : file_get_contents($data); + } + + /** + * 设置是否为内容 必须配合mimeType方法使用 + * @access public + * @param bool $content + * @return $this + */ + public function isContent(bool $content = true) + { + $this->isContent = $content; + return $this; + } + + /** + * 设置有效期 + * @access public + * @param integer $expire 有效期 + * @return $this + */ + public function expire(int $expire) + { + $this->expire = $expire; + return $this; + } + + /** + * 设置文件类型 + * @access public + * @param string $filename 文件名 + * @return $this + */ + public function mimeType(string $mimeType) + { + $this->mimeType = $mimeType; + return $this; + } + + /** + * 获取文件类型信息 + * @access public + * @param string $filename 文件名 + * @return string + */ + protected function getMimeType(string $filename): string + { + if (!empty($this->mimeType)) { + return $this->mimeType; + } + + $finfo = finfo_open(FILEINFO_MIME_TYPE); + + return finfo_file($finfo, $filename); + } + + /** + * 设置下载文件的显示名称 + * @access public + * @param string $filename 文件名 + * @param bool $extension 后缀自动识别 + * @return $this + */ + public function name(string $filename, bool $extension = true) + { + $this->name = $filename; + + if ($extension && false === strpos($filename, '.')) { + $this->name .= '.' . pathinfo($this->data, PATHINFO_EXTENSION); + } + + return $this; + } +} diff --git a/vendor/topthink/framework/src/think/response/Html.php b/vendor/topthink/framework/src/think/response/Html.php new file mode 100644 index 0000000..dbf23c7 --- /dev/null +++ b/vendor/topthink/framework/src/think/response/Html.php @@ -0,0 +1,34 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\response; + +use think\Cookie; +use think\Response; + +/** + * Html Response + */ +class Html extends Response +{ + /** + * 输出type + * @var string + */ + protected $contentType = 'text/html'; + + public function __construct(Cookie $cookie, $data = '', int $code = 200) + { + $this->init($data, $code); + $this->cookie = $cookie; + } +} diff --git a/vendor/topthink/framework/src/think/response/Json.php b/vendor/topthink/framework/src/think/response/Json.php new file mode 100644 index 0000000..85d2d22 --- /dev/null +++ b/vendor/topthink/framework/src/think/response/Json.php @@ -0,0 +1,62 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\response; + +use think\Cookie; +use think\Response; + +/** + * Json Response + */ +class Json extends Response +{ + // 输出参数 + protected $options = [ + 'json_encode_param' => JSON_UNESCAPED_UNICODE, + ]; + + protected $contentType = 'application/json'; + + public function __construct(Cookie $cookie, $data = '', int $code = 200) + { + $this->init($data, $code); + $this->cookie = $cookie; + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return string + * @throws \Exception + */ + protected function output($data): string + { + try { + // 返回JSON数据格式到客户端 包含状态信息 + $data = json_encode($data, $this->options['json_encode_param']); + + if (false === $data) { + throw new \InvalidArgumentException(json_last_error_msg()); + } + + return $data; + } catch (\Exception $e) { + if ($e->getPrevious()) { + throw $e->getPrevious(); + } + throw $e; + } + } + +} diff --git a/vendor/topthink/framework/src/think/response/Jsonp.php b/vendor/topthink/framework/src/think/response/Jsonp.php new file mode 100644 index 0000000..a098d4c --- /dev/null +++ b/vendor/topthink/framework/src/think/response/Jsonp.php @@ -0,0 +1,74 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\response; + +use think\Cookie; +use think\Request; +use think\Response; + +/** + * Jsonp Response + */ +class Jsonp extends Response +{ + // 输出参数 + protected $options = [ + 'var_jsonp_handler' => 'callback', + 'default_jsonp_handler' => 'jsonpReturn', + 'json_encode_param' => JSON_UNESCAPED_UNICODE, + ]; + + protected $contentType = 'application/javascript'; + + protected $request; + + public function __construct(Cookie $cookie, Request $request, $data = '', int $code = 200) + { + $this->init($data, $code); + + $this->cookie = $cookie; + $this->request = $request; + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return string + * @throws \Exception + */ + protected function output($data): string + { + try { + // 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的,故使用Request来获取] + $var_jsonp_handler = $this->request->param($this->options['var_jsonp_handler'], ""); + $handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler']; + + $data = json_encode($data, $this->options['json_encode_param']); + + if (false === $data) { + throw new \InvalidArgumentException(json_last_error_msg()); + } + + $data = $handler . '(' . $data . ');'; + + return $data; + } catch (\Exception $e) { + if ($e->getPrevious()) { + throw $e->getPrevious(); + } + throw $e; + } + } + +} diff --git a/vendor/topthink/framework/src/think/response/Redirect.php b/vendor/topthink/framework/src/think/response/Redirect.php new file mode 100644 index 0000000..3d201aa --- /dev/null +++ b/vendor/topthink/framework/src/think/response/Redirect.php @@ -0,0 +1,98 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\response; + +use think\Cookie; +use think\Request; +use think\Response; +use think\Session; + +/** + * Redirect Response + */ +class Redirect extends Response +{ + + protected $request; + + public function __construct(Cookie $cookie, Request $request, Session $session, $data = '', int $code = 302) + { + $this->init((string) $data, $code); + + $this->cookie = $cookie; + $this->request = $request; + $this->session = $session; + + $this->cacheControl('no-cache,must-revalidate'); + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return string + */ + protected function output($data): string + { + $this->header['Location'] = $data; + + return ''; + } + + /** + * 重定向传值(通过Session) + * @access protected + * @param string|array $name 变量名或者数组 + * @param mixed $value 值 + * @return $this + */ + public function with($name, $value = null) + { + if (is_array($name)) { + foreach ($name as $key => $val) { + $this->session->flash($key, $val); + } + } else { + $this->session->flash($name, $value); + } + + return $this; + } + + /** + * 记住当前url后跳转 + * @access public + * @return $this + */ + public function remember() + { + $this->session->set('redirect_url', $this->request->url()); + + return $this; + } + + /** + * 跳转到上次记住的url + * @access public + * @return $this + */ + public function restore() + { + if ($this->session->has('redirect_url')) { + $this->data = $this->session->get('redirect_url'); + $this->session->delete('redirect_url'); + } + + return $this; + } +} diff --git a/vendor/topthink/framework/src/think/response/View.php b/vendor/topthink/framework/src/think/response/View.php new file mode 100644 index 0000000..0b1ae88 --- /dev/null +++ b/vendor/topthink/framework/src/think/response/View.php @@ -0,0 +1,149 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\response; + +use think\Cookie; +use think\Response; +use think\View as BaseView; + +/** + * View Response + */ +class View extends Response +{ + /** + * 输出参数 + * @var array + */ + protected $options = []; + + /** + * 输出变量 + * @var array + */ + protected $vars = []; + + /** + * 输出过滤 + * @var mixed + */ + protected $filter; + + /** + * 输出type + * @var string + */ + protected $contentType = 'text/html'; + + /** + * View对象 + * @var BaseView + */ + protected $view; + + /** + * 是否内容渲染 + * @var bool + */ + protected $isContent = false; + + public function __construct(Cookie $cookie, BaseView $view, $data = '', int $code = 200) + { + $this->init($data, $code); + + $this->cookie = $cookie; + $this->view = $view; + } + + /** + * 设置是否为内容渲染 + * @access public + * @param bool $content + * @return $this + */ + public function isContent(bool $content = true) + { + $this->isContent = $content; + return $this; + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return string + */ + protected function output($data): string + { + // 渲染模板输出 + return $this->view->filter($this->filter) + ->fetch($data, $this->vars, $this->isContent); + } + + /** + * 获取视图变量 + * @access public + * @param string $name 模板变量 + * @return mixed + */ + public function getVars(string $name = null) + { + if (is_null($name)) { + return $this->vars; + } else { + return $this->vars[$name] ?? null; + } + } + + /** + * 模板变量赋值 + * @access public + * @param string|array $name 模板变量 + * @param mixed $value 变量值 + * @return $this + */ + public function assign($name, $value = null) + { + if (is_array($name)) { + $this->vars = array_merge($this->vars, $name); + } else { + $this->vars[$name] = $value; + } + + return $this; + } + + /** + * 视图内容过滤 + * @access public + * @param callable $filter + * @return $this + */ + public function filter(callable $filter = null) + { + $this->filter = $filter; + return $this; + } + + /** + * 检查模板是否存在 + * @access public + * @param string $name 模板名 + * @return bool + */ + public function exists(string $name): bool + { + return $this->view->exists($name); + } + +} diff --git a/vendor/topthink/framework/src/think/response/Xml.php b/vendor/topthink/framework/src/think/response/Xml.php new file mode 100644 index 0000000..3597548 --- /dev/null +++ b/vendor/topthink/framework/src/think/response/Xml.php @@ -0,0 +1,127 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\response; + +use think\Collection; +use think\Cookie; +use think\Model; +use think\Response; + +/** + * XML Response + */ +class Xml extends Response +{ + // 输出参数 + protected $options = [ + // 根节点名 + 'root_node' => 'think', + // 根节点属性 + 'root_attr' => '', + //数字索引的子节点名 + 'item_node' => 'item', + // 数字索引子节点key转换的属性名 + 'item_key' => 'id', + // 数据编码 + 'encoding' => 'utf-8', + ]; + + protected $contentType = 'text/xml'; + + public function __construct(Cookie $cookie, $data = '', int $code = 200) + { + $this->init($data, $code); + $this->cookie = $cookie; + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data): string + { + if (is_string($data)) { + if (0 !== strpos($data, 'options['encoding']; + $xml = ""; + $data = $xml . $data; + } + return $data; + } + + // XML数据转换 + return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']); + } + + /** + * XML编码 + * @access protected + * @param mixed $data 数据 + * @param string $root 根节点名 + * @param string $item 数字索引的子节点名 + * @param mixed $attr 根节点属性 + * @param string $id 数字索引子节点key转换的属性名 + * @param string $encoding 数据编码 + * @return string + */ + protected function xmlEncode($data, string $root, string $item, $attr, string $id, string $encoding): string + { + if (is_array($attr)) { + $array = []; + foreach ($attr as $key => $value) { + $array[] = "{$key}=\"{$value}\""; + } + $attr = implode(' ', $array); + } + + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = ""; + $xml .= "<{$root}{$attr}>"; + $xml .= $this->dataToXml($data, $item, $id); + $xml .= ""; + + return $xml; + } + + /** + * 数据XML编码 + * @access protected + * @param mixed $data 数据 + * @param string $item 数字索引时的节点名称 + * @param string $id 数字索引key转换为的属性名 + * @return string + */ + protected function dataToXml($data, string $item, string $id): string + { + $xml = $attr = ''; + + if ($data instanceof Collection || $data instanceof Model) { + $data = $data->toArray(); + } + + foreach ($data as $key => $val) { + if (is_numeric($key)) { + $id && $attr = " {$id}=\"{$key}\""; + $key = $item; + } + $xml .= "<{$key}{$attr}>"; + $xml .= (is_array($val) || is_object($val)) ? $this->dataToXml($val, $item, $id) : $val; + $xml .= ""; + } + + return $xml; + } +} diff --git a/vendor/topthink/framework/src/think/route/Dispatch.php b/vendor/topthink/framework/src/think/route/Dispatch.php new file mode 100644 index 0000000..dc39fd1 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/Dispatch.php @@ -0,0 +1,265 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +use think\App; +use think\Container; +use think\Request; +use think\Response; +use think\Validate; + +/** + * 路由调度基础类 + */ +abstract class Dispatch +{ + /** + * 应用对象 + * @var \think\App + */ + protected $app; + + /** + * 请求对象 + * @var Request + */ + protected $request; + + /** + * 路由规则 + * @var Rule + */ + protected $rule; + + /** + * 调度信息 + * @var mixed + */ + protected $dispatch; + + /** + * 路由变量 + * @var array + */ + protected $param; + + /** + * 状态码 + * @var int + */ + protected $code; + + public function __construct(Request $request, Rule $rule, $dispatch, array $param = [], int $code = null) + { + $this->request = $request; + $this->rule = $rule; + $this->dispatch = $dispatch; + $this->param = $param; + $this->code = $code; + } + + public function init(App $app) + { + $this->app = $app; + + // 执行路由后置操作 + $this->doRouteAfter(); + } + + /** + * 执行路由调度 + * @access public + * @return mixed + */ + public function run(): Response + { + if ($this->rule instanceof RuleItem && $this->request->method() == 'OPTIONS' && $this->rule->isAutoOptions()) { + $rules = $this->rule->getRouter()->getRule($this->rule->getRule()); + $allow = []; + foreach ($rules as $item) { + $allow[] = strtoupper($item->getMethod()); + } + + return Response::create('', 'html', 204)->header(['Allow' => implode(', ', $allow)]); + } + + $data = $this->exec(); + return $this->autoResponse($data); + } + + protected function autoResponse($data): Response + { + if ($data instanceof Response) { + $response = $data; + } elseif (!is_null($data)) { + // 默认自动识别响应输出类型 + $type = $this->request->isJson() ? 'json' : 'html'; + $response = Response::create($data, $type); + } else { + $data = ob_get_clean(); + + $content = false === $data ? '' : $data; + $status = '' === $content && $this->request->isJson() ? 204 : 200; + $response = Response::create($content, 'html', $status); + } + + return $response; + } + + /** + * 检查路由后置操作 + * @access protected + * @return void + */ + protected function doRouteAfter(): void + { + $option = $this->rule->getOption(); + + // 添加中间件 + if (!empty($option['middleware'])) { + $this->app->middleware->import($option['middleware'], 'route'); + } + + if (!empty($option['append'])) { + $this->param = array_merge($this->param, $option['append']); + } + + // 绑定模型数据 + if (!empty($option['model'])) { + $this->createBindModel($option['model'], $this->param); + } + + // 记录当前请求的路由规则 + $this->request->setRule($this->rule); + + // 记录路由变量 + $this->request->setRoute($this->param); + + // 数据自动验证 + if (isset($option['validate'])) { + $this->autoValidate($option['validate']); + } + } + + /** + * 路由绑定模型实例 + * @access protected + * @param array $bindModel 绑定模型 + * @param array $matches 路由变量 + * @return void + */ + protected function createBindModel(array $bindModel, array $matches): void + { + foreach ($bindModel as $key => $val) { + if ($val instanceof \Closure) { + $result = $this->app->invokeFunction($val, $matches); + } else { + $fields = explode('&', $key); + + if (is_array($val)) { + [$model, $exception] = $val; + } else { + $model = $val; + $exception = true; + } + + $where = []; + $match = true; + + foreach ($fields as $field) { + if (!isset($matches[$field])) { + $match = false; + break; + } else { + $where[] = [$field, '=', $matches[$field]]; + } + } + + if ($match) { + $result = $model::where($where)->failException($exception)->find(); + } + } + + if (!empty($result)) { + // 注入容器 + $this->app->instance(get_class($result), $result); + } + } + } + + /** + * 验证数据 + * @access protected + * @param array $option + * @return void + * @throws \think\exception\ValidateException + */ + protected function autoValidate(array $option): void + { + [$validate, $scene, $message, $batch] = $option; + + if (is_array($validate)) { + // 指定验证规则 + $v = new Validate(); + $v->rule($validate); + } else { + // 调用验证器 + $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); + + $v = new $class(); + + if (!empty($scene)) { + $v->scene($scene); + } + } + + /** @var Validate $v */ + $v->message($message) + ->batch($batch) + ->failException(true) + ->check($this->request->param()); + } + + public function getDispatch() + { + return $this->dispatch; + } + + public function getParam(): array + { + return $this->param; + } + + abstract public function exec(); + + public function __sleep() + { + return ['rule', 'dispatch', 'param', 'code', 'controller', 'actionName']; + } + + public function __wakeup() + { + $this->app = Container::pull('app'); + $this->request = $this->app->request; + } + + public function __debugInfo() + { + return [ + 'dispatch' => $this->dispatch, + 'param' => $this->param, + 'code' => $this->code, + 'rule' => $this->rule, + ]; + } +} diff --git a/vendor/topthink/framework/src/think/route/Domain.php b/vendor/topthink/framework/src/think/route/Domain.php new file mode 100644 index 0000000..8c04af0 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/Domain.php @@ -0,0 +1,183 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +use think\helper\Str; +use think\Request; +use think\Route; +use think\route\dispatch\Callback as CallbackDispatch; +use think\route\dispatch\Controller as ControllerDispatch; + +/** + * 域名路由 + */ +class Domain extends RuleGroup +{ + /** + * 架构函数 + * @access public + * @param Route $router 路由对象 + * @param string $name 路由域名 + * @param mixed $rule 域名路由 + */ + public function __construct(Route $router, string $name = null, $rule = null) + { + $this->router = $router; + $this->domain = $name; + $this->rule = $rule; + } + + /** + * 检测域名路由 + * @access public + * @param Request $request 请求对象 + * @param string $url 访问地址 + * @param bool $completeMatch 路由是否完全匹配 + * @return Dispatch|false + */ + public function check(Request $request, string $url, bool $completeMatch = false) + { + // 检测URL绑定 + $result = $this->checkUrlBind($request, $url); + + if (!empty($this->option['append'])) { + $request->setRoute($this->option['append']); + unset($this->option['append']); + } + + if (false !== $result) { + return $result; + } + + return parent::check($request, $url, $completeMatch); + } + + /** + * 设置路由绑定 + * @access public + * @param string $bind 绑定信息 + * @return $this + */ + public function bind(string $bind) + { + $this->router->bind($bind, $this->domain); + + return $this; + } + + /** + * 检测URL绑定 + * @access private + * @param Request $request + * @param string $url URL地址 + * @return Dispatch|false + */ + private function checkUrlBind(Request $request, string $url) + { + $bind = $this->router->getDomainBind($this->domain); + + if ($bind) { + $this->parseBindAppendParam($bind); + + // 如果有URL绑定 则进行绑定检测 + $type = substr($bind, 0, 1); + $bind = substr($bind, 1); + + $bindTo = [ + '\\' => 'bindToClass', + '@' => 'bindToController', + ':' => 'bindToNamespace', + ]; + + if (isset($bindTo[$type])) { + return $this->{$bindTo[$type]}($request, $url, $bind); + } + } + + return false; + } + + protected function parseBindAppendParam(string &$bind): void + { + if (false !== strpos($bind, '?')) { + [$bind, $query] = explode('?', $bind); + parse_str($query, $vars); + $this->append($vars); + } + } + + /** + * 绑定到类 + * @access protected + * @param Request $request + * @param string $url URL地址 + * @param string $class 类名(带命名空间) + * @return CallbackDispatch + */ + protected function bindToClass(Request $request, string $url, string $class): CallbackDispatch + { + $array = explode('|', $url, 2); + $action = !empty($array[0]) ? $array[0] : $this->router->config('default_action'); + $param = []; + + if (!empty($array[1])) { + $this->parseUrlParams($array[1], $param); + } + + return new CallbackDispatch($request, $this, [$class, $action], $param); + } + + /** + * 绑定到命名空间 + * @access protected + * @param Request $request + * @param string $url URL地址 + * @param string $namespace 命名空间 + * @return CallbackDispatch + */ + protected function bindToNamespace(Request $request, string $url, string $namespace): CallbackDispatch + { + $array = explode('|', $url, 3); + $class = !empty($array[0]) ? $array[0] : $this->router->config('default_controller'); + $method = !empty($array[1]) ? $array[1] : $this->router->config('default_action'); + $param = []; + + if (!empty($array[2])) { + $this->parseUrlParams($array[2], $param); + } + + return new CallbackDispatch($request, $this, [$namespace . '\\' . Str::studly($class), $method], $param); + } + + /** + * 绑定到控制器 + * @access protected + * @param Request $request + * @param string $url URL地址 + * @param string $controller 控制器名 + * @return ControllerDispatch + */ + protected function bindToController(Request $request, string $url, string $controller): ControllerDispatch + { + $array = explode('|', $url, 2); + $action = !empty($array[0]) ? $array[0] : $this->router->config('default_action'); + $param = []; + + if (!empty($array[1])) { + $this->parseUrlParams($array[1], $param); + } + + return new ControllerDispatch($request, $this, $controller . '/' . $action, $param); + } + +} diff --git a/vendor/topthink/framework/src/think/route/Resource.php b/vendor/topthink/framework/src/think/route/Resource.php new file mode 100644 index 0000000..01565fc --- /dev/null +++ b/vendor/topthink/framework/src/think/route/Resource.php @@ -0,0 +1,251 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +use think\Route; + +/** + * 资源路由类 + */ +class Resource extends RuleGroup +{ + /** + * 资源路由名称 + * @var string + */ + protected $resource; + + /** + * 资源路由地址 + * @var string + */ + protected $route; + + /** + * REST方法定义 + * @var array + */ + protected $rest = []; + + /** + * 模型绑定 + * @var array + */ + protected $model = []; + + /** + * 数据验证 + * @var array + */ + protected $validate = []; + + /** + * 中间件 + * @var array + */ + protected $middleware = []; + + /** + * 架构函数 + * @access public + * @param Route $router 路由对象 + * @param RuleGroup $parent 上级对象 + * @param string $name 资源名称 + * @param string $route 路由地址 + * @param array $rest 资源定义 + */ + public function __construct(Route $router, RuleGroup $parent = null, string $name = '', string $route = '', array $rest = []) + { + $name = ltrim($name, '/'); + $this->router = $router; + $this->parent = $parent; + $this->resource = $name; + $this->route = $route; + $this->name = strpos($name, '.') ? strstr($name, '.', true) : $name; + + $this->setFullName(); + + // 资源路由默认为完整匹配 + $this->option['complete_match'] = true; + + $this->rest = $rest; + + if ($this->parent) { + $this->domain = $this->parent->getDomain(); + $this->parent->addRuleItem($this); + } + + if ($router->isTest()) { + $this->buildResourceRule(); + } + } + + /** + * 生成资源路由规则 + * @access protected + * @return void + */ + protected function buildResourceRule(): void + { + $rule = $this->resource; + $option = $this->option; + $origin = $this->router->getGroup(); + $this->router->setGroup($this); + + if (strpos($rule, '.')) { + // 注册嵌套资源路由 + $array = explode('.', $rule); + $last = array_pop($array); + $item = []; + + foreach ($array as $val) { + $item[] = $val . '/<' . ($option['var'][$val] ?? $val . '_id') . '>'; + } + + $rule = implode('/', $item) . '/' . $last; + } + + $prefix = substr($rule, strlen($this->name) + 1); + + // 注册资源路由 + foreach ($this->rest as $key => $val) { + if ((isset($option['only']) && !in_array($key, $option['only'])) + || (isset($option['except']) && in_array($key, $option['except']))) { + continue; + } + + if (isset($last) && strpos($val[1], '') && isset($option['var'][$last])) { + $val[1] = str_replace('', '<' . $option['var'][$last] . '>', $val[1]); + } elseif (strpos($val[1], '') && isset($option['var'][$rule])) { + $val[1] = str_replace('', '<' . $option['var'][$rule] . '>', $val[1]); + } + + $ruleItem = $this->addRule(trim($prefix . $val[1], '/'), $this->route . '/' . $val[2], $val[0]); + + foreach (['model', 'validate', 'middleware'] as $name) { + if (isset($this->$name[$key])) { + call_user_func_array([$ruleItem, $name], (array) $this->$name[$key]); + } + + } + } + + $this->router->setGroup($origin); + } + + /** + * 设置资源允许 + * @access public + * @param array $only 资源允许 + * @return $this + */ + public function only(array $only) + { + return $this->setOption('only', $only); + } + + /** + * 设置资源排除 + * @access public + * @param array $except 排除资源 + * @return $this + */ + public function except(array $except) + { + return $this->setOption('except', $except); + } + + /** + * 设置资源路由的变量 + * @access public + * @param array $vars 资源变量 + * @return $this + */ + public function vars(array $vars) + { + return $this->setOption('var', $vars); + } + + /** + * 绑定资源验证 + * @access public + * @param array|string $name 资源类型或者验证信息 + * @param array|string $validate 验证信息 + * @return $this + */ + public function withValidate($name, $validate = []) + { + if (is_array($name)) { + $this->validate = array_merge($this->validate, $name); + } else { + $this->validate[$name] = $validate; + } + + return $this; + } + + /** + * 绑定资源模型 + * @access public + * @param array|string $name 资源类型或者模型绑定 + * @param array|string $model 模型绑定 + * @return $this + */ + public function withModel($name, $model = []) + { + if (is_array($name)) { + $this->model = array_merge($this->model, $name); + } else { + $this->model[$name] = $model; + } + + return $this; + } + + /** + * 绑定资源模型 + * @access public + * @param array|string $name 资源类型或者中间件定义 + * @param array|string $middleware 中间件定义 + * @return $this + */ + public function withMiddleware($name, $middleware = []) + { + if (is_array($name)) { + $this->middleware = array_merge($this->middleware, $name); + } else { + $this->middleware[$name] = $middleware; + } + + return $this; + } + + /** + * rest方法定义和修改 + * @access public + * @param array|string $name 方法名称 + * @param array|bool $resource 资源 + * @return $this + */ + public function rest($name, $resource = []) + { + if (is_array($name)) { + $this->rest = $resource ? $name : array_merge($this->rest, $name); + } else { + $this->rest[$name] = $resource; + } + + return $this; + } + +} diff --git a/vendor/topthink/framework/src/think/route/Rule.php b/vendor/topthink/framework/src/think/route/Rule.php new file mode 100644 index 0000000..b0ef3f5 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/Rule.php @@ -0,0 +1,925 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +use Closure; +use think\Container; +use think\middleware\AllowCrossDomain; +use think\middleware\CheckRequestCache; +use think\middleware\FormTokenCheck; +use think\Request; +use think\Response; +use think\Route; +use think\route\dispatch\Callback as CallbackDispatch; +use think\route\dispatch\Controller as ControllerDispatch; +use think\route\dispatch\Redirect as RedirectDispatch; +use think\route\dispatch\Response as ResponseDispatch; +use think\route\dispatch\View as ViewDispatch; + +/** + * 路由规则基础类 + */ +abstract class Rule +{ + /** + * 路由标识 + * @var string + */ + protected $name; + + /** + * 所在域名 + * @var string + */ + protected $domain; + + /** + * 路由对象 + * @var Route + */ + protected $router; + + /** + * 路由所属分组 + * @var RuleGroup + */ + protected $parent; + + /** + * 路由规则 + * @var mixed + */ + protected $rule; + + /** + * 路由地址 + * @var string|Closure + */ + protected $route; + + /** + * 请求类型 + * @var string + */ + protected $method; + + /** + * 路由变量 + * @var array + */ + protected $vars = []; + + /** + * 路由参数 + * @var array + */ + protected $option = []; + + /** + * 路由变量规则 + * @var array + */ + protected $pattern = []; + + /** + * 需要和分组合并的路由参数 + * @var array + */ + protected $mergeOptions = ['model', 'append', 'middleware']; + + abstract public function check(Request $request, string $url, bool $completeMatch = false); + + /** + * 设置路由参数 + * @access public + * @param array $option 参数 + * @return $this + */ + public function option(array $option) + { + $this->option = array_merge($this->option, $option); + + return $this; + } + + /** + * 设置单个路由参数 + * @access public + * @param string $name 参数名 + * @param mixed $value 值 + * @return $this + */ + public function setOption(string $name, $value) + { + $this->option[$name] = $value; + + return $this; + } + + /** + * 注册变量规则 + * @access public + * @param array $pattern 变量规则 + * @return $this + */ + public function pattern(array $pattern) + { + $this->pattern = array_merge($this->pattern, $pattern); + + return $this; + } + + /** + * 设置标识 + * @access public + * @param string $name 标识名 + * @return $this + */ + public function name(string $name) + { + $this->name = $name; + + return $this; + } + + /** + * 获取路由对象 + * @access public + * @return Route + */ + public function getRouter(): Route + { + return $this->router; + } + + /** + * 获取Name + * @access public + * @return string + */ + public function getName(): string + { + return $this->name ?: ''; + } + + /** + * 获取当前路由规则 + * @access public + * @return mixed + */ + public function getRule() + { + return $this->rule; + } + + /** + * 获取当前路由地址 + * @access public + * @return mixed + */ + public function getRoute() + { + return $this->route; + } + + /** + * 获取当前路由的变量 + * @access public + * @return array + */ + public function getVars(): array + { + return $this->vars; + } + + /** + * 获取Parent对象 + * @access public + * @return $this|null + */ + public function getParent() + { + return $this->parent; + } + + /** + * 获取路由所在域名 + * @access public + * @return string + */ + public function getDomain(): string + { + return $this->domain ?: $this->parent->getDomain(); + } + + /** + * 获取路由参数 + * @access public + * @param string $name 变量名 + * @return mixed + */ + public function config(string $name = '') + { + return $this->router->config($name); + } + + /** + * 获取变量规则定义 + * @access public + * @param string $name 变量名 + * @return mixed + */ + public function getPattern(string $name = '') + { + if ('' === $name) { + return $this->pattern; + } + + return $this->pattern[$name] ?? null; + } + + /** + * 获取路由参数定义 + * @access public + * @param string $name 参数名 + * @param mixed $default 默认值 + * @return mixed + */ + public function getOption(string $name = '', $default = null) + { + if ('' === $name) { + return $this->option; + } + + return $this->option[$name] ?? $default; + } + + /** + * 获取当前路由的请求类型 + * @access public + * @return string + */ + public function getMethod(): string + { + return strtolower($this->method); + } + + /** + * 设置路由请求类型 + * @access public + * @param string $method 请求类型 + * @return $this + */ + public function method(string $method) + { + return $this->setOption('method', strtolower($method)); + } + + /** + * 检查后缀 + * @access public + * @param string $ext URL后缀 + * @return $this + */ + public function ext(string $ext = '') + { + return $this->setOption('ext', $ext); + } + + /** + * 检查禁止后缀 + * @access public + * @param string $ext URL后缀 + * @return $this + */ + public function denyExt(string $ext = '') + { + return $this->setOption('deny_ext', $ext); + } + + /** + * 检查域名 + * @access public + * @param string $domain 域名 + * @return $this + */ + public function domain(string $domain) + { + $this->domain = $domain; + return $this->setOption('domain', $domain); + } + + /** + * 设置参数过滤检查 + * @access public + * @param array $filter 参数过滤 + * @return $this + */ + public function filter(array $filter) + { + $this->option['filter'] = $filter; + + return $this; + } + + /** + * 绑定模型 + * @access public + * @param array|string|Closure $var 路由变量名 多个使用 & 分割 + * @param string|Closure $model 绑定模型类 + * @param bool $exception 是否抛出异常 + * @return $this + */ + public function model($var, $model = null, bool $exception = true) + { + if ($var instanceof Closure) { + $this->option['model'][] = $var; + } elseif (is_array($var)) { + $this->option['model'] = $var; + } elseif (is_null($model)) { + $this->option['model']['id'] = [$var, true]; + } else { + $this->option['model'][$var] = [$model, $exception]; + } + + return $this; + } + + /** + * 附加路由隐式参数 + * @access public + * @param array $append 追加参数 + * @return $this + */ + public function append(array $append = []) + { + $this->option['append'] = $append; + + return $this; + } + + /** + * 绑定验证 + * @access public + * @param mixed $validate 验证器类 + * @param string $scene 验证场景 + * @param array $message 验证提示 + * @param bool $batch 批量验证 + * @return $this + */ + public function validate($validate, string $scene = null, array $message = [], bool $batch = false) + { + $this->option['validate'] = [$validate, $scene, $message, $batch]; + + return $this; + } + + /** + * 指定路由中间件 + * @access public + * @param string|array|Closure $middleware 中间件 + * @param mixed $params 参数 + * @return $this + */ + public function middleware($middleware, ...$params) + { + if (empty($params) && is_array($middleware)) { + $this->option['middleware'] = $middleware; + } else { + foreach ((array) $middleware as $item) { + $this->option['middleware'][] = [$item, $params]; + } + } + + return $this; + } + + /** + * 允许跨域 + * @access public + * @param array $header 自定义Header + * @return $this + */ + public function allowCrossDomain(array $header = []) + { + return $this->middleware(AllowCrossDomain::class, $header); + } + + /** + * 表单令牌验证 + * @access public + * @param string $token 表单令牌token名称 + * @return $this + */ + public function token(string $token = '__token__') + { + return $this->middleware(FormTokenCheck::class, $token); + } + + /** + * 设置路由缓存 + * @access public + * @param array|string $cache 缓存 + * @return $this + */ + public function cache($cache) + { + return $this->middleware(CheckRequestCache::class, $cache); + } + + /** + * 检查URL分隔符 + * @access public + * @param string $depr URL分隔符 + * @return $this + */ + public function depr(string $depr) + { + return $this->setOption('param_depr', $depr); + } + + /** + * 设置需要合并的路由参数 + * @access public + * @param array $option 路由参数 + * @return $this + */ + public function mergeOptions(array $option = []) + { + $this->mergeOptions = array_merge($this->mergeOptions, $option); + return $this; + } + + /** + * 检查是否为HTTPS请求 + * @access public + * @param bool $https 是否为HTTPS + * @return $this + */ + public function https(bool $https = true) + { + return $this->setOption('https', $https); + } + + /** + * 检查是否为JSON请求 + * @access public + * @param bool $json 是否为JSON + * @return $this + */ + public function json(bool $json = true) + { + return $this->setOption('json', $json); + } + + /** + * 检查是否为AJAX请求 + * @access public + * @param bool $ajax 是否为AJAX + * @return $this + */ + public function ajax(bool $ajax = true) + { + return $this->setOption('ajax', $ajax); + } + + /** + * 检查是否为PJAX请求 + * @access public + * @param bool $pjax 是否为PJAX + * @return $this + */ + public function pjax(bool $pjax = true) + { + return $this->setOption('pjax', $pjax); + } + + /** + * 当前路由到一个模板地址 当使用数组的时候可以传入模板变量 + * @access public + * @param bool|array $view 视图 + * @return $this + */ + public function view($view = true) + { + return $this->setOption('view', $view); + } + + /** + * 当前路由为重定向 + * @access public + * @param bool $redirect 是否为重定向 + * @return $this + */ + public function redirect(bool $redirect = true) + { + return $this->setOption('redirect', $redirect); + } + + /** + * 设置status + * @access public + * @param int $status 状态码 + * @return $this + */ + public function status(int $status) + { + return $this->setOption('status', $status); + } + + /** + * 设置路由完整匹配 + * @access public + * @param bool $match 是否完整匹配 + * @return $this + */ + public function completeMatch(bool $match = true) + { + return $this->setOption('complete_match', $match); + } + + /** + * 是否去除URL最后的斜线 + * @access public + * @param bool $remove 是否去除最后斜线 + * @return $this + */ + public function removeSlash(bool $remove = true) + { + return $this->setOption('remove_slash', $remove); + } + + /** + * 设置路由规则全局有效 + * @access public + * @return $this + */ + public function crossDomainRule() + { + if ($this instanceof RuleGroup) { + $method = '*'; + } else { + $method = $this->method; + } + + $this->router->setCrossDomainRule($this, $method); + + return $this; + } + + /** + * 合并分组参数 + * @access public + * @return array + */ + public function mergeGroupOptions(): array + { + $parentOption = $this->parent->getOption(); + // 合并分组参数 + foreach ($this->mergeOptions as $item) { + if (isset($parentOption[$item]) && isset($this->option[$item])) { + $this->option[$item] = array_merge($parentOption[$item], $this->option[$item]); + } + } + + $this->option = array_merge($parentOption, $this->option); + + return $this->option; + } + + /** + * 解析匹配到的规则路由 + * @access public + * @param Request $request 请求对象 + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @param string $url URL地址 + * @param array $option 路由参数 + * @param array $matches 匹配的变量 + * @return Dispatch + */ + public function parseRule(Request $request, string $rule, $route, string $url, array $option = [], array $matches = []): Dispatch + { + if (is_string($route) && isset($option['prefix'])) { + // 路由地址前缀 + $route = $option['prefix'] . $route; + } + + // 替换路由地址中的变量 + if (is_string($route) && !empty($matches)) { + $search = $replace = []; + + foreach ($matches as $key => $value) { + $search[] = '<' . $key . '>'; + $replace[] = $value; + + $search[] = ':' . $key; + $replace[] = $value; + } + + $route = str_replace($search, $replace, $route); + } + + // 解析额外参数 + $count = substr_count($rule, '/'); + $url = array_slice(explode('|', $url), $count + 1); + $this->parseUrlParams(implode('|', $url), $matches); + + $this->vars = $matches; + + // 发起路由调度 + return $this->dispatch($request, $route, $option); + } + + /** + * 发起路由调度 + * @access protected + * @param Request $request Request对象 + * @param mixed $route 路由地址 + * @param array $option 路由参数 + * @return Dispatch + */ + protected function dispatch(Request $request, $route, array $option): Dispatch + { + if ($route instanceof Dispatch) { + $result = $route; + } elseif ($route instanceof Closure) { + // 执行闭包 + $result = new CallbackDispatch($request, $this, $route, $this->vars); + } elseif ($route instanceof Response) { + $result = new ResponseDispatch($request, $this, $route); + } elseif (isset($option['view']) && false !== $option['view']) { + $result = new ViewDispatch($request, $this, $route, is_array($option['view']) ? $option['view'] : $this->vars); + } elseif (!empty($option['redirect'])) { + // 路由到重定向地址 + $result = new RedirectDispatch($request, $this, $route, $this->vars, $option['status'] ?? 301); + } elseif (false !== strpos($route, '\\')) { + // 路由到类的方法 + $result = $this->dispatchMethod($request, $route); + } else { + // 路由到控制器/操作 + $result = $this->dispatchController($request, $route); + } + + return $result; + } + + /** + * 解析URL地址为 模块/控制器/操作 + * @access protected + * @param Request $request Request对象 + * @param string $route 路由地址 + * @return CallbackDispatch + */ + protected function dispatchMethod(Request $request, string $route): CallbackDispatch + { + $path = $this->parseUrlPath($route); + + $route = str_replace('/', '@', implode('/', $path)); + $method = strpos($route, '@') ? explode('@', $route) : $route; + + return new CallbackDispatch($request, $this, $method, $this->vars); + } + + /** + * 解析URL地址为 模块/控制器/操作 + * @access protected + * @param Request $request Request对象 + * @param string $route 路由地址 + * @return ControllerDispatch + */ + protected function dispatchController(Request $request, string $route): ControllerDispatch + { + $path = $this->parseUrlPath($route); + + $action = array_pop($path); + $controller = !empty($path) ? array_pop($path) : null; + + // 路由到模块/控制器/操作 + return new ControllerDispatch($request, $this, [$controller, $action], $this->vars); + } + + /** + * 路由检查 + * @access protected + * @param array $option 路由参数 + * @param Request $request Request对象 + * @return bool + */ + protected function checkOption(array $option, Request $request): bool + { + // 请求类型检测 + if (!empty($option['method'])) { + if (is_string($option['method']) && false === stripos($option['method'], $request->method())) { + return false; + } + } + + // AJAX PJAX 请求检查 + foreach (['ajax', 'pjax', 'json'] as $item) { + if (isset($option[$item])) { + $call = 'is' . $item; + if ($option[$item] && !$request->$call() || !$option[$item] && $request->$call()) { + return false; + } + } + } + + // 伪静态后缀检测 + if ($request->url() != '/' && ((isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', '|' . $request->ext() . '|')) + || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', '|' . $request->ext() . '|')))) { + return false; + } + + // 域名检查 + if ((isset($option['domain']) && !in_array($option['domain'], [$request->host(true), $request->subDomain()]))) { + return false; + } + + // HTTPS检查 + if ((isset($option['https']) && $option['https'] && !$request->isSsl()) + || (isset($option['https']) && !$option['https'] && $request->isSsl())) { + return false; + } + + // 请求参数检查 + if (isset($option['filter'])) { + foreach ($option['filter'] as $name => $value) { + if ($request->param($name, '', null) != $value) { + return false; + } + } + } + + return true; + } + + /** + * 解析URL地址中的参数Request对象 + * @access protected + * @param string $rule 路由规则 + * @param array $var 变量 + * @return void + */ + protected function parseUrlParams(string $url, array &$var = []): void + { + if ($url) { + preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) { + $var[$match[1]] = strip_tags($match[2]); + }, $url); + } + } + + /** + * 解析URL的pathinfo参数 + * @access public + * @param string $url URL地址 + * @return array + */ + public function parseUrlPath(string $url): array + { + // 分隔符替换 确保路由定义使用统一的分隔符 + $url = str_replace('|', '/', $url); + $url = trim($url, '/'); + + if (strpos($url, '/')) { + // [控制器/操作] + $path = explode('/', $url); + } else { + $path = [$url]; + } + + return $path; + } + + /** + * 生成路由的正则规则 + * @access protected + * @param string $rule 路由规则 + * @param array $match 匹配的变量 + * @param array $pattern 路由变量规则 + * @param array $option 路由参数 + * @param bool $completeMatch 路由是否完全匹配 + * @param string $suffix 路由正则变量后缀 + * @return string + */ + protected function buildRuleRegex(string $rule, array $match, array $pattern = [], array $option = [], bool $completeMatch = false, string $suffix = ''): string + { + foreach ($match as $name) { + $replace[] = $this->buildNameRegex($name, $pattern, $suffix); + } + + // 是否区分 / 地址访问 + if ('/' != $rule) { + if (!empty($option['remove_slash'])) { + $rule = rtrim($rule, '/'); + } elseif (substr($rule, -1) == '/') { + $rule = rtrim($rule, '/'); + $hasSlash = true; + } + } + + $regex = str_replace(array_unique($match), array_unique($replace), $rule); + $regex = str_replace([')?/', ')/', ')?-', ')-', '\\\\/'], [')\/', ')\/', ')\-', ')\-', '\/'], $regex); + + if (isset($hasSlash)) { + $regex .= '\/'; + } + + return $regex . ($completeMatch ? '$' : ''); + } + + /** + * 生成路由变量的正则规则 + * @access protected + * @param string $name 路由变量 + * @param array $pattern 变量规则 + * @param string $suffix 路由正则变量后缀 + * @return string + */ + protected function buildNameRegex(string $name, array $pattern, string $suffix): string + { + $optional = ''; + $slash = substr($name, 0, 1); + + if (in_array($slash, ['/', '-'])) { + $prefix = '\\' . $slash; + $name = substr($name, 1); + $slash = substr($name, 0, 1); + } else { + $prefix = ''; + } + + if ('<' != $slash) { + return $prefix . preg_quote($name, '/'); + } + + if (strpos($name, '?')) { + $name = substr($name, 1, -2); + $optional = '?'; + } elseif (strpos($name, '>')) { + $name = substr($name, 1, -1); + } + + if (isset($pattern[$name])) { + $nameRule = $pattern[$name]; + if (0 === strpos($nameRule, '/') && '/' == substr($nameRule, -1)) { + $nameRule = substr($nameRule, 1, -1); + } + } else { + $nameRule = $this->router->config('default_route_pattern'); + } + + return '(' . $prefix . '(?<' . $name . $suffix . '>' . $nameRule . '))' . $optional; + } + + /** + * 设置路由参数 + * @access public + * @param string $method 方法名 + * @param array $args 调用参数 + * @return $this + */ + public function __call($method, $args) + { + if (count($args) > 1) { + $args[0] = $args; + } + array_unshift($args, $method); + + return call_user_func_array([$this, 'setOption'], $args); + } + + public function __sleep() + { + return ['name', 'rule', 'route', 'method', 'vars', 'option', 'pattern']; + } + + public function __wakeup() + { + $this->router = Container::pull('route'); + } + + public function __debugInfo() + { + return [ + 'name' => $this->name, + 'rule' => $this->rule, + 'route' => $this->route, + 'method' => $this->method, + 'vars' => $this->vars, + 'option' => $this->option, + 'pattern' => $this->pattern, + ]; + } +} diff --git a/vendor/topthink/framework/src/think/route/RuleGroup.php b/vendor/topthink/framework/src/think/route/RuleGroup.php new file mode 100644 index 0000000..5bfff9b --- /dev/null +++ b/vendor/topthink/framework/src/think/route/RuleGroup.php @@ -0,0 +1,541 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +use Closure; +use think\Container; +use think\Exception; +use think\Request; +use think\Response; +use think\Route; +use think\route\dispatch\Response as ResponseDispatch; + +/** + * 路由分组类 + */ +class RuleGroup extends Rule +{ + /** + * 分组路由(包括子分组) + * @var array + */ + protected $rules = [ + '*' => [], + 'get' => [], + 'post' => [], + 'put' => [], + 'patch' => [], + 'delete' => [], + 'head' => [], + 'options' => [], + ]; + + /** + * 分组路由规则 + * @var mixed + */ + protected $rule; + + /** + * MISS路由 + * @var RuleItem + */ + protected $miss; + + /** + * 完整名称 + * @var string + */ + protected $fullName; + + /** + * 分组别名 + * @var string + */ + protected $alias; + + /** + * 架构函数 + * @access public + * @param Route $router 路由对象 + * @param RuleGroup $parent 上级对象 + * @param string $name 分组名称 + * @param mixed $rule 分组路由 + */ + public function __construct(Route $router, RuleGroup $parent = null, string $name = '', $rule = null) + { + $this->router = $router; + $this->parent = $parent; + $this->rule = $rule; + $this->name = trim($name, '/'); + + $this->setFullName(); + + if ($this->parent) { + $this->domain = $this->parent->getDomain(); + $this->parent->addRuleItem($this); + } + + if ($router->isTest()) { + $this->lazy(false); + } + } + + /** + * 设置分组的路由规则 + * @access public + * @return void + */ + protected function setFullName(): void + { + if (false !== strpos($this->name, ':')) { + $this->name = preg_replace(['/\[\:(\w+)\]/', '/\:(\w+)/'], ['<\1?>', '<\1>'], $this->name); + } + + if ($this->parent && $this->parent->getFullName()) { + $this->fullName = $this->parent->getFullName() . ($this->name ? '/' . $this->name : ''); + } else { + $this->fullName = $this->name; + } + + if ($this->name) { + $this->router->getRuleName()->setGroup($this->name, $this); + } + } + + /** + * 获取所属域名 + * @access public + * @return string + */ + public function getDomain(): string + { + return $this->domain ?: '-'; + } + + /** + * 获取分组别名 + * @access public + * @return string + */ + public function getAlias(): string + { + return $this->alias ?: ''; + } + + /** + * 检测分组路由 + * @access public + * @param Request $request 请求对象 + * @param string $url 访问地址 + * @param bool $completeMatch 路由是否完全匹配 + * @return Dispatch|false + */ + public function check(Request $request, string $url, bool $completeMatch = false) + { + // 检查分组有效性 + if (!$this->checkOption($this->option, $request) || !$this->checkUrl($url)) { + return false; + } + + // 解析分组路由 + if ($this instanceof Resource) { + $this->buildResourceRule(); + } elseif ($this->rule instanceof Response) { + return new ResponseDispatch($request, $this, $this->rule); + } else { + $this->parseGroupRule($this->rule); + } + + // 获取当前路由规则 + $method = strtolower($request->method()); + $rules = $this->getMethodRules($method); + + if ($this->parent) { + // 合并分组参数 + $this->mergeGroupOptions(); + // 合并分组变量规则 + $this->pattern = array_merge($this->parent->getPattern(), $this->pattern); + } + + if (isset($this->option['complete_match'])) { + $completeMatch = $this->option['complete_match']; + } + + if (!empty($this->option['merge_rule_regex'])) { + // 合并路由正则规则进行路由匹配检查 + $result = $this->checkMergeRuleRegex($request, $rules, $url, $completeMatch); + + if (false !== $result) { + return $result; + } + } + + // 检查分组路由 + foreach ($rules as $key => $item) { + $result = $item->check($request, $url, $completeMatch); + + if (false !== $result) { + return $result; + } + } + + if ($this->miss && in_array($this->miss->getMethod(), ['*', $method])) { + // 未匹配所有路由的路由规则处理 + $result = $this->parseRule($request, '', $this->miss->getRoute(), $url, $this->miss->mergeGroupOptions()); + } else { + $result = false; + } + + return $result; + } + + /** + * 获取当前请求的路由规则(包括子分组、资源路由) + * @access protected + * @param string $method 请求类型 + * @return array + */ + protected function getMethodRules(string $method): array + { + return array_merge($this->rules[$method], $this->rules['*']); + } + + /** + * 分组URL匹配检查 + * @access protected + * @param string $url URL + * @return bool + */ + protected function checkUrl(string $url): bool + { + if ($this->fullName) { + $pos = strpos($this->fullName, '<'); + + if (false !== $pos) { + $str = substr($this->fullName, 0, $pos); + } else { + $str = $this->fullName; + } + + if ($str && 0 !== stripos(str_replace('|', '/', $url), $str)) { + return false; + } + } + + return true; + } + + /** + * 设置路由分组别名 + * @access public + * @param string $alias 路由分组别名 + * @return $this + */ + public function alias(string $alias) + { + $this->alias = $alias; + $this->router->getRuleName()->setGroup($alias, $this); + + return $this; + } + + /** + * 延迟解析分组的路由规则 + * @access public + * @param bool $lazy 路由是否延迟解析 + * @return $this + */ + public function lazy(bool $lazy = true) + { + if (!$lazy) { + $this->parseGroupRule($this->rule); + $this->rule = null; + } + + return $this; + } + + /** + * 解析分组和域名的路由规则及绑定 + * @access public + * @param mixed $rule 路由规则 + * @return void + */ + public function parseGroupRule($rule): void + { + $origin = $this->router->getGroup(); + $this->router->setGroup($this); + + if ($rule instanceof \Closure) { + Container::getInstance()->invokeFunction($rule); + } elseif (is_string($rule) && $rule) { + $this->router->bind($rule, $this->domain); + } + + $this->router->setGroup($origin); + } + + /** + * 检测分组路由 + * @access public + * @param Request $request 请求对象 + * @param array $rules 路由规则 + * @param string $url 访问地址 + * @param bool $completeMatch 路由是否完全匹配 + * @return Dispatch|false + */ + protected function checkMergeRuleRegex(Request $request, array &$rules, string $url, bool $completeMatch) + { + $depr = $this->router->config('pathinfo_depr'); + $url = $depr . str_replace('|', $depr, $url); + $regex = []; + $items = []; + + foreach ($rules as $key => $item) { + if ($item instanceof RuleItem) { + $rule = $depr . str_replace('/', $depr, $item->getRule()); + if ($depr == $rule && $depr != $url) { + unset($rules[$key]); + continue; + } + + $complete = $item->getOption('complete_match', $completeMatch); + + if (false === strpos($rule, '<')) { + if (0 === strcasecmp($rule, $url) || (!$complete && 0 === strncasecmp($rule, $url, strlen($rule)))) { + return $item->checkRule($request, $url, []); + } + + unset($rules[$key]); + continue; + } + + $slash = preg_quote('/-' . $depr, '/'); + + if ($matchRule = preg_split('/[' . $slash . ']<\w+\??>/', $rule, 2)) { + if ($matchRule[0] && 0 !== strncasecmp($rule, $url, strlen($matchRule[0]))) { + unset($rules[$key]); + continue; + } + } + + if (preg_match_all('/[' . $slash . ']??/', $rule, $matches)) { + unset($rules[$key]); + $pattern = array_merge($this->getPattern(), $item->getPattern()); + $option = array_merge($this->getOption(), $item->getOption()); + + $regex[$key] = $this->buildRuleRegex($rule, $matches[0], $pattern, $option, $complete, '_THINK_' . $key); + $items[$key] = $item; + } + } + } + + if (empty($regex)) { + return false; + } + + try { + $result = preg_match('/^(?:' . implode('|', $regex) . ')/u', $url, $match); + } catch (\Exception $e) { + throw new Exception('route pattern error'); + } + + if ($result) { + $var = []; + foreach ($match as $key => $val) { + if (is_string($key) && '' !== $val) { + [$name, $pos] = explode('_THINK_', $key); + + $var[$name] = $val; + } + } + + if (!isset($pos)) { + foreach ($regex as $key => $item) { + if (0 === strpos(str_replace(['\/', '\-', '\\' . $depr], ['/', '-', $depr], $item), $match[0])) { + $pos = $key; + break; + } + } + } + + $rule = $items[$pos]->getRule(); + $array = $this->router->getRule($rule); + + foreach ($array as $item) { + if (in_array($item->getMethod(), ['*', strtolower($request->method())])) { + $result = $item->checkRule($request, $url, $var); + + if (false !== $result) { + return $result; + } + } + } + } + + return false; + } + + /** + * 获取分组的MISS路由 + * @access public + * @return RuleItem|null + */ + public function getMissRule(): ? RuleItem + { + return $this->miss; + } + + /** + * 注册MISS路由 + * @access public + * @param string|Closure $route 路由地址 + * @param string $method 请求类型 + * @return RuleItem + */ + public function miss($route, string $method = '*') : RuleItem + { + // 创建路由规则实例 + $ruleItem = new RuleItem($this->router, $this, null, '', $route, strtolower($method)); + + $ruleItem->setMiss(); + $this->miss = $ruleItem; + + return $ruleItem; + } + + /** + * 添加分组下的路由规则 + * @access public + * @param string $rule 路由规则 + * @param mixed $route 路由地址 + * @param string $method 请求类型 + * @return RuleItem + */ + public function addRule(string $rule, $route = null, string $method = '*'): RuleItem + { + // 读取路由标识 + if (is_string($route)) { + $name = $route; + } else { + $name = null; + } + + $method = strtolower($method); + + if ('' === $rule || '/' === $rule) { + $rule .= '$'; + } + + // 创建路由规则实例 + $ruleItem = new RuleItem($this->router, $this, $name, $rule, $route, $method); + + $this->addRuleItem($ruleItem, $method); + + return $ruleItem; + } + + /** + * 注册分组下的路由规则 + * @access public + * @param Rule $rule 路由规则 + * @param string $method 请求类型 + * @return $this + */ + public function addRuleItem(Rule $rule, string $method = '*') + { + if (strpos($method, '|')) { + $rule->method($method); + $method = '*'; + } + + $this->rules[$method][] = $rule; + + if ($rule instanceof RuleItem && 'options' != $method) { + $this->rules['options'][] = $rule->setAutoOptions(); + } + + return $this; + } + + /** + * 设置分组的路由前缀 + * @access public + * @param string $prefix 路由前缀 + * @return $this + */ + public function prefix(string $prefix) + { + if ($this->parent && $this->parent->getOption('prefix')) { + $prefix = $this->parent->getOption('prefix') . $prefix; + } + + return $this->setOption('prefix', $prefix); + } + + /** + * 合并分组的路由规则正则 + * @access public + * @param bool $merge 是否合并 + * @return $this + */ + public function mergeRuleRegex(bool $merge = true) + { + return $this->setOption('merge_rule_regex', $merge); + } + + /** + * 获取完整分组Name + * @access public + * @return string + */ + public function getFullName(): string + { + return $this->fullName ?: ''; + } + + /** + * 获取分组的路由规则 + * @access public + * @param string $method 请求类型 + * @return array + */ + public function getRules(string $method = ''): array + { + if ('' === $method) { + return $this->rules; + } + + return $this->rules[strtolower($method)] ?? []; + } + + /** + * 清空分组下的路由规则 + * @access public + * @return void + */ + public function clear(): void + { + $this->rules = [ + '*' => [], + 'get' => [], + 'post' => [], + 'put' => [], + 'patch' => [], + 'delete' => [], + 'head' => [], + 'options' => [], + ]; + } +} diff --git a/vendor/topthink/framework/src/think/route/RuleItem.php b/vendor/topthink/framework/src/think/route/RuleItem.php new file mode 100644 index 0000000..f7f72ba --- /dev/null +++ b/vendor/topthink/framework/src/think/route/RuleItem.php @@ -0,0 +1,330 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +use think\Exception; +use think\Request; +use think\Route; + +/** + * 路由规则类 + */ +class RuleItem extends Rule +{ + /** + * 是否为MISS规则 + * @var bool + */ + protected $miss = false; + + /** + * 是否为额外自动注册的OPTIONS规则 + * @var bool + */ + protected $autoOption = false; + + /** + * 架构函数 + * @access public + * @param Route $router 路由实例 + * @param RuleGroup $parent 上级对象 + * @param string $name 路由标识 + * @param string $rule 路由规则 + * @param string|\Closure $route 路由地址 + * @param string $method 请求类型 + */ + public function __construct(Route $router, RuleGroup $parent, string $name = null, string $rule = '', $route = null, string $method = '*') + { + $this->router = $router; + $this->parent = $parent; + $this->name = $name; + $this->route = $route; + $this->method = $method; + + $this->setRule($rule); + + $this->router->setRule($this->rule, $this); + } + + /** + * 设置当前路由规则为MISS路由 + * @access public + * @return $this + */ + public function setMiss() + { + $this->miss = true; + return $this; + } + + /** + * 判断当前路由规则是否为MISS路由 + * @access public + * @return bool + */ + public function isMiss(): bool + { + return $this->miss; + } + + /** + * 设置当前路由为自动注册OPTIONS + * @access public + * @return $this + */ + public function setAutoOptions() + { + $this->autoOption = true; + return $this; + } + + /** + * 判断当前路由规则是否为自动注册的OPTIONS路由 + * @access public + * @return bool + */ + public function isAutoOptions(): bool + { + return $this->autoOption; + } + + /** + * 获取当前路由的URL后缀 + * @access public + * @return string|null + */ + public function getSuffix() + { + if (isset($this->option['ext'])) { + $suffix = $this->option['ext']; + } elseif ($this->parent->getOption('ext')) { + $suffix = $this->parent->getOption('ext'); + } else { + $suffix = null; + } + + return $suffix; + } + + /** + * 路由规则预处理 + * @access public + * @param string $rule 路由规则 + * @return void + */ + public function setRule(string $rule): void + { + if ('$' == substr($rule, -1, 1)) { + // 是否完整匹配 + $rule = substr($rule, 0, -1); + + $this->option['complete_match'] = true; + } + + $rule = '/' != $rule ? ltrim($rule, '/') : ''; + + if ($this->parent && $prefix = $this->parent->getFullName()) { + $rule = $prefix . ($rule ? '/' . ltrim($rule, '/') : ''); + } + + if (false !== strpos($rule, ':')) { + $this->rule = preg_replace(['/\[\:(\w+)\]/', '/\:(\w+)/'], ['<\1?>', '<\1>'], $rule); + } else { + $this->rule = $rule; + } + + // 生成路由标识的快捷访问 + $this->setRuleName(); + } + + /** + * 设置别名 + * @access public + * @param string $name + * @return $this + */ + public function name(string $name) + { + $this->name = $name; + $this->setRuleName(true); + + return $this; + } + + /** + * 设置路由标识 用于URL反解生成 + * @access protected + * @param bool $first 是否插入开头 + * @return void + */ + protected function setRuleName(bool $first = false): void + { + if ($this->name) { + $this->router->setName($this->name, $this, $first); + } + } + + /** + * 检测路由 + * @access public + * @param Request $request 请求对象 + * @param string $url 访问地址 + * @param array $match 匹配路由变量 + * @param bool $completeMatch 路由是否完全匹配 + * @return Dispatch|false + */ + public function checkRule(Request $request, string $url, $match = null, bool $completeMatch = false) + { + // 检查参数有效性 + if (!$this->checkOption($this->option, $request)) { + return false; + } + + // 合并分组参数 + $option = $this->mergeGroupOptions(); + + $url = $this->urlSuffixCheck($request, $url, $option); + + if (is_null($match)) { + $match = $this->match($url, $option, $completeMatch); + } + + if (false !== $match) { + return $this->parseRule($request, $this->rule, $this->route, $url, $option, $match); + } + + return false; + } + + /** + * 检测路由(含路由匹配) + * @access public + * @param Request $request 请求对象 + * @param string $url 访问地址 + * @param bool $completeMatch 路由是否完全匹配 + * @return Dispatch|false + */ + public function check(Request $request, string $url, bool $completeMatch = false) + { + return $this->checkRule($request, $url, null, $completeMatch); + } + + /** + * URL后缀及Slash检查 + * @access protected + * @param Request $request 请求对象 + * @param string $url 访问地址 + * @param array $option 路由参数 + * @return string + */ + protected function urlSuffixCheck(Request $request, string $url, array $option = []): string + { + // 是否区分 / 地址访问 + if (!empty($option['remove_slash']) && '/' != $this->rule) { + $this->rule = rtrim($this->rule, '/'); + $url = rtrim($url, '|'); + } + + if (isset($option['ext'])) { + // 路由ext参数 优先于系统配置的URL伪静态后缀参数 + $url = preg_replace('/\.(' . $request->ext() . ')$/i', '', $url); + } + + return $url; + } + + /** + * 检测URL和规则路由是否匹配 + * @access private + * @param string $url URL地址 + * @param array $option 路由参数 + * @param bool $completeMatch 路由是否完全匹配 + * @return array|false + */ + private function match(string $url, array $option, bool $completeMatch) + { + if (isset($option['complete_match'])) { + $completeMatch = $option['complete_match']; + } + + $depr = $this->router->config('pathinfo_depr'); + $pattern = array_merge($this->parent->getPattern(), $this->pattern); + + // 检查完整规则定义 + if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . ($completeMatch ? '$' : '') . '/', str_replace('|', $depr, $url))) { + return false; + } + + $var = []; + $url = $depr . str_replace('|', $depr, $url); + $rule = $depr . str_replace('/', $depr, $this->rule); + + if ($depr == $rule && $depr != $url) { + return false; + } + + if (false === strpos($rule, '<')) { + if (0 === strcasecmp($rule, $url) || (!$completeMatch && 0 === strncasecmp($rule . $depr, $url . $depr, strlen($rule . $depr)))) { + return $var; + } + return false; + } + + $slash = preg_quote('/-' . $depr, '/'); + + if ($matchRule = preg_split('/[' . $slash . ']?<\w+\??>/', $rule, 2)) { + if ($matchRule[0] && 0 !== strncasecmp($rule, $url, strlen($matchRule[0]))) { + return false; + } + } + + if (preg_match_all('/[' . $slash . ']??/', $rule, $matches)) { + $regex = $this->buildRuleRegex($rule, $matches[0], $pattern, $option, $completeMatch); + + try { + if (!preg_match('/^' . $regex . '/u', $url, $match)) { + return false; + } + } catch (\Exception $e) { + throw new Exception('route pattern error'); + } + + foreach ($match as $key => $val) { + if (is_string($key)) { + $var[$key] = $val; + } + } + } + + // 成功匹配后返回URL中的动态变量数组 + return $var; + } + + /** + * 设置路由所属分组(用于注解路由) + * @access public + * @param string $name 分组名称或者标识 + * @return $this + */ + public function group(string $name) + { + $group = $this->router->getRuleName()->getGroup($name); + + if ($group) { + $this->parent = $group; + $this->setRule($this->rule); + } + + return $this; + } +} diff --git a/vendor/topthink/framework/src/think/route/RuleName.php b/vendor/topthink/framework/src/think/route/RuleName.php new file mode 100644 index 0000000..9b1088a --- /dev/null +++ b/vendor/topthink/framework/src/think/route/RuleName.php @@ -0,0 +1,195 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +/** + * 路由标识管理类 + */ +class RuleName +{ + /** + * 路由标识 + * @var array + */ + protected $item = []; + + /** + * 路由规则 + * @var array + */ + protected $rule = []; + + /** + * 路由分组 + * @var array + */ + protected $group = []; + + /** + * 注册路由标识 + * @access public + * @param string $name 路由标识 + * @param RuleItem $ruleItem 路由规则 + * @param bool $first 是否优先 + * @return void + */ + public function setName(string $name, RuleItem $ruleItem, bool $first = false): void + { + $name = strtolower($name); + if ($first && isset($this->item[$name])) { + array_unshift($this->item[$name], $ruleItem); + } else { + $this->item[$name][] = $ruleItem; + } + } + + /** + * 注册路由分组标识 + * @access public + * @param string $name 路由分组标识 + * @param RuleGroup $group 路由分组 + * @return void + */ + public function setGroup(string $name, RuleGroup $group): void + { + $this->group[strtolower($name)] = $group; + } + + /** + * 注册路由规则 + * @access public + * @param string $rule 路由规则 + * @param RuleItem $ruleItem 路由 + * @return void + */ + public function setRule(string $rule, RuleItem $ruleItem): void + { + $route = $ruleItem->getRoute(); + + if (is_string($route)) { + $this->rule[$rule][$route] = $ruleItem; + } else { + $this->rule[$rule][] = $ruleItem; + } + } + + /** + * 根据路由规则获取路由对象(列表) + * @access public + * @param string $rule 路由标识 + * @return RuleItem[] + */ + public function getRule(string $rule): array + { + return $this->rule[$rule] ?? []; + } + + /** + * 根据路由分组标识获取分组 + * @access public + * @param string $name 路由分组标识 + * @return RuleGroup|null + */ + public function getGroup(string $name) + { + return $this->group[strtolower($name)] ?? null; + } + + /** + * 清空路由规则 + * @access public + * @return void + */ + public function clear(): void + { + $this->item = []; + $this->rule = []; + } + + /** + * 获取全部路由列表 + * @access public + * @return array + */ + public function getRuleList(): array + { + $list = []; + + foreach ($this->rule as $rule => $rules) { + foreach ($rules as $item) { + $val = []; + + foreach (['method', 'rule', 'name', 'route', 'domain', 'pattern', 'option'] as $param) { + $call = 'get' . $param; + $val[$param] = $item->$call(); + } + + if ($item->isMiss()) { + $val['rule'] .= ''; + } + + $list[] = $val; + } + } + + return $list; + } + + /** + * 导入路由标识 + * @access public + * @param array $item 路由标识 + * @return void + */ + public function import(array $item): void + { + $this->item = $item; + } + + /** + * 根据路由标识获取路由信息(用于URL生成) + * @access public + * @param string $name 路由标识 + * @param string $domain 域名 + * @param string $method 请求类型 + * @return array + */ + public function getName(string $name = null, string $domain = null, string $method = '*'): array + { + if (is_null($name)) { + return $this->item; + } + + $name = strtolower($name); + $method = strtolower($method); + $result = []; + + if (isset($this->item[$name])) { + if (is_null($domain)) { + $result = $this->item[$name]; + } else { + foreach ($this->item[$name] as $item) { + $itemDomain = $item->getDomain(); + $itemMethod = $item->getMethod(); + + if (($itemDomain == $domain || '-' == $itemDomain) && ('*' == $itemMethod || '*' == $method || $method == $itemMethod)) { + $result[] = $item; + } + } + } + } + + return $result; + } + +} diff --git a/vendor/topthink/framework/src/think/route/Url.php b/vendor/topthink/framework/src/think/route/Url.php new file mode 100644 index 0000000..d9ecfd8 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/Url.php @@ -0,0 +1,512 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route; + +use think\App; +use think\Route; + +/** + * 路由地址生成 + */ +class Url +{ + /** + * 应用对象 + * @var App + */ + protected $app; + + /** + * 路由对象 + * @var Route + */ + protected $route; + + /** + * URL变量 + * @var array + */ + protected $vars = []; + + /** + * 路由URL + * @var string + */ + protected $url; + + /** + * URL 根地址 + * @var string + */ + protected $root = ''; + + /** + * HTTPS + * @var bool + */ + protected $https; + + /** + * URL后缀 + * @var string|bool + */ + protected $suffix = true; + + /** + * URL域名 + * @var string|bool + */ + protected $domain = false; + + /** + * 架构函数 + * @access public + * @param string $url URL地址 + * @param array $vars 参数 + */ + public function __construct(Route $route, App $app, string $url = '', array $vars = []) + { + $this->route = $route; + $this->app = $app; + $this->url = $url; + $this->vars = $vars; + } + + /** + * 设置URL参数 + * @access public + * @param array $vars URL参数 + * @return $this + */ + public function vars(array $vars = []) + { + $this->vars = $vars; + return $this; + } + + /** + * 设置URL后缀 + * @access public + * @param string|bool $suffix URL后缀 + * @return $this + */ + public function suffix($suffix) + { + $this->suffix = $suffix; + return $this; + } + + /** + * 设置URL域名(或者子域名) + * @access public + * @param string|bool $domain URL域名 + * @return $this + */ + public function domain($domain) + { + $this->domain = $domain; + return $this; + } + + /** + * 设置URL 根地址 + * @access public + * @param string $root URL root + * @return $this + */ + public function root(string $root) + { + $this->root = $root; + return $this; + } + + /** + * 设置是否使用HTTPS + * @access public + * @param bool $https + * @return $this + */ + public function https(bool $https = true) + { + $this->https = $https; + return $this; + } + + /** + * 检测域名 + * @access protected + * @param string $url URL + * @param string|true $domain 域名 + * @return string + */ + protected function parseDomain(string &$url, $domain): string + { + if (!$domain) { + return ''; + } + + $request = $this->app->request; + $rootDomain = $request->rootDomain(); + + if (true === $domain) { + // 自动判断域名 + $domain = $request->host(); + $domains = $this->route->getDomains(); + + if (!empty($domains)) { + $route_domain = array_keys($domains); + foreach ($route_domain as $domain_prefix) { + if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) { + foreach ($domains as $key => $rule) { + $rule = is_array($rule) ? $rule[0] : $rule; + if (is_string($rule) && false === strpos($key, '*') && 0 === strpos($url, $rule)) { + $url = ltrim($url, $rule); + $domain = $key; + + // 生成对应子域名 + if (!empty($rootDomain)) { + $domain .= $rootDomain; + } + break; + } elseif (false !== strpos($key, '*')) { + if (!empty($rootDomain)) { + $domain .= $rootDomain; + } + + break; + } + } + } + } + } + } elseif (false === strpos($domain, '.') && 0 !== strpos($domain, $rootDomain)) { + $domain .= '.' . $rootDomain; + } + + if (false !== strpos($domain, '://')) { + $scheme = ''; + } else { + $scheme = $this->https || $request->isSsl() ? 'https://' : 'http://'; + } + + return $scheme . $domain; + } + + /** + * 解析URL后缀 + * @access protected + * @param string|bool $suffix 后缀 + * @return string + */ + protected function parseSuffix($suffix): string + { + if ($suffix) { + $suffix = true === $suffix ? $this->route->config('url_html_suffix') : $suffix; + + if (is_string($suffix) && $pos = strpos($suffix, '|')) { + $suffix = substr($suffix, 0, $pos); + } + } + + return (empty($suffix) || 0 === strpos($suffix, '.')) ? (string) $suffix : '.' . $suffix; + } + + /** + * 直接解析URL地址 + * @access protected + * @param string $url URL + * @param string|bool $domain Domain + * @return string + */ + protected function parseUrl(string $url, &$domain): string + { + $request = $this->app->request; + + if (0 === strpos($url, '/')) { + // 直接作为路由地址解析 + $url = substr($url, 1); + } elseif (false !== strpos($url, '\\')) { + // 解析到类 + $url = ltrim(str_replace('\\', '/', $url), '/'); + } elseif (0 === strpos($url, '@')) { + // 解析到控制器 + $url = substr($url, 1); + } elseif ('' === $url) { + $url = $request->controller() . '/' . $request->action(); + } else { + $controller = $request->controller(); + + $path = explode('/', $url); + $action = array_pop($path); + $controller = empty($path) ? $controller : array_pop($path); + + $url = $controller . '/' . $action; + } + + return $url; + } + + /** + * 分析路由规则中的变量 + * @access protected + * @param string $rule 路由规则 + * @return array + */ + protected function parseVar(string $rule): array + { + // 提取路由规则中的变量 + $var = []; + + if (preg_match_all('/<\w+\??>/', $rule, $matches)) { + foreach ($matches[0] as $name) { + $optional = false; + + if (strpos($name, '?')) { + $name = substr($name, 1, -2); + $optional = true; + } else { + $name = substr($name, 1, -1); + } + + $var[$name] = $optional ? 2 : 1; + } + } + + return $var; + } + + /** + * 匹配路由地址 + * @access protected + * @param array $rule 路由规则 + * @param array $vars 路由变量 + * @param mixed $allowDomain 允许域名 + * @return array + */ + protected function getRuleUrl(array $rule, array &$vars = [], $allowDomain = ''): array + { + $request = $this->app->request; + if (is_string($allowDomain) && false === strpos($allowDomain, '.')) { + $allowDomain .= '.' . $request->rootDomain(); + } + $port = $request->port(); + + foreach ($rule as $item) { + $url = $item->getRule(); + $pattern = $this->parseVar($url); + $domain = $item->getDomain(); + $suffix = $item->getSuffix(); + + if ('-' == $domain) { + $domain = is_string($allowDomain) ? $allowDomain : $request->host(true); + } + + if (is_string($allowDomain) && $domain != $allowDomain) { + continue; + } + + if ($port && !in_array($port, [80, 443])) { + $domain .= ':' . $port; + } + + if (empty($pattern)) { + return [rtrim($url, '?/-'), $domain, $suffix]; + } + + $type = $this->route->config('url_common_param'); + $keys = []; + + foreach ($pattern as $key => $val) { + if (isset($vars[$key])) { + $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key, '<' . $key . '>'], $type ? $vars[$key] : urlencode((string) $vars[$key]), $url); + $keys[] = $key; + $url = str_replace(['/?', '-?'], ['/', '-'], $url); + $result = [rtrim($url, '?/-'), $domain, $suffix]; + } elseif (2 == $val) { + $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); + $url = str_replace(['/?', '-?'], ['/', '-'], $url); + $result = [rtrim($url, '?/-'), $domain, $suffix]; + } else { + $result = null; + $keys = []; + break; + } + } + + $vars = array_diff_key($vars, array_flip($keys)); + + if (isset($result)) { + return $result; + } + } + + return []; + } + + public function build() + { + // 解析URL + $url = $this->url; + $suffix = $this->suffix; + $domain = $this->domain; + $request = $this->app->request; + $vars = $this->vars; + + if (0 === strpos($url, '[') && $pos = strpos($url, ']')) { + // [name] 表示使用路由命名标识生成URL + $name = substr($url, 1, $pos - 1); + $url = 'name' . substr($url, $pos + 1); + } + + if (false === strpos($url, '://') && 0 !== strpos($url, '/')) { + $info = parse_url($url); + $url = !empty($info['path']) ? $info['path'] : ''; + + if (isset($info['fragment'])) { + // 解析锚点 + $anchor = $info['fragment']; + + if (false !== strpos($anchor, '?')) { + // 解析参数 + [$anchor, $info['query']] = explode('?', $anchor, 2); + } + + if (false !== strpos($anchor, '@')) { + // 解析域名 + [$anchor, $domain] = explode('@', $anchor, 2); + } + } elseif (strpos($url, '@') && false === strpos($url, '\\')) { + // 解析域名 + [$url, $domain] = explode('@', $url, 2); + } + } + + if ($url) { + $checkName = isset($name) ? $name : $url . (isset($info['query']) ? '?' . $info['query'] : ''); + $checkDomain = $domain && is_string($domain) ? $domain : null; + + $rule = $this->route->getName($checkName, $checkDomain); + + if (empty($rule) && isset($info['query'])) { + $rule = $this->route->getName($url, $checkDomain); + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); + unset($info['query']); + } + } + + if (!empty($rule) && $match = $this->getRuleUrl($rule, $vars, $domain)) { + // 匹配路由命名标识 + $url = $match[0]; + + if ($domain && !empty($match[1])) { + $domain = $match[1]; + } + + if (!is_null($match[2])) { + $suffix = $match[2]; + } + } elseif (!empty($rule) && isset($name)) { + throw new \InvalidArgumentException('route name not exists:' . $name); + } else { + // 检测URL绑定 + $bind = $this->route->getDomainBind($domain && is_string($domain) ? $domain : null); + + if ($bind && 0 === strpos($url, $bind)) { + $url = substr($url, strlen($bind) + 1); + } else { + $binds = $this->route->getBind(); + + foreach ($binds as $key => $val) { + if (is_string($val) && 0 === strpos($url, $val) && substr_count($val, '/') > 1) { + $url = substr($url, strlen($val) + 1); + $domain = $key; + break; + } + } + } + + // 路由标识不存在 直接解析 + $url = $this->parseUrl($url, $domain); + + if (isset($info['query'])) { + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); + } + } + + // 还原URL分隔符 + $depr = $this->route->config('pathinfo_depr'); + $url = str_replace('/', $depr, $url); + + $file = $request->baseFile(); + if ($file && 0 !== strpos($request->url(), $file)) { + $file = str_replace('\\', '/', dirname($file)); + } + + $url = rtrim($file, '/') . '/' . $url; + + // URL后缀 + if ('/' == substr($url, -1) || '' == $url) { + $suffix = ''; + } else { + $suffix = $this->parseSuffix($suffix); + } + + // 锚点 + $anchor = !empty($anchor) ? '#' . $anchor : ''; + + // 参数组装 + if (!empty($vars)) { + // 添加参数 + if ($this->route->config('url_common_param')) { + $vars = http_build_query($vars); + $url .= $suffix . '?' . $vars . $anchor; + } else { + foreach ($vars as $var => $val) { + $val = (string) $val; + if ('' !== $val) { + $url .= $depr . $var . $depr . urlencode($val); + } + } + + $url .= $suffix . $anchor; + } + } else { + $url .= $suffix . $anchor; + } + + // 检测域名 + $domain = $this->parseDomain($url, $domain); + + // URL组装 + return $domain . rtrim($this->root, '/') . '/' . ltrim($url, '/'); + } + + public function __toString() + { + return $this->build(); + } + + public function __debugInfo() + { + return [ + 'url' => $this->url, + 'vars' => $this->vars, + 'suffix' => $this->suffix, + 'domain' => $this->domain, + ]; + } +} diff --git a/vendor/topthink/framework/src/think/route/dispatch/Callback.php b/vendor/topthink/framework/src/think/route/dispatch/Callback.php new file mode 100644 index 0000000..7658c3d --- /dev/null +++ b/vendor/topthink/framework/src/think/route/dispatch/Callback.php @@ -0,0 +1,30 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route\dispatch; + +use think\route\Dispatch; + +/** + * Callback Dispatcher + */ +class Callback extends Dispatch +{ + public function exec() + { + // 执行回调方法 + $vars = array_merge($this->request->param(), $this->param); + + return $this->app->invoke($this->dispatch, $vars); + } + +} diff --git a/vendor/topthink/framework/src/think/route/dispatch/Controller.php b/vendor/topthink/framework/src/think/route/dispatch/Controller.php new file mode 100644 index 0000000..88094c6 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/dispatch/Controller.php @@ -0,0 +1,180 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route\dispatch; + +use ReflectionClass; +use ReflectionException; +use ReflectionMethod; +use think\App; +use think\exception\ClassNotFoundException; +use think\exception\HttpException; +use think\helper\Str; +use think\route\Dispatch; + +/** + * Controller Dispatcher + */ +class Controller extends Dispatch +{ + /** + * 控制器名 + * @var string + */ + protected $controller; + + /** + * 操作名 + * @var string + */ + protected $actionName; + + public function init(App $app) + { + parent::init($app); + + $result = $this->dispatch; + + if (is_string($result)) { + $result = explode('/', $result); + } + + // 获取控制器名 + $controller = strip_tags($result[0] ?: $this->rule->config('default_controller')); + + if (strpos($controller, '.')) { + $pos = strrpos($controller, '.'); + $this->controller = substr($controller, 0, $pos) . '.' . Str::studly(substr($controller, $pos + 1)); + } else { + $this->controller = Str::studly($controller); + } + + // 获取操作名 + $this->actionName = strip_tags($result[1] ?: $this->rule->config('default_action')); + + // 设置当前请求的控制器、操作 + $this->request + ->setController($this->controller) + ->setAction($this->actionName); + } + + public function exec() + { + try { + // 实例化控制器 + $instance = $this->controller($this->controller); + } catch (ClassNotFoundException $e) { + throw new HttpException(404, 'controller not exists:' . $e->getClass()); + } + + // 注册控制器中间件 + $this->registerControllerMiddleware($instance); + + return $this->app->middleware->pipeline('controller') + ->send($this->request) + ->then(function () use ($instance) { + // 获取当前操作名 + $suffix = $this->rule->config('action_suffix'); + $action = $this->actionName . $suffix; + + if (is_callable([$instance, $action])) { + $vars = $this->request->param(); + try { + $reflect = new ReflectionMethod($instance, $action); + // 严格获取当前操作方法名 + $actionName = $reflect->getName(); + if ($suffix) { + $actionName = substr($actionName, 0, -strlen($suffix)); + } + + $this->request->setAction($actionName); + } catch (ReflectionException $e) { + $reflect = new ReflectionMethod($instance, '__call'); + $vars = [$action, $vars]; + $this->request->setAction($action); + } + } else { + // 操作不存在 + throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()'); + } + + $data = $this->app->invokeReflectMethod($instance, $reflect, $vars); + + return $this->autoResponse($data); + }); + } + + /** + * 使用反射机制注册控制器中间件 + * @access public + * @param object $controller 控制器实例 + * @return void + */ + protected function registerControllerMiddleware($controller): void + { + $class = new ReflectionClass($controller); + + if ($class->hasProperty('middleware')) { + $reflectionProperty = $class->getProperty('middleware'); + $reflectionProperty->setAccessible(true); + + $middlewares = $reflectionProperty->getValue($controller); + + foreach ($middlewares as $key => $val) { + if (!is_int($key)) { + if (isset($val['only']) && !in_array($this->request->action(true), array_map(function ($item) { + return strtolower($item); + }, is_string($val['only']) ? explode(",", $val['only']) : $val['only']))) { + continue; + } elseif (isset($val['except']) && in_array($this->request->action(true), array_map(function ($item) { + return strtolower($item); + }, is_string($val['except']) ? explode(',', $val['except']) : $val['except']))) { + continue; + } else { + $val = $key; + } + } + + if (is_string($val) && strpos($val, ':')) { + $val = explode(':', $val, 2); + } + + $this->app->middleware->controller($val); + } + } + } + + /** + * 实例化访问控制器 + * @access public + * @param string $name 资源地址 + * @return object + * @throws ClassNotFoundException + */ + public function controller(string $name) + { + $suffix = $this->rule->config('controller_suffix') ? 'Controller' : ''; + + $controllerLayer = $this->rule->config('controller_layer') ?: 'controller'; + $emptyController = $this->rule->config('empty_controller') ?: 'Error'; + + $class = $this->app->parseClass($controllerLayer, $name . $suffix); + + if (class_exists($class)) { + return $this->app->make($class, [], true); + } elseif ($emptyController && class_exists($emptyClass = $this->app->parseClass($controllerLayer, $emptyController . $suffix))) { + return $this->app->make($emptyClass, [], true); + } + + throw new ClassNotFoundException('class not exists:' . $class, $class); + } +} diff --git a/vendor/topthink/framework/src/think/route/dispatch/Redirect.php b/vendor/topthink/framework/src/think/route/dispatch/Redirect.php new file mode 100644 index 0000000..1ec9ed9 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/dispatch/Redirect.php @@ -0,0 +1,27 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route\dispatch; + +use think\Response; +use think\route\Dispatch; + +/** + * Redirect Dispatcher + */ +class Redirect extends Dispatch +{ + public function exec() + { + return Response::create($this->dispatch, 'redirect')->code($this->code); + } +} diff --git a/vendor/topthink/framework/src/think/route/dispatch/Response.php b/vendor/topthink/framework/src/think/route/dispatch/Response.php new file mode 100644 index 0000000..3ae4c0a --- /dev/null +++ b/vendor/topthink/framework/src/think/route/dispatch/Response.php @@ -0,0 +1,27 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route\dispatch; + +use think\route\Dispatch; + +/** + * Response Dispatcher + */ +class Response extends Dispatch +{ + public function exec() + { + return $this->dispatch; + } + +} diff --git a/vendor/topthink/framework/src/think/route/dispatch/Url.php b/vendor/topthink/framework/src/think/route/dispatch/Url.php new file mode 100644 index 0000000..da6d655 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/dispatch/Url.php @@ -0,0 +1,118 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route\dispatch; + +use think\exception\HttpException; +use think\helper\Str; +use think\Request; +use think\route\Rule; + +/** + * Url Dispatcher + */ +class Url extends Controller +{ + + public function __construct(Request $request, Rule $rule, $dispatch, array $param = [], int $code = null) + { + $this->request = $request; + $this->rule = $rule; + // 解析默认的URL规则 + $dispatch = $this->parseUrl($dispatch); + + parent::__construct($request, $rule, $dispatch, $this->param, $code); + } + + /** + * 解析URL地址 + * @access protected + * @param string $url URL + * @return array + */ + protected function parseUrl(string $url): array + { + $depr = $this->rule->config('pathinfo_depr'); + $bind = $this->rule->getRouter()->getDomainBind(); + + if ($bind && preg_match('/^[a-z]/is', $bind)) { + $bind = str_replace('/', $depr, $bind); + // 如果有域名绑定 + $url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr); + } + + $path = $this->rule->parseUrlPath($url); + if (empty($path)) { + return [null, null]; + } + + // 解析控制器 + $controller = !empty($path) ? array_shift($path) : null; + + if ($controller && !preg_match('/^[A-Za-z0-9][\w|\.]*$/', $controller)) { + throw new HttpException(404, 'controller not exists:' . $controller); + } + + // 解析操作 + $action = !empty($path) ? array_shift($path) : null; + $var = []; + + // 解析额外参数 + if ($path) { + preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) { + $var[$match[1]] = strip_tags($match[2]); + }, implode('|', $path)); + } + + $panDomain = $this->request->panDomain(); + if ($panDomain && $key = array_search('*', $var)) { + // 泛域名赋值 + $var[$key] = $panDomain; + } + + // 设置当前请求的参数 + $this->param = $var; + + // 封装路由 + $route = [$controller, $action]; + + if ($this->hasDefinedRoute($route)) { + throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url)); + } + + return $route; + } + + /** + * 检查URL是否已经定义过路由 + * @access protected + * @param array $route 路由信息 + * @return bool + */ + protected function hasDefinedRoute(array $route): bool + { + [$controller, $action] = $route; + + // 检查地址是否被定义过路由 + $name = strtolower(Str::studly($controller) . '/' . $action); + + $host = $this->request->host(true); + $method = $this->request->method(); + + if ($this->rule->getRouter()->getName($name, $host, $method)) { + return true; + } + + return false; + } + +} diff --git a/vendor/topthink/framework/src/think/route/dispatch/View.php b/vendor/topthink/framework/src/think/route/dispatch/View.php new file mode 100644 index 0000000..94f9047 --- /dev/null +++ b/vendor/topthink/framework/src/think/route/dispatch/View.php @@ -0,0 +1,28 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\route\dispatch; + +use think\Response; +use think\route\Dispatch; + +/** + * View Dispatcher + */ +class View extends Dispatch +{ + public function exec() + { + // 渲染模板输出 + return Response::create($this->dispatch, 'view')->assign($this->param); + } +} diff --git a/vendor/topthink/framework/src/think/service/ModelService.php b/vendor/topthink/framework/src/think/service/ModelService.php new file mode 100644 index 0000000..a212a58 --- /dev/null +++ b/vendor/topthink/framework/src/think/service/ModelService.php @@ -0,0 +1,47 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\service; + +use think\Model; +use think\Service; + +/** + * 模型服务类 + */ +class ModelService extends Service +{ + public function boot() + { + Model::setDb($this->app->db); + Model::setEvent($this->app->event); + Model::setInvoker([$this->app, 'invoke']); + Model::maker(function (Model $model) { + $config = $this->app->config; + + $isAutoWriteTimestamp = $model->getAutoWriteTimestamp(); + + if (is_null($isAutoWriteTimestamp)) { + // 自动写入时间戳 + $model->isAutoWriteTimestamp($config->get('database.auto_timestamp', 'timestamp')); + } + + $dateFormat = $model->getDateFormat(); + + if (is_null($dateFormat)) { + // 设置时间戳格式 + $model->setDateFormat($config->get('database.datetime_format', 'Y-m-d H:i:s')); + } + + }); + } +} diff --git a/vendor/topthink/framework/src/think/service/PaginatorService.php b/vendor/topthink/framework/src/think/service/PaginatorService.php new file mode 100644 index 0000000..b13dc1d --- /dev/null +++ b/vendor/topthink/framework/src/think/service/PaginatorService.php @@ -0,0 +1,52 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\service; + +use think\Paginator; +use think\paginator\driver\Bootstrap; +use think\Service; + +/** + * 分页服务类 + */ +class PaginatorService extends Service +{ + public function register() + { + if (!$this->app->bound(Paginator::class)) { + $this->app->bind(Paginator::class, Bootstrap::class); + } + } + + public function boot() + { + Paginator::maker(function (...$args) { + return $this->app->make(Paginator::class, $args, true); + }); + + Paginator::currentPathResolver(function () { + return $this->app->request->baseUrl(); + }); + + Paginator::currentPageResolver(function ($varPage = 'page') { + + $page = $this->app->request->param($varPage); + + if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) { + return (int) $page; + } + + return 1; + }); + } +} diff --git a/vendor/topthink/framework/src/think/service/ValidateService.php b/vendor/topthink/framework/src/think/service/ValidateService.php new file mode 100644 index 0000000..d96dea0 --- /dev/null +++ b/vendor/topthink/framework/src/think/service/ValidateService.php @@ -0,0 +1,31 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\service; + +use think\Service; +use think\Validate; + +/** + * 验证服务类 + */ +class ValidateService extends Service +{ + public function boot() + { + Validate::maker(function (Validate $validate) { + $validate->setLang($this->app->lang); + $validate->setDb($this->app->db); + $validate->setRequest($this->app->request); + }); + } +} diff --git a/vendor/topthink/framework/src/think/session/Store.php b/vendor/topthink/framework/src/think/session/Store.php new file mode 100644 index 0000000..03ece29 --- /dev/null +++ b/vendor/topthink/framework/src/think/session/Store.php @@ -0,0 +1,340 @@ + +// +---------------------------------------------------------------------- + +namespace think\session; + +use think\contract\SessionHandlerInterface; +use think\helper\Arr; + +class Store +{ + + /** + * Session数据 + * @var array + */ + protected $data = []; + + /** + * 是否初始化 + * @var bool + */ + protected $init = null; + + /** + * 记录Session name + * @var string + */ + protected $name = 'PHPSESSID'; + + /** + * 记录Session Id + * @var string + */ + protected $id; + + /** + * @var SessionHandlerInterface + */ + protected $handler; + + /** @var array */ + protected $serialize = []; + + public function __construct($name, SessionHandlerInterface $handler, array $serialize = null) + { + $this->name = $name; + $this->handler = $handler; + + if (!empty($serialize)) { + $this->serialize = $serialize; + } + + $this->setId(); + } + + /** + * 设置数据 + * @access public + * @param array $data + * @return void + */ + public function setData(array $data): void + { + $this->data = $data; + } + + /** + * session初始化 + * @access public + * @return void + */ + public function init(): void + { + // 读取缓存数据 + $data = $this->handler->read($this->getId()); + + if (!empty($data)) { + $this->data = array_merge($this->data, $this->unserialize($data)); + } + + $this->init = true; + } + + /** + * 设置SessionName + * @access public + * @param string $name session_name + * @return void + */ + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * 获取sessionName + * @access public + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * session_id设置 + * @access public + * @param string $id session_id + * @return void + */ + public function setId($id = null): void + { + $this->id = is_string($id) && strlen($id) === 32 && ctype_alnum($id) ? $id : md5(microtime(true) . session_create_id()); + } + + /** + * 获取session_id + * @access public + * @return string + */ + public function getId(): string + { + return $this->id; + } + + /** + * 获取所有数据 + * @return array + */ + public function all(): array + { + return $this->data; + } + + /** + * session设置 + * @access public + * @param string $name session名称 + * @param mixed $value session值 + * @return void + */ + public function set(string $name, $value): void + { + Arr::set($this->data, $name, $value); + } + + /** + * session获取 + * @access public + * @param string $name session名称 + * @param mixed $default 默认值 + * @return mixed + */ + public function get(string $name, $default = null) + { + return Arr::get($this->data, $name, $default); + } + + /** + * session获取并删除 + * @access public + * @param string $name session名称 + * @return mixed + */ + public function pull(string $name) + { + return Arr::pull($this->data, $name); + } + + /** + * 添加数据到一个session数组 + * @access public + * @param string $key + * @param mixed $value + * @return void + */ + public function push(string $key, $value): void + { + $array = $this->get($key, []); + + $array[] = $value; + + $this->set($key, $array); + } + + /** + * 判断session数据 + * @access public + * @param string $name session名称 + * @return bool + */ + public function has(string $name): bool + { + return Arr::has($this->data, $name); + } + + /** + * 删除session数据 + * @access public + * @param string $name session名称 + * @return void + */ + public function delete(string $name): void + { + Arr::forget($this->data, $name); + } + + /** + * 清空session数据 + * @access public + * @return void + */ + public function clear(): void + { + $this->data = []; + } + + /** + * 销毁session + */ + public function destroy(): void + { + $this->clear(); + + $this->regenerate(true); + } + + /** + * 重新生成session id + * @param bool $destroy + */ + public function regenerate(bool $destroy = false): void + { + if ($destroy) { + $this->handler->delete($this->getId()); + } + + $this->setId(); + } + + /** + * 保存session数据 + * @access public + * @return void + */ + public function save(): void + { + $this->clearFlashData(); + + $sessionId = $this->getId(); + + if (!empty($this->data)) { + $data = $this->serialize($this->data); + + $this->handler->write($sessionId, $data); + } else { + $this->handler->delete($sessionId); + } + + $this->init = false; + } + + /** + * session设置 下一次请求有效 + * @access public + * @param string $name session名称 + * @param mixed $value session值 + * @return void + */ + public function flash(string $name, $value): void + { + $this->set($name, $value); + $this->push('__flash__.__next__', $name); + $this->set('__flash__.__current__', Arr::except($this->get('__flash__.__current__', []), $name)); + } + + /** + * 将本次闪存数据推迟到下次请求 + * + * @return void + */ + public function reflash(): void + { + $keys = $this->get('__flash__.__current__', []); + $values = array_unique(array_merge($this->get('__flash__.__next__', []), $keys)); + $this->set('__flash__.__next__', $values); + $this->set('__flash__.__current__', []); + } + + /** + * 清空当前请求的session数据 + * @access public + * @return void + */ + public function clearFlashData(): void + { + Arr::forget($this->data, $this->get('__flash__.__current__', [])); + if (!empty($next = $this->get('__flash__.__next__', []))) { + $this->set('__flash__.__current__', $next); + } else { + $this->delete('__flash__.__current__'); + } + $this->delete('__flash__.__next__'); + } + + /** + * 序列化数据 + * @access protected + * @param mixed $data + * @return string + */ + protected function serialize($data): string + { + $serialize = $this->serialize[0] ?? 'serialize'; + + return $serialize($data); + } + + /** + * 反序列化数据 + * @access protected + * @param string $data + * @return array + */ + protected function unserialize(string $data): array + { + $unserialize = $this->serialize[1] ?? 'unserialize'; + + return (array) $unserialize($data); + } + +} diff --git a/vendor/topthink/framework/src/think/session/driver/Cache.php b/vendor/topthink/framework/src/think/session/driver/Cache.php new file mode 100644 index 0000000..c25e2ef --- /dev/null +++ b/vendor/topthink/framework/src/think/session/driver/Cache.php @@ -0,0 +1,50 @@ + +// +---------------------------------------------------------------------- +namespace think\session\driver; + +use Psr\SimpleCache\CacheInterface; +use think\contract\SessionHandlerInterface; +use think\helper\Arr; + +class Cache implements SessionHandlerInterface +{ + + /** @var CacheInterface */ + protected $handler; + + /** @var integer */ + protected $expire; + + /** @var string */ + protected $prefix; + + public function __construct(\think\Cache $cache, array $config = []) + { + $this->handler = $cache->store(Arr::get($config, 'store')); + $this->expire = Arr::get($config, 'expire', 1440); + $this->prefix = Arr::get($config, 'prefix', ''); + } + + public function read(string $sessionId): string + { + return (string) $this->handler->get($this->prefix . $sessionId); + } + + public function delete(string $sessionId): bool + { + return $this->handler->delete($this->prefix . $sessionId); + } + + public function write(string $sessionId, string $data): bool + { + return $this->handler->set($this->prefix . $sessionId, $data, $this->expire); + } +} diff --git a/vendor/topthink/framework/src/think/session/driver/File.php b/vendor/topthink/framework/src/think/session/driver/File.php new file mode 100644 index 0000000..991f2cc --- /dev/null +++ b/vendor/topthink/framework/src/think/session/driver/File.php @@ -0,0 +1,249 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\session\driver; + +use Closure; +use Exception; +use FilesystemIterator; +use Generator; +use SplFileInfo; +use think\App; +use think\contract\SessionHandlerInterface; + +/** + * Session 文件驱动 + */ +class File implements SessionHandlerInterface +{ + protected $config = [ + 'path' => '', + 'expire' => 1440, + 'prefix' => '', + 'data_compress' => false, + 'gc_probability' => 1, + 'gc_divisor' => 100, + ]; + + public function __construct(App $app, array $config = []) + { + $this->config = array_merge($this->config, $config); + + if (empty($this->config['path'])) { + $this->config['path'] = $app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . 'session' . DIRECTORY_SEPARATOR; + } elseif (substr($this->config['path'], -1) != DIRECTORY_SEPARATOR) { + $this->config['path'] .= DIRECTORY_SEPARATOR; + } + + $this->init(); + } + + /** + * 打开Session + * @access protected + * @throws Exception + */ + protected function init(): void + { + try { + !is_dir($this->config['path']) && mkdir($this->config['path'], 0755, true); + } catch (\Exception $e) { + // 写入失败 + } + + // 垃圾回收 + if (random_int(1, $this->config['gc_divisor']) <= $this->config['gc_probability']) { + $this->gc(); + } + } + + /** + * Session 垃圾回收 + * @access public + * @return void + */ + public function gc(): void + { + $lifetime = $this->config['expire']; + $now = time(); + + $files = $this->findFiles($this->config['path'], function (SplFileInfo $item) use ($lifetime, $now) { + return $now - $lifetime > $item->getMTime(); + }); + + foreach ($files as $file) { + $this->unlink($file->getPathname()); + } + } + + /** + * 查找文件 + * @param string $root + * @param Closure $filter + * @return Generator + */ + protected function findFiles(string $root, Closure $filter) + { + $items = new FilesystemIterator($root); + + /** @var SplFileInfo $item */ + foreach ($items as $item) { + if ($item->isDir() && !$item->isLink()) { + yield from $this->findFiles($item->getPathname(), $filter); + } else { + if ($filter($item)) { + yield $item; + } + } + } + } + + /** + * 取得变量的存储文件名 + * @access protected + * @param string $name 缓存变量名 + * @param bool $auto 是否自动创建目录 + * @return string + */ + protected function getFileName(string $name, bool $auto = false): string + { + if ($this->config['prefix']) { + // 使用子目录 + $name = $this->config['prefix'] . DIRECTORY_SEPARATOR . 'sess_' . $name; + } else { + $name = 'sess_' . $name; + } + + $filename = $this->config['path'] . $name; + $dir = dirname($filename); + + if ($auto && !is_dir($dir)) { + try { + mkdir($dir, 0755, true); + } catch (\Exception $e) { + // 创建失败 + } + } + + return $filename; + } + + /** + * 读取Session + * @access public + * @param string $sessID + * @return string + */ + public function read(string $sessID): string + { + $filename = $this->getFileName($sessID); + + if (is_file($filename) && filemtime($filename) >= time() - $this->config['expire']) { + $content = $this->readFile($filename); + + if ($this->config['data_compress'] && function_exists('gzcompress')) { + //启用数据压缩 + $content = (string) gzuncompress($content); + } + + return $content; + } + + return ''; + } + + /** + * 写文件(加锁) + * @param $path + * @param $content + * @return bool + */ + protected function writeFile($path, $content): bool + { + return (bool) file_put_contents($path, $content, LOCK_EX); + } + + /** + * 读取文件内容(加锁) + * @param $path + * @return string + */ + protected function readFile($path): string + { + $contents = ''; + + $handle = fopen($path, 'rb'); + + if ($handle) { + try { + if (flock($handle, LOCK_SH)) { + clearstatcache(true, $path); + + $contents = fread($handle, filesize($path) ?: 1); + + flock($handle, LOCK_UN); + } + } finally { + fclose($handle); + } + } + + return $contents; + } + + /** + * 写入Session + * @access public + * @param string $sessID + * @param string $sessData + * @return bool + */ + public function write(string $sessID, string $sessData): bool + { + $filename = $this->getFileName($sessID, true); + $data = $sessData; + + if ($this->config['data_compress'] && function_exists('gzcompress')) { + //数据压缩 + $data = gzcompress($data, 3); + } + + return $this->writeFile($filename, $data); + } + + /** + * 删除Session + * @access public + * @param string $sessID + * @return bool + */ + public function delete(string $sessID): bool + { + try { + return $this->unlink($this->getFileName($sessID)); + } catch (\Exception $e) { + return false; + } + } + + /** + * 判断文件是否存在后,删除 + * @access private + * @param string $file + * @return bool + */ + private function unlink(string $file): bool + { + return is_file($file) && unlink($file); + } + +} diff --git a/vendor/topthink/framework/src/think/validate/ValidateRule.php b/vendor/topthink/framework/src/think/validate/ValidateRule.php new file mode 100644 index 0000000..05e275f --- /dev/null +++ b/vendor/topthink/framework/src/think/validate/ValidateRule.php @@ -0,0 +1,172 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\validate; + +/** + * Class ValidateRule + * @package think\validate + * @method ValidateRule confirm(mixed $rule, string $msg = '') static 验证是否和某个字段的值一致 + * @method ValidateRule different(mixed $rule, string $msg = '') static 验证是否和某个字段的值是否不同 + * @method ValidateRule egt(mixed $rule, string $msg = '') static 验证是否大于等于某个值 + * @method ValidateRule gt(mixed $rule, string $msg = '') static 验证是否大于某个值 + * @method ValidateRule elt(mixed $rule, string $msg = '') static 验证是否小于等于某个值 + * @method ValidateRule lt(mixed $rule, string $msg = '') static 验证是否小于某个值 + * @method ValidateRule eg(mixed $rule, string $msg = '') static 验证是否等于某个值 + * @method ValidateRule in(mixed $rule, string $msg = '') static 验证是否在范围内 + * @method ValidateRule notIn(mixed $rule, string $msg = '') static 验证是否不在某个范围 + * @method ValidateRule between(mixed $rule, string $msg = '') static 验证是否在某个区间 + * @method ValidateRule notBetween(mixed $rule, string $msg = '') static 验证是否不在某个区间 + * @method ValidateRule length(mixed $rule, string $msg = '') static 验证数据长度 + * @method ValidateRule max(mixed $rule, string $msg = '') static 验证数据最大长度 + * @method ValidateRule min(mixed $rule, string $msg = '') static 验证数据最小长度 + * @method ValidateRule after(mixed $rule, string $msg = '') static 验证日期 + * @method ValidateRule before(mixed $rule, string $msg = '') static 验证日期 + * @method ValidateRule expire(mixed $rule, string $msg = '') static 验证有效期 + * @method ValidateRule allowIp(mixed $rule, string $msg = '') static 验证IP许可 + * @method ValidateRule denyIp(mixed $rule, string $msg = '') static 验证IP禁用 + * @method ValidateRule regex(mixed $rule, string $msg = '') static 使用正则验证数据 + * @method ValidateRule token(mixed $rule='__token__', string $msg = '') static 验证表单令牌 + * @method ValidateRule is(mixed $rule, string $msg = '') static 验证字段值是否为有效格式 + * @method ValidateRule isRequire(mixed $rule = null, string $msg = '') static 验证字段必须 + * @method ValidateRule isNumber(mixed $rule = null, string $msg = '') static 验证字段值是否为数字 + * @method ValidateRule isArray(mixed $rule = null, string $msg = '') static 验证字段值是否为数组 + * @method ValidateRule isInteger(mixed $rule = null, string $msg = '') static 验证字段值是否为整形 + * @method ValidateRule isFloat(mixed $rule = null, string $msg = '') static 验证字段值是否为浮点数 + * @method ValidateRule isMobile(mixed $rule = null, string $msg = '') static 验证字段值是否为手机 + * @method ValidateRule isIdCard(mixed $rule = null, string $msg = '') static 验证字段值是否为身份证号码 + * @method ValidateRule isChs(mixed $rule = null, string $msg = '') static 验证字段值是否为中文 + * @method ValidateRule isChsDash(mixed $rule = null, string $msg = '') static 验证字段值是否为中文字母及下划线 + * @method ValidateRule isChsAlpha(mixed $rule = null, string $msg = '') static 验证字段值是否为中文和字母 + * @method ValidateRule isChsAlphaNum(mixed $rule = null, string $msg = '') static 验证字段值是否为中文字母和数字 + * @method ValidateRule isDate(mixed $rule = null, string $msg = '') static 验证字段值是否为有效格式 + * @method ValidateRule isBool(mixed $rule = null, string $msg = '') static 验证字段值是否为布尔值 + * @method ValidateRule isAlpha(mixed $rule = null, string $msg = '') static 验证字段值是否为字母 + * @method ValidateRule isAlphaDash(mixed $rule = null, string $msg = '') static 验证字段值是否为字母和下划线 + * @method ValidateRule isAlphaNum(mixed $rule = null, string $msg = '') static 验证字段值是否为字母和数字 + * @method ValidateRule isAccepted(mixed $rule = null, string $msg = '') static 验证字段值是否为yes, on, 或是 1 + * @method ValidateRule isEmail(mixed $rule = null, string $msg = '') static 验证字段值是否为有效邮箱格式 + * @method ValidateRule isUrl(mixed $rule = null, string $msg = '') static 验证字段值是否为有效URL地址 + * @method ValidateRule activeUrl(mixed $rule, string $msg = '') static 验证是否为合格的域名或者IP + * @method ValidateRule ip(mixed $rule, string $msg = '') static 验证是否有效IP + * @method ValidateRule fileExt(mixed $rule, string $msg = '') static 验证文件后缀 + * @method ValidateRule fileMime(mixed $rule, string $msg = '') static 验证文件类型 + * @method ValidateRule fileSize(mixed $rule, string $msg = '') static 验证文件大小 + * @method ValidateRule image(mixed $rule, string $msg = '') static 验证图像文件 + * @method ValidateRule method(mixed $rule, string $msg = '') static 验证请求类型 + * @method ValidateRule dateFormat(mixed $rule, string $msg = '') static 验证时间和日期是否符合指定格式 + * @method ValidateRule unique(mixed $rule, string $msg = '') static 验证是否唯一 + * @method ValidateRule behavior(mixed $rule, string $msg = '') static 使用行为类验证 + * @method ValidateRule filter(mixed $rule, string $msg = '') static 使用filter_var方式验证 + * @method ValidateRule requireIf(mixed $rule, string $msg = '') static 验证某个字段等于某个值的时候必须 + * @method ValidateRule requireCallback(mixed $rule, string $msg = '') static 通过回调方法验证某个字段是否必须 + * @method ValidateRule requireWith(mixed $rule, string $msg = '') static 验证某个字段有值的情况下必须 + * @method ValidateRule must(mixed $rule = null, string $msg = '') static 必须验证 + */ +class ValidateRule +{ + // 验证字段的名称 + protected $title; + + // 当前验证规则 + protected $rule = []; + + // 验证提示信息 + protected $message = []; + + /** + * 添加验证因子 + * @access protected + * @param string $name 验证名称 + * @param mixed $rule 验证规则 + * @param string $msg 提示信息 + * @return $this + */ + protected function addItem(string $name, $rule = null, string $msg = '') + { + if ($rule || 0 === $rule) { + $this->rule[$name] = $rule; + } else { + $this->rule[] = $name; + } + + $this->message[] = $msg; + + return $this; + } + + /** + * 获取验证规则 + * @access public + * @return array + */ + public function getRule(): array + { + return $this->rule; + } + + /** + * 获取验证字段名称 + * @access public + * @return string + */ + public function getTitle(): string + { + return $this->title ?: ''; + } + + /** + * 获取验证提示 + * @access public + * @return array + */ + public function getMsg(): array + { + return $this->message; + } + + /** + * 设置验证字段名称 + * @access public + * @return $this + */ + public function title(string $title) + { + $this->title = $title; + + return $this; + } + + public function __call($method, $args) + { + if ('is' == strtolower(substr($method, 0, 2))) { + $method = substr($method, 2); + } + + array_unshift($args, lcfirst($method)); + + return call_user_func_array([$this, 'addItem'], $args); + } + + public static function __callStatic($method, $args) + { + $rule = new static(); + + if ('is' == strtolower(substr($method, 0, 2))) { + $method = substr($method, 2); + } + + array_unshift($args, lcfirst($method)); + + return call_user_func_array([$rule, 'addItem'], $args); + } +} diff --git a/vendor/topthink/framework/src/think/view/driver/Php.php b/vendor/topthink/framework/src/think/view/driver/Php.php new file mode 100644 index 0000000..0713a56 --- /dev/null +++ b/vendor/topthink/framework/src/think/view/driver/Php.php @@ -0,0 +1,191 @@ + +// +---------------------------------------------------------------------- +declare (strict_types = 1); + +namespace think\view\driver; + +use RuntimeException; +use think\App; +use think\contract\TemplateHandlerInterface; +use think\helper\Str; + +/** + * PHP原生模板驱动 + */ +class Php implements TemplateHandlerInterface +{ + protected $template; + protected $content; + protected $app; + + // 模板引擎参数 + protected $config = [ + // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法 + 'auto_rule' => 1, + // 视图目录名 + 'view_dir_name' => 'view', + // 应用模板路径 + 'view_path' => '', + // 模板文件后缀 + 'view_suffix' => 'php', + // 模板文件名分隔符 + 'view_depr' => DIRECTORY_SEPARATOR, + ]; + + public function __construct(App $app, array $config = []) + { + $this->app = $app; + $this->config = array_merge($this->config, (array) $config); + } + + /** + * 检测是否存在模板文件 + * @access public + * @param string $template 模板文件或者模板规则 + * @return bool + */ + public function exists(string $template): bool + { + if ('' == pathinfo($template, PATHINFO_EXTENSION)) { + // 获取模板文件名 + $template = $this->parseTemplate($template); + } + + return is_file($template); + } + + /** + * 渲染模板文件 + * @access public + * @param string $template 模板文件 + * @param array $data 模板变量 + * @return void + */ + public function fetch(string $template, array $data = []): void + { + if ('' == pathinfo($template, PATHINFO_EXTENSION)) { + // 获取模板文件名 + $template = $this->parseTemplate($template); + } + + // 模板不存在 抛出异常 + if (!is_file($template)) { + throw new RuntimeException('template not exists:' . $template); + } + + $this->template = $template; + + extract($data, EXTR_OVERWRITE); + + include $this->template; + } + + /** + * 渲染模板内容 + * @access public + * @param string $content 模板内容 + * @param array $data 模板变量 + * @return void + */ + public function display(string $content, array $data = []): void + { + $this->content = $content; + + extract($data, EXTR_OVERWRITE); + eval('?>' . $this->content); + } + + /** + * 自动定位模板文件 + * @access private + * @param string $template 模板文件规则 + * @return string + */ + private function parseTemplate(string $template): string + { + $request = $this->app->request; + + // 获取视图根目录 + if (strpos($template, '@')) { + // 跨应用调用 + [$app, $template] = explode('@', $template); + } + + if ($this->config['view_path'] && !isset($app)) { + $path = $this->config['view_path']; + } else { + $appName = isset($app) ? $app : $this->app->http->getName(); + $view = $this->config['view_dir_name']; + + if (is_dir($this->app->getAppPath() . $view)) { + $path = isset($app) ? $this->app->getBasePath() . ($appName ? $appName . DIRECTORY_SEPARATOR : '') . $view . DIRECTORY_SEPARATOR : $this->app->getAppPath() . $view . DIRECTORY_SEPARATOR; + } else { + $path = $this->app->getRootPath() . $view . DIRECTORY_SEPARATOR . ($appName ? $appName . DIRECTORY_SEPARATOR : ''); + } + } + + $depr = $this->config['view_depr']; + + if (0 !== strpos($template, '/')) { + $template = str_replace(['/', ':'], $depr, $template); + $controller = $request->controller(); + if (strpos($controller, '.')) { + $pos = strrpos($controller, '.'); + $controller = substr($controller, 0, $pos) . '.' . Str::snake(substr($controller, $pos + 1)); + } else { + $controller = Str::snake($controller); + } + + if ($controller) { + if ('' == $template) { + // 如果模板文件名为空 按照默认规则定位 + if (2 == $this->config['auto_rule']) { + $template = $request->action(true); + } elseif (3 == $this->config['auto_rule']) { + $template = $request->action(); + } else { + $template = Str::snake($request->action()); + } + + $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template; + } elseif (false === strpos($template, $depr)) { + $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template; + } + } + } else { + $template = str_replace(['/', ':'], $depr, substr($template, 1)); + } + + return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.'); + } + + /** + * 配置模板引擎 + * @access private + * @param array $config 参数 + * @return void + */ + public function config(array $config): void + { + $this->config = array_merge($this->config, $config); + } + + /** + * 获取模板引擎配置 + * @access public + * @param string $name 参数名 + * @return mixed + */ + public function getConfig(string $name) + { + return $this->config[$name] ?? null; + } +} diff --git a/vendor/topthink/framework/src/tpl/think_exception.tpl b/vendor/topthink/framework/src/tpl/think_exception.tpl new file mode 100644 index 0000000..7766caf --- /dev/null +++ b/vendor/topthink/framework/src/tpl/think_exception.tpl @@ -0,0 +1,502 @@ +'.end($names).''; + } +} + +if (!function_exists('parse_file')) { + function parse_file($file, $line) + { + return ''.basename($file)." line {$line}".''; + } +} + +if (!function_exists('parse_args')) { + function parse_args($args) + { + $result = []; + foreach ($args as $key => $item) { + switch (true) { + case is_object($item): + $value = sprintf('object(%s)', parse_class(get_class($item))); + break; + case is_array($item): + if (count($item) > 3) { + $value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3))); + } else { + $value = sprintf('[%s]', parse_args($item)); + } + break; + case is_string($item): + if (strlen($item) > 20) { + $value = sprintf( + '\'%s...\'', + htmlentities($item), + htmlentities(substr($item, 0, 20)) + ); + } else { + $value = sprintf("'%s'", htmlentities($item)); + } + break; + case is_int($item): + case is_float($item): + $value = $item; + break; + case is_null($item): + $value = 'null'; + break; + case is_bool($item): + $value = '' . ($item ? 'true' : 'false') . ''; + break; + case is_resource($item): + $value = 'resource'; + break; + default: + $value = htmlentities(str_replace("\n", '', var_export(strval($item), true))); + break; + } + + $result[] = is_int($key) ? $value : "'{$key}' => {$value}"; + } + + return implode(', ', $result); + } +} +if (!function_exists('echo_value')) { + function echo_value($val) + { + if (is_array($val) || is_object($val)) { + echo htmlentities(json_encode($val, JSON_PRETTY_PRINT)); + } elseif (is_bool($val)) { + echo $val ? 'true' : 'false'; + } elseif (is_scalar($val)) { + echo htmlentities($val); + } else { + echo 'Resource'; + } + } +} +?> + + + + + 系统发生错误 + + + + + + $trace) { ?> +
    +
    +
    +
    +

    +
    +

    +
    +
    + +
    +
      $value) { ?>
    1. ">
    +
    + +
    +

    Call Stack

    +
      +
    1. + +
    2. + +
    3. + +
    +
    +
    + + +
    +

    +
    + + + +
    +

    Exception Datas

    + $value) { ?> + + + + + + + $val) { ?> + + + + + + + +
    empty
    + +
    + + + +
    +

    Environment Variables

    + $value) { ?> + + + + + + + $val) { ?> + + + + + + + +
    empty
    + +
    + + + + + + + + diff --git a/vendor/topthink/framework/tests/AppTest.php b/vendor/topthink/framework/tests/AppTest.php new file mode 100644 index 0000000..6b86015 --- /dev/null +++ b/vendor/topthink/framework/tests/AppTest.php @@ -0,0 +1,215 @@ + 'class', + ]; + + public function register() + { + + } + + public function boot() + { + + } +} + +/** + * @property array initializers + */ +class AppTest extends TestCase +{ + /** @var App */ + protected $app; + + protected function setUp() + { + $this->app = new App(); + } + + protected function tearDown(): void + { + m::close(); + } + + public function testService() + { + $this->app->register(stdClass::class); + + $this->assertInstanceOf(stdClass::class, $this->app->getService(stdClass::class)); + + $service = m::mock(SomeService::class); + + $service->shouldReceive('register')->once(); + + $this->app->register($service); + + $this->assertEquals($service, $this->app->getService(SomeService::class)); + + $service2 = m::mock(SomeService::class); + + $service2->shouldReceive('register')->once(); + + $this->app->register($service2); + + $this->assertEquals($service, $this->app->getService(SomeService::class)); + + $this->app->register($service2, true); + + $this->assertEquals($service2, $this->app->getService(SomeService::class)); + + $service->shouldReceive('boot')->once(); + $service2->shouldReceive('boot')->once(); + + $this->app->boot(); + } + + public function testDebug() + { + $this->app->debug(false); + + $this->assertFalse($this->app->isDebug()); + + $this->app->debug(true); + + $this->assertTrue($this->app->isDebug()); + } + + public function testNamespace() + { + $namespace = 'test'; + + $this->app->setNamespace($namespace); + + $this->assertEquals($namespace, $this->app->getNamespace()); + } + + public function testVersion() + { + $this->assertEquals(App::VERSION, $this->app->version()); + } + + public function testPath() + { + $rootPath = __DIR__ . DIRECTORY_SEPARATOR; + + $app = new App($rootPath); + + $this->assertEquals($rootPath, $app->getRootPath()); + + $this->assertEquals(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $app->getThinkPath()); + + $this->assertEquals($rootPath . 'app' . DIRECTORY_SEPARATOR, $app->getAppPath()); + + $appPath = $rootPath . 'app' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR; + $app->setAppPath($appPath); + $this->assertEquals($appPath, $app->getAppPath()); + + $this->assertEquals($rootPath . 'app' . DIRECTORY_SEPARATOR, $app->getBasePath()); + + $this->assertEquals($rootPath . 'config' . DIRECTORY_SEPARATOR, $app->getConfigPath()); + + $this->assertEquals($rootPath . 'runtime' . DIRECTORY_SEPARATOR, $app->getRuntimePath()); + + $runtimePath = $rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR; + $app->setRuntimePath($runtimePath); + $this->assertEquals($runtimePath, $app->getRuntimePath()); + } + + /** + * @param vfsStreamDirectory $root + * @param bool $debug + * @return App + */ + protected function prepareAppForInitialize(vfsStreamDirectory $root, $debug = true) + { + $rootPath = $root->url() . DIRECTORY_SEPARATOR; + + $app = new App($rootPath); + + $initializer = m::mock(); + $initializer->shouldReceive('init')->once()->with($app); + + $app->instance($initializer->mockery_getName(), $initializer); + + (function () use ($initializer) { + $this->initializers = [$initializer->mockery_getName()]; + })->call($app); + + $env = m::mock(Env::class); + $env->shouldReceive('load')->once()->with($rootPath . '.env'); + $env->shouldReceive('get')->once()->with('config_ext', '.php')->andReturn('.php'); + $env->shouldReceive('get')->once()->with('app_debug')->andReturn($debug); + + $event = m::mock(Event::class); + $event->shouldReceive('trigger')->once()->with(AppInit::class); + $event->shouldReceive('bind')->once()->with([]); + $event->shouldReceive('listenEvents')->once()->with([]); + $event->shouldReceive('subscribe')->once()->with([]); + + $app->instance('env', $env); + $app->instance('event', $event); + + return $app; + } + + public function testInitialize() + { + $root = vfsStream::setup('rootDir', null, [ + '.env' => '', + 'app' => [ + 'common.php' => '', + 'event.php' => '[],"listen"=>[],"subscribe"=>[]];', + 'provider.php' => ' [ + 'app.php' => 'prepareAppForInitialize($root, true); + + $app->debug(false); + + $app->initialize(); + + $this->assertIsInt($app->getBeginMem()); + $this->assertIsFloat($app->getBeginTime()); + + $this->assertTrue($app->initialized()); + } + + public function testFactory() + { + $this->assertInstanceOf(stdClass::class, App::factory(stdClass::class)); + + $this->expectException(ClassNotFoundException::class); + + App::factory('SomeClass'); + } + + public function testParseClass() + { + $this->assertEquals('app\\controller\\SomeClass', $this->app->parseClass('controller', 'some_class')); + $this->app->setNamespace('app2'); + $this->assertEquals('app2\\controller\\SomeClass', $this->app->parseClass('controller', 'some_class')); + } + +} diff --git a/vendor/topthink/framework/tests/CacheTest.php b/vendor/topthink/framework/tests/CacheTest.php new file mode 100644 index 0000000..5b5a13c --- /dev/null +++ b/vendor/topthink/framework/tests/CacheTest.php @@ -0,0 +1,149 @@ +app = m::mock(App::class)->makePartial(); + + Container::setInstance($this->app); + $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); + $this->config = m::mock(Config::class)->makePartial(); + $this->app->shouldReceive('get')->with('config')->andReturn($this->config); + + $this->cache = new Cache($this->app); + } + + public function testGetConfig() + { + $config = [ + 'default' => 'file', + ]; + + $this->config->shouldReceive('get')->with('cache')->andReturn($config); + + $this->assertEquals($config, $this->cache->getConfig()); + + $this->expectException(InvalidArgumentException::class); + $this->cache->getStoreConfig('foo'); + } + + public function testCacheManagerInstances() + { + $this->config->shouldReceive('get')->with("cache.stores.single", null)->andReturn(['type' => 'file']); + + $channel1 = $this->cache->store('single'); + $channel2 = $this->cache->store('single'); + + $this->assertSame($channel1, $channel2); + } + + public function testFileCache() + { + $root = vfsStream::setup(); + + $this->config->shouldReceive('get')->with("cache.default", null)->andReturn('file'); + + $this->config->shouldReceive('get')->with("cache.stores.file", null)->andReturn(['type' => 'file', 'path' => $root->url()]); + + $this->cache->set('foo', 5); + $this->cache->inc('foo'); + $this->assertEquals(6, $this->cache->get('foo')); + $this->cache->dec('foo', 2); + $this->assertEquals(4, $this->cache->get('foo')); + + $this->cache->set('bar', true); + $this->assertTrue($this->cache->get('bar')); + + $this->cache->set('baz', null); + $this->assertNull($this->cache->get('baz')); + + $this->assertTrue($this->cache->has('baz')); + $this->cache->delete('baz'); + $this->assertFalse($this->cache->has('baz')); + $this->assertNull($this->cache->get('baz')); + $this->assertFalse($this->cache->get('baz', false)); + + $this->assertTrue($root->hasChildren()); + $this->cache->clear(); + $this->assertFalse($root->hasChildren()); + + //tags + $this->cache->tag('foo')->set('bar', 'foobar'); + $this->assertEquals('foobar', $this->cache->get('bar')); + $this->cache->tag('foo')->clear(); + $this->assertFalse($this->cache->has('bar')); + + //multiple + $this->cache->setMultiple(['foo' => ['foobar', 'bar'], 'foobar' => ['foo', 'bar']]); + $this->assertEquals(['foo' => ['foobar', 'bar'], 'foobar' => ['foo', 'bar']], $this->cache->getMultiple(['foo', 'foobar'])); + $this->assertTrue($this->cache->deleteMultiple(['foo', 'foobar'])); + } + + public function testRedisCache() + { + if (extension_loaded('redis')) { + return; + } + $this->config->shouldReceive('get')->with("cache.default", null)->andReturn('redis'); + $this->config->shouldReceive('get')->with("cache.stores.redis", null)->andReturn(['type' => 'redis']); + + $redis = m::mock('overload:\Predis\Client'); + + $redis->shouldReceive("set")->once()->with('foo', 5)->andReturnTrue(); + $redis->shouldReceive("incrby")->once()->with('foo', 1)->andReturnTrue(); + $redis->shouldReceive("decrby")->once()->with('foo', 2)->andReturnTrue(); + $redis->shouldReceive("get")->once()->with('foo')->andReturn('6'); + $redis->shouldReceive("get")->once()->with('foo')->andReturn('4'); + $redis->shouldReceive("set")->once()->with('bar', serialize(true))->andReturnTrue(); + $redis->shouldReceive("set")->once()->with('baz', serialize(null))->andReturnTrue(); + $redis->shouldReceive("del")->once()->with('baz')->andReturnTrue(); + $redis->shouldReceive("flushDB")->once()->andReturnTrue(); + $redis->shouldReceive("set")->once()->with('bar', serialize('foobar'))->andReturnTrue(); + $redis->shouldReceive("sAdd")->once()->with('tag:' . md5('foo'), 'bar')->andReturnTrue(); + $redis->shouldReceive("sMembers")->once()->with('tag:' . md5('foo'))->andReturn(['bar']); + $redis->shouldReceive("del")->once()->with(['bar'])->andReturnTrue(); + $redis->shouldReceive("del")->once()->with('tag:' . md5('foo'))->andReturnTrue(); + + $this->cache->set('foo', 5); + $this->cache->inc('foo'); + $this->assertEquals(6, $this->cache->get('foo')); + $this->cache->dec('foo', 2); + $this->assertEquals(4, $this->cache->get('foo')); + + $this->cache->set('bar', true); + $this->cache->set('baz', null); + $this->cache->delete('baz'); + $this->cache->clear(); + + //tags + $this->cache->tag('foo')->set('bar', 'foobar'); + $this->cache->tag('foo')->clear(); + } +} diff --git a/vendor/topthink/framework/tests/ConfigTest.php b/vendor/topthink/framework/tests/ConfigTest.php new file mode 100644 index 0000000..271a34f --- /dev/null +++ b/vendor/topthink/framework/tests/ConfigTest.php @@ -0,0 +1,46 @@ +setContent(" 'value1','key2'=>'value2'];"); + $root->addChild($file); + + $config = new Config(); + + $config->load($file->url(), 'test'); + + $this->assertEquals('value1', $config->get('test.key1')); + $this->assertEquals('value2', $config->get('test.key2')); + + $this->assertSame(['key1' => 'value1', 'key2' => 'value2'], $config->get('test')); + } + + public function testSetAndGet() + { + $config = new Config(); + + $config->set([ + 'key1' => 'value1', + 'key2' => [ + 'key3' => 'value3', + ], + ], 'test'); + + $this->assertTrue($config->has('test.key1')); + $this->assertEquals('value1', $config->get('test.key1')); + $this->assertEquals('value3', $config->get('test.key2.key3')); + + $this->assertEquals(['key3' => 'value3'], $config->get('test.key2')); + $this->assertFalse($config->has('test.key3')); + $this->assertEquals('none', $config->get('test.key3', 'none')); + } +} diff --git a/vendor/topthink/framework/tests/ContainerTest.php b/vendor/topthink/framework/tests/ContainerTest.php new file mode 100644 index 0000000..72ff1d0 --- /dev/null +++ b/vendor/topthink/framework/tests/ContainerTest.php @@ -0,0 +1,313 @@ +name = $name; + } + + public function some(Container $container) + { + } + + protected function protectionFun() + { + return true; + } + + public static function test(Container $container) + { + return $container; + } + + public static function __make() + { + return new self('Taylor'); + } +} + +class SomeClass +{ + public $container; + + public $count = 0; + + public function __construct(Container $container) + { + $this->container = $container; + } +} + +class ContainerTest extends TestCase +{ + protected function tearDown(): void + { + Container::setInstance(null); + } + + public function testClosureResolution() + { + $container = new Container; + + Container::setInstance($container); + + $container->bind('name', function () { + return 'Taylor'; + }); + + $this->assertEquals('Taylor', $container->make('name')); + + $this->assertEquals('Taylor', Container::pull('name')); + } + + public function testGet() + { + $container = new Container; + + $this->expectException(ClassNotFoundException::class); + $this->expectExceptionMessage('class not exists: name'); + $container->get('name'); + + $container->bind('name', function () { + return 'Taylor'; + }); + + $this->assertSame('Taylor', $container->get('name')); + } + + public function testExist() + { + $container = new Container; + + $container->bind('name', function () { + return 'Taylor'; + }); + + $this->assertFalse($container->exists("name")); + + $container->make('name'); + + $this->assertTrue($container->exists('name')); + } + + public function testInstance() + { + $container = new Container; + + $container->bind('name', function () { + return 'Taylor'; + }); + + $this->assertEquals('Taylor', $container->get('name')); + + $container->bind('name2', Taylor::class); + + $object = new stdClass(); + + $this->assertFalse($container->exists('name2')); + + $container->instance('name2', $object); + + $this->assertTrue($container->exists('name2')); + + $this->assertTrue($container->exists(Taylor::class)); + + $this->assertEquals($object, $container->make(Taylor::class)); + + unset($container->name1); + + $this->assertFalse($container->exists('name1')); + + $container->delete('name2'); + + $this->assertFalse($container->exists('name2')); + + foreach ($container as $class => $instance) { + + } + } + + public function testBind() + { + $container = new Container; + + $object = new stdClass(); + + $container->bind(['name' => Taylor::class]); + + $container->bind('name2', $object); + + $container->bind('name3', Taylor::class); + + $container->name4 = $object; + + $container['name5'] = $object; + + $this->assertTrue(isset($container->name4)); + + $this->assertTrue(isset($container['name5'])); + + $this->assertInstanceOf(Taylor::class, $container->get('name')); + + $this->assertSame($object, $container->get('name2')); + + $this->assertSame($object, $container->name4); + + $this->assertSame($object, $container['name5']); + + $this->assertInstanceOf(Taylor::class, $container->get('name3')); + + unset($container['name']); + + $this->assertFalse(isset($container['name'])); + + unset($container->name3); + + $this->assertFalse(isset($container->name3)); + } + + public function testAutoConcreteResolution() + { + $container = new Container; + + $taylor = $container->make(Taylor::class); + + $this->assertInstanceOf(Taylor::class, $taylor); + $this->assertAttributeSame('Taylor', 'name', $taylor); + } + + public function testGetAndSetInstance() + { + $this->assertInstanceOf(Container::class, Container::getInstance()); + + $object = new stdClass(); + + Container::setInstance($object); + + $this->assertSame($object, Container::getInstance()); + + Container::setInstance(function () { + return $this; + }); + + $this->assertSame($this, Container::getInstance()); + } + + public function testResolving() + { + $container = new Container(); + $container->bind(Container::class, $container); + + $container->resolving(function (SomeClass $taylor, Container $container) { + $taylor->count++; + }); + $container->resolving(SomeClass::class, function (SomeClass $taylor, Container $container) { + $taylor->count++; + }); + + /** @var SomeClass $someClass */ + $someClass = $container->invokeClass(SomeClass::class); + $this->assertEquals(2, $someClass->count); + } + + public function testInvokeFunctionWithoutMethodThrowsException() + { + $this->expectException(FuncNotFoundException::class); + $this->expectExceptionMessage('function not exists: ContainerTestCallStub()'); + $container = new Container(); + $container->invokeFunction('ContainerTestCallStub', []); + } + + public function testInvokeProtectionMethod() + { + $container = new Container(); + $this->assertTrue($container->invokeMethod([Taylor::class, 'protectionFun'], [], true)); + } + + public function testInvoke() + { + $container = new Container(); + + Container::setInstance($container); + + $container->bind(Container::class, $container); + + $stub = $this->createMock(Taylor::class); + + $stub->expects($this->once())->method('some')->with($container)->will($this->returnSelf()); + + $container->invokeMethod([$stub, 'some']); + + $this->assertEquals('48', $container->invoke('ord', ['0'])); + + $this->assertSame($container, $container->invoke(Taylor::class . '::test', [])); + + $this->assertSame($container, $container->invokeMethod(Taylor::class . '::test')); + + $reflect = new ReflectionMethod($container, 'exists'); + + $this->assertTrue($container->invokeReflectMethod($container, $reflect, [Container::class])); + + $this->assertSame($container, $container->invoke(function (Container $container) { + return $container; + })); + + $this->assertSame($container, $container->invoke(Taylor::class . '::test')); + + $object = $container->invokeClass(SomeClass::class); + $this->assertInstanceOf(SomeClass::class, $object); + $this->assertSame($container, $object->container); + + $stdClass = new stdClass(); + + $container->invoke(function (Container $container, stdClass $stdObject, $key1, $lowKey, $key2 = 'default') use ($stdClass) { + $this->assertEquals('value1', $key1); + $this->assertEquals('default', $key2); + $this->assertEquals('value2', $lowKey); + $this->assertSame($stdClass, $stdObject); + return $container; + }, ['some' => $stdClass, 'key1' => 'value1', 'low_key' => 'value2']); + } + + public function testInvokeMethodNotExists() + { + $container = $this->resolveContainer(); + $this->expectException(FuncNotFoundException::class); + + $container->invokeMethod([SomeClass::class, 'any']); + } + + public function testInvokeClassNotExists() + { + $container = new Container(); + + Container::setInstance($container); + + $container->bind(Container::class, $container); + + $this->expectExceptionObject(new ClassNotFoundException('class not exists: SomeClass')); + + $container->invokeClass('SomeClass'); + } + + protected function resolveContainer() + { + $container = new Container(); + + Container::setInstance($container); + return $container; + } + +} diff --git a/vendor/topthink/framework/tests/DbTest.php b/vendor/topthink/framework/tests/DbTest.php new file mode 100644 index 0000000..cffdc84 --- /dev/null +++ b/vendor/topthink/framework/tests/DbTest.php @@ -0,0 +1,44 @@ +shouldReceive('get')->with('database.foo', null)->andReturn('foo'); + $this->assertEquals('foo', $db->getConfig('foo')); + + $config->shouldReceive('get')->with('database', [])->andReturn([]); + $this->assertEquals([], $db->getConfig()); + + $callback = function () { + }; + $event->shouldReceive('listen')->with('db.some', $callback); + $db->event('some', $callback); + + $event->shouldReceive('trigger')->with('db.some', null, false); + $db->trigger('some'); + } + +} diff --git a/vendor/topthink/framework/tests/EnvTest.php b/vendor/topthink/framework/tests/EnvTest.php new file mode 100644 index 0000000..cf2e65f --- /dev/null +++ b/vendor/topthink/framework/tests/EnvTest.php @@ -0,0 +1,82 @@ +setContent("key1=value1\nkey2=value2"); + $root->addChild($envFile); + + $env = new Env(); + + $env->load($envFile->url()); + + $this->assertEquals('value1', $env->get('key1')); + $this->assertEquals('value2', $env->get('key2')); + + $this->assertSame(['KEY1' => 'value1', 'KEY2' => 'value2'], $env->get()); + } + + public function testServerEnv() + { + $env = new Env(); + + $this->assertEquals('value2', $env->get('key2', 'value2')); + + putenv('PHP_KEY7=value7'); + putenv('PHP_KEY8=false'); + putenv('PHP_KEY9=true'); + + $this->assertEquals('value7', $env->get('key7')); + $this->assertFalse($env->get('KEY8')); + $this->assertTrue($env->get('key9')); + } + + public function testSetEnv() + { + $env = new Env(); + + $env->set([ + 'key1' => 'value1', + 'key2' => [ + 'key1' => 'value1-2', + ], + ]); + + $env->set('key3', 'value3'); + + $env->key4 = 'value4'; + + $env['key5'] = 'value5'; + + $this->assertEquals('value1', $env->get('key1')); + $this->assertEquals('value1-2', $env->get('key2.key1')); + + $this->assertEquals('value3', $env->get('key3')); + + $this->assertEquals('value4', $env->key4); + + $this->assertEquals('value5', $env['key5']); + + $this->expectException(Exception::class); + + unset($env['key5']); + } + + public function testHasEnv() + { + $env = new Env(); + $env->set(['foo' => 'bar']); + $this->assertTrue($env->has('foo')); + $this->assertTrue(isset($env->foo)); + $this->assertTrue($env->offsetExists('foo')); + } +} diff --git a/vendor/topthink/framework/tests/EventTest.php b/vendor/topthink/framework/tests/EventTest.php new file mode 100644 index 0000000..707a35b --- /dev/null +++ b/vendor/topthink/framework/tests/EventTest.php @@ -0,0 +1,143 @@ +app = m::mock(App::class)->makePartial(); + + Container::setInstance($this->app); + $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); + $this->config = m::mock(Config::class)->makePartial(); + $this->app->shouldReceive('get')->with('config')->andReturn($this->config); + + $this->event = new Event($this->app); + } + + public function testBasic() + { + $this->event->bind(['foo' => 'baz']); + + $this->event->listen('foo', function ($bar) { + $this->assertEquals('bar', $bar); + }); + + $this->assertTrue($this->event->hasListener('foo')); + + $this->event->trigger('baz', 'bar'); + + $this->event->remove('foo'); + + $this->assertFalse($this->event->hasListener('foo')); + } + + public function testOnceEvent() + { + $this->event->listen('AppInit', function ($bar) { + $this->assertEquals('bar', $bar); + return 'foo'; + }); + + $this->assertEquals('foo', $this->event->trigger('AppInit', 'bar', true)); + $this->assertEquals(['foo'], $this->event->trigger('AppInit', 'bar')); + } + + public function testClassListener() + { + $listener = m::mock("overload:SomeListener", TestListener::class); + + $listener->shouldReceive('handle')->andReturnTrue(); + + $this->event->listen('some', "SomeListener"); + + $this->assertTrue($this->event->until('some')); + } + + public function testSubscribe() + { + $listener = m::mock("overload:SomeListener", TestListener::class); + + $listener->shouldReceive('subscribe')->andReturnUsing(function (Event $event) use ($listener) { + + $listener->shouldReceive('onBar')->once()->andReturnFalse(); + + $event->listenEvents(['SomeListener::onBar' => [[$listener, 'onBar']]]); + }); + + $this->event->subscribe('SomeListener'); + + $this->assertTrue($this->event->hasListener('SomeListener::onBar')); + + $this->event->trigger('SomeListener::onBar'); + } + + public function testAutoObserve() + { + $listener = m::mock("overload:SomeListener", TestListener::class); + + $listener->shouldReceive('onBar')->once(); + + $this->app->shouldReceive('make')->with('SomeListener')->andReturn($listener); + + $this->event->observe('SomeListener'); + + $this->event->trigger('bar'); + } + + public function testWithoutEvent() + { + $this->event->withEvent(false); + + $this->event->listen('SomeListener', TestListener::class); + + $this->assertFalse($this->event->hasListener('SomeListener')); + } + +} + +class TestListener +{ + public function handle() + { + + } + + public function onBar() + { + + } + + public function onFoo() + { + + } + + public function subscribe() + { + + } +} diff --git a/vendor/topthink/framework/tests/FilesystemTest.php b/vendor/topthink/framework/tests/FilesystemTest.php new file mode 100644 index 0000000..df5ffe2 --- /dev/null +++ b/vendor/topthink/framework/tests/FilesystemTest.php @@ -0,0 +1,131 @@ +app = m::mock(App::class)->makePartial(); + Container::setInstance($this->app); + $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); + $this->config = m::mock(Config::class); + $this->config->shouldReceive('get')->with('filesystem.default', null)->andReturn('local'); + $this->app->shouldReceive('get')->with('config')->andReturn($this->config); + $this->filesystem = new Filesystem($this->app); + + $this->root = vfsStream::setup('rootDir'); + } + + protected function tearDown(): void + { + m::close(); + } + + public function testDisk() + { + $this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([ + 'type' => 'local', + 'root' => $this->root->url(), + ]); + + $this->config->shouldReceive('get')->with('filesystem.disks.foo', null)->andReturn([ + 'type' => 'local', + 'root' => $this->root->url(), + ]); + + $this->assertInstanceOf(Local::class, $this->filesystem->disk()); + + $this->assertInstanceOf(Local::class, $this->filesystem->disk('foo')); + } + + public function testCache() + { + $this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([ + 'type' => 'local', + 'root' => $this->root->url(), + 'cache' => true, + ]); + + $this->assertInstanceOf(Local::class, $this->filesystem->disk()); + + $this->config->shouldReceive('get')->with('filesystem.disks.cache', null)->andReturn([ + 'type' => NullDriver::class, + 'root' => $this->root->url(), + 'cache' => [ + 'store' => 'flysystem', + ], + ]); + + $cache = m::mock(Cache::class); + + $cacheDriver = m::mock(File::class); + + $cache->shouldReceive('store')->once()->with('flysystem')->andReturn($cacheDriver); + + $this->app->shouldReceive('make')->with(Cache::class)->andReturn($cache); + + $cacheDriver->shouldReceive('get')->with('flysystem')->once()->andReturn(null); + + $cacheDriver->shouldReceive('set')->withAnyArgs(); + + $this->filesystem->disk('cache')->put('test.txt', 'aa'); + } + + public function testPutFile() + { + $root = vfsStream::setup('rootDir', null, [ + 'foo.jpg' => 'hello', + ]); + + $this->config->shouldReceive('get')->with('filesystem.disks.local', null)->andReturn([ + 'type' => NullDriver::class, + 'root' => $root->url(), + 'cache' => true, + ]); + + $file = m::mock(\think\File::class); + + $file->shouldReceive('hashName')->with(null)->once()->andReturn('foo.jpg'); + + $file->shouldReceive('getRealPath')->once()->andReturn($root->getChild('foo.jpg')->url()); + + $this->filesystem->putFile('test', $file); + } +} + +class NullDriver extends Driver +{ + protected function createAdapter(): AdapterInterface + { + return new NullAdapter(); + } +} diff --git a/vendor/topthink/framework/tests/HttpTest.php b/vendor/topthink/framework/tests/HttpTest.php new file mode 100644 index 0000000..8b6f28f --- /dev/null +++ b/vendor/topthink/framework/tests/HttpTest.php @@ -0,0 +1,154 @@ +app = m::mock(App::class)->makePartial(); + + $this->http = m::mock(Http::class, [$this->app])->shouldAllowMockingProtectedMethods()->makePartial(); + } + + protected function prepareApp($request, $response) + { + $this->app->shouldReceive('instance')->once()->with('request', $request); + $this->app->shouldReceive('initialized')->once()->andReturnFalse(); + $this->app->shouldReceive('initialize')->once(); + $this->app->shouldReceive('get')->with('request')->andReturn($request); + + $route = m::mock(Route::class); + + $route->shouldReceive('dispatch')->withArgs(function ($req, $withRoute) use ($request) { + if ($withRoute) { + $withRoute(); + } + return $req === $request; + })->andReturn($response); + + $route->shouldReceive('config')->with('route_annotation')->andReturn(true); + + $this->app->shouldReceive('get')->with('route')->andReturn($route); + + $console = m::mock(Console::class); + + $console->shouldReceive('call'); + + $this->app->shouldReceive('get')->with('console')->andReturn($console); + } + + public function testRun() + { + $root = vfsStream::setup('rootDir', null, [ + 'app' => [ + 'controller' => [], + 'middleware.php' => ' [ + 'route.php' => 'app->shouldReceive('getBasePath')->andReturn($root->getChild('app')->url() . DIRECTORY_SEPARATOR); + $this->app->shouldReceive('getRootPath')->andReturn($root->url() . DIRECTORY_SEPARATOR); + + $request = m::mock(Request::class)->makePartial(); + $response = m::mock(Response::class)->makePartial(); + + $this->prepareApp($request, $response); + + $this->assertEquals($response, $this->http->run($request)); + } + + public function multiAppRunProvider() + { + $request1 = m::mock(Request::class)->makePartial(); + $request1->shouldReceive('subDomain')->andReturn('www'); + $request1->shouldReceive('host')->andReturn('www.domain.com'); + + $request2 = m::mock(Request::class)->makePartial(); + $request2->shouldReceive('subDomain')->andReturn('app2'); + $request2->shouldReceive('host')->andReturn('app2.domain.com'); + + $request3 = m::mock(Request::class)->makePartial(); + $request3->shouldReceive('pathinfo')->andReturn('some1/a/b/c'); + + $request4 = m::mock(Request::class)->makePartial(); + $request4->shouldReceive('pathinfo')->andReturn('app3/a/b/c'); + + $request5 = m::mock(Request::class)->makePartial(); + $request5->shouldReceive('pathinfo')->andReturn('some2/a/b/c'); + + return [ + [$request1, true, 'app1'], + [$request2, true, 'app2'], + [$request3, true, 'app3'], + [$request4, true, null], + [$request5, true, 'some2', 'path'], + [$request1, false, 'some3'], + ]; + } + + public function testRunWithException() + { + $request = m::mock(Request::class); + $response = m::mock(Response::class); + + $this->app->shouldReceive('instance')->once()->with('request', $request); + + $exception = new Exception(); + + $this->http->shouldReceive('runWithRequest')->once()->with($request)->andThrow($exception); + + $handle = m::mock(Handle::class); + + $handle->shouldReceive('report')->once()->with($exception); + $handle->shouldReceive('render')->once()->with($request, $exception)->andReturn($response); + + $this->app->shouldReceive('make')->with(Handle::class)->andReturn($handle); + + $this->assertEquals($response, $this->http->run($request)); + } + + public function testEnd() + { + $response = m::mock(Response::class); + $event = m::mock(Event::class); + $event->shouldReceive('trigger')->once()->with(HttpEnd::class, $response); + $this->app->shouldReceive('get')->once()->with('event')->andReturn($event); + $log = m::mock(Log::class); + $log->shouldReceive('save')->once(); + $this->app->shouldReceive('get')->once()->with('log')->andReturn($log); + + $this->http->end($response); + } + +} diff --git a/vendor/topthink/framework/tests/LogTest.php b/vendor/topthink/framework/tests/LogTest.php new file mode 100644 index 0000000..269306f --- /dev/null +++ b/vendor/topthink/framework/tests/LogTest.php @@ -0,0 +1,143 @@ +app = m::mock(App::class)->makePartial(); + Container::setInstance($this->app); + + $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); + $this->config = m::mock(Config::class)->makePartial(); + $this->app->shouldReceive('get')->with('config')->andReturn($this->config); + $this->app->shouldReceive('runningInConsole')->andReturn(false); + + $this->log = new Log($this->app); + } + + public function testGetConfig() + { + $config = [ + 'default' => 'file', + ]; + + $this->config->shouldReceive('get')->with('log')->andReturn($config); + + $this->assertEquals($config, $this->log->getConfig()); + + $this->expectException(InvalidArgumentException::class); + $this->log->getChannelConfig('foo'); + } + + public function testChannel() + { + $this->assertInstanceOf(ChannelSet::class, $this->log->channel(['file', 'mail'])); + } + + public function testLogManagerInstances() + { + $this->config->shouldReceive('get')->with("log.channels.single", null)->andReturn(['type' => 'file']); + + $channel1 = $this->log->channel('single'); + $channel2 = $this->log->channel('single'); + + $this->assertSame($channel1, $channel2); + } + + public function testFileLog() + { + $root = vfsStream::setup(); + + $this->config->shouldReceive('get')->with("log.default", null)->andReturn('file'); + + $this->config->shouldReceive('get')->with("log.channels.file", null)->andReturn(['type' => 'file', 'path' => $root->url()]); + + $this->log->info('foo'); + + $this->assertEquals($this->log->getLog(), ['info' => ['foo']]); + + $this->log->clear(); + + $this->assertEmpty($this->log->getLog()); + + $this->log->error('foo'); + $this->assertArrayHasKey('error', $this->log->getLog()); + + $this->log->emergency('foo'); + $this->assertArrayHasKey('emergency', $this->log->getLog()); + + $this->log->alert('foo'); + $this->assertArrayHasKey('alert', $this->log->getLog()); + + $this->log->critical('foo'); + $this->assertArrayHasKey('critical', $this->log->getLog()); + + $this->log->warning('foo'); + $this->assertArrayHasKey('warning', $this->log->getLog()); + + $this->log->notice('foo'); + $this->assertArrayHasKey('notice', $this->log->getLog()); + + $this->log->debug('foo'); + $this->assertArrayHasKey('debug', $this->log->getLog()); + + $this->log->sql('foo'); + $this->assertArrayHasKey('sql', $this->log->getLog()); + + $this->log->custom('foo'); + $this->assertArrayHasKey('custom', $this->log->getLog()); + + $this->log->write('foo'); + $this->assertTrue($root->hasChildren()); + $this->assertEmpty($this->log->getLog()); + + $this->log->close(); + + $this->log->info('foo'); + + $this->assertEmpty($this->log->getLog()); + } + + public function testSave() + { + $root = vfsStream::setup(); + + $this->config->shouldReceive('get')->with("log.default", null)->andReturn('file'); + + $this->config->shouldReceive('get')->with("log.channels.file", null)->andReturn(['type' => 'file', 'path' => $root->url()]); + + $this->log->info('foo'); + + $this->log->save(); + + $this->assertTrue($root->hasChildren()); + } + +} diff --git a/vendor/topthink/framework/tests/MiddlewareTest.php b/vendor/topthink/framework/tests/MiddlewareTest.php new file mode 100644 index 0000000..bbd092d --- /dev/null +++ b/vendor/topthink/framework/tests/MiddlewareTest.php @@ -0,0 +1,121 @@ +app = m::mock(App::class)->makePartial(); + Container::setInstance($this->app); + + $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); + $this->config = m::mock(Config::class)->makePartial(); + $this->app->shouldReceive('get')->with('config')->andReturn($this->config); + $this->app->shouldReceive('runningInConsole')->andReturn(false); + + $this->middleware = new Middleware($this->app); + } + + public function testSetMiddleware() + { + $this->middleware->add('BarMiddleware', 'bar'); + + $this->assertEquals(1, count($this->middleware->all('bar'))); + + $this->middleware->controller('BarMiddleware'); + $this->assertEquals(1, count($this->middleware->all('controller'))); + + $this->middleware->import(['FooMiddleware']); + $this->assertEquals(1, count($this->middleware->all())); + + $this->middleware->unshift(['BazMiddleware', 'baz']); + $this->assertEquals(2, count($this->middleware->all())); + $this->assertEquals([['BazMiddleware', 'handle'], 'baz'], $this->middleware->all()[0]); + + $this->config->shouldReceive('get')->with('middleware.alias', [])->andReturn(['foo' => ['FooMiddleware', 'FarMiddleware']]); + + $this->middleware->add('foo'); + $this->assertEquals(3, count($this->middleware->all())); + $this->middleware->add(function () { + }); + $this->middleware->add(function () { + }); + $this->assertEquals(5, count($this->middleware->all())); + } + + public function testPipelineAndEnd() + { + $bar = m::mock("overload:BarMiddleware"); + $foo = m::mock("overload:FooMiddleware", Foo::class); + + $request = m::mock(Request::class); + $response = m::mock(Response::class); + + $e = new Exception(); + + $handle = m::mock(Handle::class); + $handle->shouldReceive('report')->with($e)->andReturnNull(); + $handle->shouldReceive('render')->with($request, $e)->andReturn($response); + + $foo->shouldReceive('handle')->once()->andReturnUsing(function ($request, $next) { + return $next($request); + }); + $bar->shouldReceive('handle')->once()->andReturnUsing(function ($request, $next) use ($e) { + $next($request); + throw $e; + }); + + $foo->shouldReceive('end')->once()->with($response)->andReturnNull(); + + $this->app->shouldReceive('make')->with(Handle::class)->andReturn($handle); + + $this->config->shouldReceive('get')->once()->with('middleware.priority', [])->andReturn(['FooMiddleware', 'BarMiddleware']); + + $this->middleware->import([function ($request, $next) { + return $next($request); + }, 'BarMiddleware', 'FooMiddleware']); + + $this->assertInstanceOf(Pipeline::class, $pipeline = $this->middleware->pipeline()); + + $pipeline->send($request)->then(function ($request) use ($e, $response) { + throw $e; + }); + + $this->middleware->end($response); + } +} + +class Foo +{ + public function end(Response $response) + { + } +} diff --git a/vendor/topthink/framework/tests/SessionTest.php b/vendor/topthink/framework/tests/SessionTest.php new file mode 100644 index 0000000..b3b48a7 --- /dev/null +++ b/vendor/topthink/framework/tests/SessionTest.php @@ -0,0 +1,225 @@ +app = m::mock(App::class)->makePartial(); + Container::setInstance($this->app); + + $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); + $this->config = m::mock(Config::class)->makePartial(); + + $this->app->shouldReceive('get')->with('config')->andReturn($this->config); + $handlerClass = "\\think\\session\\driver\\Test" . Str::random(10); + $this->config->shouldReceive("get")->with("session.type", "file")->andReturn($handlerClass); + $this->session = new Session($this->app); + + $this->handler = m::mock('overload:' . $handlerClass, SessionHandlerInterface::class); + } + + public function testLoadData() + { + $data = [ + "bar" => 'foo', + ]; + + $id = md5(uniqid()); + + $this->handler->shouldReceive("read")->once()->with($id)->andReturn(serialize($data)); + + $this->session->setId($id); + $this->session->init(); + + $this->assertEquals('foo', $this->session->get('bar')); + $this->assertTrue($this->session->has('bar')); + $this->assertFalse($this->session->has('foo')); + + $this->session->set('foo', 'bar'); + $this->assertTrue($this->session->has('foo')); + + $this->assertEquals('bar', $this->session->pull('foo')); + $this->assertFalse($this->session->has('foo')); + } + + public function testSave() + { + + $id = md5(uniqid()); + + $this->handler->shouldReceive('read')->once()->with($id)->andReturn(""); + + $this->handler->shouldReceive('write')->once()->with($id, serialize([ + "bar" => 'foo', + ]))->andReturnTrue(); + + $this->session->setId($id); + $this->session->init(); + + $this->session->set('bar', 'foo'); + + $this->session->save(); + } + + public function testFlash() + { + $this->session->flash('foo', 'bar'); + $this->session->flash('bar', 0); + $this->session->flash('baz', true); + + $this->assertTrue($this->session->has('foo')); + $this->assertEquals('bar', $this->session->get('foo')); + $this->assertEquals(0, $this->session->get('bar')); + $this->assertTrue($this->session->get('baz')); + + $this->session->clearFlashData(); + + $this->assertTrue($this->session->has('foo')); + $this->assertEquals('bar', $this->session->get('foo')); + $this->assertEquals(0, $this->session->get('bar')); + + $this->session->clearFlashData(); + + $this->assertFalse($this->session->has('foo')); + $this->assertNull($this->session->get('foo')); + + $this->session->flash('foo', 'bar'); + $this->assertTrue($this->session->has('foo')); + $this->session->clearFlashData(); + $this->session->reflash(); + $this->session->clearFlashData(); + + $this->assertTrue($this->session->has('foo')); + } + + public function testClear() + { + $this->session->set('bar', 'foo'); + $this->assertEquals('foo', $this->session->get('bar')); + $this->session->clear(); + $this->assertFalse($this->session->has('foo')); + } + + public function testSetName() + { + $this->session->setName('foo'); + $this->assertEquals('foo', $this->session->getName()); + } + + public function testDestroy() + { + $id = md5(uniqid()); + + $this->handler->shouldReceive('read')->once()->with($id)->andReturn(""); + $this->handler->shouldReceive('delete')->once()->with($id)->andReturnTrue(); + + $this->session->setId($id); + $this->session->init(); + + $this->session->set('bar', 'foo'); + + $this->session->destroy(); + + $this->assertFalse($this->session->has('bar')); + + $this->assertNotEquals($id, $this->session->getId()); + } + + public function testFileHandler() + { + $root = vfsStream::setup(); + + vfsStream::newFile('bar') + ->at($root) + ->lastModified(time()); + + vfsStream::newFile('bar') + ->at(vfsStream::newDirectory("foo")->at($root)) + ->lastModified(100); + + $this->assertTrue($root->hasChild("bar")); + $this->assertTrue($root->hasChild("foo/bar")); + + $handler = new TestFileHandle($this->app, [ + 'path' => $root->url(), + 'gc_probability' => 1, + 'gc_divisor' => 1, + ]); + + $this->assertTrue($root->hasChild("bar")); + $this->assertFalse($root->hasChild("foo/bar")); + + $id = md5(uniqid()); + $handler->write($id, "bar"); + + $this->assertTrue($root->hasChild("sess_{$id}")); + + $this->assertEquals("bar", $handler->read($id)); + + $handler->delete($id); + + $this->assertFalse($root->hasChild("sess_{$id}")); + } + + public function testCacheHandler() + { + $id = md5(uniqid()); + + $cache = m::mock(\think\Cache::class); + + $store = m::mock(Driver::class); + + $cache->shouldReceive('store')->once()->with('redis')->andReturn($store); + + $handler = new Cache($cache, ['store' => 'redis']); + + $store->shouldReceive("set")->with($id, "bar", 1440)->once()->andReturnTrue(); + $handler->write($id, "bar"); + + $store->shouldReceive("get")->with($id)->once()->andReturn("bar"); + $this->assertEquals("bar", $handler->read($id)); + + $store->shouldReceive("delete")->with($id)->once()->andReturnTrue(); + $handler->delete($id); + } +} + +class TestFileHandle extends File +{ + protected function writeFile($path, $content): bool + { + return (bool) file_put_contents($path, $content); + } +} diff --git a/vendor/topthink/framework/tests/ViewTest.php b/vendor/topthink/framework/tests/ViewTest.php new file mode 100644 index 0000000..e413510 --- /dev/null +++ b/vendor/topthink/framework/tests/ViewTest.php @@ -0,0 +1,127 @@ +app = m::mock(App::class)->makePartial(); + Container::setInstance($this->app); + + $this->app->shouldReceive('make')->with(App::class)->andReturn($this->app); + $this->config = m::mock(Config::class)->makePartial(); + $this->app->shouldReceive('get')->with('config')->andReturn($this->config); + + $this->view = new View($this->app); + } + + public function testAssignData() + { + $this->view->assign('foo', 'bar'); + $this->view->assign(['baz' => 'boom']); + $this->view->qux = "corge"; + + $this->assertEquals('bar', $this->view->foo); + $this->assertEquals('boom', $this->view->baz); + $this->assertEquals('corge', $this->view->qux); + $this->assertTrue(isset($this->view->qux)); + } + + public function testRender() + { + $this->config->shouldReceive("get")->with("view.type", 'php')->andReturn(TestTemplate::class); + + $this->view->filter(function ($content) { + return $content; + }); + + $this->assertEquals("fetch", $this->view->fetch('foo')); + $this->assertEquals("display", $this->view->display('foo')); + } + +} + +class TestTemplate implements TemplateHandlerInterface +{ + + /** + * 检测是否存在模板文件 + * @access public + * @param string $template 模板文件或者模板规则 + * @return bool + */ + public function exists(string $template): bool + { + return true; + } + + /** + * 渲染模板文件 + * @access public + * @param string $template 模板文件 + * @param array $data 模板变量 + * @return void + */ + public function fetch(string $template, array $data = []): void + { + echo "fetch"; + } + + /** + * 渲染模板内容 + * @access public + * @param string $content 模板内容 + * @param array $data 模板变量 + * @return void + */ + public function display(string $content, array $data = []): void + { + echo "display"; + } + + /** + * 配置模板引擎 + * @access private + * @param array $config 参数 + * @return void + */ + public function config(array $config): void + { + // TODO: Implement config() method. + } + + /** + * 获取模板引擎配置 + * @access public + * @param string $name 参数名 + * @return void + */ + public function getConfig(string $name) + { + // TODO: Implement getConfig() method. + } +} diff --git a/vendor/topthink/framework/tests/bootstrap.php b/vendor/topthink/framework/tests/bootstrap.php new file mode 100644 index 0000000..991ea43 --- /dev/null +++ b/vendor/topthink/framework/tests/bootstrap.php @@ -0,0 +1,3 @@ + composer require topthink/think-captcha + + + +## 使用 + +### 在控制器中输出验证码 + +在控制器的操作方法中使用 + +~~~ +public function captcha($id = '') +{ + return captcha($id); +} +~~~ +然后注册对应的路由来输出验证码 + + +### 模板里输出验证码 + +首先要在你应用的路由定义文件中,注册一个验证码路由规则。 + +~~~ +\think\facade\Route::get('captcha/[:id]', "\\think\\captcha\\CaptchaController@index"); +~~~ + +然后就可以在模板文件中使用 +~~~ +
    {:captcha_img()}
    +~~~ +或者 +~~~ +
    captcha
    +~~~ +> 上面两种的最终效果是一样的 + + +### 控制器里验证 + +使用TP的内置验证功能即可 +~~~ +$this->validate($data,[ + 'captcha|验证码'=>'require|captcha' +]); +~~~ +或者手动验证 +~~~ +if(!captcha_check($captcha)){ + //验证失败 +}; +~~~ \ No newline at end of file diff --git a/vendor/topthink/think-captcha/assets/bgs/1.jpg b/vendor/topthink/think-captcha/assets/bgs/1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d417136bb4613984dd88ac25590d2794344c990f GIT binary patch literal 30428 zcmeHwcU)7=((p+mw9rASgx*U60YdK*igcu^ln9}O7K+#a0R#OQ9wlj zu~1ct(k!5YfTE}%-$}6G^E~&ym+yP;Umwfw%$c2?nVp@TbJ!)>VfpFu2*74;N-zZ= zPzYozWGetHk1{HnM3Z&^fRz;>3jhE;fP`=WFc5=)KLCUuK+tdi@PY{Z!u=uAKX{-Z z4+a1sAP8Pz5G)Pn0`b%XBmn+Hwh+8`0yy6h0FYw)c{lJ0_9CKf{DLXL;eNp(Xd`

    >%aJv{?GGXn!NI};-lJ2xvcGb=YQCnq;2CoelQt^ByHRQ?Jf zC?+Np3yO_}g^i1ag@ua>Sh!Y1*#8p+%gq2gJ)jSqgF!?AC_4nk4q1K%4x4eg1)>L9 ziGa`wXfUlV7!8(m2z>$K+N4MQua3 z;}~)7O2X})i181mQdxzG)yGqFM7A3N`7{ppGF3j2jOG<^v=XJ1*+fj|e56^TubeJg{v)s`+QNhZB<|B^^ZkoGy z;=&MsnA*j3qC0{`xbJ(FsZqYZbb&tW$!{4*8$H&HGg>)sRbNz3kq(`Aor5CH3^@pV<((}xO z7P;M`YdrFL9KMFX;u0x7+Qeltc8HpUuPAvNO;b-sAbFoL#jE{H^g$Px;$}_iAUkc*=h!;4)|9 zwQc(>pM8w@6jyq7+OXJwVM1$`B8-a??@MNs(#6qgw-e>8`Qdu9B#WTgj&gf*eoYuRcdT>s=mO zPWri76YJ&9r{#k}(*pT>O73vHx=wfFw$st@>c{(35dwz<$GwfC&)|f58N%bjUq0uk zt;>J;nPG3|umuS+)Umm7m|?LOL)o&eaL>C;!Dh{%?{@p$nT(9dGqYCw(?|A+8j3jC z_Fo<_*4-H_cK_T4S3y)lJtrzu+w8j??!M$!)};5+iz8*4bC#NsUjj5sy%b1+)o(>w z(l4^;5*`{2UQFvL*uV2M?t2-`A|ZB9;Z8Q2sa?;F%wnYscVgx&4mh}ZUPbLfg;_w- z#I8lYNXoexSXH-yzT3L1&*sG97;AJF#|8SKC&Ee7z6qAli?#e7#D<|))tUA8Tjy=D zeD;w^sG?@AsGw*88-b6XkkHL(QxK`K6w;tec=GexHRW`sO=qV+2kB4ii62QlvLz#6 zD57^SBea=rSV(*y0&BGSCdZWcgkE*ZhY5#(%Xg;42AYS-*Y~ECc=*L~A3FS|yx-G1 z_tjb75Df{PBf(EmVUvOT`GtD)2D}b-_|`5Rcyi==v)G3$p`GE|P>|Y_Vkf?rei5;g zd=&pyh~N5CvmVFhYYDpvAI}&Gi9b5u%)q}#IA)_6a;yjWdd%j8yUs;r>(?mN@AuLU zF+uW=;}UCCGaI6jvGh~ZD90C>EaH6e)^T=G-J%w;v$Hm*H;>=n-33jQo?Zr)yL!L6 zswelEOb1S$A2$+_GbsH=e>`e|E9aJrcv3a*abA9fM;oMWa#w_Yir=1$X%WE<3aTxR zG)tdU2xo4v{ZhC$YUIGAs^c5iIo@#qa`F3zB5lW=1#Uau!tQqZ2#H*4Jt}+Sm^Q0T zXkqH?w{{Pg;s*^kZco&c`rTR|?8@!DTXT5(l3XtGdFrjZWfwYYPjBD@amXY7iVmoekX{o@;t(XkVAg zhZEZ=bf^6&ty^+FGX70MbEF5N?Ijw*h2GT?LzM?t8TzF^bY z4A^*F9vmU=eQrb5;NwBQEoy_v5|#jC@`p2q{&PYeo)<4_5)`HO&w5>a&1ME)-S zfbyOFnWzupu{P)Ky)PWDiblN4A?T%xJuH1Ry)dVpVb8Yb749qo{hr*k&!<`S1b=j^ zbWQIQEko0;yyVx``Nv9G4mjAdkD^)OMyalQ%AdU+UIsJ`Mz1&XNAH>NC^cy2otgPy z6K)oHedD5}lnc_K<>b&_zfxG-(9R+D)1}!PReRbQo1?U6hu_mz>`rslf;~!+uwL$8 zo?>PGy<$^QR0cE*3080k+H!%723G-U8*FN&jk?+d*H6%&cbc3et&Qckh+ZtPq7g-- zQP+>rG)}%>^^G*GA82(38Uz7kMT(JD2UlrS9&n{eEsV5P8x@1nB))g z1R=OS1PkN`CGTX;FAA1McLm{39vqFL@S8%@xw1wK0oQ>4SYQ(%|9_#4+BeljU;)>w zv>J6K4gkzF_yf@B%CrjI%JPmzp^kw%F6x>VNu$uyC{(Y3G^qZ{^eOEK3?%O zKeY-2myAC=L#+aU4S2PI7s6N84|(DQpa5XN8nuVNmen+>1Xc2nvYO#%!w=J_RdPgN zAb6t=m(D9Vg6tD+?d9(c)_%y@c~hue)4byVZY~0Y$-ZEnRxF7-D68v+l;EHrb($G= zzJ5R3six6|2a>#r;ZA{;;b0B&M?VN!8%X8=FC?u(FkYn_=^GXt5%LF#E;x+jOCl4= z5ka5~vxz-byETml)={1jl;BN7GBM1PLi7O%fWyuZ;tyuV6=o`h+Cm8OMT58h_V{5D zVSx@N&JJK#Kb%W-{+|@9a9`pd6gtm9ii4-`A2b$kA}B|UrVzr-9IPz8f`bF83h956 z|6peD3l57h2qgLb^c3sL;LU!LK}nH5BOeP6o1Fa7^vUrJj?iGa%>0B{5^2z7zP3K#%BKrrA15CJr} z!SDld3V4Onun>@g^MBw#14e*7u(AoH^{}!FM6P@e0s%ig(X8^LP(n17l*r+Vp487X z6upCkl%hRDlrW0QN`SUrbcm;S0Fi?BB7$pv9ntpR$kB;aToRzXwh!N3`WEK-f zw2#^B;2jg-jrS4N(`D3-){G7c2_jNF(a}MH?U_^Bp(P*@Gn9mMPJ7d!yl3-0o^oNO2QBjIfDvH5jzDgK89dWJ;uav?=Vsbg%nIiQ}ud+J1vTis3^6gUuDHaAMaoNgn;`6S}#7{ zO2j~75Rps?2i<{D`lTF{)%Nk$+z}iWH^sXzMAR-$&i$`INp zsS5r=|DOy5=j4}#|2SEHSO;=z8if%(Dc}|X+@|Q#KFRs#&#JVk)BOkYZ}({bY9bng z`#D|e$65*)tO8ce;pfL%a>^Q-%F3&htZ@EChgGl-X~)k0M8_)5zv=)Z$H$Z6`5$Rn z&HG=N3M;FBKN&$mO8*pP;S@XK?|}ZtX$+@s>6Gk<;lUAM-b9f7cT7{G2AmKpD^25I z?+9vK5{z{tB1k@(riRKGyoNCrkHxDR8)7g9CKw|F6%9ii7N?9?RmIV!=TEsmoeQ=R z$l(-EvN!RUPNV-!=PJ3s=`<#Wks^screVQBwD=D33=1bx2dE?ZbA+qImO4P1i!@1p zF-AjO*~q{|O#=@O=bs1oH@V-&{8sDp7r*_dYFEkqR{P7TzX$p2;r`!x>M5ih{~}(f zEwq>PY6oglshZ#)W5C$(q`vlaG1^LhqpcbOt<9M_7l9EpeifWDwJ2ez@Q3W`_P@%y z{139L+y5&2Thx(EqUd6OboUqXU!^vK1B)aYlYEKcpbSn;9*a{4FAea*%VX8B@>q3M z@B(QXs`5A$W$?m)I7rt}k;mfIYU%CHqnTnc*nyS32GG0xY2El1k$6!|=mPT2DDj*$)S>aKYr%I{QAULJq zbb%BQf)rH^oH7l9(+T3>WP%W!esvWvIH(Zh2O*vcH9$@fQu|T?Lxl>dy{Ld8M1`O% z2x+ol0I6bB!B#2+tp(ugHawo%Bc7%cPqhTAj8T&Z!&V*)b$K;;b$JbWygcX{ z3`QPhfUBV?kc;DZ6iyB0>-*vJH{YGkTx zprVS!tKd{sjMY@|YFI-9&}Jk2kIDRF#{Rd1Jmlw>Y5qCVe>ML-+a#TAWw2&UIz0Q38RiF7=@!$Yj>O{qCx0PxHEXzI84 zsrc{m>G4W-m>vZ)8#MYi{XfFky+gvlEG`gg`W+P?@YE@YCxCch6eWa8r)EXr@(Q5h zP-;pat}xI*5a*@hzALyqjb{bdr{X?AWH5malxlN`Pmm84ZvpXxkrC9yIxtHRPl_ZF zqd>eD#Ki+6f=D1v&E>=uMDzrc{lKXiSHvkqZ$A)M265&v2RkDW*9P;gF#E2;y;k8A zFvAVV3m655?4;#$hQx&NE?TkXeOU^fs4BmswjG~gJJ1Dpj4fl}ZSPzBTh*MXbB zU7!QZ8r%mA0wcgn;4Lr%d;-3K8O)Fn6oeDP2N8xyK;$4;hz3L#Vgj***g;$%+abOX zG9&`B8?qmA2$BKGf#g9-A(tUnAvYoIkS<6+WE3(9nS*?V!l2AhE~pSx5~>8%fEqw8 zpbk(Es4p}W8Usy$rb16Z^Pv}^wa}Z;4rm{A1o{>_4<;05g7LsaUM z9{4DH2L2s^LI@({5Sj=A!WrRG!_ zC)3B%XVaI_H_~_0zo!4jz{ViKpvhp(;KQ(!;V45P!!?FS3@;hJF|spCG3qcnF#0pb zF`i(&#CV5si17mx6O$+tp2?Pp#1zYPf~k_JjcJtW3o{3^EVB`_J97kcDsu^QGjl)l z2NVh=iPA^8q9~|TR4M8<>N#qGg_A{*g}~y&vXA8yOD#(`%QPzks|2e7>sHnn)@;@* ztdCgVu`#eovKg^?vh8I%#dekL3EMn7Cp(7Snmvg9Fnbw$JNpC&l0%Zigu{m;fun%q zHpe(8j8lx$h|`;MKW8E59nP0rbX-zg1TKHBLtN!t54mQzIk;81ow%d9PjTPi9^rxU zNb(SP0(p+|RPj9K`MN=9gTV&khU5*GHgs?J%qzgF&r9S@;jQ59k)+T%uLtv!s;d7RdvW zb&?ZOyix?I7^w?VL((W|J?T*CeCb{pIvEX_0GZP=ow86_oUEVhDcMJIP&qX@lH6&z zE_noau8}OCFaJb=S;0UdQsIKas3MP|rDD8do#M2TxRR?BpscV(P%pmL$|Acg~D zj)})y!^~l2vEJBI*j^QsimA#zm3oy~RXJ6n>KWCiI8K}u?f~uwv;weyHI;vM^wjC zCr@WY7p=Qp_nhvCo`{~OUcTO#zL>s`ezE>*0~rH}U-3_40XMmXMbVs&zNDs}q2#du4`mJw$q=RM9HF8nSemwH#E ztCMT7>%5zZ+cCG7?l|`(_s1Sm9?>4{Tlu#JZoRRMb(`n5E87vI00pPpZ~-#d~KDTg%cZ{~m2 z|8szKKuN%I;FiFOAo`%~L08EfPj?wG&%bIPT8HwJ733`#uV*>@ABStYq!YmxZR_B z4EE&hh3xg(duyNAzJz@*V>iW~k7JArh@}m32&T`}O`b!Fz@+x>L4pjn`5tVN) zZ@>Jw%A)Gl6^$#GswJv(YdC9CY9X~dYiH{G>PG5a>btI*U%hor>sn2NVnfMwk?W^! zaNjuE$k>?BxZD)eG~XQ3{O+dj&GB2?ZVldczTMkm+w$;^#htdhrgv|*8niaG>9k#M z*KEIfPvc%)hgwJNecb(;2e=0{57i#lK2m>F--++M)}`Im*sa%nv&XpSZZDy?qi=Ix z*JH=WPoKCy8F}jSbfQ17e|8{p;M-vA5Mn6h8QZh$=Yr4khh>H(0rs8`vqgo!VzrR1@ zJo9okY<79>@CUvRB_CBk-kP_WfBq@x)3?tl3w#Ubzi51E{krAr>u*tu$i)*&GE3LK zTYMi{4gwRO{?2%>53U7PGTy^s)B-~A_aS&85pXyHNl!WS^r-$-rE3eFbJ3;{&&WEJ}~1wxU2>L-2t_L2(7>oFen`a_>u7* z3Wcq1{WG&56au4Wyr)CLKmZMgKw<1~00E}FH?XDS^aNAhb79l-klZU7=SNj|yk^A1 z;%6m{RP8hJtGvT+;f$p+3$CbbaPXnr?jEC;+|R(s%a@R4Vp>@3)Z-}4KR5n?n)RL- zk$7w+^Zma_e6L~V>=%9T#QFNRrxOb@c!CRQXY$F?tL^=hUt~4SUHxNHa>}mV8+h|| zB||<8fdI4i!|7qLAX>J1YLb2fge_<>U1(f7Ht+Hb*Uhd`F+*-UudrDaaaE&uo(y}5 zeDA7T$nb95nDPD%4w>Np1K{P8R5Rh1@}W4Y&lOy`EiKbC{vjc&u=-DvO;=^>U!AP~ z51apu$$uu*KXd&d5o>OlasSSM6WP+@bO+~E+}kr(*n0|Ii)RF$8;B&OU4{n_`)}+m zY5MZ1Au+K=q35y;zgwUMUG#E zLv7)xJI^Ubj>?xet($lCG<6gcZ01_3j!oW*Jw0i)7^a`c=$(~kIPWpR@Urr0=&*c0 zqG6Zsvx7?ml|viHV}e|_v~r5anbqjAE6l>aIh4)_1gDwj_L-{aDKZAw$@G4@#6HxL zH~l_n%Ij;J#HW#DkL2${*w8o$0%41N!;9{0ZJ|caO0IV@H;^4z4H%Qbz3Xm$h+M5L zF+7TL*>Jo4=9guxZu4^>2%m&>=JaKGv59#AqtH>SZ=SLjZXcGusV@%I4BC1+;C-48 zn0mc)f~D}P?@(fXPsQ`dM=q?nMbqify)3WCN?aphb?)^%;`q_SZaB49NYO?ioo`+& z6Sh4;ms$?Be4o9^Zu;yK*V`J_M}nCQv6j$w{4t^&b8R2CRH{f;rf%OE`xeB`E2EN& zIY}6a7G;j;2FDXNlrN*{=gdXryA|JbcjeW8JeD00xe%u%)K*bvS*CLA(3=4-=_kfz zatC!BERy`r*%0Ke`co!Pa?sWK!?#W}e6w&nWqoO|WyZ{kUGPax1T&G?S7|{xkyno&mcHYq`eJL1?%;b%_D2y$ zk(;zm#_G%l!CXbyj;ZL_=Sj6toa)prH zN|HCE$XPbWMt7$0^N)#<^sUv;+n-dp73XbZz*Ua2QvX)fDZ>@p>^moEzpIC)IqvU$~=caJ190Ypjm&McLK-x=e3U(XJ{ z-#mD1W~gc0m;cTTwzuZ{)w8l`&sqeyU2r$F?}Tz$hz@x$atuYwaKG<$cp{t1;4GCE zgcrLJVKCrs#M!EI>uY{&2-ow%?h?gZ!c$yJY+$k8*1BtwhN)G7=N}HjE>FH6lsU}2 z=RuO8#b{2qx}=v!MuO=%p|`dkcQm~*qH4yL2G302yb&^Q&oJZ|i$ z`PNoKR>JtJgzlhh!u=|nRz@%lNNOylBiu61pn|QcaVjV^t?tl<{Ap*|_|1LfVN-g( z(7r(#$ZbmIpxc9}H=FnhQ)(Rjk6gHcVhumZk#@w*-FtU-HMaj8wiI&2p|dkyr+KD5 z6dLJeK+kks0al?Id(kZ>V)D2N0udnGDv%`GwyE}6YhdL$CjakVRrv?T%%K4@M=n_1 z(cZ1x92lRH+HG5ML_h7#I|ytlB!txArA0LLK9qPRwy$AJmuGd4Zl$XW-;$cmp>}g8n|SNLLU8wPHPBc?l1`d`{+i-;nWZJ{}3#RXH3+ z7{)4`zZQ0+<%a&@ph{qgSKny4d!kCLe@NBRyh9-HncRqJOtrt)u%I43i|Hd#euu6J1P_}oj#mm zZnkIyS5*}(bq{SurR^Zp@J&A$H9P5~XYJPu)7Sc_+wbFf>#luu<5=X8=ZqPHVS7&M zm&|>tNb+D0WH7J_;C}S}5a7p~^`=i?>cd99Kp!Ixw$6v0kNKRcP-Rg7zfF)wWx8K= zl<2IST<8v*wtBfHyU~bTTGE&rR<7y0 z((NNhY9L?tR05F7QxeLR^;fFL9&t;^!_2KVL8HzU_d7Y?b93_%7oDHp*}Xi7?kZKXv#%iaubM#b8qO$l(U50eRE;^GgL*GY>-r z`wwQeEBAa%4}ZHi5_lcw<{!}A#72xo4WNY7pv=?LCyr<%hyxd9<06K;hUCw-fVe-d6qGP7@x@)jF%g(jY-lt(YOac%XJOYep?~>{K9p7H0zV& z)#W+cHaqI@oJ#L~a>*=_k}7dAJ*PYF_(0==Sd~MwXwg2uZw~v;y65Btqd5ySG4qDA zPg8JOg1J`cB=wykvnreT(9(<_2gfD?40pZq@#=QEiM1>;?21+8E|olOFnh~Hf`j?O z28j!1vc0$n|H$!?fI*Q5c3-xViWFbSCz|O;!YYBtVTFSb1bmOg_m7wN&c9KcR_{n! zJW(TfCM&(I@O=4BhtrLt$w$h9AL6+SeHAN0D);lcVgoe9dd5T9HazT2dz>d@UnvkBd9Of4=8H-ea5TptRJpc7 z_^{J~J#RaE-w&(A)(IAP^^BV##vgvjpigt{+51A6e+TBC<$1>MSJE&k4PQi>to5E` zwQ}-m9DF9!C<*j(KF(@q-k77^8TQ^g}b^I;YOERieD?QI2`lW$5t~JekGbQ=trpv?Kyb=L{v@IX-3nb zCy`5Kfm)Frhq#@N=+NcZ-!m;?>}B6p=wsl3u@i-Cx@%=n5&UV+JpXX)neCUQM!672 zNMC2Vw=MUcH5(~)5WhSW*9lt;f2?2fkl;Mtb6~72^YH=iZ9=UE8LtvFvTRc}S}i_s zoiYzvx~j}O;206A(8KnqowG!rVdL0IiWiK7;D%_6C!^~adt#-gf|}gZk0d}3WxtI- zdoVw8Vz1c84AK)hcHfqaA=m3e8JLIqgLWx$LuB2(e7lL3vYpaJP2hiWfybrx=5YzU zyc6%~J%1>6g8hC9E64RxqbDVe;CA34I*WKFUa90XF|1fkd$9ObgH3A9M!e;R8DLOw zw~66f)1E?k+vj{+MwtuK8*d*AsO!c)eVG=3;i=N0lUB%{TN*Iqw&*g^Wv@|_ikV*q zRN`IZt(kY$GJ9RT;2)V?{1|0;6WSa}v^TK&#`syNinmBnj8D;wvGVw2ol}!rGMPR$ z3~0zGbBvNK4BEE4t%LJcKxDm8kHRL8y4s!DJQfE}+IJa7y)v=#V<<`LKXla6Y{M1G z71sT1^Rel0h*2)`>XL z+a8Ke)4E)~*Js2iU4uvA2B7-oY;d+()@Q>y=U2Nf+_6bJTD=Ug!9Svd?QKu&Y%de+ z*ei0QyjOl;Qp5rBz8EE@9WdF_^-=tZcduuwuD~=y7P;Z+=~t&igQW_)V1fs7S@~E{ zq)M?0_eV(vQoPLvT>CwiHjj;&U|PvY^e|KK*4UA(@$FGn?5cLJBr-Fh`skD+b#Dh- z6`6Su&VyrluIc7BDI06vCbBN~okD)R>2>?4otl*A$N5JdqQe?~*V^9QANpLD(krcV zUhTF+%Q0khm&;WJy>`_iKlNd8e4ccUspIxj5`@DtKxR+vw;lS-TwY0Y(Qn}jGw;N? zgmtSc=5P7(evo08%3yE20-Kd62-&3ZqMSjC|LE>YTb{cIefT}@9L~miJfAZ)GUA_V zj~z-`641Tn#lz#t%_uP)j>WUc3#yD)x zR%sCz5K)F84%X&rM+SLyC7Ou036I6#cmu6;J`byH<+7~L-K*j*6TpcPXEPIEuiFP} zbbst-*2(HH536V+hZH7OHForEY-0U1mYC%zJ>9FtKh+ebwiI2K|6qb}jRpQrHfG^W z(*+1mX=0Xt&q<+J037wFWF2HvTaR>lu_rEdWblCgA@T6^hZ~AyZV-yF$@+v`AH)6r z_pi*>+Y5$P@Vc^Zh80EEws?gCGpNLx1SmV@FPetsbEoRX5aXDOP-*c~N47alE9~!oez6n! zcs5fond9#D_#Cc0sq@3YF*DoOuQJrs5-p@96SuoLx@9L|QYk)R0+j2+gn3qq-)N{5~DMhi`8U4Twk1GC~hY!de4979y3&VmylWO zmbFpng!hGKs`aT~G8~=9>+AHMwQhxf+iiGSg-2V9qG(xv!m4-wTV{G$+k?(YFZIRk zgD#vpI2S^1Swnb{`tYuqdn@l)%h7oQ?jpHb&oQ7a{)J^ao8f^IqVk?68D2`~iTTgw z2`u4vocO>T&SD~cxk~-Gf6da<3-?T7SXs|nwzuo@*4)xINq_Dl&}O{N*rDgjooA;MI z9?hat`njX$n4F#`bT>pG11mibe%QorQCG_RIw#W=K=>gd-}WeY^-3E^MU+fMA7*^5 zce$fvK&)kcG9^*c7n@ivZ57jVb<$nNy)q^#^_g_^yz0!`TDW31)(-+mpX0T0yL`rt z)W~vV=9=1@!52Od=5m#Q8k-Rr*WKv-SDyy=ko&hViOZ>IW~j~6mq$%&@5V-$=|4j| zEtsj=T||z5oolu^ZkeZ1!{iVsV`n9|u*+vGvG%w<-$5sIJ(KyA!Q&fpNw!RWSA&(@ zKC_04>Ypo%yLVs$DLZmh^VxCsm%+W>_6@|o_n zK1)o?+THDjpDIX4-S^BRSD(+*K_T5Ab}4q0?!iYtj(s<1-xS#IeZ&~aVRt1UXg*Hpd`;uwNBqjp zy&Md%7&cOOy~KfC$;E9ixJ`^~dVTtQ>?S8K>d)x=n~=sW&uDu=4!>?G60l;$aFw%d z-;j~Bv1ZD$GS>8+!6kEZ#y0DUhX$XLhk7QZST|b|j6}9@!@=LSEyUboRpR0$qCko3 z>D1xP&_ukG#zb>ZImu&@?zQ-a459w3Jo@_3k`n)KqfT!enP6Ll{mvYlv@YOwd7~0o zaOpwq@asl4tsbjHAJ@xcP1T!%8w9E|{c%bXrp>`ls^^hcheZ?329p&Y`7_peOnx49 zdJ%a}$MG6}%Gm-Ao2yI?I?`pPOBd211e33aS}1}CT8+#dBHDW73<=U(AS8V}tRwCG zSFIiir=)2^u8pOTwx^xFv0A-HW@1Z&o-PBM;QZWApOh0sPilNH-`KY;i)ip7_q(L5n**13*^CS-@WLw?1M2| zZewB4(OC_rau+k)8+`DBrxvEVIBe_G)1ygPeb_ms$}hx`z&kLd_uT3WWkws9>N>oN z%zaI=%26h|9$2GHj!HsHU=#cF;CDVn0jn|wXZy3(5Q7CD^V5%|75(&WkTw8(i8nqc z=x}Ie4a;EEVn~AY1rA-6dkqehl8!*xVr!9ECAI)p{&Z_p!&rHyt-h?b=AMPJr*CaE z>&zE=iV?5+7fw3_Iu$j}jwZTFFkn6l``K3x4esuC4kIn7gJBec5ri-OCA<^KNzFf8P^ literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/bgs/2.jpg b/vendor/topthink/think-captcha/assets/bgs/2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..56640bde4ed9a02c4e46b951f2108e5e4814b14a GIT binary patch literal 29677 zcmeHwc|4Tg_xLlr8T%Td#va*bY%{XY*h2QLRG1k{_A%Brq$08>5k<<$UoO`x=?z!iA+}q4^X6nIIFC?(s!rB6Y!C|m9 zur&}g^&FRJ9vkQfL3VbK3Isu15C$d$Apise{~(wogyO&uD^JU;20>W5fkpW@hc#1O-?;aRR z4~vO}h?<(Z`UIjrQ5R3p(kJTaYia@&5Mn=U#M@iI@o;f*VYzs)SRO%c9Jin-KMxPTsJO7OsIaiOAP=YfxJ-BcY+=0I+`N3e z0(^V|B7A&&BJ74wWLiYp zyC6WIAW>)x7Z%42!r^x!41yzm5(OX_5{7^y;V2B63x(j(0z^RsQbve?GIjJ3mW@ax zqD8VxPnyZei#lEL)zW4rbx<%0InHCx$7zu|Vr4a36sfr`bn~kRSh@>3UHcesPbFXL zit2x7p_Es?_4KaB?t%9Q&s@JdIN|0Oy)FMxZPUFMAM`BU{bRQ8uBdCi|MH_C1cw7_ zksO;aXp|1e1Q~)55?Bx+D~uv0W{a>bxZ>0?rX}zDoSBqEaTcXTYL6?R*#=+~b*^>- zBMvN}o4e|=7=6D?_~#ZV&6qIt2;xC-#uS8%p%KX^;6}Iu+Yc$jFz2=ehmYg9!4%;#-UboYNB*tljY>x^~r>?p=!dS2yN3 zTk)wvA&>D*7eb$?xUQsTaitVr_$s*5JYimmlL<8=0Tycx| za%yLT1>$pQhGV+j^4od9^9 z8`3jNE5R8*xE-U+UF=3#LnmS%pUADdvTS8Tuj!=1kkCS;&9))K?Qh8V ztIY{~xBl)*Jb)(Jn6y&=~ua*Dp#_cMZp0kg%n#49Ktb7=bP?|FUPR_cC1lqvtOa zV@=LXXvT}(%t(0E_C0!l+oSdNP*0cA&`$3SF5`O%TO5Q9Z8Iy?H2ZrBo{fGzIMp#S zis?Su(0pcF+*ZcXqi=jPw#XNkH)nsh7__?hM&UMVpSI)bTcJal8EGZSqtp}$-d7#6 z3H9#Ok~2Q9z40W%Eu<}Gk>PcNwh@KXSL9YRaKV8>S09d=Ee*POOO5Z*{f!E$8{@h5 z;mb_cc&+J>xz;7r$&$~E`H+_w5DTq8eB7eWLu>N##WN;8Nj~j4#Scmo&Uy3tUm^Ln z>-3I1326?Zhs15Jub@$45*LE^YAANc6m2B&&A!zG*xOgFgx15VfTX@>GS29<4nEbvV#d`Ut{?AN#s)Y@n}e3BK?6 z{-Oop;OKViyOq)RnkDML)E0}kH%>vWmfh>Utwr74TUry;0s@i@RX#SpQn0x$iFh{| zb|WD5eC?`*g!3kRcQ#;{d#}guhSn!U-Q^K_orBmLq^_EvC(&Wnz&#S^6QG*Cil?~o z+v1oPLq#h+xX%U;dt7kpTRp1PGo0(y^i8Za#<{iu`8vVMAoc5A@9x$S`JIQn`Cd53 z(yhC3Pa?8Jbabbnsm_s;6y9V{WHxVbjGN)AjbZk7$qjr`-`^g>@}Um#r|A`0bx_Fe&5M1+2FZJ$_I$~!sz1?jK>}~;s=m3hcPK>=`{2Gd zoI0X~vwD%$$`JIP+<&bTPf?D($> zonPx9Q*J%#LMh7Hy>{8#Zc(K+{tfqamHiR{e^H`J)wW2Las_8n^ue_T)y{rpVB znB}(Ao%T4H45=#EvBMWtZ$4s61v)T*o30S3^}$!c=z_Z zF2crgQCIpclCOe`xHn*)9SFK0P}m zd#evYf4dS$O%9D~dJhSMairNZVb6}eb;fcqTpSEr1Hi#ert6PYSp={UXB$54Z%K9+ z0d}T8{KM`-kOQbKprZU$0x$&ykQzh)J@yEHmf1MA1Y7dAGMnKi;fHDLZfI0+Fu1TM zjrI+T3Z+Nd`>vyb-VZq^8jC$N$44&U3=JR#yV$1Mj&F-7A!a{!ZIc7Nd2mGY7 zO+!Zp2htdkZo#&Zpa=VH92AEJ&_bYMI2~*1EZrD?W>{4CZzyyaGtfUUlo1*g0%Um1 zo!Q#$IXKYg^@(DISu#QyOdl454iJz_TsY$gGj5uhjbT%)L;UgJ^1q%xB8nO8V(#Gr zhWg=Lw)20-*hTs?e#4-Bf>|y;{=eb)Xbd37h-FzvTDjQS`i6xCvlVjvME}N&4G3e# zn+6B^|MV39^yIC6qJboa&hYbz3T6Qi8_i&{{)XM{C;E4GZeM>&Sa29~mU9KC^_yA# zA^;I+MOY}?*H~6qxP25WlJPSz*fd-)2&8|&^7w|aKtTNio*OK2z@O}#`)&za8N>rB z%y^6gPv2wg!}@dxPv4(x4hS0s8n)Z^gK7f6Uhtp2y6 z94H)c2>%-nJVb$K?+QdwM-~j_41L;=x8XBRI>OSlbX4Gk6AsVqh z;Ti;WO%2GvI5yme7Q|rTeHq|XVJQ3N{AF2uAl*>bUB^z-E}X&$2(*f4GMwXAxX|K* zXk@yqu@TN7RzEf*JcPmW!N-OKheqnh8p?8%>jRjL){w<>SXe=ZvRdi{b%Gj!K#(=U z;qiC_Cf!fpiE8mf67&pZf0!5(6QdrZr5?ug*C3F|WDQNC29c-+IMgEJLRmhsYN3&G z(@K8op)w+A%)oF~U|1-gt=9*fkP3upKnXv|=LjA5X`9(a}^oLRCJ{DJ>>27)#D zW#Qj0)^FAUZhZ=q;ll!l5O5GO;(R3a_aC|$u$TKc<{9@G{30=^;KXRe{(Mf2KvW~@ zx^O<9TdGL{AJNUyFwORd0=qDJpkLg-RWOU~PX!=m=sql;f3IRT!=jip24J5FWp=QDb+EJ3r-sp@*x_hRHHwM~r0eUD zNJMi}Q(aR6S(|D`AefpHD5hE@GaaIiCRtlshqExh%l+*X3#B|VIiEb4)Irw+0n|LAjd`efqxi7($l1vn(LCtU^;(4 z!GDmOF=j?B{SUwWr)p=(&8Yq5)R{^Cx~KnJH#;lP@1MjAo5FcE&vu{z8>s0085JV{HH zNY+)=(j=&A5lEntRdtAf_?E`sKXcfWe~bh+R^K5omJ#eh4Fu1M zNOm-U$F_mS-%@6Id4}#eBT4#Aa2DZDLC$|`IfKmtgB^PuU9(Vsa{uNsEnSkXwyL%! zSyz+Of@RVp5T{!r2Q%Gj0lW@jnnzoeEv3h4!IFaI0vON&j5bL}lhcCb1Ta`k(1PXH z(*nW4ZUH}N$?TQ{I6=!EOACYwyJe4}1wx430$I>U z9+Aw^NoHF@)FkMtg0NKup{}Z{s;5d)C94A05D2OSqAEd4m7uK(!Wb|S^i)C269F%{ z6TpoC?hzeuyMSm1HwK9JWduzs#hj>3vCuTt(k7C%bhNdox>{siqM0eMnL_@tn7^&q ze>=#-e|{P0?<4&e`5(jm7fIhLFcNHb;xv9fi`h^A87e0h!3Kk2q-CJ-cj#FWIzzUm zP#l8AqN-GV)`#;;BCEQ^8B|En@H z!T;3=K=1q@b8_yyyXM_BClAbtc|N-4-8Cl<%!zqEy5`+AClAbtc|N-4-8Cl<%!zqE zy5`+AClAbtc|N-4-8Cl<%!zqEy5`+AClAbtc|N-4-8Cl<%!zqEy5`+AClAbtc|N-4 z-8Cl<%!zqEy5`+AClAbtc|N-4-8Cl<%!zqEy5`+AClAbtc|N-4-8Cl<%!zqEy5`+A zClAbtc|N-4-8Cl<%!zqEy5`+AClAbtc|N-4-8Cl<%!zqEy5`+AClAbt`CmpCZsxU9 zMksjKGzPp>I@QPH0ltpE*1^f%!rIoH^M)*sm2F^X7#!s72?=E}*#4 z`e@O?%ccNM25@i;E1ZpIr&|&64PwJ^cCH{1CNL1d;%wM|8dl}-Ov5H@m>v=eGV{RM zHiy$g=xn$Vz$wvD?2J7KTL5p14rIgtxEsLo!BHWB0A{C(5(#1WfGk2tb}AQn7K0W5 zU`+t?FkPG|05$;WaCrP@!M?L#7D$}~cp*wycpN9041Nhs84un%A>pkUF~JNLOU(hi z3+%(B<0)Yw;Xa{p5Hvk!wiG1v4{u0t(9_MoB+ladS0H{9LS)lvmN@Y{9A@! zoc|n{HJ&c+MhxEe-@l&)+{?z!MmpnCIh?? zigyE178vRemOGRl$a#r6F!Z-~U}kCfKZ?!Lzy_z|8UVuO-yxB;>X5)~5eV_R4MGZY zLkO=DK!N>QH(RV5C$X3N;+NBL&(`oWi4+I^(ZDkS0FMmhdXBTp&+q4MYR)-G@L-C8K#-I<-7myqc1LK7W!z5sfVG6LN zFd~cuGlH4JY++6?Pnb8%9~KIWf^C3pfu+H6V1=+!SQYFftR8j+b_3P{dkA|Ddj)$7 z`wU0GdEg>&X}BU>15SdQ!foI#@YQgCcmzBio(#``7r@KlN8q*aEAX4}yYOE42z&x0 zMCL|_A!HD02oi#Vut%&!_#v2xO^6+cd_)=I7~&kF8PSF4Mf`=BM52+xNIX&vxeRHA zbVbsT5y(x*bYvm25?PCEM0O#cBgc^6QM@QA)KZi_${OW?@<+v>wxRM-hfrrw*HL#- zgQyQ^G+GR;gw{h_p*_*-(Cg9Z=wkG7bOX8r-H)EYU@#Jxr5HnuJ;n#a!feCr!5qO{ z#&lu^F`u}&xfXK~xh%L=a)ojwapiMWb6w)<I0Cx;`9oK_<$IZkRWI;7$TT1SS@%% za7YLvq$p%AL>EdHIv{jSs9zW%EGJA6rU`EmE*HKoJSc(|Q4+BhStpVva#W;UWK2{@ zR9nYm`emnWJ}aZJds37sz^FY#z>Y(UYGo9p~%8z3uy~?EUa1hND3~cBIP8t zUh05Uo79B#B56zMaOpkL*QEbiB(}(8(Yi%>i!LpCwODwu(c-|xd5bSE9>$B}P4U6_ z0(>KWOh!t^N+wFCRHj|#i>#8Yt89|&aoHzwI60D>pIn~YRk<lA65}NiOUjmXE2EW3%0bG-%6C-Y zDmp3wDn%-{m%^9oE)85-ytG3V1>S26RV`D!ug0ThsurzwSnavGn7XZcl6sx`sD`}8 zN{wudW{vNfI-0?n<(iKPLWJdnB*HnuTcQe)Ml2$BYw>DXXl>Ryt2M5@RGXn)qWwTe zSjSFhyUtaeZ@PNAOx*xk107tf7x#sbQ}X-pJc%zfrHTjIob#nQ@vn5B;8ddmhYl$DKD zw$*)WX=|EwmG#(iz2zI1H`?&nINKE3^x3M|GHuVLCsvuS+O=xXOUG-Q*S*zBt7BK+SR=V6c+JJN z{A+#Ip7KU{yL(rAfAz8VDf5}|wf5cXJ4U0>cGE`aCiFb|D~2H>hw;+S&@abt$luUE z*Z)<3aX@~+UxAds!ocx$R_pey`xs;&R1q{4>>hkPge$~5q&`$AG$^z&Y*AQjSV#EM z@NMC}5&99kBF30D%tMi|$kmZ&St4LF)fTlRYHQTFQ>=&B>bw6D$)d6LE<_iMNt8lX8;Y zZ*kvpE?GJ`A-R96<<`U7__i^(-QT`!`@R%pN?=NRs#fZr)bBg!J6h8;)AG~4rqj|} zcM^6M?3~K*%V^Kk%`C}6XN6|n%Qnug%n{6q&*{&#%dO4B=k3UQziaKT8~NJ#`*!1Y zNA2z{uq`;dM}AM%p09-gg?Ee0ijMD<+MBxfV==wBv&5w2*golfY5P9!58VHt)Uvd; zOtCEg0Qx}mffwa&<;@342dfTA9!fj(ts=Cdx6-Myu}ZJ1s#>Z#^Dz8y)Ztf0ypG&C zN$<@)3RsE&yM%%_FjBWecsmR-1oSj);}^3Iq-Eb`33Kb{FjSgRt*t{F1)gMb!T|h z@Zd=J$d|viy%v1EcXY|<={F{C+QvM_2FID>Q*YDXNxZ9gul@e&gu}$s47Pgw|uA=nxF(HI11;E^ymLJ$d|K+1koN3^gH zNZBt!%r3=CeKV7SDT|7+hCfed_(z~n;8zEbTnI!6C)+;zM+Qt$j=*AcL}E6v^yHYx zm5%3fW};5M%yBJwZAy|@j!8wvQwvzx@Cb&F8DnIaS26Tb4evS%T@2~fm7F( zD0lV0OU^4l{kzE)vwm%0_KywxX7j%=`S%|M7#^?0iMpsPfw=@j3nAr_;6-^wJ;$&s z-X9OG4?y9UUK5Wv*%KwPA!3`5Jn2B>r%ei1Blvd6b9uE68xT)PpmjwaeqA-*^6-t@ zx0TXGTsLeJa5oM9S^|?B%x{*@R6HeKt+HYY3dr6g*i4S}X@u{*Y9q0~s^zv++2i!2 z8iliwX5~DY$TVf~WUG_em+RCrGMEvAl`vtkV*b~K*?S7k8zF`R^UGF?UVU(-8<$x@ zq=wUi>TfhVZ(Yb}{E&>nXIEseTfMxKs`BdoMNRs>zP;;A^H}dN^!)y=32eISdVk~H z;(hPmMhl?p9KE}b^0`0n3OFdM`IbJs{<)A{Eh#;AS7X)4_SBW~K7A@La*99PfID9; zZ{r%tM|&HCr2c|E8WAPYiuxB9;3|$wkZiAx-oFPg+~E$j#1oetTb0_PU~ZYQs;|8^ zsF&M6?pmJW={N6M=r=S2YSPVBR3o;zWbJdTIy;0NBAW177D-QT?ckzput=63Pp93r zR?dsjEcgEGEfjEi*fJv|e3&M9qbZ+guQRfg{77H<(ZzRi*YhSVwg^GPFA`;){MMZu zTIMX*%k_rX+^7^#sneI_CO=@|Z0JRMkERJ4v@TjT`Ppets$nQ);F+|6i}^rXuNYn` z;iht=+EX4AOUr;aXFpwhr?DvS#`XN=Yl3^Eo7QOONDB~;tIYI>;dwG=9`8#C20oK1Zz$y-%# zxc#<4FHQcUbVB95uU0*pKBxH4^OP>H$7e&iyqIU-R+c?A;=P0S z(+XK##nWwZCQoYNf_HWecqywsAq&>}_rCNF?H?F5zpnb_j_YOrkW&l^x;i=Ct%nk! z!sn{a*Z2`bIQ8mnTiC5rQhg%*b@e;F5)g&3yk@(6e62)doxxB zov(B1m?|E3WL4@yV#b-9#6X%`0Ym*{ac^aGb+kn2ZYRPH)kvyM&XVCQ;jY0wN~ibV z(S93q|A0Kx>5`~;aj?DSC73HkcoZUUASvE61%LIlU*&%i81-p%vlj8uh1a{;Mj-qg zvrpIbwW9L~-k8_Un*M3xJ-c-!$`QeGh#dk@n`gm$pJ9VXQc%yEU3XTDtPEICC3@9g zpv}zuV0O82eQHq;@1?JT*}FT1uXwdy(5<<#CddMvH|a-Zb?&yPA3)@S4D}rmgA~_e z&7>t++?Q0|U0r$tS5=b~V>D^->CJBZiJS*{CDxs%b&f}5UE_Y3m$I<>a{!&M_wAbG zn2HRBy$G%T#T~^JSD-6*ck3WcUsyTJIv0>}=tQ=}m ziG+WuGeKW&ku~(xTT3NQ5!2ldEz6mFQE*vcApP#ZZQ{C~%0_nuv56R+R(ru< zk^O#~T;#W8VnYR7w)HOEf*&Yu?#S=gju~ijcuc1?hs6km%WBp4DX&HB`7T9-b(C8* z6g_c!Ix0;xQk9s@aXSB|*3T#3z^s7Y#C+>w9iu+nV?w;xz(K}M+ zO&h%4t=Gt_x)gc@S* zVh&0SetBqg)%jEZWCUfh)6wwj7AMco0c{d%6AvUl<{5)j7nY~z2f95)hl}gL+S0`p z)XfjeH>?(~kD;eZoSiVdEOjd*S9!pJYEo0x^mebA&?Zlfn|?eSxoD^cCa>wSi8kdx zBI0~_UZ8ZKcGd|YT&C2`PI^AsrJnTASK-EDsg{?1BII-1Ja$Vu%4|r^u3f&N)<-OF ziAnjLkEE2OCFM^lZ&r9(#R5Y{>cGjnG~(BjjhjV6R$^@TH;FI6t=5OOswtuP}+LRLhkde zf&+4+Hjg_tKU8`~sAZaG92IXi*)E-X{Y6^sX-$j!LQSsu<+#jKwyn*X$q{0E2Kuyd z4<@(+2YOpYP2`t#aov)Tl*zufB+b;TJiyf_>#T9m%YryOMlNJb{vH2R_sF>q=D7Iy4Jt+x zEh`jXjxLTAFv>5Fn_PwZl2*v2hY`VpZ6s4 zfxDidsfVeEOXV8*6Gl31``UQc$DpMYSJfTrc~>A|goUb=MJn5h6)!n!N2^AfZO_rs z5TzBm?f32hf9W+w_8jn7lGDF;eZs-@gz%Dr!!_L{^=={NZ+XUdyeJK=$!=6Rf4|Rf zY|>Aada$RR$@@9_WY02#JO>p4mJ)_XPL63Wl``U}3y3O}yFD3&I=hwE-jlpep zDr5<16Gldi$O*3laMM!XWl+qu3Pry(sY6>2rC%zlHs!~=r-ticdi>gY ztOUjSuxp81i|mQnYCWYU56$kdMqcl-!REhH>$tUwy5yVdmiTqok~YX>+$B3+_dCBw zYD?inEz_#Mi}tRGWaC+Qvx0vCCNHsb*JGZ8v?2qOE#3-EkD#FTddDn2|5Wusmsq(T z+}^`YymYI}Q+G#V7L@t!I5}?BEUVhcWlYT6DvnKtw={WT-SuGJvG>&Nl^*#9B@Y#fti#8h@{ z{%aqOVIVy`@nFca$oYTg}ya@V5C*1L1+2VzQ(*+?f)w z{|u*-!IoSL4Z@?DJR)%&o@I)LGU`e?at}33Uaa! zf-RDisihk!vX=>C<3q}O;7Y|?LRK*kidUSA3|X0VjCx?dNF~{eX*>4io9!T18g+Qp z<6FcqSpkvG^TGThH>3PJl=*xP^K0Tf!?SP1Nio6ycKV%0ehMiNhI>MW?JihBd5x1; zRBtE>uB@Ki9gCAHf#h@Z2jg?~oTR7ag9tvv{cK0ld0T&wqO;or#t941b3T?i8uZZtOED z5`gg>+rYmye7TPBWzo&&JQ{^iPNGLcAI6Fug8ZrcD};v&&Q zOhJpChHjcGzJIG3dbM@c&i+yG6EXLOPoQ%gC7p9ww{?DHyoHyBt;kb9Fe)v~2>xZIK!u0L)o!6mUZ(XH_wG7PE{MPLZ!8%d4$;I;+5WMA`YI;}K z*eo7xc_3X=-P}^Y>(ztNBepgtVD1f3Z5y^PmT|eu5Jr`oa!0s@?w@$9x=q}fTJE|L zYxT**YhO}^yvSI0&Omp_+I*Tl(q8vL+k3NksQbQ8e*y8zq7UQ5l-fO_I05jO;6;V^ z6)aRud{HyZCF7UxxqMqsQ^oNoyM_rVCCZWvp5(va=zeE)__Z6*u>Ix(IuFkzzm_g4 zO}l8dy55fn!-pdfb@utL(xx@`)epyFR5osiPd-~F^4xqF)3v+VnfYv2`0=f^H#ePv zX;OCyH1+H$svpT6my1aG>|27UA6}JV@A9PD;le&zyh|wYflbuX>#UEjeoOz%*G+d`e7JaQs|_ie zmcKtO*-89lWyNH=_$|cO-fOCw_^j2b~0^5`CmL$d|Cd+TS1kP?Hw7rFxs8p7uyd#I_AWb>#&o3ZIz0OI||3R~?Ms z`*1L^*j-6d=wOif`~5h}1@bw@Jf{Sn@6^n$$-NnUi`5Bp@aP(RtV6st(#LGvsGV7N z$yq*X`69E^lP_-boe%vrYK?N{Q*W(RY552gRc`jq6mGARQD|0`xE|)2O zuxrTrRq{&(2s-ldqnbqe*}mwIN~_7i?apMJH-Wm)IjO%xwVOvgf??RiiTFTeub8MbRI&WJ0%NPM4t=c}swfYmjL?3Stp zw?w5Un&A>#;9Nandjz}Ns~>$`Qo51Yl$MuHukBRP&Nourmayfc-x>o?jKu-*Jll`h zNMUMrmYtrl{@}yZy|#e~%~wNsgI_${o7i#!zUvT;rX;v*75Q3?>kzLuimM5qp=N#LPM3tvg_>S`j~rGj}}_2 zvRhY)OdXFQpXeHB#8ig%w+kyV)*fBSe=%AqhOek;tvcd%Q6Dbh|l zT$tee>`mJ`g|p~SpJ>)$owQ4~=2Ag+r=-WL=|q%LZM@HkHafSPB08_ZQ$p7#ObU;; rK5jelOsSzL!0ahTK)A8SLU8Bj!H(;}Woj$P-F1|lF;8*hsfYg$;V&%M literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/bgs/3.jpg b/vendor/topthink/think-captcha/assets/bgs/3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..83e5bd9026f9d46c96738a4209f1abb91f7e1e6f GIT binary patch literal 32109 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 WW2Q1p-X6|ip1UGwC*Qp@{Qm&B(nP5M literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/bgs/4.jpg b/vendor/topthink/think-captcha/assets/bgs/4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..97a3721bc777a569c6665e38dec04a82df9176da GIT binary patch literal 29081 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�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
    5eqK))^(a`g}#Vel}`0jqQ{$m(#9bM;B`pV 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%0Dja6n-|cc61%dSLS`lUd7W-JGp5n>o88 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૦ilU=I8^3w$Rh1aryLRN1@vEe`O?@pzT+nv6 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 R;s=GvM3(ZxPL-v5{|~;{ne6}o literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/bgs/8.jpg b/vendor/topthink/think-captcha/assets/bgs/8.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e10cf28115e47d1f5413e76efeccc39cd655b6cc GIT binary patch literal 30188 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 literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/ttfs/1.ttf b/vendor/topthink/think-captcha/assets/ttfs/1.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9eae6f25e4cc49edc868d45c8dc9d4f85b4a37db GIT binary patch literal 46124 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�%{B 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 Zlv{d@NF(dzyKY&^pHc!3*43K{{|g=w6#xJL literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/ttfs/2.ttf b/vendor/topthink/think-captcha/assets/ttfs/2.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6386c6bd2adc00ba4f1aeb6bc5e01e1059071885 GIT binary patch literal 30352 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 literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/ttfs/3.ttf b/vendor/topthink/think-captcha/assets/ttfs/3.ttf new file mode 100644 index 0000000000000000000000000000000000000000..678a49178687e2fed4a35839fec9d8018ca0252f GIT binary patch literal 319636 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%0AttF5TT6yUMOTdf?LOUFPGL-hGD#QoZQ0y6UYB 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%0A0;m*W$DBZ}!O_Nz$L(@k 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 literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/ttfs/4.ttf b/vendor/topthink/think-captcha/assets/ttfs/4.ttf new file mode 100644 index 0000000000000000000000000000000000000000..db433349b7047f72f40072630c1bc110620bf09e GIT binary patch literal 217360 zcmbTf2|!d;`v-i^y?0h-UqJ+B7zac|gaHvZMg(M25z!b^#2qbHTv9U^!UgvYcQZ3G zG8@gze9f{lGcz;Wd&|uB%=YC~xO~5JXGYPt{_ppFV~0EU-gD1+&a*$ydG16gA;gS7 z0_mJHsG#pIQ%)4&yYC>xI-_q+ZXSu_pCWw5{pc0lw`9Peunc_$&T*e~?K^02wl1;f zvp9c;5dPHxgOXDp?zQU-A@nHjSB{=Ea%#d8$yJ0H4r78gqi4-<==+85B_wJs?(Z2l zb^N3UMjkN|VtI=Y#o_TItEUnxabdiBao;fh-Z|rDblqA+h2p#Mt^hlR`r;Hw% zVEOmYSV|h^8!~C+eN$z9I5nQ%g6AERM@|}B?O#?)_^|s3k)578rFsU}=f`^qZ}bup zmpFC$*r|P&MvslT5+ z!{^}n3s~nx5`%kt1@MDBlh}n6jG-hPe}a_qO5m}IUc)h;tv`f&d_RH4a5E1rhV{Yv z=K;2K`93m+dza+#*GVbvRWaPNYXWJx&QBr>q-&>13U`_~rM3J<{IZ^88pAieK-{=q z%oCE0=S$>0NfBBnv^K!KN5VV9{T)r-)FLukNOWMd2sY56heV6UmKOG1cA6xI=)h>v zx&f|QcFt(gx=FOSf-$cHe+=(`)8wC!3W*k=1EWQ#fd(Ie7LVijG}=|+6q$CD4vZG9 z8{;!}&S=rPffkI`j3#W|Z2tc`V(n~xhJ(L7G9CrZ+4|X0!ViO!;pzW4GJa+}^^ZsJ zI$IBTp5SQV8e2ZcI@bc%9i+84l4u;?kZ2$$>A|BP@?0ipz@v~6++T-h&oEvU+-Q&& z;Ovp$(HA@huGipxGKu2sElrG$Z0&yh}32N)7Ne0ERLjnH?( za#G0j99y4!6z~ciC$AurcYl{6QVJ=|y4*cxS*&>w4-MS*v~4-)S(eFC0UOu<@r2m5@9_5DR6*;*yJ1YVeJ zke;1QbZjj7Nzk@|6v`vWS=IzRBij?eR|t@*`mmeYqg&lp-M}mRzJexNIa)@U_@^I%-;t$rBkWzRxQsWC-n&>bR zAvM@|cI3_l8s8JN7hsPpWFF6frg>zGY8M&9`~%(%A7Kh?>l9MLUxCe0i*xvRG6}dE zg_a|aB-@0eBul=9tO5;ZE1{3%>BP-=6+AXh-jno2a|DkQL09Ha#LJ+=K)YgmuL8fg zWqZkN-b6IPahVShXpLkF@D?StUF2g){}I@9LZ_iEg8hp}v!HcHOF+v+^Pst~e!{%E z&=EW-xp5SHFU*l-nb2+MaE^IPfe-qZvBu_MID#Eh3$>8Lqr}AImH7rCdm=9tFJa7? zyoYR2%p_5)VV(0K7u9k%>|!a|OGwioLYlQWM&O8{o4ZRq&iI<~8u&|Thb>(NJ3Wrr zWjbP43`ITg-5Z8yHAG2A^c6^KHU06pAF$h;l zg6uD>H5qnkQDDu=ci| zb?jjB54*{ZXM_V7?=a~p%Ojr9k?ALAN{zLRuLkUn@$DU`wp+xZ^c>X*wC?ml0{Q)27AkpIh@RJ062f1YSMF#nibmKqyT7m0HAw2#6J%;f5 ze;kJc?}h(#pV17qeO~amlkrz;ALowqk$0Tm@`*z7{XdR(`ZOVZ@V|}{Ux$2~)<@8a zkQ-k@k4(c6SZBwkDl}-ao2`oOB`IhTtno=C4ZcJ*_ZvxqZchMjR|snmv;0l`23->+ zA4-NXzeDoXzJ@KkqjBJWG#T2{T=$mKf$uF(;QOy=U*miT+P?(oEAC79L+FnvH_*tU_vy|5;`3HWFe80&Lp1{kO#cU*viV!VoOVNOA8=(0OCTjo4i5ZqV1`NjsnEH=~ICC zIu|ZM{3;;+01%U#5I+crSM!hXPw*E2F%fh^iBKsl6V?ka3U5V|=w8taqjyKY7JWAQ z7eGuLW{2J3kRVQVWCkIg0f-*~#82D-@!dg)jjbRa1BeMAZfa?1xk50WI2qrP1ABFz-D^H4E*2Ny2+k8>TSOIWUzC3l zer4_#^9fD<33z$+cV4U%}|0Gpe@ZWH$H zMYPc8r_h%>j-TQDI|{ACJ`}km+8M1F4H=lwhfc-$^w8Nq9ckr1-MRg`l+nT^zMkLA zZ{fG{+xYF|dwvJ`f!|4fpOqRF%~O##Py zXc|qYU1$dFN;7FU+MV{GJ!vnRMZL5)Eue+89d*+(I+zZjchPd{;~%EO=x|y=N6<>h z%P2aUj-g}eIDQYUq7&#udJnyqPNI_$%}k}!=yY05XV95+7XJuWMR(AhbQgVy?&kOM zkJ3lzUiv6)ppS7AxQX;T`aQi$f1uaskKpB>=`ZwG`WyY7yNCWk|Kv7s8@WwfJ-3P@AHrG`}jQmagK15pTbY& zr}5MIYJLVklWWVb;?lTuZa7y#h_~&B;xlG_WN;*3Hv@+MvyB)^7 zk*-|V$o!;^j@Gz`NxI21! z13kSrds2g=2kF74a5?9< zjK5@Hd2UXm)9Fj=jTw>bt8|qEF9%>7+iG+ zHJZAqxj;85Dfd%cKei&$pSRNIH&j;9ZU9wUdR}Rf-#qZ{azE$Jb5xB4GVouP%h@&3 zX}sA71N{AMgi(Ef9AMb#WN27%)JsO;#J_N0dEneZMnxVX-sD7|pQ~hdUJTu_4rX^2 zhVI;aywU~Q77Z$|LyD$gj4KxyUoq0Za1^*}A|s5;;Me^T>2%eZjE>A?z=*yM09`O< zg2OM1^UK*&tsekSvPbIh2PDz`5jgx1i3#G2CP$_V!?1C3UAdLP|7KN%V@3xMou3$B zgtBtKHwPH=jtnwM?!nHHJpLB=aV8aRS z+&hMGl}84K0R#G#Zl$A~i{yRiXut(W9=^D;d*H8M;Z~vj&d4FLcIZo zKf#eZHYeDRo!>SnPIz~p{LpA}c8YQOw}}+dqO$Cyj!OY9kop~rlP2;aaWML*5V+$FjUeEfGH`97bj`;;2MNQd zS1t1@y(+JU({hmq0W~1Qm1FRHRg^rfp;{Vw5KjR{Ts}${9#nZF13ea^hu0T?crXsZ zsRs`&e_BKEnDiGDWwQ_1CAQoe)V!n=_Ghh94NEd{8QN zhA)%6TUE|{$6yDI9vqX;4~~hZdN|!rMf3fN;$n)6JTXOi?wGhV!(g|k-QWmwON>Hj ziIMXyF@*)5m;&50drX66lpid3@H9{Ld=~!{&-cxXi1|K`x;(Li+j=4g+dS66Myeld z@aPBY^#k-=jQ+fy)9YLGoE-LkF!hkZQ^*4H6#0<|20|CwsEi(^YY&zUN=z&|s%U|U zP?g;6r_22ALF})0;84GOnV$?EdUyFjN>}@8SFIx1QAPgLLFIl&l&{D?244(O2W=$V zS6!W$SW!J=W+MB{NUWYAeF^=MPQ&585V?ieNq_9Z*~v`V5!pFhYV{HFiG{3#mwlC8 zy!BVKuaioq zJ~6?61IcXCLg&$|+(fR1JHUO&TlwDn2>507Ai>W<8{ux@IpKyZPxgrHlsrwoPJUW` zLlLRSQH)XiOW9kwQ2DVcLN!=br#h-usx#I1syC`%R$mT_2^$i&BkV&>N6j3~8=9ZA z?X*SOHQE=nU+GM`F1i7_>ADTN$91pi+v(@%4;vJQGQ&n=d*e9cM&sKigDKv$!1SEy zx_N;45%YVN_LeHkqn0Lg&5@%c7e}6q{JE{UZEo9p+dkU%leWJ`DWjsJ=0&ZH+8K2q z>V>EaQJ+L7MrTClNBg2DM&BR3DtZ@~_hd{&Ooy26F~u>%V*&aTdUXSs8Nb8f6G))?!IO^NLtTN*n$c1CP%?B>`Om);fQN_J(r2DmC+ z4ed1T+P3T1u1C9m?S{8I-0oDn_u75c?oYSEZFa}FJG;H^f$ov+>Fyf$M)zL#GwxU2 zZ^m_tD~h{2?%ufj<5tD(iffEJ5_dZ8{kU)9{)$({N5prC?;hVb{;v3{_&M=s+Q+u{ zw9jcjxc#{Hv)eCgzoGrE_D{8cwf)=eKW+bG0!h#$*b|Bqh9^u;n3GVOP@m9{a46wK z!e1SdI`rz$zr)ZDV>`_1u%yH04xc8*Cw5KDPxK{DNSv3rGV#Zb6FScASl4k=$A>!} z>iBZUcRGI2@%JQIk})YNsZ&y~q=KZfq_IgelMZzfI$1lpJ9X)l*XgcK<2%jiRM%-o zrzbl-*XdNJ_d0#u>91sEa+~DDPfhQZJ}rGt`l9r2(tqmGqs!VZd%7I%@=BL?x_r^) z_Y6hGJsEFxm3JNA^;D)QvpBOM^X<%!x^?W9)@?+$*So#l-Oznl_kG=e=;7`$yvMPg zhMpsOKG*YX&wuy4+Ow&bwpUEADZLi{1@>Fj@HznuMBpTs_Q_u16v z;~ZDc$egEg^|?cGD{_zJS@Y8J?$3KL@AbZ}zIXS%r|XXek(ug!1F zKU82Yh%6{Bs3|yH@MB?G;rzm*MarVFMUNL9D|Q#B7uOW8DBe)~Xz`Q%++Wu}x_@$iZ~xN%WBSkRzoh^6{{H?)`+wB`&jHo}Q3JXSm@r`5fWrfR zDH&Qax1?@hyMY}CrVYGn;JkrL2ksttu{6ANN$FpMCJ%b2tYg{kvfs*@1{Vz;HF(b8 zwSylUq8`#~$mk)Pha4F4_FbuWjk@bfdB^fzXzHj=CYDKlVx}tKhNnrXWEYec+7+)&+wX)GzpGVf4Z& z3!h(jYT{*<%cjwp2OoRz(1Rx) ze7)9CJEV4F?T*?%mW)|)W@-G=MN8jVmbh%rvR9UymycWSU;blVQe9o$`np|pjde%r zUaGrT_eI?wE0inRtmwF+*NT!AqgKpVv3$kO6;G`=x#HrAFIW7zQnfO2Wzx#*l|xpJ zS~+>;f|YAmKD_ea%9mHZyYlOm|5+8bDr!~os@|)HteUuL-l~vyZnb4~-0H5Y3s(dmY7tv(8zKeM9($?i+G8)NFWi!?lh5H*VPY>Bg@%sWurmP2Mzj(;xL*y{>**{i6DH z^?T|M)t|2ap#IzX>zg&3qc(TioVB@d^WB@rZ=SPx(dG@Cw{L!O^D~>D-~8t0k6=|f zR&yh$VaIu*Al7FEUd9Q$f{^6YWDiaDBzsaio1I2y2HHu!py}BvZcg)3*^%poRl-+z zdP~a{x?Fl%M-sgjUZvs$L2sZ`!)fFLd>R|aldP;nqlsjOCmT&P)9CRSF(!5K9zM;J zYO`A8uGl!5H^FoM@_pU1yqRe^bc5i!et214wzqEO`Yi?I$E~i3wE+vLnquaR%1dSg2bP{=is~@Fuo;2P^HHk&QBsAz>Cw+j^8XyG!M+#**y`8IYwTpjLkDg}*J)8E&YYGa7OXz1^Y zuo?$w=>Q|u8ns55-OQ_HB-xYYF=ZmQ9X=e(O*9g==HO8R)$TFkJ|H&PGo>bdOHB=2 z0d{z&6{|2yEgk7yG!HK|E5#}QZZ?e+&y_7N6EBo5D-o~Lm>ltYnpnD`l%|v|DWl4! zFKKeNc!94G_b(Dl=>gUj(Xs{fuvpC60&zbr1I=q%mJ1rW2|3|7l0?RN)8mcqD7zqZ zuxMpYLLy{Fm8?^;TPxT0^YQX_x(>QxUsQ+0wwAX2eD)3&AjcxJVa3VPdQF+BY_&#d zt--%0iZ!zJOGpS1$s$)+UForL@#!|3#~2rvp4KHJ-D9=c6>;&#XikxaLl^+X`8m~+)>!*Tlit~Cqt)<9!F0uJ81vrk}GD1JDDEs zy?f&-q;^S9i@WnWbqtIo7S(}K^qFo%1TPg z$_nY(ts7Tw-L!u7L!#L9?glj_{F!^E?xQRTGPi*JpR~|PdxhQ6IZ^y z_UVXPBn6!<)5 zeSDIxvn-j9h~qnSa3q@?szRSbAX$kd91BghXM#{p}~Q%kz!&RW@o*jH(HZDyT6o(dpGZsv>S1l^QsOtBWZ;jf?l#Oq^!>`rRuw zu3Ni@4J-af?6&VXJ^Ryd^v#n`i76O$2)97cA!^f+&fZ8=TvCNrtqN1=4T73#IgLiE zhW=7wk1Fex)SJA?h{sm$w#&@WoAG9MhK%RdCDPSx#G1eM`*-_)5tl~MrHOKjICIL8 z81YyIoha5<(7c!$ca26 zTxBitsT91v$j3(n(w_($! zhQ0ONC)oX}!>;3W`T(6SJ|M0aPl}&lx28M(xy4I>8WA~n7Er56JFfvH#7Y{b5mX8V zRmri_#B>?7caX`U!kjK+T83P%h^HRz>>i~x?VWO3vr;fEo?-2@e>zRXh+|+y-O!#9 zu=)0IsxT9?jtXre4eBDFK|#ZdeQaQ+K5l6Z4D3v&y`UVJ7F5JDy=b*SH&~s5yD5t< z@=xu$`hmM28B_lHwKu=p@t*i1_tP3$b7;%jK{J>47%*+$#X~E^pWYHrBU3;LYP*C; zKoC#*c-uu1vqC|5TdY>zK7qH}?6xAG-L7`KqlvaJI!~-vyZ(vSHat+-IH_#t z_lw`XDpagI6s@!!UVq`TtK+WZ6q-QQYc?;rXKq^F)V>2>W!|`;_?v>4awl%Z+_NY&Cmbx^c7JYusg}qu#=`nWpMkqiUoFtnVEnp8C12Ab|lB^ zYGVv@!U>TZ`8c;GOc&M97pBu$c#FNrXNlmI@JL{egIva7%aojt5LqR2Y#`25yA>SA z@tz>ZxnhYdWQ^soS+<#U0L`D)yWi;V|I%nCUpsZ>Kkr--|DfNm-no9=(0X6V25uU5 z$Dc5-i4Z>)U)_K0jW5I-bnt6WKfbP^aB<%FLsg6)LDNLwQ%+*M1}a1OJQO3(6~k#F zjD{gOfD}+@Lo20GTt(9r{#RAu1nY~VS_SoKg z4;2jl*SsSio;!YHW&dZUKJ@&JhWnPRoI7%JU+;E){C#7FJ(%62ZrIq_jJ6Z8I;J!1 z#7%m8V^PqGv>A#*yhSebMsPrc3vUmNh%pZn%4EdFci|uc^VZ zrVWJDGw7~w-ui+nw~8Or&PVsIeY9|4-h@Nr803=WK&2J)q@cqM5DP+VcAa^EPiMGk zM1snWi6`T{*0#imK<5stGHYII+rs~A=~8B5ILQ{)VlE|gLo7H+tCgu#7ITKNKZ5Ae0K z8Po+nL(sLA1VxHULtYXr0SiS!Zf(d&!5GS+5?jZs&iql!`qs=FP(QN!^KZWJPJHnL zV|yRE8NYU!xw))*M(MaI?v$mYk3Uf`W%T4B(?>YP_k%$#N9MHT$&bno!!yr9nsgBo0j5 z*?Fr)vSA!*4g}81v|)x-?s5<~7ww#>f{Eh3*~~1m{Al^^sv)z&lT2>9Qs4rx(Oz+41W+s1-RiWPW9}*d4Q+ff70a&5a6HM8O5# zII|F?)<;C>)Ph0>e?X}Z*M}GS^m-l9MHKpUCSou2;ko}(xvlh*WO|$qSV#C3g3%(l z5VQwuj>~8aemjFw78e!Pt)TtHKd*^gBMm>i%m3nansV^zXa6NTa^U#l$0O94;>WN2 zo6niHWZtCabHnLFN%(5Wf{Ki>EU-WzuDI z!soQ?XxaMyOwxccSvfEUf1T+=ouERkvdJvd7W!nopeyt-DutZCn~53l9&$(y!sCm} z=y6~SakjWdyobJs+Mv0IG1r%Wo<~tpD)+5eFD{ZD5toRM(P$cbV=A0ZtQqt2e_`G* z=CjDvYAO&VMLtHZD)7O4ah$Bc$MF;rPHzElr_aKGKujVv{;#GBd~)+VuA+GlS1UWR zSxl&J{;JhXDw67LgIIy`O3JIl?wE+V{y`nWm@(u`Vs*h8Xmw*~cnseB?dBlmWIZK4 zg;iLT5gezBR0?gQNMr##FPTPTEbwUrnZ3X#yG6u1S3#Y~j4&|{(NPj7p+M)-H>YuO@twzZg_>@YSTF%2qmC_&x99l`Cq=nex;govt*CUH* zY!VwAd9IQ3H+5*v#T_z_*w0klP~sp!(T-{|p;FNzBy*IDkHhCr_T#DyUD3ExUk z!`?BR$ha^y!waXBsaoUYmg@yTT~r~V1Byxb_O<5kw>CC%o6j^K=1whZeiVdmVgbH9A_9OLWMu}f1TRzfPV1RQ#<17F*cNzJ4nT<++#0S##u8pK5_T3V zRU3IZA`2ZshA+#*vXWrZkTnjN4JUQktSpQGgdQ9bMo_*)G$?gDDWT_;^rG0PQ;Hgy zVcR=R6|y5Y3I)Wr{DD0uuKyC`7M5u-kWOB!3Wk#E^-$zSQy8z%D|xC2ams(q>k3Yc zY2&yIa7)%pO_!C1oiFlHN>0Z;B%J-=aMMXl*e#N}v-rMD^FZs#PW)XoUEos*yuQH4 z-x8UdJ_o8Qp?0AB@V9j|EjuCZ6klOV4|Rw+h?Ym)sBZrG*T4S!<=19J)eno4AtP0& zOk6Hb6?cp8i|0`7*a4Asig+%d1qH@mDo`lR+eQt%1JA^4QG z-fsdH^ze1kya>8&;1^yE9l~oB+K2+5R#2FsJ`k2?y?Qe|x+y@g1;{tS^eFxwE1$nf zhy5vD$@oXid@Zib7VBvt_doG-9{AC~YtHw&wUlxil~ECn=&Cc~F7f=ghxa}4{3l#x z^KRLZH_wZoj%%L6RjyyNX5B*YEQ>@qXyA4Xd(mb%^WkQh;EvNo^EMl_uub4$QChJQ z0ntM0hb0RHmm?JNBFKoBA}Pt5!i{19rQK!|IPsgG#HN))->GWc-*e6SH=YtNeDrMk zGfynt(zSN^S5MN~lOOci8`p7Bb@9m3w1U?je*CqPjm0y@7mpm6Qi_BP1y>PaDDbC1 z*2Y9o7{c>Pq>KdU1c7G;uC-cZnucZBtWIu4qnIM(iz%|0&62%22APS#I7Z_38Vyvf zK)S|cRPurr0|mt;kTDCP*uo@5Qiq7IpciEk;@je1_;;!CwU?fIO?ITI|8?S*E* zH03?}%BiFLQNW9j0F8#MMjLM!%yJmw34zDUQCVy=MAACIod5$eb`R-I0!3OB+us3bP=upJga%(R)L zXF&*PAB=8hqX#E3dt|5fi62_isI9a3`95*p;jcT}BGak-Fg15}n$y2J%wO#Ns^!6* zO&%<3&WUZ$KE=;zTCn}))o<{%j0!MKLOtLJBQCE=kjtR*Q3(*n9ugRU z0CVF%q5dTNo2iHCS7P_$sA-=3jM$y4X`atDamSjU=lV1kv+)_$=3#s#ad`E}Q_B>* z3RZaMpq)U#9;rqpiW8BBw$4!fx&v427QjAuL(U>+?vAi5y z76nlVR8WV>1gHa^DsS_QZaFN-%Sky2r;ycT=9SF`{)MK$_~=?;%huW(6EJQA^4L=_ zt^!c%PiMqS)F~d9Ute|I$yUpfJfC13o|vBn z`tHb|nt{7xoU5VvvtarZPk6-Rv?(+*Ucf;1RH-70c*wz>GutsU^2|;Tro4oyGmgkE zt@;o1-tZoJyx@|ZgnAD5s<3~k#5-nq9VzLkA_%Q9oENkvF>98xvZ1U%Xp^WoMU#~k>85SKK z5n)pD@Y%Sq=)OKK42cMvq8Z^83ghVf1d_(hN41)J44F92J@L#qZ-vG*XuP=yoPr;wM1hz8P!G*4*<(; z#FFQO$8ZZ~@OOBt9g!d>rJAI)cU-(n!8}Tf!qderDcFGC=MH@EEn zobg6u{kF!f_4UF~@k8+!{Cjsm=_>4IELkvi?~0ed{`&N#3-7(nxS<*tUV*p!Yy`2B z9@a<2huh^^KxQB&K*qKNTBWX2I?IBw6WgDRb2*GGX@)SG8+Q$fK-KR9b|rZ-7N?4b z9@)Ko?PLqycF<5W?HFrcWs4Gry#7J=4Vl0XW)(7k9~1DC?R7@U?L?B>D(^l@dA4Uc29gf@Z*wbDP`9gHMgm%zkL74pWeGP zTdNQnmWsO?w{CA-zkS<=$M7iJh)TG^;~JeD<;^Lpk2kEKb>&$wZe^YPX5dNTXsIis1}7F zK_`#F9t^TO7LCTtVgFyoTWxBHf*J-=A^?B;0VGH|R49v0T-Ze9^GN)oFwezQ&GWpX*J$llOuG*OSb?`lT5-(bW6kw(U z$soPSWN)v;h^}r;Oix*gnVMx>huF3;?g({upSJpReR`fx*}bn%9jol1SL&6v4js6@ zz7G2KS$%!&4Yp2weYVITkA53U@skfVG$_?6&&)V;hC8+7!Q<~W zzYOV47~FNh-7mb=oX$MsJz$h^c&DF-Z|w3KS$>&PgHfx<_h~sjWt{P*6tM=Av~ZeG zg(6K6C_@?2&~UhGhxXmNweQeX$fpUJ>0P>Z&B(ymE$c*!G`0r${El9mIV?=8R7SM1 z8S;HLuS!qAeehZ&&C%wzNzAPROhfD05=V5;?bE;D){LShVyR{DT|(0hgLqsqJT!R# zr%}MEfpmetuT!hT!jy7BrWA}Oc&`S7QpqdAth_$pF(iZI*`_tz27HsyN+pj71}+ed zS`@S_v7C-NCFanN&xrHq@7=59QhJW2v&E$56`cHDah%-JbUFjSvcc#{hhT1=V3|-; za8ihbNoMpJZ!#oOAP#+`-tx1M5*Nwyx~xW{3FLRFOfJ5iyRFS?HAM*82x!`v2!mOV z$cga*7$La11tEZ_hCJ;6=eJ^rTbyC{U^~ts{bk%CcTb(QePhGa**n%XER9qqKQWQg z0m_tPvyVN;ovEog^jz}}cKp}7%_oKY`jVl?hKzaPZN@P{ZUwv+lHv^~7RIg?mCdSA z84O@ngF&tTCuY5!S8u|?ICcMS28QS8v{zqaoOrUKvT+-cs{Hd2JoYGl`X9$25>a@C1;+tTt2iOi#hPfWkk(jI^dk(}3L&i&mvlt2yLA^je~}N}3_)?U*uKSCi0?5n|eoA&=Wz(9NEcR{MOzaudeBR*8;|vmaE)8{APho%1u}-s7x{OLbzRRHkkYR zbY6pA0YWK)glco{w&Wf*oR$FZvt=6ElphgB#Z3|E95mBX)%QQp@!w*D$g@BUOO%1H)p~Cy~}xT9NjQ*$cYR1 zNfOM=VmS^ohat*PQ?&+LcX)e&P2~y2zsRy7JoR)jnGqxI7Ap^3Ezv2%X1;Mqti+(R zzQ{?Z{kYCISUinbN$$dEZDDOJs>rBlyG^G>)GjF7m|$*{Om#we2BKhA5)h1pvHgKU z0JarkGBKXYFbAgWf+>aMGv+j9`{?s8itiqnI7O)pOEH}}{7P4gQgFSnU%bH8bieS_ zh~@>zAB+}DiZY)`=Vmsq*gvyfJ@;<_1*qb&My0gISg%ompY5Tj0a78f46_PYECY!_ z6bOfdkuZy^T=b||^E`D@$G^lHy6(7mPJI11m%`b_VRUcvx6SA2aWMzubC7pA#<#Mp z2bRg(>;e)+aLcukN?7%*)SF%d3%FaY4LlPtv>6%Pp`QkrmD)jH9TF4r{_Z-p<%{GfDfL>l3qSmjnkKUSNSemry9iMJlOZ}E%|j(m0Ll4jg6ZY9^ajV4$5 zR&m2BY3la+)eN8lQ^Fp>8c{W7cNUVS%L$;fxeCf4S2$TM70?he< znN$&v_tYp|YnlSx76j`Cx zj4Kfm_%cXAJFk(~hewz+B|hGy#}7J{_~axxkr={XNq!};{Q$=v_9mVAaY((v=&(Ib zn5DQlTAIF~%b2w}(|p;ZlDjPIGH!ML1NlWmxifvbY@XCMu5F|@vwpJE;lK;`*yk5l zAa<{Srz6!eqmUU9nce{Y&`7n+1|C}n0rtDCmKjXwGFzmo3I@W*tdx09j~-c>o;+^< zjZ3oPrG33w`ChE*1oZdE(%w%mZ?sLR<&m|8`z9#)wowr>&aBqrwL7g4rVvp55UMc+ zW889zLR=yh&@y+x&FW@ZV9J6SDKO>FPS{X;_9R`ov}kooO6{cmdmegh)#{(R$X|QY zL55DLHnS``MiU+p-ruK+ zh(L*#q1a~*Co&WW-Cl5VTWL~&i*H#rsBg9libFaw4JfGsLvxKM8hdVAGjBd^5Qp|I z}9+f1N^c57yNFfx06Yy2n#c4P}8O2H5Q#!VGmd9bPBy3^<2bk z)th6?oZhTAYp7MOVU$w_zmLVW(grN2Y~T=)!|lVy2@3uL zYJou#Pz{)wWoxA{OwtfcM>PE7SKYeYmesvBMM zURhSYdzZFJa;M4}-`D4~stkR7DyW^H5+zU{w>$afP!!7~nB`a`UWP0))(Mm>-Evyu z;I)8?c02Pe{?Y|CL*{oLoA=UNpS-YeR=0bbHorzI zUT5tkanD=l#XT=iI6#y3AD|tcIv~F9KOnyMl;AqBZQq`x`z>vM{@}tNJ!W~tqtY|t zp4U%_4R4*NLtlMTy!hk+n&1yU#^gMYw{X*Bry)x*1iQm_d8C?B8}n-&&bDf`DZ+*V z0-ocwrWh>so#C%Qd?eYwX-2`eOxUH&2t0ikN)jdf8{H^%k#e1!C4AV*5mUB3I&JEFi(`t zNom%bVoV(LzL_(bP3C{(Fh+n|I*YA4pgg4D&*j345DK%4m$o|bD#ZU_HtyoRB_oFn zpGXf4?ssk9`K24FtYQ0&OaGJIxa)(wMZK4m%!?Lh(oy0re%@m7)c;~Q+HzeEe^b5z z68HCceL;TXH@qNYSpW`Lzz^fDK_*$;?)2)k(0ZulZevitXycjSwRxlUn@G@U0kLPy z*xKqWcxLh9Bc7DO@493idjj<+v1PFqjVI_(&iaV(io*X@Hyh6}*93i94&Vu{rJJ zRyFUv>MM1YWTlPD&92$<;0E7@1N10YSoPJAk;Pqda^q6Vr!1aYvbpY2%<1GZr8!;5 zzQ*cN-^!b!)$(?3({S@7GgoY;Vdh9PXErO_IAgR*WECVegcqQOhd2X}v{vSj#WdG{ zS6Fk^r8)ki`?k#3Fz@2mGiQ$KLph`r!w1oI(u zi1@@q4a?f7r+isou2wfR(D~x^=iiaS#>a-0?G|5@v)QMKO+qESbUlg39-|C_q%4d# z7*T7(>t(2f3%pJisLTw?7853yQBre;E*_^)IsM)0US%Jg{pcGmNo zP`aj8ZtJqN4>oW&a((U|YD*eX32DuSB{>00!mPF1Yho|CVf!xvAtkdPRu!`!uMBT3 zvEa{;RkX=kxry9~C+gQfzHjrEN1MgFt0oK^HeviQVancTk3IazGe`E!#b@5ES(vc| z7Ght}LO?RZRM=wV6`Wcn|2z8tB%ziBKbs{B9Qb|WzL_*eygZYZi!chI@0>=Q&=b!XcGs&j8FyFgO6%{mZ+Y_%PDX$)64d)Q%@x)c z{yyvbIr@?re1G&+9O4YDE9==9@4Wr&!f zNPAY(t+YhDXj^?-mqkeEK%%gt6%~cI`y2y&aRy^pfzRl=iT)b53#VYZU85Gsft?k(ANS~IMXem)X z%^75IBr*MOddwoVfga)i(1R8cSD;7K?LCr1v*51qw_~_NJ;+3ofgb9^Jl9SdJQR+&X*mZJ#BfN~KvDm@HpgPP*! z`At-Js|X+vVd57-SbZIweO4XDVh*IXv5$@v5(_w_#x~C6i<(W%;uSx4j6c(SoQrC{ z!sXm3qbFubWwpWLN%}VT4CA8t(5R?S1c?VT5W! zIFqV8TlJWQU;Sm2q1J!sL5o^$1bVc&y$8c;V3vu*Bw>}K&YM{60e5qVG*8C>B;wO| zK*H)2@zOj-3G|rNGV*pv7?*Gl-|9h !}#gv~NV!5|5YF|kE)J0y^zWbk4>=%|6F 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 literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/ttfs/5.ttf b/vendor/topthink/think-captcha/assets/ttfs/5.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8c082c8de090865264d37594e396c4d6c0099fe4 GIT binary patch literal 162876 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 literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/ttfs/6.ttf b/vendor/topthink/think-captcha/assets/ttfs/6.ttf new file mode 100644 index 0000000000000000000000000000000000000000..45a038bade527cbbf30f197c5a116be3cfb2f0a3 GIT binary patch literal 353824 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 z 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 literal 0 HcmV?d00001 diff --git a/vendor/topthink/think-captcha/assets/zhttfs/1.ttf b/vendor/topthink/think-captcha/assets/zhttfs/1.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1c14f7fab9287c0746119a6c1de788f9b8e8bd93 GIT binary patch literal 2183628 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%0AxGNr4ql@>e2TVjC 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 z

    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 z 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≻d;ycWSqKxMrFva1_ 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 ttadbN)KkB`o93VPe`p>kARxCs`}iJdNs z>g6eHxQoS3V#=vahNGX7vehV%vhN}G-=839MBfI)+_f;JhSAmsJG|Uz7PL4xxPbbQ zso(dW__X61-b4K_dD+=RVLI-&!$oz-Z=LEH<m;fcI(zg8% z)X5P}d`G=y;lz&ppzI@DyPY6zk8wMx7apTw2%Z{4dJP*2$$Z6G z>+Gi<`9Yh6AEr2yvP1b{^}M7@8C@Frm&c@OGUXt?8a{Z4QnWU~PLHy^fF8*NV4ZiX zXA|0s(dCH820+#>5s=myJb4jsS4~Ono7=(ShNg#Cf(2K zeov#VzKO2dSI^k)$zxdTVp742+LTIIS>SA130+$W#o`{ggHjS7PI@TKHZc&-vn=?1 zD_)Bt41G!)rY-?-__54r{1571VWRK7Ew>GbS1a%eur-LA7xGd=TFW|c57^e6E9c7| zGyoMoB0z1Jp6nCn94H7s@@(&n{XA&-YnT_WTAib0FVSi-4k-im%-zXcTob*83}_mD z_!2VevplaM2DfRLDjczz#_92nSq{dy9eSJ7OPgwQ4b$g+SaxCp{WG;ge%}%JNrmw& zQw(+D0S%K#MK!%r8m$^KcL+Ru8Tlh|DIaeFTmc2ck!&k7!Mp2F!<3ONi`CZz6Z-Ot zC)S_tsQG7bBB`Qz9Lr4lYJMjroSH9bWYm~@z&?eZ1(+IGm4H#e#R0Im0WzS};M6c~ zE>X`t0iH%{!C5(7h=GFw){5=nN{in_@;h%8lXsnmphW$6c^5SaB$9t z?;Cmya}2z{r*_wg`LiLf6hVw3lSE7)c7Sp+2~9Fyq|QF3P*ytrP>|st!!V=GQ#qF7 zc&qpO8$wZJ%&s9v4ct~4T|!_FxMw}j*(7OziFLUB3fMie-(nmtF?6(4nGhg;9r?GC zyMllM#s-wM5K5XVg>WojklaE-wYG+xg?_dt^Gt2znZ;%SqZT zPoEs5N$(PGxpKx7ssBRu@^*9Qi)tZzT*)r3F0ZlT?ji;_F8Yr6`rtB8smD7Hx8if- zAZ5O{=dA}>XPzdvi;sw}M7zLzcZ1t*yY97K@2Xea&L2Zs zuB}_a>sLnVa-+rn9B8CR5h)riJqi>O)hke{4O={6X8@uKsPDs6bGQ*Cm?%WqY^0 zX*RENnKLczvrz{WF3FqZU_LRtS@^fQ#jPlNG<*z#*-9`$d)68v&iOKgB9w?iOQ|Th zLo-CbUGxth8W(YSgtt`Vpto-BlelR~eVMjV#p}9(OZu4HA7BHzps{`c;S~&Fk^*9P zE0cj#6t-oy#{!YRg0zlf>?X&T0}rgBe9hH=X} zk+jpZL}t{@N$+YL-cGK7AogXb_Lh3~m*F@!&27W@U2&RmK6>d84t$oj3}hc|dYO!4 zp<4_EG=3MG>hz(k2q;!E?P`MSLtJLZ@PKql7?93iGMh@~1y0Z$v>v`h5mw0BG_>!L zX%!nWcdKeHs;($xVlXdQUH=ZP;RjeKq@%r}?i(D7ykSbvY?MU#>A{sd4-jBWKA}Ek zzG4K{eP*zp7_ZrOt$s_PVdK~|QDcw-BPV9^F(oSn?OJp3{s&#vIWBWhPm#V>Bus^5 z$2n6lTl`etkgPO-TLXQs*%R(uL!GUVeL7gjJ=mlX$kj2q`6f;3uv%d{kD|OnkVU{M zN;)o5;Nl!pPxo)MoQvb(r6{`-KS@vK)`Y|>s-!j%NVos4a7ECbG!!y_7)|7LQPa_V z(6U=DAD(vePQEx&rBV9?Z~b1;OYkRBGEv~5l^h_!uis-|r6{~vqm&?2^4y6a=Lfl2gC94 z_o`6|iB^wK-E`dgDs#?sL>!HbHH?D1W%kwCA<35}+CychNxA`TAL-yjCLLS(x0!Y!g$gX6fghgih1|bTZKEeGxNlx^P!MOetQjki^W3WXmv8~E!yx0K zB-`J4_=Xn~D@A3;ZfirH=Oj@%OV|O1=IWN=8Z2>Qi$f9O#i* z=(NjH%CH5CKp$Fjz+0z9a(t<}o!i&OYxlu;qKAs-P#93a4Vln+wAY3eyGQP`gVX+CLI=dP zbs{muU;1#)q1rUNt$1@IWkhV^OE;rE`6kJX=K3+LRFmj{OYi&{jEKoVTd47plPg-* zA3ztEkwJ}iuI0q?CL8KNgBH7_tm{(tVm_YSoWXO*uZxrRRIOvhF@Pp#ZMedb+cO8T1{fSXcz|jD5NJ~@c79od?e6e>0|W> zQ*aqtA(H4_>WS77kFv>KuI<*AC-bT3T{`#Tqn-SP&ZKn?%VLcW4O|~zW*jfdJiA8e zIScg2SPi9>;%i-#EF28p$9Y3zjm{pM3vg{(p{UDm*#!>r?KLvvd8 zRBxj?Zg#neU?D50^h()rS+1;VxzJ{v)gAaMO&?p#<#ZtJ`#Wb-f6&I7>-D_&FE(~E)iE2Kcdbnpoq+OTWz*{aT4F)BjMr?*ZK+BT|i*&%e zewWM6@9wv};K3>d6g-EUyZ!uB-J2_PDij{M0wmCj25J398#|*UeBd8`3v@ai@3{!OU#!2dgq4U-E4N4 z71erE8&<{Q^?~J~20`k&f7`aR9xHLc?c%=3U(1kKw~2W^i2jgIo$O@){;QPo;Mq4Q zry_GUF{F0L&zGH_WSGlS#D$*tyDFkp31tFw)KKeAjFLz?6t87-lTccqiB2d)4noib zg36e;#8(D^ac#iKo2HFt!fC#zYvAh)djE&v(?7hbhk((y`i9#DIO z_RY6u9(2IBp#ZM3u5L32nikWzF`rV;SP!emP3ybViOyX55#tuK)vfiT>=QL4hJAcA z-E*@#Kgmclr!}iis2jF%hCyq)TY>X{d(<2wYG1rYEO65V`=#d+Qk%dFeMwemO#&hs z5-iyw!<&j{n~C(w>N`~s(_WDjTexLNPYTK}1wvODx2xPkbl6}<222qD{gN9r^<(b> zI?eui0v!R*@+sN`pSW`&0;rs~9B3GwCJK;(&nvzm4F3RXb;DXNNn;D9A899pI4>k~ zWQ~M$N#=iz`#hpGyaq4Yl#ei|VoTcIsT6^sjr#A%XZK+dM<}$5k`vYWkN4X!^)9Ir8i+f`(SJR@ zXf`Q4YZ$dhdghKRk^Ksu2_gJ_@_C8%0Sjh#iMGZx7OO>xnY5|E-b(2}iFn^t8Ok*| zb_|3=EtC!$;^@)&yNC`Rvv%8p%p}c5!$+o-w~!&?S&yK^tKf|QXUQdNUV6d~K?V(& zgEiN>5_GOL@Hq%G16~4E4V|*n4Tg9}yOH6fKi5xtqv9B<%ah5&iSuxKaLG$=#E)X# zm-ISDh^ez-dfL9FUXl%#kyplJ_*INII;9kLO(ImBah^?DgKZk*sx>3+c=L@kPhFYm zgxW&!$#HduImz)^4j3kmVVj1RyuL)#!X(4yf7dHqa*bwr&7v0Iz`Z!mD#Tx^SF&jK zn7wX9#zK%`i31JY=xyf;wJ7GZ|K_4}&mzC)CG~v&Iw`o$<#G3lTihs~M6a&U&s#=T zp^h4fy_aNcBz;y0mbl59%-JTfQgEQB^Wc*%IclEulhbHK;@fYsTgS_iwmFO^0!Yjh z+ujZd6>M;TT0{@0Xxa{dR>GK>%(ahVeo0Y98FZSNPr&0)IVUNVDrGSxZ6n+cX}iGw z%hZd%VE-@Uff2sJDtRC%u+rT?S zE@MRcVLm1KFi_EtlkNjgk*-)Get=7XMj_nvG^(4{u9jOb0IDGOs?xvM{3VR;5=R3O zhyr%Pzt#5|9xO-UCc;2ASG8P}ZZCuMNOx4*m()|qW2tjvIJy*s*VD&TMQ(}LGX`wY z*;gjgBTgdd4is|Nid*9GK(8;6=5D%1aSw}-iECnusJaJjq zw=oJa&fO)3fDN;|Zz`Z92;%}h5DbabxHX%LmbLs1Z@%~(Q!?$gG49gnI8OGDI)gkO zyMB^-c($G>uO;5a&EbX6zkoX({?TedB_;(?$q>I#TUtK!k|ZRAhPd^TVQTxMz-_s0 zE7+|UYc1c-`upDY8pWpmDE=wwKZ;=+qoLZIzWwVdh1uN*^Is0F#f zkO3r(Cy>JEZdL`R5yGbHGT}Asl{{*ZrA|p6qc{9E)lG)gElIO#1&n#aN)fpJN3>R% zOLa>}hM+$orcy9Wz*+J9OTelzOV}^1dxme)hXe;AC`DYRpg9EoL$oL2 zWuduCE{8A3)Dp()ShYyr<~E-HE-tMUrNVis_1LYy??v_;zq6Vm^{Ic$!rd~K}F zc9fwdg%06Xk5KC;5Ce%=e*+(Z%@RcXTH?)8)bn2B8yrnu)WE7iIUpm*2(PLZ)wi*^ z<+){j=mAUyz{ctxhhH!hGX-2h7qxV}O+guKl>i+bw7^1URWRxeGbhF&3md~B!q91Y zJ$xL7)Cv1f;x&FwJ<+*TSeJ(5OHo)4o}{;3A~PS63jc(LkNk$SQR_(43@=M*sfaLj zq>;N1LIPncq&YmIlq@9PGTcL}i)3j_Wlaz8JcSq#7-rsK+#%=_!E7_@_>MH3Au&kw zH@GW&FUP+ny*MT24MagUa1IdN4mC>rQd;KozIR`oW0({j3K)-+{f?qK4pxH^;Xa? z`=cV>>UTa#d)9$KGucqBo#XIv+rUdHdH-dL=ATAdIZThAuA{kbtrav@$1Py=Ybk1o z9y;C5J4vfkcCw%~KFnSu?8Sd%-7u`jYea;je8YN47z z>O_yZn~q!~?}8~%nr-5K$_O!86desn-hp7z&D^7Q$k=td7Kn^gNxYSi?Uts)q!?vV z-yS)=!*mtNoiEUR7Bh~OAh&!~9Nr}t*{E(wQ^u-Gq4ygZ?c;GH#~Yh!d!{DW);0z) z*=z}O-I?vqXh~yzlgR_6craPFc<=uV86kBZSao+-T37Q*p4t@Auvl)Ru>QM9sVSPZ z3vTceY49`?pfT?)TJ(PelYx=ruw+y#>G#T%q@>*qb0Q_3tQ$$3O>##VXeU~QLB+OV zKng#krWJrOI}eKmxZwFg9=)VXfIlJ8uH8ZxRaq~JHe}>@O2RCjF0!acX#0T-v0Xsz zSZ303>g&Y)ULhBv;qmw4F+>I5kxk~d@4gg{)Oa2VRIqxqk(zzh)HfIT*KGX~q1pVq zFcTRmAM!WoAwxJbjqp3*XMx!14=0gPmWQmz;|=6_X?n01W7}e~C^-kx2+53(Mn=|h zU8i&3494bCnG&bHBpcF5i>9lL>A@pqd3(?ZKodjc`{+lzCb~jK03yU1v&l3^&4b2z zHjy{|(jtE51n(sWg;xIi?n`*vo(@T5?0Y8a4mVb{=!(ars&<)rMHzYBlT_?LUY1#% zxoW3ro-@H{6>k%JcMJY-{T@nbkl-EkKA$zwHQ)kNDu4xa;R~);32rr1BQc?b`8jkj z7bXuX9QD$XlcZUY^}^PeOb%K~L~ie9LGBRVt6+AR)QtPo2g4zOo8x5u1?xski0H@{ zRIw?Y^hn(iR&Z-pk*1sk?K1IOJzCAd4mNd>pKg>g1tltt?=ExvNU@~&FJ zo=s!AnC)?rIA!Fx7gM<8(C7}u6kmON5Ebi5EAouc>479L5+k4knc-MR!E$;58pZ~e zw)U5*9Q-oMH`^4n=xJy)< zv>9pxR9Jx(wKVFW{{19PwiqmoWXRx%KIH#xZ~#zqXluS)Z(R#F zspc)v)i7q*5mKzruxnzgU~*XXqkJPv5`qlw`11sf9%>`m{pi^9un-J~&m$8u28_oe ze0Sl=qcL@Oc({YI8wcHvhZZ>AMWcHiIvNicYyBu?HeGZf&E5YHYwPR8TD3ou8)FYW z*$Qw`P!r4)d384kQ_k6MK3j=7;d#ROKw&ly!;}Z_Xvd@1f`;arM=c7G$jG`xtl&FP zF;zHD&~???1r(4Zp)A@<#$ncPx3G-G*K&-)UbF%92g>5Vp9Zm%6++f-)>V&exvuBE z8$ge6{$IfWuqM87ioU9O5+&FHe$po*U17fvc#lqzmqberk#MbT;V#-QC4Bvqj%>=x z6(9K>#&c!VhOT|dcRmmv!e^m+GTZo z$ZKKFFl^B}Ws&+ii(h{jFG)HrT0uS-ZNuWGYU~sq4ejla26QyVri*XH7;LORVh~Dg zVyPHvgDhN0Zars29-+dLUiml3jtax@r&!R@K?es?tKG|Er%=z=%(dAd;1rni#609k zZ%=#2G$eAZksVf>}HO);NQY^Pd2+LOOi#h zAlA%_27P7w07wIpW_MS3+pM;%7sLh8GYqlFU5iuzTKpT*azP&N!@RgoPpmL*L5gJ0 z=PA9*BJX5}>;|wa`4oEhAcezH_sP86UHlma!gc}~kD)Hg^&^Jnwz?7i(X11QS-5Yg z@d$lIt;uc{XdC}QYnL}0zPj8UB&<-CUW}~aUi6eL(<`g>g5{%{?z@^`H4Lh%p7V_c z5L~d0wE#0?5(?wtAh12O1`lHoQ#1?)d6M*78BQCg`)gP5ZfKuK6s(boi7l?s-&cN< z{%g342%(UsNOH&LaebkQvF)^p91w}QHj^B75|SA$HbKf{)V~@V+bA#tahjZrM4%Kj z?JXIwhZZ8J?Rq;P7_Ng5#ZMK8_$CKly0^+aMy+|u)`GD$+Y8PLXRQS~bCD~;W0%qs zFv+$z%ND4-lcM!Uiwr5QC{*%fuRvhK5j|_4-Y$XRL^rqa)kX<z*Y2FkO(1xL%rKpN08h`oI4qY5#T=wXzm9T z(sqe*Ek^%gWYPJqOP+Gxi>dI~z$FiIxVG3G(jQdfFQtnM3HT z)l0Lg>|!|EUiY&M)_#)02b~82pH_>ZMn@PD@5OlPz`Ymc4|3~eY&|FULyji)% zfku50<}C2g*dW`_+5{Ar8M?b%gMoqEyvp;fskf3 zwy{9U?isVBox!-F9K=#Fbg4L@t)vmy<2OPxC!Ipm03;4)m zcx9v`iu_xGq0+m~JK0THwUB|Vb2ishPzi+IejFI^b&Uhi5+^`6@-=}+HRs2N$pr`t z-8l}vE&+@k!mfkslH+QC%;+$Ruj{4Q$q@uyR&3IoY`$6@hWC3?c zXQ2s4gb<(U#pwkKztO}cOI|=wf^vXC;36mB3DVcnZx(Y6%Ec$fR8i1Hqmz865`Jt{ zRM|-=Mw}vT9NsBy(fmm_s5&T4K#=NYlt$_5Cz1=lS?r8LuZMR#Hv)VFRLVaUq?euq zXr34T5`MclJ!@HKtPw_xL}C!SE^v)b?ovRD4jv}a2F({`Iy5Q2!_7w#>-sF>JLpBO zHS1XMdj9l`EDGUnH#f4dVp?XODy0TujW&7=kNO2P(iO$s10Y5Qbi9S zNa5Ln3~)bqOE>G60Oc3d9FETJTcCS>>JY83>_xCbw)%>LBdl6}lfqxW(UerFUz7#Jb3X1GAuEADl;BmC^g2Sq&1Bx-$NP(c2i4mz! z(2^Ps43}P0-4k0(t18Jfu&XNd%ML_~r?r}KC2KSDx|g0*H*Gim4YXM_2|Ct-1h8j` zg&n7t2&TJv__kPev=ckUJ+=~R@eC;zk*Z+vGyb8D``tv*6bW|#%hD5~(gMB$M+6j= z$BzaY;w@QuAfPOudjRtVN{{Tsg7g>1z>fk+2?ILn#>6xw9_x8G)TiRL&^lrVEjng9 zCY{L6nJ%317!{@zJ7pw@wK`D&QyN6}k({|9e)#E;qIn|fFV`%{U$z5aBb7a*7?E;y z2oR2j*nIRJR?@~uiD{>DPaWvi7x$4D-_a~z`I!}5|v_=@g>0+xfh4S|& zD7zG6(Q-vST#gxJZJPV(P7vT2@rkts1jF<81hTT6!q3s@+Ce))#mDc8Mb9*NijmQX zr*vxO8)64Z*82aAbzXfD3gwAhZ-91y29Vxo zw|%3$CUIOWN`K9ACwRNu!$Ef;`3lGEhf}1Z7w$2R#x{nbNrxm-(g~t~x&+9ppuL9S zN`Jb45tQWM4vAR27ZR}AiCx{V9wswy_nDFv<)_8PVohXPQExzz)l^+NB!AMOtE%r; z)S<#(e9Ksq)k=4(* z0T|Z}E^W9jQTxwxT>RtsE~rEx`amSnvCp}NGx5z+IB$|GNA^-rio@tUF-g33+eY$k zN|U4@Bi`b)&SKd(W|gTebQYaeC!ThR_T0i0eOmThm|TPEP`PZUfTU`UHa{C|KOpvs z6EsIyA%BDZ8VcZj&Hove4#+m8C$4MFjhtcL4vpwu#zEy#6vylVW5B-q*sh)vciae0 znh;<80eZHEVZn@!zQn4CId?A+s1TVLUxxV8U&8dyU>vl4>#2)J#5MhEzy|Dgn2Lb* zMweZ?=%!IG_UJp??z9|Nkbjb(0Cq`(ZLMPz6-SWuEtc3{39t|-Ze3SPUI?YE(El!Oln4-k+wuV4=WLNxLNWrkyRfSlKkB58 zPpP!a{}WgORvf&HCQGUuG412ZI&TGscr7Up**qbsWL<3wX04-I2-7!yk<2i8X=tu% zx^P`O7UZGhwnz-sBB;TY-Q#xJF93mmxhOr zh3=6jz@l&*OLh|Fz9FNW_#=3QWuPM!llYrj#}3CXz0TbZlNQn{JKJ0-HGqCu99$i4+co>_i|kuH~+!^)K&QQ@*BQp9k=0ZGqY zay4BhvnOqPdoudGDgblXV#ZZ#pD0(i|0ZV6e6~eg0Iv*x4z67EX&GF`GS+9EJVpYr zcwdk-<+C5=4-zA@x>5~_rsStFij6XH3?H{ZK^GqU$J)bx5@Y2)a?_R*OYhPo$f6Mr zh-eh5Dqx2`^L7dZWZ)zp)pY|l=nxRsasW$L%5X^fz$MCWJljW9qoEimQ&Y_Su}T=a zlry=iB6-X8+CPn(;3#g1A0pl&+$DH|s?!MvKBqQlZ;HEhQ|0$$4IT1s(PPfz@o*v>?tn5)A`0VjtvO`vNkkWJODEh2az_81*X2F+x z_11>XfCNk6$ns>32P+0^ZjysY!{s2eeq8+=Uc+n@6$6>*i`_R+6LEQ?Zpes`_rU{q z)Q4#=Dv`qIA@1;Vsy>eQ$R`b-Dx}yg`eB$40>;sAjsVh}9)0+>9q+GyPJQnCY28O> zzfzpUxDkl3A!7o#tHh-$CEur!R5W(x)B514@{u9|0*H6Q>% zYktl-K>)&*E?<0Bt@9xNri~Gdu_YCj=hRU;{v`dJE$vLxMA8w;j-OX$M7_OG0)ZPr zx=O2FFbQjz5w=BX^zTRFNE@~GhcVg2&mdb$sD=~{sD7w+M{!Y2E~~5C2rZ0fw`!5Z z-=hGTZc}{`Qk#-fz?+LLk2#QmxMB(Ahb;4A2zuDuaUr#g(p=gt8D(a!A2m& zBKajNJz$iYNeFY$tO1y=epeM(0P5>F0iRE}t~3wG_*)x1Zdulc)p0LbD+6b1 z7$p*uo5|S`CKRaWsm0>QXxs8)Y@01^^tEv@ynb|#0U#0 zD;B@n`-2z4_5=sycY`o;a>F|{RP+z{=e**meDAJ)GI~lfa(ac~+*U_0KxsL1M!k*^ zf`a}gbB0XZ<(+nf@oKk^?On7;!R&WC8R`VfyTb5g`!RLSb@MYf5Bbh9p`07?iyl@Cz56@g%lOF?hi}bU!K% zoU6k6t>79RbI|cn68#^OcD7$o7qu@*MvR=!j(6lae@mr3!2Jf`K8x})R1i;ya0%oX5%2A zrfDXo1VK(xs_0>drxN$Nnxal>Pq|1pV;>hKaYbKhu`Uu=A*+eiK*LNI888Ts>dC{y zYwE*PITXfLhgOI^8v1sd2pX8xK-Za$grm2WiL2VMD5m#WzYL zd#J#)H@E2!L znQxL@3nc#-KJqno^$4(iVMQHFU;>Bw03i1O4rl|GvRXhIoWnmsx3a402HoU02j{|z z^tE8TKy|%~3moWG%xxt$X6;*rAB6ai4BB^fDoU$S187@wEW>%{g)h>Km*Fj9GYNZ! zh<8DmZAkgY2|8{mE6QkwNgaP+Bmz3-%Sz?1I z6$=-{;ef#8UIeQJFEziZ0Az!Z0vLJSpzO?>d3;SU3~>G|to*+Ip_r;G)yZ(>%9w%U zZZxTi_2K3N1k4|#{8yK)lMOsri%A5r$);u+lWE{KqOw6; zs3ZtuUJAdZf0gjpKhhaSw~^jbclK_yrgu_fDdR{=*?V;f-N+lxA;C`D34a&h91!9{gH{koqmMxAfbW5d z^}T#?UV)(%phqVHgbbx+UyU^wk>$?lOWKJensXUxKZ{#~UKlx_qTJ_w33IApNEc!i1)MTdiq(cFjYu4Vc9SutJgxNMau|EuBPWlOdo3f-o|T<~en8ryy-vYd_!8 z-8U{0ZU27t*91;1RP&h96JnACW8W^ev!JgorSi_{V6C%K#nZ4ZQ+YhncNTF+t%b z2ncgTuHftJ?2sxe$@<P$Lswd9Pcv@JMyJR8AUbB zhjv>fGZ*@J`iUa{=)V%aNC*RF-=uVAV2&>PhtikV8fLkU9rQXcCkJt^Tp~3to^jFNtai zyrB1~$6er&JAK?yLojmoVIahPv6N($B?2q8%5IA*9iVIY?P;9|A(ZmtX^C zk4SKH8dE<(Jp`LUe1zf&K4Y2!20Y)8ic4a^pJ(tcOqb}e)@P)X$yU{)=S20)QaYCX($E6Pdj!-av?YPCt|7L=pGF^eWvNds8~JK@|8 zt}N>TMRKd__`iz8=5vO3wpp}1j&|E|v35~i-RvjfsOE_6Zg2Q9=M`VZupRrY5q=(A zep`5T=$s|KB(CfQq)dk1V1(1hG%oSI)TB{Q&!Jr=SSH@||3uf6cVnu+4Jy_MT>=Ew zD~PnHD*>Fm*UN8+w}Iwt4p3JZCx=#t?;>0SJucOlOT2BaviRK->eF(6MOH9EKvH5{ z-yG&0Kk83XKk%~lS_Jt_)A44QY)-MFshh*Lb4mN8H$#;6inwaKh0J2;Fpvl^Ziu_k z*`%?(WZi9b&- z5u$q~?S5^BaxoF2ACq8XlY&P!INn7X1;U_Qe}ctI?-_8~zomj*d~zBeW!C-I@man> z3!)WwtpJ`|0mFv+Kv4mNTUE8Z0L=u3f^Yy(ACY%=D+%VH=L&uA68Al@t{2dB#ZQl~ zvth{qt1?N+*TeY0dXkhO^kRu#!&wmI<~z|w%>QOCbW7C}WM#teur806Z}huzMv zkx7aS&en$u$~|$y6S>8=)Gp#-?zNbH>Qui5F?!!e0NnM$&tr6QeVARJ#J8ltw?4q$ z0l`o)ZCo*Jr;3Dm!vM&G1l3boUS%{T#-l+fz^DRK5{04#y+aF{8;wghu`K-WG^Q;G zl9ZALwzjD#xu-e>x1~n~8k&^kG>Ip7pKzXdrLPiIz)}^M0207kqh13(L1%slO3Ryj zbOG4}Am@rK6GE@*c_}#01?ok!OB~beq{(Y)V86uihM%@U2q;?s(1%&FXz*eRK6*}s zIYNhOeDh9L#2NVrnI0BoT0cuk!8IxyA0iG=MSa$#@fZ>p4C-RN1)2@^rS=!Rcb;$BA_`yt>gI{vCeduj@M# z&+ywcR=`^G6eMq0ufR+LzTpu9FM&D?r6Gg4;QE5st{jm;%CIXc&RLLcZjb>%0OV8L zuQ0zEWj>Nx8$`4>HZpLK#7eZQ4>Y}(H=l|T2nLO#KaMB&Q#dS{C5?j@&j||XbbA(J zM2=w4&lCC`s7(YtbNF)7(^9AC!9vWFG93#|#XAgM5=&nz|6R;cJkv`e8GlKAlo1fjw`2Q@>cU}C zg{)su{|kD1p$<8CBzlyNgmyfLLSsX!$dDT=b9s{C;M>8l1ZSv&rGej;LoU2p3`SU@ z6T0PyJEBdn+{6b>Bu%Vgk+>JQb?LtQUV)Zgoj^s{6EG7(I#{uQ48mCgO>-XkP>wX> zLtgWRiu3qpT>?^li4vq+od=8i$(JHx%~U;F-S~lsn%X1@g!$mMVD^%C1X+DC%d@|@mVLHomEIsLKH@42j3$7H@!ER4C{@Cjz4NU zzoq7Z?bn&x=be+LYfQ8`AbrZvA_tY7v z&o(yTW7L$Ry_odN$$DKka?P|Qwf0ZbKCJ_ZpyM0H+z#^8$lGJ;=yEh&`etMnwFabr zyfsM?npE9d-w-Vjbfmo$0pZNWuO}+;V4t}|^tQ3B`}52+adMv^O6W$Og_1Klejf25 z3{_^+qXbL`E`27^v;vQEQ05$G>ipETwiYt@ITE;H8uDMV&HhYh@10YZ(5b=8C5izQ zVOT4yTmeTu1#p}u&;{%jpoG`~X9KE5#q0XpKBYn%R)rgdX`6WYsZh;58Y8$_6;Z)Q zxrGs!o!56LaRSPyEPIIeh59ryF1e?KklPE%65kBnFO!61iX|yH7q~8}4pZzj*AJHiA_+V_?`}>XvJX&#j ztxgzbB?7@%-y~V=^WwXwIEF;H3yI{zjZe)sgySRs#De-d7SsnRV*cbkRO3N4k{F?N z0Ja}}frYVBK@-;1up%Hd7iC``o^vvQ(0&&LClC<45h%S4Qnfb+S3J$U;8%-=@#7z) zED1+3V@601r-IX>Q;Dl2RYsYY-OILFGVlP?)Aa{d%efRcp+ z-X{gFBkmkKj`Bg47}!pVxh%Ftr!eMe7&N6HFq{!G?zpD(h)nNO&e35M7F&)g%NZjebM@g5%!5ok@$@pVNimJ`ZV;FBhK!qOs#IZzMYdR9Viahu(_CizEl8XT` zR1M$_tQ&AP8^H!NFs?XTAT5~N?15J28phY0D<9vx6^oh!va9;|V!b0)0RCQ+G*A(N z0E!lqhzB~j+0{2kLcujbi$LbM%vjv|ukaFU?K@2Bb9C@Inw>0r>)L^5NkV4&d| z9cYV?p(;?{N#?*37`wW~S?1&ipu@OC&O(Ti+e6s|8W|oz#x-Q5$%h7tG8jFOyszMC zdK9Ov3ZJa$g!io{Zu>0b189mNqK1Gi0dJpy1|$Md6e00j%F_3BYT}ehWwiK`{5zRr z`G29moK+Wb5J`)1trJ%o0JZ%3Hk6$&1qD!&4H1fPHNFd&p$7e}=6egh6$iTmcl^aC zkw!ytrF=-8^22tY94IfTw=TQU@jl7M2J^4X3yk6>!h2P{DE!~(V!j&28k!DS$Js8R zA}o=*{!0mC3agNID8G!V7*b&*LBT7?Npbz>0QJAIoQArw|5?JbuN_53hR|YOf%uRZl#R#Z_+_9#QOs#pO ztY1`O;Q*y42nro*qQ8gimoThq;SV)5&*>l?$jpCck-D9N8_d$XC#*4P%{+B@JR009O7rFm)q z2?D(xcygF?H00(kFF?hLvH{9Jsba@cM=PKcE+Xs*8L*NZus}tZ`5njTg#sJ3<1&r% z%879HJ3mjY-(leL9XK^Y=MmcfUE;_O4Ar54Vm8+$2k-c{#DQ8!girEQ+T4jHThgqE z{)lw#>B6-raB}SpN*hr+m~!|sZCFqa0S3L-1OiRJz&{|%=26`E((y{XN=t>KV%ZvD zs!GcaFh{TkFuaolMNWti658X}qQ3iu8JN?kAY2KxSfikzp72PKI$#x_)QcM#<8ITk z^(?vlTKA<*g-g55q&SaAao$kJ{it0zZsPT}_UkAZwF)WjL}|UGx;b`FbeM(1%g|9X zsBHdvyGQBZ$TrjeIr0z?3`frV(`X#7Up%*o{6zu&Bj7fSVG^ANlIt5e1sf)HqlaQXKZRsz!8TF^Iw-L>?m@{K0)sQwgYos-$5u=&| ze2MXSh~H#b?>;l3AQFsX$#!fs;de&oG`NAV$Xoza3(Cn00i8b9d{Q-jfjOto0etQ8 z;p}ZGlKRWFc7X^o@+r>ds&-*gbQLlwsDV&%f*{m{5WgQ9yDxSbEM~++c4$2fgBuRa z8s85?=owQqo|3mdw8AneT10^RQC1ap9$~b-_maBwWP~r>{eU8x2j`-ZQ(}Uv#hU0+ zINPd2TS3z8mJh<>a!R+AFFiC3jD;SV$A;5$QY5$C(_N`lw`aCy1K%qt7wHEf`klZl($si%- zis%f3Ycn^XP~S+r3uqT+OW9F6X5Zf%Zoo9JPVYHk6BRotvOJVp_X^;{o z5?*2$;;hGRV?r2Jb(E|YLC5?pnzG5*PV{3Y$x!7RNGS+;b{QC!XVc4SVbD5`Ag1cT z5M1xCG4$@?phuEs%Bx*66mUA=@g!$H8q$534WXl_X@o6Iy5!Kww&>-4MLu&n_9V2e z^ID{G;ws!iqROwT*9Fc3VL<7*0AvXo-UGMQ6JX6m{?r;x1^VvlrEpPwu4XB`5lJ<# zfG>xI2slymQIOW9D+mY$KrlJ+9@9MtFrtj`$fc>-7Cxweou|>~zew){bUctA!@o^e&Gq@1A`*!W zN#lqqmfGL%m^3O=G!)vJ1r`cC@;?}oHQ62kV+(j*P$#x})8lAf$JLh^t-1Ci=B=In z3tmN2Iyy;H^GUKPUWGqFW;YUBT6El6Lb3);K~jxiAY3hw5Qz&AbkfE>LI;R)7^DSA z0;;)NRf58GO`#`DMq)o6W!+>7&{lzr9{U*42@|=qMqZZ2==Fo?9Kj1R%)w=X}KX6DdeE`%L6^iQ5pi=9Ol4??HLrMm;f0EY~QDyFqfo z^0;Mdf?wMrVS)S%Fy5TzF=;~7wq`vqAH`wmIqlET#`6ZlwnEeUB|1UpjCMqsrZRMI z4_9f?YCnl^IL9+*B4mo=&&kWk>2BRp*MlO+IY2;?+pr>Lac&1zx0^z@6e)$B(v8=} zflTBK=cs3pJkfYf{uB?CbO(H;i9)U*qd}!%0)R?DBnF)(D1oB}LIb?JT&f{90pAkO zgiXrpYKc5R(5=9ypIndCItrNQ^wIC`LrVD0gc3bh65zXQVRkr1wvwxlQ;CG(D1ft7 zQ8Gv|m2|8?lIRRE1uzp;b9pYY$?9_{?F+s$Qp#GWDfzM?12LiUa}d2kS5m14uz7VTd$88b;Gjh4??? zB7;_rNs=;t-U!X_hFkg{OsOxj-(+q**0V|}#WJRpM^q_to6vj6d&3W$5GDxi)Ay3= zrWPYi90V7BS*FS_V2SHQa|-HYx&c`{O#Q~J-wr6MPg{!Qv2cdrC{uZT=A(>cB4Cg) z9I~L9R1fKB9qDaO)TaHiKO~2hKDJJjyZa&Ym!n5X3QLCUoTu&WZ{mM_9U1o_dV;WX zS_u{W2DHrZP^q=BhifsETjHR3_zi7=%q)|m`Er}S?|_?(<4Ta=WKJ19KAqtXeomPxLp1hEq& zEBECU-4*xPnS5>Bi^IWTPPk*89e2?;Lq=25r>BQ@HWKY$XM+#f82*@q!Li^;JBj-; z%h`61V#=$C5kUQb`56q3PWVx3ijjVGO@{6f^s2{}6a$2o5UVQR@1fGc9lvb%(u_vSR|!}#|6il))+KE4g( z(8wex(_@{lc$2XjilV z2P<7Mg(YMFM*}1gRgEu=3Y;=D7qCh5O-Um?L1^*=JWnY1l;ckD z6BDrZNd18eTa>m%SaV_4E7Cl$zZ=W)r|_A^_Pg6EJ&UCG^G}b}49gjzV>6YhJh2se z*Fh^8X3?HpW39vYP~+kZEmx>V z%1ksn?W4j3v}ufE|3%asxZ%%$2ox4Go9Qd5`sWp;<4hnyQ@9V)o6_}jY7YYP26UuP zrhYh|B7}68I1zVFQL6Pr6F2;fut*Hd78jF>AtWSG0g%7dcKz^^UU!YW?4ui`?YpHo zL_DH)ViEpJtqDE>TwhSHHW@Q@1@Z{ht>|oqvL`fHS1>6dDbb~$0?*fg?H5$ zY#+X0`}^Z$fK7&Ke1>LgRKg*$cDG$SqX(|qeuV4|6@tF`UWeMsPw3QOni3tM4I9Cd z;Hxs@@<=H&*>Ju}hds-8%tUHs09O`T8AU;qBEZdZX?+0W@=41ghXDD9V&*bs!MrXR zppsB}zZqLWuTnI1;z&5A=)u3uAa0C=0Jusf?Ei_Ty$f-O)8)Lni2Z^L0dPPSC}_Z} zC{(khy8z?_Q4Bampal>G8$rh9p=-pJP@gfuK7~qsk!L_xo}@!QRyGk!P7*eZq)$o8 zzOXRV{geEE8JtYKC;0;ZFMdf?C%0UZAs(QrNg5pQ_yHnbNYJ=DJZx5iIf7gt#tt*1PeLDSATK_FmwV@B2OA&Sh2oAj`%zgU64N zsUVQl*!|a~LH88`EPmb&y1mc1!E5%nvEh2mchTm_h!673Z+pu2HM`v4*pIdfT-M0I9Ha)H?`FAkw^m z%K=kw*8CIz$$xLo*`CnTVtKwm9*D2#w4u@iz%J=j@6OMXoTF8|vuMm-Kf;3)SexTK z@H4zr1S%@}_nYcmtDSXxAgKWyP+g*K)ual;{4|L+5EXfPpnNRq z2A=F#B^n|Z5KOP!x^8H|oy%KJb7i{(nR)5Cubmb*OJAz`j0Hx|i}3@100y1}2m%8$B*-B_7y>f` zfRF%6SOu3_Q6%U9P@*WUY)CK)?ryC9(Mk*o%g~CFf-bbN8`|G@v)=0lv0YuSTvk@z zbI&>V++)78+@MwgA4uHt;vP#cYKpx6ev{x`E5q&AmOsrXT_f_>ZiA2f38SS1oIEvR zB<^Ur^FcNxN$pEWNA>_I?uvZ=CXRj(*1;HZ6@Hc(PMQNDuI^)p>Op5E48yp#e9T-L zf%{F$wF5}wun`MODmpe|@o%m}K&EQN{L)XGyK*m0_muvD){fjAe);jJci1d1Zi1-N zBlVDWJxn%!2jS;@o0a7q_ygv9pkj7FNti>VqlF#}-e)L_#6_lRZ2tq5PR7bo2~ZEu}!91FZY$k!Z- zKhzJif(42+eJlcS7Rco!l)2bE92J!0^-Uwe4=)QcLEot2`3~&pN7=>L+)a_Wg!YiG zqOSf{l%B8l&~aby>_0-reRhWKVa4ZD=xbFnl(uB%#Fo@KZ&Z_*^BZOPd7^5k1v(@G zU*L9_ooAoFDt@@620Tu&xR(Q(MuV9+0zIR#&_rRw<>-2Ju_CP2o+{y5@b%1RtIW8l z_LTAl&(PpS4i38fsV+K9$jmXX%YVi;oDC1lxB@W>$E>o{+4gAa@x}(A08JNH6vW7r zsIllLdulaFvrL?v9N@QA1_Y>m&VFSU;abA71CWSrsXEznl*EpVPMqY8)h_X;BrJ=G<(#@({_iD4<5K09WB*} z)nw1HG-B1)UR0$WKHVBXX`N*xVUPPg=EU&@IS7~s(p3mC5M`%)ig`gR9O5qP3wnJS z_5m;nwB1DSmixeZ}$kFdLO9)`-XdBOua9V16ph>#Cth1^K&_8yxz|FkGx zKwX&fDz}R~*U}s+iLoKM<=0Ru9EPploxjJFa3;|{m)5a{$jrVG{Psz6a}c)-$r_ND zH65fmb1@zQ0NZb7?K~oTjC@s)?YQbH`oV4!7HZddciZvS$XTR2E%{GoiFSm>yiyO{ zw00k!VRwO^HSRZMo&gYvI1`JdG+x#m_<(WR>}O%RSfjXbTf2dEcu+1W9HxUqJ4sXD zdXFKMoIO~u)JO4C5#Gn;VuBXnhlXi$Q7gQ-f_( zTtPlNkNeM_#8}52o*p;PcbpFR-T^A%`EU^@eRXE|bBktr9CNep>_5HKAin-vus+C%i2K1Jxoqj@na zb*xARq4kD6N2MEP2)53`pE*^F9a=^J4J`sHm5ZVbaK3m_&mxkYlBJh&h6TpH4X>bR zS(MpuvV4#Zy3kzngH|hizSnB@e82a$7tN`V{M^-cYk9JA5AeJ+A77vk%O!IUxp?%0 zgZF+N=FsnvdDnmm8%fv%6_gh1aAD%G?ik($21thlpfU{D4s13sA@IM}dUvXr*$wXM zfY=E#!D0Bdje?D9By(ZcF>83593c8A|KQ8y2y*2@TmM7WuYZQLKXP?nDiMb1pcEvU z6H9cO(`s(XiQ@D3L^zISazxjVFX@AQ{Dt|4;e0BmUx@>ht|K zs}Jm+!72pp!=NWCNC8y?zEIIk54^xA)Xrr<4>l$b<7e5F6jXWV&^Ql~4v(^fG;xlk zxu|NPA}uipa21dk5=+xTy;%TO4S&QQAVOYRyBFFWVPHB=uu6C<(-BU5TpU3p^A#!u zfZN#*d*;wioIcB8N=>Lm_&ghSVWX8g0Xd)g-_AlBw1my&dei)5G$P{B;MBUEhnN7j zupBCbzS5NXEaxH>e}mV=FIJ5)T$T~2$EZU~yIHkx*iS`VxJ-Yc?7<=f$BD{U1>SO} zPVwj&@_1}gpyQl3ufGgetiW?00Ef&A(ha#qAZJbyo=Za#?GIna(l}(oGj6!(F?Mz< z!2&z3W<>b5LB0XLzW8Y_`kQ27vY=prT0=5nZR)Xv0A?`)v`eAv7KW!ymRh3(g-#AA z-+|e|9olkJ5@3i3QGisZWi}hQ2;guMtGCB87ZoE?7Qw$p-8@N@?I)-RncFQIW~yU0QG}aCUe12) zvT6JEK5$#Lu;_t$hxLJX#d)te62xoWDDHt#eDt~?E=PFgoR)jm+!kfl^+c~Om)yoA zZ%xe9QJ0_Y*u1yNNnjxCQ9pQO*nF|aTC^bmD0XC|1h@&!24mv9KH0wRE-Con!Tbhf z%vq(e0m;(??o`#R>h?fZ0>wb7^3k1sjlL3yOUsrB(L}U}^-1 zG|EkHBI5whLu8ti;*!A63I!If6n$={%6P+hOJUyK@G!W3C~kSV6v_Lp^^iV`Yy3qb zdd$Z&$M^!Kmhw2`NJkWts}! zs?G$DPYbq)Tqxbwsq{bt;HQFo>+Fzt%!#bvbU$f6#fFrnYi}X&)`~H;SDyP8;~#cH z8-=Iy6BzI04dpc)1VrcR37X^RnuLzMX3@_Y!*(OWJ;na&3w-NY z@?o>u6FkFDu+YW!r1sNyqBdL0(dr&D;*wD)-@x_!C7+I8Q_m1yXhJBe4S9M!pCc(P z+Q1A-=lpnqLQgUZnk%hF2-dz-ebhWmCRuhYTS9) z=pV%i=PWhq^j`<1E3M}((uZK8sP8TuaI{C zZd{9N^SkmN_SgUCkoI?&4_d8kC34Pf$fedP8I#hoV#KRzmZuW)X?54vM6P|3RgVWR zXF8)jgXk7OX{(^86_46kxX7+CC8;k2JBgYhFc`8HMSx2X#iSk784&Sc@xy#c7o9+6 zjJfQAq2=9@)$5B%Z8)k=f;evx2^j&)8v%4tZ|0q}9}+z2fbwM%^D>V* zJxXOYP&Jp1d>NoyimAHlnkZB`G7JNnC~7-F)_e$#FfNyl{OXwP{I)7|z}@56wRQ-m zO-RXJBLnHPJ{Xc_oYZq`K7i&%R&$~RJWpY7 zZ{bbZ&$PP^#3y*v3VR_I-M2>zXbu}*Lu-hux5R_+B#*oi6qa3i3CCtC(4;>h0VjWp z&^8Xsml2LH!4}P0(&#tpMLWY1?ft=v=Eb`)DENQu(~X#HrTZA;F82v)>kB~b&<2TA zu?B2)bQ%P^xFT$Lw;d$7kAlu(kc==g&9gXtO=BJHaVQ+opZIaP4Rq6ge!9vU`7Rpd zHtV^&pWXOVHt+x4cuzlnt#mSQZG)ujB&!;t7)jbuOgSsdYx%BXC>VG)!i>5Vo40yHF_hBqwH!Kx5oQ`5i< z#7I^DY|;Z*&_nq#2)6+k(Wqs4R?i!8Tef-R-Db#UALFR1xo6P$$uLFzQ){1ds_Zeaz&bBO#2tUFf zV^MsY`6g46t>!Ybtd;H>-7D>3Ne>HKy`X8(+}K&gW5Ao061I!kd|s!UmMfSgO_=42 z{b^EmBQsyqZY09GAZlt?LL3LFD-4aeOP>R3JhF5#^+wsv@21%$F$k6{^X_{f z(iBS37-@ugi6#7AnxLJW0HaM9GVN0v4?I&lpeYqfVy&xeR7~{tkzFcB4xRD>0RLBW})X0 zO>{^MWCMtE#=+Eh)K(-k&D*vY0b?(i2ry8nBl7Mw%?1T>u>TMjhq)ftL8JCn6YQV^ zU9t&%nw*o1%a!0kTtFqF!W!%VSXuxpsRNJQ%o31ifOEr#n~?RM0u{Da&lWGd$ffup zUkWK%MhgJq)sI07ST*M+W^&YIBU6yXfn!ruCH{nX>_tS-y9q20LBjx77TA5aViw;< zw(q8lQWGEZ7)ug`pLu z)({WcVGmQ19HWICsN)eRsqR?j5c-fL3BC|UOB|G9$)QgH(|sYJ$Q``Rv)5@!G1m!l zla7i}=*D2hc6R3*^({hKxQlSZ5VeqBQxW{fkr?f8e$@OpIr>-kIZzPYV#z6z?$5;4 zCxx98(UrUYN^tV2mS8EIYiCL4(P5eqri52~tl8jg`+pkhhj>mL2UizrUQxRV=Cr)I zV<_2zyf8h}q_i5(0TP)F#S*5%WeBP&cYlxcZSQ*MM3n@|CG~p08MJ($ywvqdo}Z6p z7mr$Kg}w0 zTiA~ZtDQK)>O#I*2}m&u`BHTv{bV(peEN;kFzN$n>ElcRnJ`Snd-1tMwcsW8FqlhD z01%RCt&!M?jR@-D03$JPQI$(Zso0)bY_?}}CY zwRn`pLyFAmo1C*ha0raME9wD55u6uf-(c>g`nCx8V~WXRb0d}|!BfCg2gy;^CH56f z8miDemyLd_hdmq9Vwk!wCILy(kKP>9*=5TpE$uM2|tr=DO-8$W6x&v$a9hYlmzRtg9A5R@dD)3PCgT6lei9 zMoSX^jhsq3S_8CCX4Z!ZrSMU+K|e^r6D#|#Liv0nbbPVO$Q3^qQX}H$nRwWe4|0gC zSIGgPbts=&fvA-J{7rrE1LT+O%R5EEcQ^-j7NSvPd6YNU(g?Wf(%Y{}nBTN@z`DU4X6^*9JrZQ5<5{fty+xC#@X4>yVHIe^aB zgV<@Yo5P_~zmdWyoa2wJsNyF1O-yJ|v=Oso$+Am-HF@KR2jbG=hnI3X6fP|G00!O! zOdt+M$Eolp#tN7*`3Q7j2BD`$3PUgu-J`>}-I$xeCA`%jQaBpZYIxXC>0Ue-w#>4u zt`@6*Xd*J%{t`P1ba|W%ZMbS+tHGg$=rRqYqAh9oBkm5ND5lT&tpJ+eZ#ur8f_a@J%A=NZj^j^NP&n1S1net%Te4LGe%jXyoB z({4etD?rvRxh`MEO>kd8{%((oJgcl%l@iGR(@EZMwwB!bmVoQ?iF6vk%`89Qk18Lb z!6K0cv{(c;4MUf-c$9v~n@z5(fPoh35$1QBD$Lus?X)^c&|Bsc%E3GI7<9?USB8On zW8Wj|=Vo?@50KmOByJSC&CTgqksI2{)%62vVb1dqR&$_@vgSd@b0DuZC!5v077(8g zN>=Z3#-x<9YqgY4TxezvG>#UcZxth2w>f}qk!>|(#8>>wIE4vAthRf^s+Z|VjX$C} z?P#s+kbRK5;Tu6k1REn;C~B)6^6|6Wd$W!7e9`Qw@se3-QCzh{VN~r^dGUQZ|B;}% z=G0rY4E;};Ot+p5GNM5y`Yh>~ZSoITttradwQKcoDWW?|9E1BwbtJfkRQatO;-fvb zm9fjNkGf#8k5N}GYRwB=zR4|Ne;qVylG?DHt%(+1KwQHoBp4g4MQ)oeE$h^HVKvY; zmEP3dLgfo%>n&Dov?|tav;MR>iXTLriqwU;T=yTO-%OKI2}Cu4IV6@$RpL@jRFNZW zS0`vb3Hr>6$?p;=ClzKitU%kh%x4-|Lh`xS?g3QOPP@tiz~kXLZGn}Co9y0v5B@^y zGfq=r3pyvwUQsh&%<#I^-ow$&C8x0wHJ9$CL3XD#YW@y{W0wHI6j>L{bC%&ds`ZU?0XP9PCI;ylw7ZLKz4?=<94$qeV<6 zFbtdh521FpZKG@~4ouL_z_j+Zsi(;)i%C4TAh}QQ!W=4mN6WxoIp8?|=(8y0&aJ1Jkw*QP! zRw(00X_S}dMSZmR)`%U2zv~4|)gtf`f$0q*?cRv`^l&SE#L%;X<$Y}!9m4tm!5~ZYuW6ZOizD-4l zDjFpb?9nXai(D{uMdtny1JXXcTM5W4WCF^W=9h^rm~EZ#cTSlt zV(1KM3t%ErILO0|POxkJF}Pa+{t3x`9w~K$q)~L5Ak5`2nJ_A2pv4ZLRJtE3FKJTSg79A-L#$t$wj|tVj({ADAza7bE~9Mw0|}XCWUV z26`&0BU8|MQ_D6FgbPDx&Xg4F$;#OiD^#)9NW;UB#8?)HJJDI!JkF+tRqAoGUW;0j zhP$-1dBzV`mno)4E04Tky}iVSMIFgHOIY_)G?0KZ*=3E*_&E@#Yk1Nyl_;L8b*KvS zkEs;3>1_ix{PZospud*&uABP)ktfHsk?ViO^noixQan8LEDz9>{8Q36(CtFF#afAj zXymt|E}>aE0r-3#8#cYsXm1^$?S!lr=9D{odJIu;G*tW*foo5$2;e4cwZO`%5j#v` z>ilZ7k3;`anUrzyBnVA`cVU&TqBKJ3lYe|3ldYIniUuNU$|Mq%9|A&(@Z3dGCd1x& z#w;8N#uR$n84s)Z&O>`HO^=-l{m~>AJX)!E<}`aL>Mh`9_k`KRlwp3BOmM^v2-Z@z z%B{yDsq|h6t&!U_+S-KA)UBv3iWkg+*m*t^O1TsP!y>ej18t|_)k!F4MMYoaCEN^|9|?}; zNsnVuiwuqhk~shxK?wsnXPwUt@(Ew&uB_m*=EFnxL7J|-;Q6P#V9aXvq73qeOHzHG z(how{wB?8~jX*L64~lA6+(b$32|i@&P`Fszo^ysaczxLYBhahcpnetWlAf|kuv3N( znF;)s7Fn`{p?9H(w{i|IPkd%0Tf>maki?~>)UU0vC3Z0vS`j&Wli zMQ{QBUdKIv=~KfwE#GCEJBtH-?XrH-?6ge-bjyI5Be?5ibVv72Q(XQTx`E<~aqb~u z!AXKVGCpSEt7fpLCdZKR7)qOx92Q@6gV5e-SBkAOWs*~Ks^g?h2czW@x5H)_5MKlZ zvKL1!%IRWf0Pc*z#ff=968JH8Yc$kd2+~H=#Z7c$vjLzKjbBOdXHEUSjmJdL_kHO8 z4@vK1pokbDG!~tqmFNL&EMJQ}QZ5|DWQex=N<>x+Z&wHCsipi({I0puB=BON^qfPp zInx)W7@ej5Pt_h4{&bu-H6iW_syeZ~>sd#kEF05cOjv49R!E%=fl&iUN~*0p6yh38 zdXNIWCJl_pabe5Z$>jUZ!NTj4+tI=~Puy1`G$B?tc5!lrXH+olpGRrrL{C1@0$*Y& z%Id4cT4ezOAfZfpteJw>-NllkSegFKy{&$o_9V13kK@+z7;J+Y)>Dtj50Qd;bj6(N z(gej%qe&VE-6bLb{#2krd7XBnPOxoukETBD4m;E(vZopexR8s8h~NA-R^$-II0P4* zA`Y(^sVFt4ot+M50G{2vhWw%~Bn;K-kW8m>VwebD_EUd0JR=PdHwx0}6tBXJeXb>WEG+`^K1Zkur z*?Kb=ciXE8=oD+bwShdnRI}}DR^__};9O}veu&yVvO!8nmdT20<`n#SlPh>0Hdq}O z(N$Np_0pb|0I7XOIw*NR@-f_p+$_)(pjmHBhTSw}Pa;vePrOpqCMvU0z5}7~D?TRA zr2bu1AEJq6?n=?X!uxD|mCdi=VZ?%YfU`>!eL2lJ8vS9l396mv1!ot<%O`NPv{iEk zVZeK5BZ-z+GhbxC9;3UL37d}yI;xz!-U104I5QQ3klSTb=t&e?B{MYa=1qL?$pu!{ zcJLBD6OxaDPw?dsaOVw1`n5v)95l2r(5M+hRVS(gSwc%(AhZD)&Ec4i3z6TU_M^QJ zWZP;&w3$>h07fLW*;%p@p=^pmh6fevq$$ua=j}IvszDmys+`TFLZG1)JK1Bk-OsDF zHhC#c3cr<>JU>Lq18u-@_8$kMUM!s;c%_YVJ}h|31B_~C0g8%8#ke_Cr*#J|a59J5 zLf;Sl4KPTX>?2okIg|FC&}guiwQ}&^aN>EFp?Z(y9P1A&n`?d_8_|1!$qU`+7Cze` zgJgwNh|}iqN=S%ri30{CJH}h)3on6&)YGmA*Sg$VXO0T(_9CWSY>oriS?|&9np_+F z_!R7ayO*@v;o z--vzpHncKa%BZImx4}(tlwAQuj>dgsiYVF@%vmM=3+&n`eTht&(#%+0wCAz|0>n&U$G zd%O{2Y>Olz z!qt>8HBc1ZWwuKFmujAsEOopPo$Z}ZOYSI;DPUppF3|&xB9DnfuoXPD$WQC7dPcng zU?7oq@&b7o>yCHD{EZ(cXnFe$=7!Hj37d`g<4oGNJJE~g#jlvJ^gdud5Wiwx`3aDO z3V0V|Aloz-x50aLS{W&>-GoNPwa9n2RxYW@qUXuWeH+{uVeVWPtguO1gvHOXbrkgB zm`@+Yx_*`Xc{zP!ys`fk3aOs=B7s(6$lqym>xJI@al3=GEG15|RML7S)d(LeJPIW& z|A`gtF^~$i^Zm9Ze4KNiSv(@Y$G4zAF=cQ*IcHIl4S&Y4=>|WM82)A zfqGU)$fSUW!;;qrGr=>+KP_fZeTo%0y>>P^Qs2-$L^Seh$}97abA_CRe?h^g9EH?O zr<+VMQ_3-~K4$)g`55Mw%c{zWWLHf&yb3knU6bdMALQe#%4=FVK>eyzH6H6 zI27<>ew-H{x0KV&1_lI!q(kmGu6J$2U2l&wJYlXdz0e<*C8io76gh%1Y?l5Z1jReT zO4w&BgBZI0i)^O|Q%5s-OsLIs!5AcGg~mUTxs*|NO{9rvcN#PgucPy+Zb2|?@xY`X zw(+@9a~KfF#Yw;!>J#cKCtY%28-askg4ACxU(G>}k#*v-mj1s;Q{{C$kJf)5l4j$k zqI{ugKv0;7QiQJ*Nl{U4z69{Gj$&#=cx0_)4xwr#WtBFvAL|3%E0x7T)e*R1^s#im zeb6`e{gPKtY~}6u*I`kh`EgwVA!XXP^Mbv1@VGUmM`5Rfw-G291jSQ|2#aom6uH2| z=FZ*#!vQNn)oLAJ!t0o3q)WErMFem`o6R`F*#RC=l29!ftkeFX9S5D@Vz1t${M$bc zCN$0!6l8-$A{M6_iXISh?`zB-y?=u`?nW6um@gf3InDO`E>Vr!YAfy7Ul`Kq)|o1N z*cW~>uKM=CoY@HXC}N;Y?8>1eSlIhGnYXO<{AY@}CY>y$qcbt@Ws1!LjL&BpbO#H< zVbp8nBQO$GEP;5lV~iKnwu@9c!aZC+Za=)>c2)njUDKbz*YebSE(!6U>>Xa zVWts6O|n*E-qyS@x%2tcVfK(v$1zu-a;@fbY2{X5DRiG+a}JITd2|1sT34|Jy#Rdd z3da1)Y&x#PCI>7Dwa^2en6!B;QPaxcTF=qU)5_^?4v|NPcnO(Rz?T%{`gPJj zsJrjH6{_u`Uw$rO^{qvBK*KA%Bnj)__PW``Rfd;|Jo-#WzC zR0+AL*d=UfaXkJJb8KTPmDGsH)!HEn&OZMZ^LKiO&>ghGNaIa6T=m&GykG`jLr-mu zs6sNgb>ONlMe}F0nL(?N5C7l)qxp~KA3?(XGb3G0o+j$*5AZuoni!y*eerGP>-95c znZCQ|v>ljRKj(#HD&CI2li*9(LU{D6E9(QAqGgSs##a7DQq|m6%WrMV-^`B9aXQD? z^EhUW(fz6Uhg{SCHOyuHV1Sr{c|i+=cbMO5pE0{B^P!^7cQCi(2JE?8wN(VSRw~q*57EI zO*61IVh-1t5T1ztfwVB-0$(Fb1#Arvua2`4|0e7_9raxbmFOE4T#vnv*6Cs;ZYolU z&zMjIo!!U@Cld5W=D(PKf*{Q4#+7TC(^zJ55KRv>?7{MoWw?v5?Ota-esPI^1dqPcG|3xqz5LT zPT~m={7jP%!DhfK>~}~l=&;b*2*Y21U8V4dI3z-6%d;DMbx6Q zDn!{_09ZW%Osj0QEyhav6 z7d6a!j=j&d4#w{@_mhM`k(VOEG~qTYbWAXZ7SU~ecExJvT}R=esHC-(ffi!L?XbZn z3TSzCHm#Vs%nM}sfQc=KFu+h!HRZ`%4yq&GyGkp*WZd35X3_(y`|RO%~bUwS~vZ(UbGc{%I|WLVEb97esP>9?JT`}0mLT1aU^6H<^o}| z)BH$y`eL|;PlIpbvr2vs6H&vfa){*n5OnJ?wz!51w;B$EjEmK>f0gjoG%qdL^#?xD zprt4H%J(|8PoMH@M`z{A#E<(~ym4&d)FW(E{WD%P@v;2hWCq!L&AaKgre(mbzq(9X zSUvnM(6&yij04o!Q1xN`Xc|q&J;ypwO=-#_QMPCiK<$ZiyOV{9~D1F*|eg%&U z6@Ev9xTxQ3`kz!J3Lhfd04m8*q9_KI4hkv2{@^1LVwrhLCYk6qb|!ria4(QpNP|7< z_9+O);*l@Hi@dv8HfX#|NCjVd>%adA6#2(kFiM!6aJl=d2V>TV^Er`1hRHwuot6a@ z;l-z)Howx_yB|gD?$J=PS{horgrJt#N*-Y$IDzc{dkmFdW=>WC3}@@%;~S^;kuJu> zuy$F_=#0*7cmr>Zm>JE|{|V~TcQNR+J7<>cI>zOcXecIN%9CjxS`q&tRVKdFtiZ86 z?(<~H?38?!tN-d9u7A|`4pFAHu~A#`Pj8$hbw)Fo_7r33!G0YOGFHJXIdNL=PxPNeZ2>sjq=DXmr5qD$M5?F#xH7DLMd_N1p|>R zGE@dS56{hcQqvMlEvrHYIGJPNR#L^LA)kDfW&ColOzO&*?e*>^KIotH;zg7;w&D|F zuo%~3(yz5n4z6&pAMZw9^uk${-B1?kwI{7;x|rU&V@AI!Y{f2!uz0q-uF~!nbCAJU zbxE-wGO;ywBBmD-*q~=3NcoTs^Uo!Vo2KY&?)lLNz;arZu|U!|v;NkCPZHkqyoa&WYROtc+Mddr|!EFkp&S^_2wx^m#C zZeL3<%M1JG1u|%9al=-cQkB>vL$RTdpJem$?#mI%$)pIl+muX?=ock5XY* z-b`9;kbW+gINAn-C1P(HpmHOi)rgOUNLd6j{+lSTrt9S82X|RIdr>m3XVk~{8*5w9 zKTp-YoZ`)btyPm!kSnY8gct{qs`QmaB)u3eYBvWoJ81dIO&zpv54^%dWZ+Sa2y=x; zYe10-Ymkl8KN#JHv$=?~VcqX}-U87=sOVe#AmKgqsMI-E*+=_KQlf+_uF#{UPNDbm zsZ2OXBpTU`7f&nV98j>>Eb@iNmBN|RO6-1?yfN#@in;E6_nR*eau@*~!iqZWn6L-I ztOUsnZ0>Yd7Lsi69_)p*L2AiDFr1do-ciOnof`LkTQ5;+&H zgMXM%G*+r{Z^?6ja0i7K(2XSM6LGX}lfUqNJgonMpJ$7wArw4k6kD@X=3))*JP30$a>f|%E z)OMId6ZOq;v#9wT`F-g68am_;&Hsa?(qNLF+s|q$pbEoexR9h^*u@Nb1w~QvGUrVZ zaZZU6si{OzkNO5GTA$?=Q|Za9qA^4+csiYO$^sP)!J+h&AA4>a7dZQN5If|0Sfv9P z`&>C>ARpVvdHr_^%(VwUHE3zJnDi%|Anvw$9tuqVctyc z4J%ylRu<)F*og6*pv(mv0N;ec2Iy6EIf0*KO|@)tV1%_5^CAg9OaSP&Zf>Pj5B+^Z?>x4da|K0Z8?PRva*b3WF;k7miDK6> zwQ(l|6y>fz{vuoa?FV+!X!BDz@ji*LsQ`_((DSvnki!fGkisiGCx2q>2 znKg_=5Bp6>qNn-3A;mZC>tcRjSs4eMAt?4KnO~)38N4r=oaK1WA&B`plAm00`pFHb2TD47XSkh57W%0Fd&E)dnD_{0Gyzn zK~ylL+|m>F1XjnL_hOrRr-)H`=2>o8`i%KT|94qo0HE-3Okg!Bt;n#^=}^u}MpRCs zLZ~t~D#|gd5CjY{<0*V;Ja`}Z7gR^czvMi|Dvdb+U_%b@o7X8N!5KrT8#2X&(Z}U& z99wkVMpL+SXj>fbIde!&13ao8IA_ge_AmFN8QyO`Q?0zLsGAkP@=z_a1#={#2Zfy@ zQM}Rzh`OE4LVTSg@F-vAiZ9NJGOV8Ec7}A=CMV$BJkxB6>vgkJ8|p+%?g69kd#OH6 z!)6*i!C<5>5?x{xAodaaQG-kC$8iX4r^$#aVp!F|YFeYg72R+zZPr*(8|09YXT-7L ztxOGDZCuk+R@oK8wqfUZy44H(1%aQs&KR!*+5uch^u*aQa=mMwpsrz^n|A^`zyq9R z{DpubC^~pG-bK<07^>&Z{~Wl>etpeq9uTgcoK8rm^t)u~JAh_~@ds%rBfwyD(#w(~ z=1E$#D@$b4Z;_SHisB#lJ`lEjwjRK2CC-|Uzq`@OT9M6J^=bH}L|EsXcH1bQB?5E! zYkH&x2&rvFQ7&OT{26}Yt1)ABnvm{+qM|ncATNrDdpS1?EcMGmQ-F+IGouB^@SlAM ze|RSGv=4>U7;o<1b-r2IHuu-5#FoG89Q&e|@q=B$@L98a^@50n(1D#@H-LO7TA|v3 z;ahtUPJFF%6wBFsg;qFyfY*5&;0VpY%Gw%>N+P-tv1~JlTUy)$m;wRLL{5K(}#Nq(Qe>+9n-5fVc6@l+)b(QCN#Tr;^tDJ{bix}{q;BD?Oe$G^V{hBj|b_T@TSi|LO z_rO)0%shZP09Xxk;-lt&hc@9QT*;v^zlOJxND*|Sr7D9VVDh|j?d}=~uf$0%=r>11 zslJbf1(ij=38xfSf0!Sfg;t-62@uhMBkZ$aIt|{sg{omUZ--+w}g>5s9W zMU9I;L=CPo*VHvGNx;n0n&t~ORxgW0CNBKo}1q@E}u5&PI z>=U-*GK@K=H7sSx?A4b0dn~PvJ4|Vtp2gQ?r+*z9E<-sgJZeq!wAZZNZHPcfm6Bfv zzK1Cl^sBAL{t34Ai-RVP*vo5VvHOchEsu1;^ZBog2HOka%DK9tqO-kzuC(ACG#yfP z%_z`zTt0tUu8Pg+bnqy9?s^EG#l(EpJTk@Wo02ec?6^A^3<;t~Ygte)!u1QwF6}to z-CbhnIcaHbZSZSmBtcq2hY)4QcSNH+EDEjqh~1hTNvp9}DxiMM^XL`~`T$XEdh=S| z?6ML|+pIuHb~DxG&vl15(&}ck1=?U*7DZXUn`Y_m{rpzR7VIJ8oyR8dHfq+wxXfit zn2+D2ntc(Hs3FXvIkiAaBn_rgwP8?yn6rz@c#$_tnc)8tPEg};D`T2oQLdsPYRs}i zVR@DJ^n{CIxd?S_P?T*Vkt_`MIuP18h}S4dn}o;@8x$pb7|wi(3WQ|UkJlWtxm1T) zmngLSHKL2MbWqAMV^MHucgc*IdW@Ke-rNL#+k|i0Ew6F@aNcRhZZ`q|j_dBQqfxKe z7AuYAVQWKNd(|3(E>$-!yYepS%BxkbIv$FKc`+M3bPO;NsQkBqn<(ofY;G!K==U^r44b{(!pGkyIY zM4t;c55fy>*iiO}`RL=OPFo$uMO5bY<&*XJ!~)|RoQP?vbBlBs0d;tU?T<=#9KY+| z$|(RMz=x^^f75QWJ=i3>YOkL)3Db-6T^pOwl`g>VT&rEyq!pm|oM}p~5EZMxm0H6l zL~)dJ+RqluV_YRwy;`{(h`w$=aF^aabjQ$k;FeUG7PTRb+tf9-D z6A*GD%=LcVI?gaZ*+GEExM(hp zlX&?MPl^TuE=|;gCr$h7B7@&)cIkA9^pmSaZxM1bgW)!5TS8G|b@vG}$v>oiD&Jvc zP#0=>Oc=Huf0#4sGPm5s4DHKCCGbH}SQ=d%yHO#XIz@Eh=~NB!#wym9;s>0dd~(&jW%x;59+2ef*4X|l61Q$Z6| zJ(kU5xLV1;(J#S6=;Y}NVUB*&>#iipdQ$7)hU3G=0^JjBY+bzyJ8;eJ0heFP~yvZ9rKW4M;4 zCmOw%PE&O!#bWWer9D_h7R~Jvzq5-D^sDcjSs2nQA_K=D9rYT?YRWbnZT-jOe0+zi zUd0>*j_Ba3D=x~fx$*R&YLK ze)1%UDY7{D2i^q+>M8aRgI@#!=>}+dCx+&a6YRT7UJtCyK63FVP&2bDujcuPt_%}! zemPu8B?<^jF@KNwd{-|)K?8|QwE&uLXAoEv#N{{sJRr<(6M!&$XkF(j7+ z)v6u2#IWMUN@?X>WLducfK{;wnP};5L8A*7NjSb>jvq>#oBG2#y+-<3eJ7m|_r`(W zWh8&|H(@bl+a4zIhp#zd%fE{&Qu>!to{ivduVZC-=jFc4nvbZ#A!|++w4&w1enmE1ZZRUEQYU*w>G&fRZ=38VX1*Czn#!rn;pDmE0 z)BhK8`5nf)fIN&Dwbii<1KL;P&XGvQr{VLqhRVa|AL8KGP)-jKL)(OHUWVeIfDK>0 z8TL`Qhlk%{MUYOI8EOV8$q4_KMe`AEi|>Gqci7XOxBFVgN{n3Ct83^iEMtCx-`6i{ z$+ACO^5fifQBdAa2iL+ea7{UTRgg<+AJwBJE?$a%gVk`E+ePO5QTFWdLhPPIRsRI3 zgCO>r_}93mf+3GghlB}xk!oeCDk9cup;Y6oey-61x=R{07RIk_W13 z?RF1QWk>9#bY5ob?Dmc^*R^z^L3_uAI)!mEwCkypW9mr@1!09!abN=6HLp(INfYtgFJ_TM7IVP>dKBD|`E#xp_NFC#N|qq4O#RDBe^I zHd^j_5S=`l-^G%9vEzw&A> z515*F%S{RDOcNSNH@t0Xya&0=7f6d&bi}zYUFi-NdgK6-2Eg#{U>yB8OixTHZv`%8 z+Fj$F$Gq*GC`~TDb-d6yOW^%G9t9IKI8#H#E^*E3kVvoF!Rc&#A{X3l36wq7ij!uP z#RKvj5a0L>;g&%?a?M1R(9EG{6c6*{gB8eRl!|!x3m|(aEIhmtJ=yLZ}3+2g3IL+IZ_AMH$VRf zgC6fXL#pJdkU|=6!BGBp+=ZFc47-^~r+&BLF8u!(&mEz{x=+1kUVE%gW_CalsvrCg zq;8mXax|5x1D$A|4W$71;hB&L2p^{@TLn+hS0!$L3{=t#>W87~iNqi-j1uvX1zP3h zmAL0FRU<8@x^k<_xp1UitL1Dep1MXiSfQAYTJutA_}A};Ii6ai%b4%J-F%23f%9e) zoN@f2cNa4WDpd1uaZyb$55shiaZzs2rQ~A~KD+ZybLY2k5VTeDNR>MjAVBSy9~rRY zKrU9zot=7?&@vM+nTW&oh@cYXrC6pvzE30IWxs&FvGPpKy{8?GCtW(XKox5t9 z>~(YPVS(85_~spl^F0dVU4S6xG3LIhWeKi+9{1o)7;lbwfqlWA`Ik7pk&J@7oix?K!F@>)Ar8gH5ze%BS*pz&3MDy#JI> zs+r+1NdxMLwS5he1~{<0e$clV(}q)*afD z5LSTxpkJhb3i3tJ86?8XuswbWnQ&opfnYNf*d|TSTM6A0EUr0HQDn^qS!#SnEp%-e z4-_*EW(S1Re2}S&d0NBv{XTP{{f$zdWR?H_jUFi}V6QTSB#?!_<@5^=!bq?2mB*w} z!U@;+FgDBNMswrC6Z5xGwr_G?FfaU$T{0KpabW2Xef%gdQR2GCFMg0sP*qPXQx}L3 z_UH1=9_8S#)vUB-LIZ5k856lU&fF3Mr(^(D{vLYEEtQ!6#=liigNE1OUr-E&V2L8DZSg z-dcVU;5;FKTEXZU!I&CKdB`!s&_KaIAp|dW3Nkd88B*52xKHlhl%ID#|!mv zh3;Y|ag7GbC^QZ&YBLeQ4qgP9-}O14?%xYu7Y{kCL`ai^HeH3;$6MI6os2{Q@s8SI zU1$00DgLgJv^GJZC_7&7UgGud3I!OOSUm$vxNONp!kwrXhLH(ah1wtP!pb4{5J!UW za#FY~`GCqw;3&=FpR!9)UHut^^hQR;YM{%W=IAPfrt-m6i=M_T$i|-j=WBoZ#Ji%}Kd6`rFNLX}Wp`8xVi7(d?-2IMD8KN$a#J61VcYd3~a7 zA@?g=r0M|w|9cq*=?R3-QN=a@Pb6M7GSYGAN7*E65dF^d;+zq@RmyS4R~hM;h{py? zq_DMg#N1~2&u9!GSuJAN9<4HNs_WL}GnQ&_GGKBMK81YiIxO{y>E&}CI3TxE zU*2cS7M_HgUPCRTI~YX`;7SDOLGw|%Y`V>;$5r}A>q!gHzZS&+4XY!#X7Y45fhqFL zQ&8bHHnyv1-@6p3ID;6<#KB5a%bC-HvT(Do0YCc$GLu@?j8k+d#u-Q#<{c#GI&@sc zs^2m{g`O18s#{63%4e7lY(CmbJyNNeHhAn6THxZP2Ulm#GGF=F{Q z?svk@j^mHov`AQ@PoOdzS?kbN5tR5dq*p!EZ?0C2YO%FbJ?C}Nr=o$3`Au{vBd^}G zoG^n?DoR)xfk#;7P+PO!qf(Va9O-msLajP~4U8*Lz{rZKXJihg;UnbW3fJ3lcF1BN zD(WJssXxwon}o}>o%G*t-rrvWU;SI87=Y=sN=d3Ifwfxh=KPj^gQ`~525U4XzSa4VBN4YT=6+0 zk|u$zQvd$^Q)c=OMOFuG=AwB7E#s^v#(3)v$i=!i43H z4k|a%kn1OI>oprE_-t`$IcaYc!{<^qd&|R^VCA82@Vy1bdje7kGaHjV3qExtS}dV8 z7nKFw!}tPONjKwu6QJ~Zw|zZ!=f@VPUhXY42EuW{*bY1_AV#h%%s)rFN$M37KEn!z zezW?jEO`jI7t`QiUPT2<2_&JMG4)76!PZV@1m5sDc{rRKB;jbj&h0)zy=P(633~Vu z829E=lrlN_8*0hPCcSP*4kJAQ_adcxs0PSGWGZjd1Ib%OcpgQ!Pq2YH<_Xu^aNLK{ z-8)#?vf#P#e-9hzXUJ$7n9XJ@1rump=fFfzlvZp-K#M-|kPFO~-4EZwmggi&Umdqj z$)`)s<|&?oqKQuUcWC@?^ISUr2kZw%4nY_W_gvO_$wM{&GYz;DX#x%@Uw@G4{T$Pa z$w@M2jTvb5*yIB&?jzoNY-rs_KwKo20i20ZtE6EJyX4SO$}duW1^ zUSVAz9j%f~AsI_Q11JIu%y5A*Bh$*6G9QBGVirPoi5n9TZZabD^1iOFK47wD#jLRW z$`?fvz2Hk)qRMjNabj?kt9lQ@a8&yI4?{Oie{mEwlUCymK;U($C^paHTy7MLU4Map zaeKMw+*_Abu2C}lFhKmn#M$V~RDOff=Av<{d>&&9Wk1o>&+hj8#jHEvd%w$_Ln#yjhox~gthX#S@~@iCj}toe|giIS-XM9Z&JFBQNv%nNoW|<^An~I&e>Q?92ntF z3|uk|ai8E5P|q=F&Z_$Ww?q7~&(KAw^^t#<33w~gvOhLPX2&M&BL-#&dQ$N@Io1TV8eIP;2T%~7^jYlBMZKuavX$&Iu=b%KiY7GWo#`)Cpe)`qwv6`wWHZ}U{;iU zP&EobeS}MEH?hh*O(u~7+W}bw! z@}~j_@DTLXbG#7xgAN!Jx_Dvh&CoCPaey72ha-7C&B9awv|YJ-2W{cIFa!m1^*kgptug zvm(?}o`;q+5XinO`Qvl`ccBLY*d;s4aUMtGdHTyKFJ*qNK>U@t0}+c8zFY`=M)o>-{diL`osefnT;52 z2F3eIW}BI{a5G^2S)|Q3?Eyf7S;i}}(256`IOiDZ5>qGm3klI~N;@p=-qmqn7Y8?t z`!v(FV5e1p3%IP9jbb4}i}jZ-nOTn#dG){B0eNCcMT-rXfLwfrFZs~(BR1nQMysmw zSN^%G2JS9W#H4%RU#SOCz|vr!4i#IYhjIvF$#4xJm|i>C(1S0P)6hOL`5Xj z|45$xG%(J32Cx45CaaLa0TGy^Rx5772Xik`%r59d6d0L9iG-9!krG!-@ zg%yaaE05^Or-dH1c%gdBUr=v|8&t|QGb+B=L)Woyj#-6|!AJLChb?0dBPiIq4%78T zUW)`1!~e-;ojrZ#_%_4j7@{_@CY7wkuL>oO`jAUBsYJ-{b7!cTq>DuSN* z8xXCSOUkmOgx7Kcvvcq#E{z@Wji`G0T_WN;U2`UT4+D8IQqA^w;TT!Xh{DBuBY z30b4`nPf)H0*xy1nJ?Vstk9ZeDONy9eL)9Q2W|GB&|2iTQ`Tb-4c*6ze3;14{kTTn z3L#dWWh1k?MDrgf5b8(+M>n~;4jmgX=pr9QOFWDgEAlb8Al0QLceR6l)FMSETw9(j zdC@p-{eA3OU}y9%z^`_gEhE|IXu1G)(SG$lyf7nhn@PKP=U2@o>@%8o0CknMAW>WX zH~LeONX?4m#qZ!(goaknp)mVCc55zO-4tsj>l+QE+UR{h(-o%UR_F=YEXP2hyrQT6 z2Kr;=XHF3gn^hzhnc*b+hrdNAg7ehkrq zu2)foZpcstWG|F35i()J4`f&spxMPu0TM(S7iZw59T~)u3!t^4J$sz5B*5ROBE++ z#IS%SAC8iE<>HJvGf37Ld;tv@C!7+p6hpOXpjU{ZROqJ46ms@&wU`ZiSMN%06S zqCtQQ=0PC(>&;10qa867Bq#8xxcHT5$xonbnBU*6L9)L8Ifnr0RqP(W6opfJ%T50ICGZm_|wz-}xK-6pkF~RfE+q z8n!~PaeLVy27?hkm5lx+vB(^5x&x&l>Y}MAw}BwlEia(2=m)1j!vYnpcPa|8J%XG8 zLYh~qeO5xiiguRZe39>kx?9Q?WNtFqG_g&P3nes+**UH(pYo2HpEjqw%j^VC^j7ON zFQGh#9eTRvhT~v8I~Amx!N8}pM4U{T0Dg`iMyBDsMv)Sm#Pm{nvvJTa2UA=g3c(c+O_U_J z{hsfVJc|z?V(gPcB(fIWRKw;zD=Hnu$YCO=B|6MM6E*h*H!onjke50`$uXaM1c^E6 z$)5crqLtMqadY5Qi+rXOGN>Zpp*CHWG|~aP$Dxa^SCElyIjowu+$}Qz#{rAR=4Gs# z-$M{PXz@*0<{lh)({UWqxlWzV$be;EOH~db*Q1=Ayqu)u2ju()_K>gb!pLxx@m>M| z=`9HJ%}6IDkfLeb+5_L?m@}-*HzT2vPuT+pn%{B?3NBc4i zc@0(cCx>&YFXYAi35qV1va7^Wt}<`c@{zET2g|3^;JUTFS(qFhb3tI9EC#hMuqD3* zb?}3^WY#w5-cAqqc6iG&T~H|PC7!ewB&QaAynAPY_|y^7s6PC}tloIbY5(`pW$Z3Q zp*mx{OvNJ*yN%{#)Jn6cOC=mlvt4kNnKaTIBX)eDn-FF$wo^IS8Z`oL_$#lYc|w@b z|7=Z90C0yvkJZL;W6f11yYPX8Dxj{x+EF}Zo~uwgEl-Heppd;+acWr#jm5EffX?@G%N?9%PCS+1qvIXnTvy`>t79 z8%E8+SVj?^_p#?w<+bJ_KQNxV(T?g8ygja8*k6^f_D-GiXNE4)og_`Lu3#-?&U~@r6~;)z?`HZs+#N z6Yw%#SN;(IJOMm57J^Spa!@7GO-`IU03*;6!mN>`6?9OM9Yn6?lDnExrMeya4JIeV zeTy+gb4NDl=o2-rXGm1QbImb;hI~jora@InJVAtnkf=SZWI{HN`nv9Cm?rE!PBu+&(a)14_SYAw*;4f(MotLwzt=j4wR|+7gh$y16vdBg@%AFf zTyLgdadMlXR@n=G9~)XA)&R1p+TFN^7^^z9YpcnBbB@^QG4#wX4lVYoYz6^H7&N+o zL_+4c370YhNtVW-RiM4eMhXB5wHXx3rx$A1ccB&rIKwJuV$-51i)*z+QRX;7n=e!0 zj=Z7Ubfq-GW4Li%}S@p#aI zhe2?#?whQQ8Mq^&s&Z(ag*4KibGVIDc%C9v(FcU78`1TE^srWU|BsX)90nWg$vnGLdz{}fcYsjipb-@isw)BaUfSGa$D)AH+N zA^mO4J%Oyla_bj{-T#**{ZUm;jPC0!FKQmYWG02V7i0|vNibb zEA^0_D-oYRr^0E-=H!uTjD;*GJ3^lATL#R5cw<&TfCEjzN+)N|CQ~@ow+iXY&FMZ9 z{ouiSTDMsvT)1#*^1^k_p2bf)FnfRN2sS4b%#}FE68BHDvq7u4to$e021n`tN7$Q3 zOLEnBo;M;g*38H~GcxnN%$IM=eD772YR{-uOONyz$Otk#@wlRq1EDICD7;uQN7T>KOre8U&gNeN(?C% z1tm?^f(at%GG#dZ65fFmfGX%D%S9Z;6%e@H;AGq!PJq&Mh|i`@=r3D6Z=We0a^mHZ z$@Z5h5^~Jc9)~KD8hP+mkyo6Ycg%}7e42s@g#0X({b6uB2fv}3zyg9xA&g&L^U{VJ zZ)^^dN^1ph?j0arcnBmH`0G69*}mJZxaB7{abd6V>P6!=<)gHK6QFbBNU!bLX9iU3tP|i_F2}!ozgB9R570_pCK+6coehE^ zv`Gh1Vmen&2*;U>Gz5Cb0Me7FS7k5VM(;RNQ9=L_qof@z52KZCg&MK`HNaL^W3R

    *gOJYxR}?F7>aYmCD>%iq-iONB!HGC056!pasX%oK{IP3eDDSqE18+%ZHVqO z>p4v5YCsy(;|?(cXd?$&XvY8!@ zJ0|OcfP+fC_f8h+8}PfV23gtPu{?3WuFN$XTq&*)8hnYq_(1Fo9_Ba$1K=;!`WGD~ zzAn%Sy~_a~=Jh1`3Fa?=2LVamuV*PZ;&)jt@1s3>h8njjch`q-3T`@VZNV;s=wbg| z#yb5p@4g+0zKkpOaQt%^)j;HVG*1s=w~}X8Q4Z@nNDLr|j)GQ-LD*q_igWJ)NJU)W z{n>%}1XoFw(CH%KnT&g)vOH{zZ=najgc>5|6U~t3!ULn|4`V}EpqWD}cIO>2yCC&^ z3nCZjHOEhmGMQELCUYp0*_CNg#Z~kF0G=BluTJj}6a7UX1pcdw>y%09|DT{7SQypP>=vT%EI^V!n=v{mBrl6 z=7DVXE)1iF!*orI(wG*HnXI`FeBNV}TLDp)CWufwyn>NMy~AHRur z@2$CQ6{(LI_e5#JluFhACOdnKm{YS5kL@`Tify&-e1`9I_Dw zutLh*^EDc@1}j3OaHB2U1xm#eLaq>sVLe+D`p_SL@+tGFk#=LaZs+5M&&A>&k}n)9z@yhWw7~9m21(wO6EjPFltxy?~r)K8Oh^4Llnw1_*){vU3&hTZgHRXR`(5O6%S-sG<0 z#`keiqh1MN%4V0D>OPI6JcOlmB@2-eV)3?o!(-Z(*}DLsK%1TUztm%r4Pqv*wY_3I&N4(Upj{6wZ2Pm#dw!!M}F@aOuLiP0UwC-V~D)atIhOy7AQg@!Ni~O&Z zn}t2h^M^V`5_TyIom%PtgQ&r@sxXL}NiRxY<^km7yDGggI9S%|(#hwvd z)6`V4RMZ92yU7BuwS1UXRN6m}{R^4a`}AHK41lPCz|zK}msbH6tWV;NIAHxJ1(h%F z;ZU~+BMh+WPr^!Csxx_M1Ex(sRQx~>xnV=gRLSexxV0|X@Vu%yO=1_z+OgHppEs{> zt(!4odxl4g9^_}}C4gpD_0d1HUWjxRf5KuwI5>|1VL=apEg&uXE*2tO1|Lr+>Dzi! zz&`@tSFpBNML>f6@WT!;`~g&yV&JdhjEuvV@oJNLpzbaLy#i+sOkKmPt&OQY<`XSg z7+aK>GP^JbQ>yfM59+5%ME6l%aVE<*fBseG-lp7boLV}G?x78D*yo{&$Q`WDZ=csU zi-@~U7VP{}Oi$~k}lDp>WFfYITh_nG&N@Rwf0UtW_&gJ?R`9+ z)MISMUu9~b1|ANAm^t#*xY1!b{=b^n$5L{ZH9g7}MO(-|{zpcr*=33@R8}~CcYZe! z_sRCrevPbYK|As01S%#|3&WgxyYTAJ@FMT$NU?I` zTq|dLuapA1tK7EKoJdc5%S7E#F166Dy-u?nkHd6oRWx_T*_~bMQg_eIdrY|i%U0pQ z{GjY-mUCqPD`FDYuTga|z@ zzZ9pvGp43$jv`;gI=H19faH4A4(jR)mn7}ei=Aa~i#u=_m5JZ_4T=`=w3^~)j!u+t= z<36l~pC45UL93U;t%^|9v0%0^-Rk&;m@QT*88@MLRPHssa;;EKevgU>B|ITAeu`gU ztMn65J8+8|_+pqFe+1iq2PQ}p3BD1csiG!6-CCwvireiRiV3s-t^!YtFKCk07E}TNy8Lzb)E8$pB zxjt0%W0wTfEUjCPQSg^uM34!_RGjh9l<+#U4i?)UqLgYSyS$7B0%k~|2(TipLWp9` zIY9y?6N1dymt(0Nh4r6h1G>6vdw{bvF6Fsex8G2+7#vS*=BRKo8l8eUe1>@xp8+S( z{pjoJQoTYAEgGa1y^LZtE8fIKGM%g>G-(POd%`JV7II4)iWC)gM7i z|Dyd&(Yyy{0rkZn#_du^Lucm`H2lLH^f&Zj`5mM|ixf$LWc?@{qp>kkIECRa9urRT zh6TXaX-F>JxRCudE(cgR>D$cxO{R>im`XRSWjunaH)v*M*?I#Qzm6&Sp)*dsR4e$k zO1+e)`)d4ZPJWccvE1)m&n(9N)8vxyIkf+|(> z`ak7kd~|V2DBv-he^?4mQvnoAI0X_W$%Ez)Jy4j0>C;d$bZ?_$2ko7)6tYEn85i=z zG?|Wb$n4)9`*fvsh?Hs%;&7cH#2rpd6g%a`SPP`yl5-T9Cea>kU0Ee{^l4!1v!p7n zaPT};m=*s*4zX7x9IxmHCHAM}Zx5)p9kB)EDEW@WUwS;U9b9PT$EDb##;Ix`vo6Wf zlh?fpG0>81LWMcj9hurb)7dsDGsV~T1=Z?pvKcgA3a4LX8dGeftm{LTTYwxq3P0dZ z4~w9SP$%?(AIl%JRB!Ow*C`&m@to%p8i*8XyUoqbvvA@~$W*!P71mc(ujCZBo{UlM z2Y0(f@g1d5P^25BMI`Ld;^0m&5Y^+<7?m;jTQcY_Dlxph!gasWpZC80F(#%iBzece4eIY z;(}PDTmuKCJj3_FIt%q+7owcfkEF{Hi^i9)4u=)Df)niK%m(r-i{;n~5m+50{dlto zh3MGSB>o94ciLQyo--%#npDdDI5%k4S|LdQloE*vAd$Q6aqw0P8f)s(=&TAXP5a8tr{Gd*;c*T1pLtj5|R z$gWv4SiYF6%o3G{kP>ys^y^g&#JYK=$l`O=e}&bp1GZzBPvLv9{$~*u7JD?y;ouev z-RDupB^F>v7bPpeNqjxh66MU0HQ7EC^FtB)k&l|_G#ZQ444l|_-2VoT`|rYq3jJ2R zNGeGOC?1Jambef2;hlwQntm>Gz`WD!a-1c8?rjM5 zF9}#2Q2!iD;UtjV2XeXZeKX#td+CZzTL~{1)obJOSPPn{4~v{;cbps5Ij(~kJI!?` zq2;e28}9*(?VO>zazO#A8L&su9v_PpwS&_ss=LIgQYBui53TV2%Fd9f9rEgwo{(v# z(F2P=OC==*WdYD!tN;&0EHo`xn5HjM;-~WB^TcI5z(cyQP3GS&@?)1z(D5%Q2WAIB zK`6x|^xr#8Sv|qcM$~dx8{>O{KU=tx12lEMjQLmwWz;=nDjqwe`%&!$My`?L5Ht@K z+&VoTJhy(xbFbZC&&MxDiYz8Z^=DaPXqEBKu9x@U33*B4N8Pv*0zAYm3f@vi1qq?! zBIT)A>GR7(7BpxaNb4jt@UNIp4mw4LlY&3b%toc8>|Dj@@dXwDd~n3>gNL zYGU^HWHBvq$7`BRf`adb=W@B#yU_LAkN&Co)2D7{<}aa!XuMV;0TY}gdZM@v>lHGW zoDmtv)pECpNpzO|Wka#tbJ#Z8C>#_#Z<*$aSW`i68z{lUPN!B9Ue(P=RrJ1YcL|O& zucX)!Zs4#4#!N08fGt22r>6QGaK(>e)G53PR(Nm<9EsHsO)IAyC$m`%6&6ur1O>4| z=NdLOwXerMkh#Howb`hSs7_Kw$6U=^#1f&xTD`I1KqNfcLz`k1w-jfC{cu{|%xF(u^k`McJG@J!7245K=zy2I zgd~nDn)%d=PqlQvYSO(@?Up^9%BeutgH03Q72%Pvgy&?970(2}pg1MPh2FmyC&E+8 zH5NTW&f*J%r!X>kuldC-CddSin| zEe^9DEhE^o!j7t_K{TE?axG{=TSD6t!Ikh4eQZCdlY`R6WU7!9!qeMMGFa=w1Jv+pRUZuUAr%U- z0@SDn>5x~fz6J15phNQCtO zhe97XlNhH{2p;LJR8}g~vgLBITqD12jlq(9 zOk)LNHdUXy1BcRj-d{1N0;0PTCzp_F(lFylhy^@1HEd2ISJcI6S_V&XlvSU(#Ikl_E z#PSG8fY}?r5k%2h0p8{f`Z0mSI+cf6`}6(~dx$lK?kL$^oTF>E?3*&nBW${W*1PFq zfj1QS{T)^diuO%AxLk`f?iN-kufV7JD)FI3fzXgXnh7F3mtt|-`Nu_g^ivk}geN}5 z6g}hfpjL>~P95jwdSHegn4}Ru&4d^J8rOaX#2$yP3bHuBL{p$98-;G!Z*s!m4NQ1) z2kUkmyq0-f#?h{HcpbZg2RSE1TO-3|az_bqnxEF&@8(e?Lz5yS8G2dz)OfC8 zOK!t{Qcz0Q zsV8yrz81U-vB{Jt;RJl!*P5{xv)4=L0{Smj2$tz*Qm06}lq*wR`f1T-{;iP57m0YC z=$PkwN!B=N63Rw<)XigFXx6~)5KOQRW0p{8@-`d4p%{*xEDOj+BT|zZUDnd9M>qlPwHOWrR1YD7E>NK$$#3&uNojbs_x?M>aw9VG%`O_+KeB31!zZixXl0?C_@OP9Y zKrW#}?04Y&63TgqQh6#Y8w79#JC+Xrs$^}JY44h2SEkyxkL(3tK z71lCmc+i2ArW__*<5^@y2L2}zi0PjCwMdtA$Sa|NNC3yC4^3Fui_B5>0K>^w-4XH`K7%?QKCS{B;vQ)~j}F4CjYBvrov~Y>sjZqe2JVteVG^iINeuSqak*0spCWHrm`}T~{|A;HaUT?~ zRPWLBd+2pYH8z6&Hd(0cqDvWNQ>bGJ-&Kz=LnoNKY>kIFy3wdJc&{> zP5qn`wWs>n;=z~bd(y9+@tu>Vw4~?PZ_6Ge^!!xjZu4&sp^wwsHY-fZAG{gU6ORMf znIK{tkdf}5L8Taq6OPg@EkV(ff+q}`PB%xV@NK0_nOgM$91KwXEdGdtP;s482ZMTc zcilzXy&L2n;wBUy_l!p)D(^NAwL8N9yLc83Av$znPXdJqhoKs&6WA!_@SJ8`;<9j` z5p+ieq1u~Q><5@&+I$^%v%$YE-!Kd))6Di79uk)IOW*rPLm)cmZG9_YM_NpGp=il` z5xa$^Dz7uI<8J(4$GaNi-Ub;q{@16%z_-|H|2kSIt&4IYN6$)-bX@wKBEoE%Nb5lW ze!x<~=h*%nuU`eT)MKqe4ER{W8XqAU6+(s_cgk+{!@RFxoy$>bmvgK#*`M!%Tr?R? zSi8WX@-3f3_b3JtDOyj9mV)x97WEst`cWib)Syk2MQ(vKmp(hA4{g|Cn#W!uhHrQX8UUhcEn?ntyc;mzVjeM zwZqQ7-rA*pbYw!JF*qHKmd)}j8R2l%tbvGY%$Aec+LZgGMYM(1A<_{P-WMt=|?#?x;PO_qE#_Uav8{0%^2`c^L!c4>?A3qK??3EsM;>F*+A1RFR4Wp z=5D{t45)b!`+zT@uR=)K`D?LwW%Mq~RjE6)R)^GYVPmB=@ix=g(U}Dj3kgz7voGu; zkrhxZTQVt3#lKUi3LZ4&@ZJ;v#RRay$%diGi#2hu2u~+)Hhb(0wm=(X- z{9sOINN0ftaPC$%{rR!T2{ObBDVcdHU2bS`B$p5~6KiSY^(?=z7s=aeE`K>^PxH8j zMab^?@qpt~Jbsitk`ZeaqX({`FT$5FG=cCis>B$RhOJVZX4mtdd#F4e?)JFHf=F&5 z#cBM|J?xpIiR3KPE(n*%mQyxK8VR26fOPG&YOOg*s1H;Y8iC2fLI)=-*gUl;nzJ>g zg=G3~e#ZRF81EGWr3TXP!Z=+zCv}MPG(D<|eWIR(jZTSz&s)1_ls??WWcEuav}i)(MBhAAdqx!CT_J?*$;`u^(D>MH_2CavaD~^m|+*&rc;lo zp|F)HIOiZ=pD}jEY%vhda6QXG-H5%&mjY}$?{!p*BWR!gym)<^pD|U;ePy_4xy%0K zy)Y*$1)qBBm$QD??d`~cteO3yCA4}^ImXo#kx9+Y4LuGp5)f>M1}b)6?!N>7gt=Dr zNG;WXJppowA@B+KIbcYjRl&M|vlb1YWhxZdfB&mbdVVtF1Idika>}Svdjo_Zpr{&l z&PQ=sZnI)gZWF~3V2V4}9|jo;g*)wgt&lKDrG>Lrp?WdXFrQ>)?`)Zs{7Rf{cd2`Q zjdcArKMg12je^!%l&Ao)HY7rdLExg#kuFlCgB^R9XE3yiu=2xb1V6=ex_6ao(yZE3gwUNXQyn#U2 z%bLlQ>nsOJ8id^x!)tqpgnSDsN_y%O=9}2-7?O-G0)2=+2XK!~m-7t7H zu^;3>-R4&7NlPklASV$rpYIKSlwYa>ex7EH-%@KaOLo8%Ws6 z4i3TwIzgMf%fm41x582!QR54rGf=CB!#9W;tYQ=py(MrYA=v!DG3Sp|=#LYv!sNT2 z3DQS%0(R=u$J

    ps1nsCqSWLCK*=f-pfq_RNvG4ndld(ilYkU@jz|Ew9AQZ?)6ydU$WK9Fpn7zpbM9E-g^gg53qYDGGZ`gwF%VbT#<|uknL>j?} z(nZEu3rgNnCTLM+C|e0wj#j^d5wD#&-A=v5e7Sv0JCr?hm&zl!bwc5l(jpsfdH;?e zDkJr78H;+ED)?sQ(+FRO)$2?jQ5BePq6xo*?U3^Ho)jKYlyRn{y?FGNk@ZF*7ES~N z&p(0|an^HTiTLF~rco$XT5f?YYLDhScW$>mh>8p%^is>CKhfkk7^3|Oez+f_NrNtZS%PT*boF7xGv!vnx*fst^|teho;`-s_Gj%j#+W4D;emWfW$)b-m4`d+BFYOV?k z)inyFVRWUs{6CW#esR=YbB>I33X`x{cyXp&#D^$wSeA(@Nii~~X96-ldCp`n$@r@t zUHfuWazURG@rupF-pF3ZCqKC9*4!ZQ@N-;8E#({~l~@WtEftuh3+rSe+0V2 z)?a#uXf17O^#b}wA_o+yngGm&D$*%Ynm3V4QD1O+yhI+Yx&jxAtEV%8&izE2TvI38 z&tdrGT;(JXK`(0ws`u%DyrWQFEfXqAi2%;<=6(Aq=%^!<@6E$Z|p=I=M-q z*3E}~s7Ap!*1H3`ZsN+s=SDp-a;dd;A~GeLRSe~hVKE<1WIX1mt>AQc8wY0`5#mWb z-zy$8U#4yg_{4H6&{AS82x>|FW@PCWO|8;O$_;&ikDa$cg(qk$K}hkmn9v135B^`k z0f?ES$|A}K8$vCQ=}&chVnaeEOjv-*VhZrwm)leRjW44x$VTc>R z+p0;txIi0`;CiMWRi?ROyBU9!P(;!eh)skK1^_sQwKiF9bcTKQ@(4C^%B5_)Vs?)5 z`QgfQcm~uJvDozeS~Z{u!?1%oh|FpFA7O+34bj5i!0KGAspfI}f>|V;Q~Cmo7HoVL zysP(R!88T6&p$m9Jp(v8;4Y${Y5Jz}Sy)GrzwG*`lsl?y@D%`P?Z;=mXv+7bJQ z1NUkMr=VipWWfATbAors{VZ8YiURi2RU}U9YF*G|sg3I|+{sK| zVP8to1?so*w@`JVy;U_uGa3V(P5ld?em{)O1b#jb<}6i#a~Lgh=EteJn>AIpzDgJ^ z(-t;u0Seu2GW#eQPj{GXC$6{raqKsvxOxk8)8s|a4p@4O8Rs!R%DsQh{5XkQQK=QT ze@#Vn6<^?aMDH`pzt#Lf4H0%@mc?r{T*T(W7LB!cbSn>CjE+A9PMP?NtB8=|=0%SpZfwq^Dm59dO?VPhCDN37ZI?S29q4d+4|N4IY)d-K1`Vb}k5XO~RpJ)u+gRwVEt8=@=W$dE zPN#ggm>UxBi4Sxy-%gVb>|3fo>~3UgD@-2la)-W|S#o15{|W)yUEBGDB%XzDHe#6(b4r%tWjOH>VgzMlBLy z;a3`3Z&}pcVy@^MDFs_YSfswYQa;>2XFg1R5}`Rnbns2byS2D=_;K^tIz8;xPH;wD zrxl^|4J1v!!w*eGNa&q%1%$OEod4i_;X0cjX?0J_E68?^+wJCT`!E~u;lUOPyuB|Q z=H1=PXCdSJx^O9kWhaP;7zG+riMQ&6VX?i9!uqQtDlKN4yX`v`Zt?F6@UI=u>|!|< zp9$=XpojS=c@tqSi+T7y91#b52TS?=M3b4`X1TDRawS)o_x1FR>}z=J_NbsdF=~}+ z+}n1mxoxvw43oX~Ea6h%L-Mnzm?@0B1o;{OLr6)GVg!7xAs^l|>O#d#jGDN`oM>KB zQ#(bKX&*7K2L#_&^9S0e@KkT~Z(KL!f3XF`FbsWkz{`S3z3KOJ<$A7x41ud+F<)6O{3c5XoF?w4iHvZGzif>lz^YV{|~ZOvLh3O6yZtUCTX{;mOh08K4Ela#|=JT5Q_6lmrrg+)+kDSE1Q ztW?;mZNu8GLUqv77rGWf6ZRN3s8Pvibqdaly$N|V@i0=F64Ld##~u^u%X~7 z*7W2;Ico*XF`7-km3h2ImLR`iC)|2e4y(Ao`{X(oqEYDu$cv4d+pRUm;f5b|*WYVC zs_hI-UOtT^C=;KrjfrAzJZ{Sxg#YQfewv6G7F_z0 zp-yI3VNSWVWzX4M&N4*rOs;eZtjHRPvEt)7mt0ct_m04OYfo4?keo3;H!ufCBT+@E z?rxJi5>i2%?0s=3aZ^m8utsSAxeo_u9E1aSA9^Cmq@lBBub&nZUrQEqdq0Hnva+ps>B6kmbR}xVm^!ev6*xB!gbZ>&GqM&3Z!>hUidb3 zmA;0SIzAsYLt3cqi&+AUFSvNd;9+TdCOzAn=~5WH27+;PFn3u~g$!p}y%wVi39@h^ zHO5KAbSJ?c^Q<|L%N>F-bGgJDWP&cm{~hN@G4tj=YYCR%)S^%eAocsobUGfb$R9E{ z=j-e(5v{jkD#I&c`#&=msqo%mb_3v=W|BgqqyRun zQegC-g$5cI7P_G5usO6U^X*kreb|0rPg32M6mm|f!TN7l8~WK&1Z9%7ZDDzL+q(*8 zYAXE*;BRL#$sNe}eS8yx)~Fm$Ufyxs)k3k{{Y*<$&M3dd{*K=W%UP!oXX&`vii z;oG~|3J?=IE3x%hFHw}F{E1Xmp4I? zi^D9a0(1(2r$}})NuZ+uv$%kOkkH!jsTB{}x`)3Wk3xRSrS%z>R)C&lbi5x&bs*^$Z3@K9ujB=owORyK$`SYoTC zy&pz|sJ4$D0CXy?n3?CegG@vrGrVc^uG~{C6{9UP()5p+rVT;m+ij3LR?IE2RYX;3 z&m3-%0LBPeoD-(RzHcok1Pvq?zh=qKcVEZ0ny|4UJ@O)wOZlZ-!Hk>&Jp(yYO@a$^ zG(El6KmjinFRHdqL1m&O;o}g7%@+&Nu=v9(nR4l9(L9qGm6pr-ex*GMucpGSlwc2-(FgWyRSTu)XH(A)o#Xx@(9%j_R%rQj@rZc z8COcnxsDb9oZ+N?IUwWYuoKC@}ILx9!FJmnwonrt{O!9uL(h=L?RpxdiyV;`SyHr#Ntg=`#^6+58F zh>|Mt5ioz#6Xwnuaa@>i!4iQQ*a;#pAwkQ)+A%*$v;Z~wh&3`hVVnv(RSB}SZAsr3 zma4;UPkhiJQk3{*N_eV2t@8Z8!3Lpf+`bs(RB38Wnn=#1ZBvaY9_L#0?PSV3fI3^d zaECe8-Ib5ZQPM#>vc;4SN7;ZnJc_<4r0$_f+=vYWmRcVb2{Hh2!M zn+sqne(50je}P{Uj_WM9&bJr1$6T?pvyk6Q0>7!RydUyh&m+jk`Ds)8);}S4paK(^ z%N0Pq-K*5vlTEXG+y*GsaJbLQmcz#S+vS#HTt1pu{X>TA9%x(_4@*1(Hto35712v^ zZ)Yeb=Q($kXa%`g{ma8ukG(FNj}&|==c8_6_~YC76?#%xa}~bp8~1=4tP(Z0!6aVZ z`Oolpfnj*j(}FSydr|Dy9y50|YQ_9$J5z@$ug$NJiTajqwidaCoA=RdF^{@a9Vf-K zejSEXossX?%r5~6h+&fplvn_i)+*VnJ)mYD31p{PMou}Zv?G~MMDP~6Hv&z94U{Tz zjVE{53D_dIWEAB_-m{!Y?dhC1#Mi6c;UYQr%{i!P*bCIO<09uwua8kfjB&u>tkcf{$T=N2L;B zAhg%Wd9N_HQ~ocVUdN;X0Nd zwd46eko66AvMlwc7l3Q}O$qr+EPx3(naVP_n2emeh;x7GxH*nKW8s@Z#__UQ$y8cP z6>p=|m_((GRxLlw6@zEBo*i?QEA^KUx>)Yo)pDU2<$BKnR7f{EeG8r_a>dl*_sB{W z1SG|3BQ6%&{aI$C)|cYj!nSb8>Em!YDs{@$%9G~qZmCKGY_up=vGl>rO5JSg&vn5| zz(Dp;*JuF%5;f~& zv5HNbvsqIko@fHPXxPYFSt4c42B;vJsuBUJ7@^73?JNpb-pQ_DQ#*siG1#$v!_Eq#HCPjy^TYGO zaRAj5oxhl+_l!kyd3Ml>eQL(#i3@m z;^YqhDKH-eEP0x>=qYn|r(P^zGqOR86e>o#2bkNT_SNE2IFylz3sb$ac;=jNIF)K) z0|pa{R{+7~dIc^m#`SqHnyzY^uezI*vG&rYm%C*9%IVPGy@NQPN?cy0?>ejGe4%(7 zMLSJv39rzbayeXEL4Hywv`^ypI|l=iV2|Z|nqaT&KAQCY1`<1I#csLgbsEKbL}GLt zm+)ikr9k=;5y8<1GAejprY|C)Gqg#e!#t6YpiW!4AdyK&P2qPo$z(%{q<#OIDj+XF zSfTd&=4_w^m=qruv(6gePGFv??{m=X<0Zg#omw0>n$2Dz-fPZw_s8LG;(g3;TcJ8l zj+?D8-+hph>h02HG)d@JKO#YtnsKS{&S8;W&Xgi8RO9BhYs?MXx>3|w=S)Y@i2F@c zt%p1@L&}%C?y5RfR;IZp&5hk`Sm~=hU|ZGL_V1%HF=g6_j_SmHmZaCO zG@K5JO?WE;w=>9)ndxF1$8pB2(h4A1SBc^nm8Aq z+|T@uV^p)DcC7K}wo0%}ScsSmhlH5kf(Ghh4`(hnkL6t4`cZy06AN@PENd^ANu}sG{nWIu#@s*OyRpVjp5l9% zL6pbK**mX)Bt3#8U2FrfLOF0iLSf)-xS1Sx2`*dHTlwGlECWfBK;trybC zHZ*%P{u*AN>xkY;ln+!U+Q_9QAX=49YZL*w;#Rt1P^zHpj7vk6`En4@4d*S;QInUC;*=>9%07ogoPZA;LOXN>k8#!e!Q7C50FaR$~!wKVcNdaBqw_mG2P@V z!teciDlB~szuEWe9}5}eodKBV3(yNxxAJ-s4^$AOhP>~BOngZ8gipnZ8Fs>M^j@RU z9F;2QBU%||izJFwaXTQ=Q524%A8xVDAtGkONI`=Q+Aqc^`&=xvn8-KWh1 z9oo#rq~b@V_y^2AgJLCGW&n+ht0)s*^ zL>CICMtS=dTCAZ^VFRS>XlF)Qq<{@0{P_Fg=uq?Izg-HGZl?aZak046ylq@tAs1}N z$oE$>Ka1^Q0SPE?#9mS4l33f@Mp=i=RwbY8Fh5?aZy@0HVy_eT%Km=8*$lElr{&`X zq)09^!lFlSgoTQIn#`o-;Vhn~@X-ZuF2X+V{vu(#_wjg^($4onX)8H*niH+P)f^q6 z$7Zn8FYoT2GIxEBZE-a_m=L-8Fl+?cGgL-2OJTL#A75@RTWaS^b$V@RM6w>VuQg^g zinxBMz879Kx{I}e6$9&LW%MjB?_~dDF3N<=4|kRQD&Kbp)CxVXw%NJ#4IEaM-#xtb z4s!?P#we<9yVc=4^t6q=oU50D$Jo0sn8$oK*UWDi?3|q=!W^c+u}8u1TK{Ul<_}Sq zM;K*djRX`Av={yD5HGOrbOy>Uh;#yqJ!U23T7etQr%aq%MZR*b0&CKUgl%pYE4OD@ zFy=d`=7k#rCK>L<4NeSUkfmlq6uBR3j@PI_%w{H|--j?L1l}t&Yp*ePRV#%OJ&4sI zSZV+pnYcCT+hfQp36@fsRvQQN)qEP`{!hpzLk22uX3b#yEEDw4%#tEiK{H(dG%>iv zJV^P$)@P^@;(8n5qWkh$LhZ=*x{)vw>f^FRBXOe>+>5!goyS`{bI%HOFE=-^Jj<_cE)%$Nse)ICnuc$*`nd8Uy)sF87ji5Dfh-wN zE!YO|QM#l|M204WNcE~tTZYoSGo8hf!UZ^5-A1d}1yM)^C1&(z7rrB-x@>H&Mfgiua+W<6_oej9h$UqvyIR8q zo}so;&9nlya22HVRGEYZB<#Ah3Y0~6*KoQhV)xr<)31ZRLzwdOd1EfJ@D=xk9s)!Q z@f;WKwYyHaAbu&P@6|)*_F>?)mR5J|WRhf!N9Frg=2NyH_iXY40`|{$7OR%5-?K~Bw}umr4uR6czN;S-~v~G zx(Qnxvo&$dRN`wfq#jcq)vxVBTN4r;N6o1fw$g*@(o)6T;Wf*{IPBIMU3|c?+^;d# zU)Os%Wd|FL(yk^gX`jOMq9$E7hb*w9#jQwIj#{rI`BHQrwusZhPoeH~$5$%FxLT>! z*vE|XRJ6Kl7?n$tQPrGX_LJUjGvJMzhMUaTOwx+G{tKXg0X{iL)ayU#MVg|N5O3H- zW>?BCscfg~qVueS>Ozo`Cf9%gbO0#WJwnIFgugiOho;d6)ePiucrAGj`3B`)D}!Rx zEhim6?j)gK>9Q6Ym>>${-bdSxllK%I!VFLg?!W>sl;4Itp#C9p4kgEK9913$Bb8@$ zobkY9PWC7d*Q^xl6}Ch=rP}V5z^#~DYUO-kOxSy7fIE>2iCIt*E#KbRU{yh^HCjS( zw6_xUmg;N^EkXc&(E-dYDZ5JqnwAxSk#|808k>tePQn_^mzX9m*6tD^zUMKNMJpe= zH(^AF<4mwdT40nNQh`!aApSw$&l44>z{^}KPY-JNg5(WK>Y7p%waDTDLF~?XnI75M z%S0P!)dhY}`eYEZ+y2wd!G@n98TDV5*g1)-Zh`9fWRqZt=4dqGxUDKBC=~ctje<^s z8ziPN1g;UbnCq32UwOpbP93p=Cv~#$Mr8B(`oq+UE^D<4N#y5MzeB5ErpZ+JNRpZ4 z1#!9fwIl~Toj-@9fCWEk&cG%7Gy!{{SW9XtpBbE!T1R>{ne7pP{2~Bq-oSc8@usik zS)gJmlLzNuD_v8|^y_&707#e!*u>1W#&o{i^eHG!Q3C7{a;kcWm_k9i;mCYszBKdv z@&C`)n+8jgUH5%AGb{I{_RQMezEtmfSN3$z^mNa@VfGyZU>3{_2Ky=!1Vs=eNQk?* znF0ZVG+|O=&JQt~H;g=L2RW`z{t5CxOAEYY+n%cLCk?|-xE^_vE$dGlV^ ztIDdE_uO;NJ?sBSp2FEDbsi#LBwQxuF^YS_Ao#uJxge@1twEWk*&X~be-^tZ$Q1TF zYkayhK#j#G(&`QK%p{}fCO9IyQE`v|l?cN(q{Sph_05{aN|&XYD5ondLoG?LI5}g7 z(TUuXZR95x8e#*TrQYrwHo-|c&whsQy^yE^e31Y!HToQXm_JA4D+I<4nTz`&NC`Ze z*q?XVM?n4LS@J&fbd?qnl4Am-;4jgH8k@wKp?hLiD)yCqx#23Wc1L@|YUL21Ja`+j&3rMZ&(}du* zE|jSHX|ms)Jx?7{6OB@)<(gK?5>|`QZNrn6F)LPL_k_K$=J~$*BG3i<4GAo_LIsim z#QFGCZeGEHj*H)Z%P}O^Puafrum)mi#+kc=5N(*IE;(BnaQc^y%k3|(d`F*33bqSC zoX&?GhD<_`7Vn)J;YF{XKh2Z_ck>htD@E}M^K8FkXc%xO1S}6$^cJ4Nx38#C+7>`iLV{VR`W1*5quFwPC+O-x>vrIMH5q<0hgp6+||FTX8E%&f3 zHf>$Dx9oM*O^C$eM!z`w~h6SnBM-C^nn;z*}9J&S8$KQBIMUf${!$u7+RJZodsam*~q ziCJtH{r=uNiK1_S%IR)fn@-WLZxBI#P_1vx{T|%$(pY6thqg@*53NxPJa_{{D67(* zUgaDy{V0E*vbAP=&zSHQ>{Uuh8D^Z~8@Mb5bFPJrCeI@E$K+<153{WXwlMqW#WvYRz6Ak?W#*lq<5!z4<-l=wjVH042xm14ua&86FfTE z^npN0vu)nSh}nhuSR?D z7szmK>_0%_WYFCylJTU3?z_Vryuv(Vo^;4&W3T67Hccp3Fx^}*1O`UmGX5)TPL_PM zecyV(8OWac;Wy` zvJFNS>y)qiM|||EznI;ILB+UYO-U|aSn7v2x2m~*E#YqN2tH8@kJOUU7Upefz38F0NDzLqZlXsXqcSljD!$AT{ zzWqAVw7W~ne3&!tz;9=C zpE;h4d;0<7f@ZVz9WsjEkwKfL^b>eHKt<7EL*yx97L3YCiZly0k}X!)IBRU#2e(^! z`YZC^q^u~$5G>BRIlJ49DJS*wasc)%j@h8AurnWFfPbXw*?L-e^oDt1k`0pe6THi& z{cxCz;a#Zlp6H=^W4+FiA}!;5C+coylyFRn9A-nP-N>KLNs6Q? z`CDlpk%L8U^UE-bn2EYGy0xKE%fGMR8?3*hxg-eBK6fnb&rY4(NRr_^sV=OmMeV7Q zf~0o56+SvW9tXnvOl-#e8^m#~J@IXns1H%3;c8LmfLAJBuHPoWBEddGR*zw{^8yrf-UNW^Ota*1H?>x~t%A=ND4w;o%Jooi2e zer1-ZnN2pbh03r$BMMyNbXUh!#OGd@8 zi+IVfh(MfJ5z`KUE9Jb|XRHpXP{t%VE)|fY={j)PL&8|aLv$SeP(?F(C!Yj30zYT= zlpbf*nkVu#{*-*jC0oyfs#&adlNGV-dQmN^<>|XTspKbW(Y5sSfhNuHD0PBMbl&McTc!lfR4JELfmQ{|Ls%8kSa) z&ytN_LdJ>n0TRaAr)h!d|0AHAe1s%Vr+BWs)Gv=)>To=dy0WvV1zj+#aONhbXzA!| zZH_V`rq2!g6i>=zQ6B0~IH|r#_sBl^Ui=%Y(^*>;zU^!}Sat)FSC2Y7gQmh=Ce1>AR)lV&GG1H);=22jzzSkHLWyk z>r?sOE~w^i|MG6TdLL!|z`}40%0Uvr@bdr_GE)ZJzR)}oXLq0lE==Rj_C4kKT<{Ye6s%Q%4!<7NS{Y&nN<*~ikdwf^O$`8?oA7OyYhg+*v3TMT}% z(a@t_RF)em4#?mmW}L+na1Wez4X7Ih`pg#ZQGBX)TC+(75aW=FK`^>}f|wao4P(DG zqdO#V@(hVle1KV5opCtjVleV7V_d$(w2NOH&CXDe#z&v(cY7{<$j2DzNev$QH0hZK z6|WzM9?1-M{2~zP6hz~Is6V$i1_q@4Uh^0*bKPAvwqdW*@RvlRJ=11F9kaQh&VRxd zxK3a2(-aE4_l8cuTCrQdsH?iJtXkw}LmnFwfga-e)z5}DBA6%%70XKGgGd$9VZ&_m zGA!r3rCPMt?TNr)F6R+kJu+v1OWhu}QGm1^qdo>eZBpSFF_j*(2AHf6{LLBDluD37TBoff72l0%S%1m=+-5+KL7E83I!#l8 zVk+IyggQ9C1><_4rJ6^IZ0KyCG+piu?EO3lJCM2MeeC7EZhzFB{)M2y3GaY!DH7;@15q{ zvD7`0zGB>C+^93IZbgsz0IdLOcRFgH9bCk05ymdD^)LPbWq~S|bj_KOm*=#7oHO0A z)2pZ^)WAN92*9cXHh%j&{z{L^JPkWi6+dr(Vs*u2`gI z?72av) zf?m)lKO~wW4(6o&RMMt!lQ>~SPS0^tatDnjQ#P5AkL}$ctO${XJLo7Sx1U2)HCikW zN@6{OZklhOa@GgCREFS?7Nx?m!i9;j))dc^&vBY~@WFY0urVdetL9Cftr6CRgj3(v zY@-?m;nXV&`nbs;u{4fuWkP#QIQkI!Fsa&!ytuC*UECEeJ8O@(;g*W zuh{%b<2X_+fgdHk)t(rdwJ9@*F(k8PnyU5d%)|Y z8qwMll}*&k?1OaePsXchs;CgWCpNP%FfE?Y7mUBu|~ndnmPWL%izwm2I=<2B0=`cg`_}WuPsn+za;d_Vz!1+B{ujef{Hi8})&+ zqhxajb(Wl#^Sgc~?kon^e@QaMyHTK|H?D5FMe3$B4Q?gjcu4KY1Sj)ZYOvIVK=_LK zh&&$-H!ho7H_JTh6Bn}Qhj7xqfs6^sKsdwJqg>uLGIfCO(HM_*qk=i2#NrRD5v`eT zep)H4I3u{i9w8y?)|v5))Rc&5Q)CmeDC8L8%qb3OOY&zifw%HBz$b0OKnW+-?H;p zmoXsL)u=y*2dfALxKbSW6cj%E=H*uKBz2RDk)lCttti;GbMJD%8bBQY9gIu z0eZ)MbInVxK@ydBlE%fJOc*QXF_w=p9ab<_k$0eDF(PQx0j=^J*MDWWIak3eUH(76 z0a;Nuv0r|#3A$h(gN$s>rn6VfqkwcVnR^RjIQ)smsdl4cfI{~CZL%Yjc&ldNBzjnx zn*Rd|oNH=>w9EEeDTTuveR!QbW{EXevRqUjEMK&fy221?ED?EI!9TbcuD+i=2gjfq zMmE{PILUM^qmcGS6rnV?u-(oMhktgmsq~il(H%~(iK;m&b(nxfjIA-**!~A>G(Gji zqetNxDro-0wn*#GRDv}<#P-a)}gb4pe;O-Fp z=0$1jKe2is=f>`}($cW`(kKY)TBfOfv%Al7OT=LQH`B>7gsz&e_^Nqx@YCdcfREDY znfU$@^T}e2oHJE@dl$!&W(HDK;ax+9?jkup6+^KyosDyX*vM1|#wH8G@kzj;U~Ol5 zvK<|*s_#SJu+=eXFEXOE$<9u|@*Zd0P@ORWc1Y3fbi2ui8EY8=yswe4%Q`ckBaVy> zlcRfKSnb@7Q47AvnSQUk4Fsk2PX5fIW?VsN6)_a+BPLZ27!jg?v zL{gM(0goY6P_mq(I*Ltf468V#k8@yH&vMxO0^bYcobm#4y*&VYlqSPdqZ|sr3(B#R zd=jqx0cCd7@3$@xA^kG%Lr=tsPPq{{win%<9f`br5S{WR5xU!4kDtmlVzEe4)`eIAbg4&fX?REnKAEs z9CH61!G*SY4xJCb=EQoR8G)9wMfGwMa6)C0>gE@sRSd{Uu;wPRx70VMKK8dDk+2ot zmO10rVN1Sr-`c!+!=-kicDJ}C$`|?%)U#dUj~?Jca^Fk-vukJ`Yc&U4x!SL?**2{P)~mHY`~0ktX{z_A zw@`bvL$VXCk{8Y6ImeXz5Jf=5M00Id=5+Xn%I9=Fx*v@@G~nXB2r}-R?;o(0HEIha zE#XP7*r_Ehy))uzjk$Okr0~bqCIOGZW_&fL37a5aa(KJ)p}c8 z-G>nnUWA}G!&$JavmX-&lzdh8^cg_ojl{8zEftKR@VC2)rMV6}c71Xx3s0{j50i6IeqwSr_n5``u_yc4s2?Qxxb0KN)6LK2 zTb;H8a9}d~d(OlGh=V5ZR_5$%;$t%-3Iz`&5V5G%bcRUluR|`ikW^8dx$76rVltvZ zTd6MjX#EGvxLdZucz4_aGI<;&Umi$o;z)RcWt|Me;oDOtro@1LpbQ#h{c}~`pEjJq-^G3zDX^^8r-f{T(J&*pai7P59#tbqJ@4yO;q5M zQLNl>wi3}jEV))c-Xr{dTM%7iWzq?8hD}NVa5Mib|_*v(A?;WB2GwYk&rs)pq}fB7EP z*HdqIPKs)jKhN^d0}gf`Dr}&D@FtsnQ)1QvFfsV6ZcMAkxUy`dorQ+l3ypP~W&3}j2P}O2S?HAi-zqMaW_G3xB)IH!5wqY3K_%dgSvY4 zB(n{j?GtqF6vU|8Kvw(V{=RNUcZ4k@B!3&txUm}tJ0a^pi&g>EjVEjVV>|1m?CA`J zNFkT~{dbsaHnyY^*-gXb3#$a%t)%0HcqwAKENw^A_6{4usE~jx1AI!V5ulZD9aSE9 zzs~w(t}2>#$$S~mTt3=NL$|$&|K}71z!{@z!u$mpk+6Rh>8?C{HUeuHyZxNhI12*!T!Z!(hbicXqT1UhAJj0$0r47{w*;{C zfPd;bsL7^C_(fcC)%ZE4g|l#O{26m)#wZmUd47gl$iT=xJG@kHo6Z^F-V<_3z;ZwS z3;)9W3r+LHI3l`g2M^_pLj@4$0hemRA|A~M_U!a?l=K;nbjINzFkHWiLVlf^V)gMY zBXre`8?Ln5+TpqQ7`0>tm`&8}YwHhfs1#Mj|IKTQ6I*C3#?>{R$lUjLjoaFZ-x@Bq!OQd0WriH9fjeRaS%-rL(f}+E%FQcORT8 zEcXVZi?JI?J;bt{j!*=@gdNk>6@=KACClm;BaMyZtVat;g4M_HkhxG^0)_)XO*mtX zj+k44VY}bF^LywE-hj3D055Wx2<5qtj1!kJnXTW)DzJ)3F93x##Rhn%84shb+OMvg zs~cq5sx_W#!vTcx_y%q#3_~fwUO00iCj(5KbqdAoO&$$!`^f}yIK3z50SFaE}aYQD|YFXn0g;gT%yUf zmn-fTX&zZ1eR+a6<~UE9OQW-z?}j5n7ahrcCi^H!jeX#pcy@Q#zMm!=E_usb7*9Z4 ztY#P+j9cMg4c8dR5sp2x*NQ3kG{b&}pe>!QJBmij=^%6>pJN9!pd|5WgmqogQ{ev5 zZw8TDEiiREW02z}PuO=x^a;&XAxbzGpbm+eGldrP*s$8z^iZsW9Zc_g>^Gx0+iqqOS z&Ff3UF|duA>@OuiId7tE53%sT{Pfh@oke2YS#L1RWuaE92~bURL%??!yni8-MG3KkdzfwX9Z z;Xq@*+9+@>F@s@tlrkx_He;5<6H(qHyEe{=s@~#U<+tUpwUnPH;e9&R#&&g zU*fF+c8GKM_K2cb{9x0YEk7VwE#6@Btyc~mMG5G5@VaOtFCMQ~9@^4967I5)axj!@=6eFL|NR>sPdY7mTQPNH7 zDUvpk+9-5)k8IpWVSt)thzd}D*rH=%?;5EabxPpyopjlB4rdxTd3ogLIjH3f{&er) zPb$K34gy#;G6?%=pTiu7myA0zpw)PeNY+-c#irGBjW4fOSs@>&Rr>>QNX5|Ik!R z-P@@BVrWxMmE(z4G zxJm4CiAskUH9%-rD6U~-Ug(&%^R-saSS-Q2yqhYD{Gv@qj+{J9y1J5w=l8t=Qk94#Aw>BDv#4J;u1=BXCrC{!Hhr?2aaqpsw0x?#g@d zF2CL9#>`{e?T==I(F!_7?eZI%zzAX$s3(%>xkd$xg+lSu!oHu+nTM8HLTdLRPt)KJ zx6A*bxEI^tc6z|Bv2_^5fj@DHZS`PQKwQHt#1Zn_Wa{A;!r4HkM(q;l8@Ni8L`l48QU*DGPMq-)L{ zkqQyArifH*L#>-!Wkf9$G3!$QcXsgdds1`i=lDU6(iYGFgZ8?U!7b;UkZMC(v@*X; zF(#PMpu|X!ra5V^{}E`q`%klSz@A&3_Al#rK}`~27sw77dqDlo&Th}y-MYVYfGy0g z}R;6_sThp~{;1SeZ7AZI^*nkuJ{(E4L=@-J47w_$|61_)9sc3N$#!L*nerL+W>g zc^wH)-Yt`877Fv1GjqaBxH4{?<|B9WHr`Gv?H3qGK}&O8-f*7o_wePLIyOEwW+qM- zgCkCE=~D`A<=0Ax0wxitYG7dCZIr<6dYW=?yOey*~ z@2S`x_QA?5|JK^Ld3&3ZD^-(0gf6T{1BM=!A`F5;eG(xd3T4nH{M6i|t{V|!bI-UG zV8dPHu|yO=yD<8YQ_8$SIBipjva$5k@mq@l9{`jGHL=#GWmIp#d&qOxa^U7?WwuZY z1M@hwJ8csmhv7a(G@SF33YBgb+(_!DlGrT<1By3Rcu8+soffh#Rs(m|Whm;vjV!S_ z^T=n2ZI=|}3TOeJ2K51RB8w{qwd85|x?#)Z+eGC0yDCs|k244uG{Jq_Yvek6ey?&S zy$$n7FvdlKn$3}y#DUM)C>lTmW&;9ky0!pTJhY+28+Glsp~W7Aw26`Hh$6hw3@7Ay&_50OqZ zpms?o124ft`_S96k%-eAkxK@XUJ(821M)#~EA17e*4DhS8F(mTEW8KJ6Lk4FOiR;< zRV(JQj{Joa%`g<>z+uiFYMU9HuFB@=u<-GSu&W6$fEH5`4B0YR)0TBd!*vRA({?)g ziFMB-e;@rrKte!S?Gm>q_cLG+-&FjA4q>z)Pdzkqx>#A)-Ma=*uL^ClbgjDal)jIxclDRO%4Z>R)A7FU|k65>C{ zZ)nnr)HutuxPB5$#ZND=+H;+2#uaV0QyJWPaefj;tP zEi>v6YV=z1=M*&-jVKS%!C3{T)AALXRWn95wswzwdSeq?K27)h@4g2_ILrrK>~L5w z3y5M+s422zADnHfRa|#{x?t*?-wwU>9ubdNcVMluKf|Z{8iwo{ycA8GuzsB-kf?>6 zEy>dyiB`A{bBmR&vO>KD4DFJUZDJ9^bT z+8HGI{&90xg71@pf|q_B)8SrLuVpq9HNFn3g1N%lqzG>8c3sQy(mETRE0aJ_5lm7aQAPehG?#qz%tH=`N7BmM09nNGpvuE875CsT1TD@o zni@JDnEMh808q;x7*jJv*m+OEYH%a?6nMpY`xo3`?5Izv5d}Y@N?~L!o$v-jYDx3X zI^oILR%abRI)YkQOdO6QYE0u0h`e{?NfK|3TBj*M8+292Cf34ik75bbXJ_s(2J=Mq z%1zJc>-51vDM+w@Hrmmpid`vLo-OMIikW{atD>QrIHGh|BImDtw0^;~aZ zj^q_I0Hs*e_P0VdKMDc82Pb0$-X>`q3g|Rang;Tni`_K-ED0~nd)gy(C6{8RQP17! z1IG!?;n5%}w&X*)KCtRyJHRuzcw*EYrk_MiiLV4v_KJD3lTZha@XzHgiAlLhR-!Qg zMa40z&VWCo4*X4C6jtf|%PihPloJ80NLhN>#}G>lCq8Q!Z<*79QuREn#GX|>5BNoP zJ@4n?DOxfi3V*u^i2F7y_OqmSl=6Oz8*5Xpq;L{t3b5pqvZJ46MB=U-7v~;EN)YjK z23Sq^(g|U{!nuNd*@OUQn1QGH6mjJ`)6+FZ^06o=TCG>j<4M<{`;+s0Ds15TYIomj zz1%h4;F`I#6$HbV&xQ_FQB7B;rq?N_wwm577FjNtWy~8fWa*8piBINQbjY{XuJ66` z$nn1*q3HP1xkk3t@V4>p}C1dFU|=JWXz1$J0B<_g6@+Y1=w1t_Ocj zqjoWvUNDP|A=uff+V7cXXz8BgL(7fU7t+wO((p~ZD`j2nZRy5V*2E1Z!hJRJVOcud z=YE$mp#9S#BuWyMeVHA4?LL@8!x!%4T4xyVIHfZwDF`6Qt9`>f zJZz=$@jck9na1<)k#ma)QrCw#MD&0UYRCg!So=bRtSjkGk*2X?tqN^S4*P_NV}${Z z;caE34tP@7ga?=lP$ME{JV!9vSJL$I02JUole^T7Xum3HZ}uo98&U)d z(Wp@bmO~n%9eM(>x{17HEn?OcuQWu3!atGSXattcb&EL)uKSn*A^6Cf zW;WWm*WAB0;y`GPPJnsqXYtE;i*2Hetvw|fnj#f1f!V6*wnUT9cp~Tl2jT>6fg2HX zl5P7Z*kx}S+3q@xZ(6SyN`hn!H2Z_4LjX=#86xn_+lgg$kPeULZSWj)w!GCy;M+d_ z{VZmcUSW_1<~BFI(_HaR%6$a%0<3tvXmc{0Q8E~%dlXC^G3$?Z4egcS zg_1gq0S|?cYlc}7NX?k~;jLxZ60I~ezr#zSBLs?dR0HHfV=gsfI%}OAW!E#i%p&1X z?O_E_-D6Hp2~Wl8R0l4pFmRD#s)V8y1||^NRl$v~bBq zS|+a5(TmjVv3gvpRkP5H#E$RILgVGbZMrbc423oXDQwK_k!%vW6V2!BpWYzS+>bDg zd2^l+OD=Nz1)E;nj-5u>K%lLQzV3SF;8 zU&d9o#t1O(202tXS5cu^MD(NYq{J*48ARDU1KrYJb7v}m9UTdn+XzdjbYMGbkB}9S6SKQLy71IKgNS`_`!JN9 zS?cG7>vuY9$0DKLVFGZBKN*H4X z`1YCokWbqli3B>mx*537?_Rr`9HfsIs6nwKkmozlw%w&{Me|KmUGYtFNV3SDusYEa z6SY@WmhVt*aFh;^ves$P5J#u&lFCaCtC7b>`z_$XN^hz3wtCS8Hi#+>Gd@3_a}LNg}A7z)K_bx%kT<(C$3>w2*SwN`DwoSeFz}`pU=m>TYSlumP2Y{ zJi?=@B8PITk5ZoC6VO3Nc7by0Z9i!4AR^+lK~?n(4QL=9Ux>^1n@4A@EC$>17_cM9 z2#hMN#_Vouq5TzI55gW%uh?pt^28c;f(#G=uDZb_tda{^I~>Jj_U9o|Sb1F0v*Z|t zHm@@!2)qQK#wP&>WG5eWc2N8+@6Ken-AR4N-|q~D8lQ1or>Mf=E+e5;n#!*f)Ql5F z6^SrgqK=>01p(LD;W0aUFZ#>{#vi?eg=M-V}|!A{+1vU?K-gzal1t$*n7N|d&3~35sjb< zb+SFAw>AALy`sH-n*Ioupu&Q_C%pz>M*`{~)~V{;*G5#d`F=Zdr)ejQ@ZJhEXfa&V z9EZkDQkubHpi&VpPD5OAmo@!_ind-%TVU#YHI*w`Kx^=8V_LaJ?9&RR_APE+Sn}7Q zx}=IPel`?2M52ba{DfX&GfQ&ls!dpJM!5eo-V>NW6^Hfp!KFODTtSWTLN$k{$JZ%? z8uMq~*>Wcx)XB?fZ;i}0VZ(IrUG1=(ky1;?Zz;xcC+om}Z84kS=pE+jCjCa9SI7y- zAr|S|#63?q^8t>C2_^V2d%2%PJzzjI20~G!e?tx4A7imT*I4&bz8vmV!x-OYF4!f1 z+p-sRv)s1}Xf+RDIPnZjS=ICK(bE(Y9J_LWyiG}MLbPZ#aAgZ&+T&|(?ipUnqpL&x zempKt&+Y~o6);J1hCw^uDt6GpLA*v)0+m2)X)Ac#WUb#ZXZxiZXT(hOyFk!KI0p3_ z@mLIIb~cBGrg`-FZ@aW)L@Lj&Z|g!$-mkC;b( zkku}0JKYYFG1~!#B1kS5rlc#>?IqPZ4v(Yo{d)$A9{G%5%b%qrpIFmp%%hQorp-Eu zYV+eynLE#`iRv{P^do8C@c-4!9s@#XE{nw9|{af(^&d) z;f;5fpI|zVZB9dXoZxGLrafWygH7VrxNI1W_UT&~w#yWEl4!WakRwf^_Bu7QyOcyP zHIE`8oz8Eut-ObLA>1N+(iYqhRiac3?cldu^?oR@g|+xC+aLB0^S4*Jc}0Nzx;d>&yZnYK3UsZkqeWde>FcT%=SW*DjiW|u zSM&Wt?_7OWa~T&d^-#$*eDRxN_qeiZOCi^YryNQCVUP|ql+9vVb=2KQtF&o4B;Cj0 zwFtV9n*}PGx063ZMR43j#d_;EhwN`#sKhcLU_Pqwy0r1A` zy9^mNjb|L2icIDSrY?V&9<=a-w;Ulk3vgskl0577L#HeUOiT(wAo6{}*JfHcNeJ5a?i;B-d=uNaSkn!OKy>XiLl3O@QabsQJJGnHln(fUd&hvJL6M1T= z4e|A8Q7ySl&o{DK)rf6C#K-Q#97R^oo4s1VzY^i))<~>*3e&uabFnx%Kp|!&d51o; zKDQ#gXq`|p+Pm=%ZL(P}91-new8^c2e5STh@pI}YT#aH{ z|MJT7ar;UW%m``G(NIR-T9tPZP4BBb?M(#?fSjI7R*9-jd@=Hz&v5@ zK0(%{Lq8EEA09pIub8K3F7%3U_ozy{RL}HR)a-9_Z`V1RWP3FvxUpVV3+)bQR#%WF z;729;5Zw{o4iRq7vm#MLS!iBE*@l$wA_hSOg5($-25QX*b}UlYj}vUfMQUvdC^_~0U0X9AmLn_sL;&N zF!{xNfr&yNFn@=dR#Hk9sgXWMz(SJ04Yi&}Bk5S$W}8%z#u$#XRvY=g%G=7Q$c1|L zE8O&xsBtgz0k9<;3Ig-|=yVkg9zks>J+)q84G0HG*1%N)%CFc}v3a%KJbR~ecCnU( zaQia88=cdrC#}rpO0*mv&8yWl3%$3wbV&|g6}>7xYG$56O*?JEF)o^S(>yFw5|Cf_ z1BSl6PQROE!SvL|y&jZl#YI`>al3T;XUv_Ef6P1wU$n@pM*ef=w%)}gvvU-xOUxqZ zT*9Iu4&^vs+GU&}9gOH8LI8V|Md7oFV_c~_WVPjH)WCIpMpM#<&7GjGS}t)c)f1;o z%RuR|2e(40ZWNdO$tiPT9e@iki)BdKkZcp#`ahvwfe-hbsMqj4i-#EVd9!4@=t>mf zTXeG2tq&1Z;12pjh#u9 zxTcx|@j+VqWSX5G(&RFTI!Cu}Gml{PJ9nDR&UDzDs-76`$NK3eG3j?g>D%U6*ZYvU zI6IO@?YlSnCE2@WeCy=&a@X{Reus&({gN2wh4p@s5))+-5LY?Vuzj#1VX?F#G@hH8w;uX^}FsTK_FqX1PY3 z^PS|0=j)K~vz#r1#--Ba`Fl}N?=-jVZRD*}J8;b2nJ~LBxNcq|YWK4Jy7yW2K0ybh zVnoHlvwV|=b^1lVcgfV-;50C}fau5Vv5D9D)?KQ0>Myv7R$Q8Q@oU2e3?aa{Taq3vMF|FYRPD@m=b_57_2>h+i8%7)!5{c~Xa*CFyCGC&%>Es@$#p@(&)(_zX?Q}3b^ZF-p4B-=;?aeLIj5-**G zUm>Hm%QZwc@2mLh=r?^e^99gif$cK+XQgI+CSNpvV4fyC-F+Rq9;}ZdJh9v3Xt;9J ztP!n!9=3Uw2nBU&7*^`n`WBIgKjJUkMLE$c#F#&#wQ+~`Ea1lVuQpB!tm5u(;sCCc zO4RrA;exl9)gsgjdW$I0yh#GRyn5eWGv~sxUR-DB#($MgTM_B+Nz^X^WCzzXBM$tc zxjH?XC&05KgqMTP(ebUMI}pvh<0Z_j3j!cV;!CHP>N7MaC<$IWLDLWQiy&~(B1u`^wZ!4ic9cyem!IT6?3u^j*W`SL*U6=G$xV6F_v`NO&R=js$z0tpeRGY z2vz#A65a$F5GM`*dM*DrMjs`%^FGt;fY*q#mO2*-@{&|J`>g?{HklgyF8GJ}4M>){ z5%visse@P8qn3vbNzd}!uwk9b@{ctw(3boUlR--Kru}W+r3!8tqf&hlyhcJpAu5_* zsT9Y!iSvzc<6oNZ=TBlp@O>UB`s_!|N58})4nQ()&{XD_%I5IUO#%|h1CV3b%t*Y#?KL)KN=&rDbqj6 z6~BR)NWk$#gp4ekT0aRBgkjE5>X+G`j(Ilm#~(278Zb)I^L7=LTlst>T|T_U-{J!` zukL>*qjgc4$(t4_LEf)e0t;NNu#pg!Y9H_#TZSC)D=UN=_1um|XmpyaGn{$GfSBnZ z572F!2p|Ii5`tNZX5)&5xl?7E=2sQ=0TV(R>UJ~x@>0Wv7%-?T+%zV)yeDD^bcBQ6 zW_{1$4TeGdLG$#GO262dGxYNuyPvtiMW~_5Y-##tPWabY-F=uF2YIC$n}rRj?AqqF zZoT13>(E*)z^lAKOg2Cz?90Jlu6n^%(-YY2{QjOoGnHZ&+Ek*lZ4wYi%rCI77~W1B z)dVUYrFb0MXUuPM;Hdfv1;Nw>Eiu% zi(f5IQ|`*2nVsnf;?ddUZ}UYifGAMpr$PU9;PhgKPCf~A!l%r7=u--*SXn@qkh(pd z!hZRvb{Yn)U`@z?ky7%7@~ZhlPgxWBW)E_Cs$mJfjS^63^*I$MIB%~OVQ4jCV}9?? zL-EB+3?iH~b;RC1-V~URR(lu|q0(e)vI&sPiGgfxM-0*#P7pt8V7Id17)_ECYqLrs zA?YL&6b4zu<~SL>tcpV~y+8b5HDNX|ks=JvmNJl?Uk|9al90G@HyioHRLP=|GAo(5 z0frZs>=D-<2flTfobsI6O^Z%13{DZR%d(G{Cwi3P?tr5OQ`yf^$cc(2G*5UJMIEC! z%?Y=KX#&JE=>thqL*=(fX+QIwb%uB-)Q^Uo2U=pe72-L*S0rU~ZX7AP)_#4IWVy8} zU=g7)3Yg(CQbjR=ia8ZCVVW>!CD*MAIOH=Gz2i%31Lkv`wSDI0&IZINkEc2Az4KG3 zIxUoee-<_bOk?FR=IQ7S^K{yy?T<#&Erq0)1PL&f>CO#i8l~#0;NJDt@^+aPqpa#= zZRSqxrJN0``S9NW({aOGLlT?$@Tibbx`Y1~Vn7Mx(rB2kn5;1^Zn_51v&Son^`E9G zz1ey9vBz**j+tnN!AdOc3~VC%@G*CdV8#aE$|M1^5gz)si9tw#0^B;yb-gI*c5|{j zKRnxr{IywlmD6vg)D3P_6x{)|M~nu-d+5Xk6Ri^RzM$}HGQdThE)?#|x0uG$Q{{}( zsu>HkZ=PAnvP&hw3aF_t*25axwa&dveJPZG-`Q80ckI*wL}c7sI3Nq ztt3HuYB9Gz;kL#=Z7y8u^ya04?E*o_>hY1zO4c3rsao8c&Zq$80M2QOac(oGd-FKK zlwx3GJ7LnTGzy3DW=y{f(k;5f* z1F!Wc!PhV?0i82#Nj^-~PRk&AfiOx6i&8g)h$Z!u=+6ZJnA;=HQKOS2Na6zQ2jBlL z^L#66Q`x_D0$n5|K26SfrRmD4bkvDXJXq1vK2_T%55)`jVLWuVRaN>|M4nfAw(1rb+0-g1KKSIl7Df;`6g zB24d7jDvX=Z7L2@nk~X>(Q%qc09iXeV0iv_rhBsz(!u)`_3ydKeAwf=9tJCKA=|!eZu`3+VX%4U&9!d z1n+P}>qNNAVK^Zp#3zf;Pu$ajm)A@XJS{Xh@)><@}SAlTCCY8F=c>Sfl~Xfhh;%=3*dQdz-)ouJ@8&MjQn@JfPl+ zq&Wc!_oCVH^H!^9XI%|~)KOaif|s_b4^Ob%3FY#%s^g{kY&SO|)i8xUBg;zk(Kk;j zm=85-*{mz7%$p}H!Af3%VI-P*Q$uMiKb~IF{C93Qud&_)@z5{=cmvNu0M_4w`AS{V zw$BKMbvFiY0}@h5;kG~D_Ohm!;NTDPvT=Lwa)|sp4o1aUvm4`lc zVX3XpfVK<(RQkjUkc~U$m0P0jNPqY^?diiwpN5(cWGTORCSXc$6NTX0(03Z_Q|Ot$W*%;* z;b3&Woeinc4}v81(`)WzmzsOG+~#+GQTB4eLwn}ko5vl$SAdzH2ki;qiS$0X)WC}& z5#!HypAQ1xot_Gk9yT;=&Pk%$ygjtteFScvvuCncY*8&LsidmmueZr(*CaYp;%JWvyiOP6a1VpS^gWDr3Hi6{8|7bEN2~din7-{s+I^Oim zbk7edaa2JXA>3^@-15zJzWn4i^Vz{3Wwiawqfk;i;kT0WG-Pq`dVSgi)WczG^C+?k zH~9s9R}e7pN&0=5a4Lfy)A0Dm8A3oiMA7j+FASk=ietdy@EEN`!2(_GMB;W@gQ4T~ zHo|q-)9o@PY(V=6XUYy?d8}Vev-@|P4#FM~{;Q^DEo-Kr<&u(?Lq(aewvA3@6I)nm z!vm#gBTFG#z>0HS)ipFGkR|m{*Inc~rG7;Ue`NM4ekH?6g6sh;S zV_<`bR04tEwDLgp4TG+~HDJm$qXZJBhtj4Et}y2X2Ms+mxKB$tC-8 z<1OP=mfPkcI&ueJiR$nfA(gtU8;-RfTR}tKqVKX={H}m7@u=LMd4xDv667;~3ZFGf zAKI#Ar~vycri>-LSRzmpRP=Pa)k1dB-S*5K;c5*KOs5#08pk2{m^Y}1FY73xmRYBgR=~9WaEkR`@>q#gtg{Y5g{!!*_G3UeW z>+eAj9cPyYBHw-5yw?xjCv8NRjXOm6k24`JAZ8Pwj=+L|w)CxJ!%)fPE(kJM9GY1} z(2{z3&xOM|q>I?x3a|zZDA8JYlrOiqVB>13L8$^=#glsI5s z2Gf&5(hbgt=*cE6@hnRvCb~RsqvkG}cldhQady0TmwYhF_{S$^&gT-9QL>_fkbP=* z%<)kg^;8L|gtz%=ALUXyZM`)@F}Vms2|~NVIPgl- ziE;0e3U6PcR=BStArPC`HNpa{klh!@G|EpDXb4p`S`V^_kGQD7zhD4vW0(l_CFz(o zHzoKsFq>h-Of!toAf4Onh{AZnUOz(tcT>?tX-SJQXXErXbJlCEMcz4~w>C>e5|s~~ z1VgYiM+uF+a1<$WDj-O4>J`>0`%noJYU0}=5M+LvsHGRRcFtB{P0|J|FE+3?i7@Dz zx^~$lO;?ntq19J*y^S_vaV)zbfp%Y7NGe||ZltF5-LKvSHjpylVeX8|J(+-U815^f)#tohkq(j!ott6ZINA8e`b56kccOtmwZ zRi|MdnIdOO&SEmC>a;_|VhgA^0X2hSi3hP9M3jQUqm&ai2OcxfY*2>155Z-m2$AzO z$=@&!rODvvP79zq>gdcqVv07zdP>oO>LUFXxz#rbMazP__uDO6DfiOK01874VJWdv zERa)@VhKtBlwZUB3i^nk&1<~M#TvSq0W+dJ%NY|~bizrCBazAo!1JsaMM08vIQ*4x zRvfsA@#Z;oQJqQj3>RO$YObaXV|VC9WaMq}z-1~rlq3w|i{^(X?jRvu0L`Dr0K`h8 z#B7*`!G-Ae!|5NA~*B9934ZY+ZkAz-ul2cp0o2Zs+!ZfI8>kY}l6d778F6qe$juLkS1zn#H< z_y{`VwAmfmk)lDXJEE(4>jvtI7@nhtLyF_KH8($OuK5cWssD-Z$7+9uGL1W4K-Pio zdske zng9X7He`2~EMMud6%5NJ%ca8mHL9i#DrAGzH}<=IkFLK-h|om3=>6<-ucYiUUK>b- z_WNFV{vxBHhuqIGVUxEBNCQ0NWygqa*%2p%X6P^?IHLd%oPte}7fhxbUnDtj=k!#V zSd72*vw3>5yaa8MK$wIM=nz|!>bQhx#SOGn#C^X#LEEbJlG0F04P-0v_rk~Y(Q381 z+Irdk4gMCs_Hz^yVAc#`XI(}-;qI!leufsis>`e$o}p7;K_Cu38_!mK-zUwdElnjL zl8GizgEa7KEjpDjhIGh0(23osWArf3iE1~i=SHIJp73#p6m=tLhq+IN<>EzlJ+w7- zE}b{@d&g^?jB$siRdlw3Vzge&-0)nRURA~sQFnJPpAL?8!VVgyH`q;rt={H51q>!ihjXP zh@vZfFUL|6AYK($>wVg{1yAujBEkiFt+Kjc{&y?7z`4H-69SO1!F}C^1$35s^9GFT zf!Eu+po{>5#?g;_UNlbuAr8P8B^9c~Qs%Q6*h%Qe zS*HtDki?iP7WKm0;LqH_M?%Bava0)4sy;ps59>cx3*`bxAVOI76Ai<%f;c6lXb2*% zUS5Ls5Vz_#DBZ-(8lUMVm7ve7AZ6nru?PArp5&uzp0vO3KS_Nu{k;IPa!61>DytlG zne-dcb5+wY4+!8KLieQKiDW`2aMTk9ovbrYjiP(7J!5y8V}S!eh3SU=CpF=PS!ok{ zBn+VG9oSpq*vAlPu^V0!?FqE5?4<ObsKxP1nwq(6_`ZC#A8?(vR#9RhjRk~Z2%wMCspTKMVWV1&V8bi68hB;RnLVCn*mStJd7Q&)k znk}%~BSwedkXxMI*uR$iA&zdv^VS&P)%iRSA1t3KiTUxGHhA^q?_Dx?tM{^`lFN4n z?hc)p5uUp5^?IWmFkoob)0_>^PSV{XKcZDb)tC2i*A99lRLPkS(+K1IPHN(!&KjrzssUOi0nV76 zVl(Kqk|My7V2oVqbUUr;D1k)>z@;>FuEgD4`s!u=Ffnv`hv@{}*n9~(Evso68_6%d zbdUlfaop^8J0$poY_@uxc1)5>{czx=MR?TQp&T+*)n}(UD*x0@ zKy|b?%qJfVj|@Umy`59R{w-kaq|CfsyT<1dLUi48S*Pc{0Ec7Q-702w9rFLORR1-0 z{F}I}*YN}qiJJc`JFSi{*h5PexejPi+0zUjf(%@z*YpiRo1+oVTWVsxufwL=rV)6Y zhl~jK0b2-3MPpi1zK@$)#&bf$OUg?<;}>fDn?7n9)$q$InW!C^sf*6m$W*$x?T zuoV5z&6XZ9dO~$|gCL@8lkyH`4S&cynfHtE*uF{x)c`QX`vKy*20X4(k;^YN=s0ns#1$4hLZatSkT##4h`QFcMbCw`3=K z_SX0x1)y3#IgL8WF%?Ok zM#-R&_-vJ>1ZfTCTd9$Dhet@P+ruPoOr?8WmQOtG3Wtc*!P%@fD-CiT-Hy$i2XuC1?Qd_U7|I&l!H zqs@B|I_ca^b9x6f*x|sh|t6Mj^ed?Hasba=pdjlmuF`rSPHqSc#)JeytqjQPwjK|olLPE6X}<;39g>UXRv#V4mOv$bJq;Ez;%auGn3_nUW* z$w+LedZGi5cg&AG(|m+aCcclAd4Ty0u^9B^?6i$!>)No3#MSB$NX)@F_BT+ zGD?ogYQ&^2ID<2%^$GLrCiP{mM=ZI)VL{1j>^3rvxVKc-qAXzYA~U?nyWkSrE#wah zDem7`)E`X)dI%l-vN#wrS?Z$KAykP`$A8+5Qp{Ub4IN=e`)H*WwG-6=JL{dWa>$z+ ze%ITZNAvyPzW_;IgE!7`LJ^tseq7@Qu+=eF?1j;TEERPQKDKeki>+az2HIUp*V;9CLzo# z7OHXrV3K%r_rz-#P7X>YPP@~NKSid3F%XeMHfdmfzO#$)`@N}u2Bhj8RA_5Fq#m(B zkX1d)1t|CWchHs1pfq?8Z=5uu*r7M*>agOCY6Mf5PoXi{ zY}9|0y*paFYs#DOnn3(Ow63nxW0rff7}$9{S4pp{{YAx)u`GG_H_&kU>2h zB*kPxxSCJml`pFMT4n@%&Bx{D3f0`HLoVqWrg_#PN922Vn@fX!CtBOv;Y07|A}kHP zi4MS2_dt}$=@5LxlHA%(yV3eZbL(cGnMiZYvuy8VJFKwWG!OmXV!2(j_3V!>F-BOh z6<^DCb*;7EAdg&$M*M60uhc~Vfe%rP%jb0k)oRPGs8)ind>4pQ-`1PM5q*?5R_49N zpM#_B;>ZmtO4)#?Xx@ow>le72yf-SSsI{Odu?*fp_s+v)fqs&J69gUH%DP|VouAjd z7jYQ5oH0cIr~Umem_I5BYj||QULD1l%=Ah17&`)X_SPwz`f@Y>L*~9tRHVo88c9J@ z_!+*VWss=K2|mV%{0pu<4CbJ0)}`toVAo+)(g>C`V9>Vp_&)< zN?pG)0wq{jlS_udqKrW98gMn zMHGWg2AB-ad8}GHKgg4cz9=vemo3C4VS*u=NxF&C*t~}b%Fl@xiTz`lVaBqzhj- ztPyC$u8Q|^+PTj4>)+=*(>f_|;@S#OMxhFl(k2er9@h*n>UDxOA#IX3?wvHJh8RJ3 zK4^QMEAVge^P}Lpxsow~4pp?x(^bJ6zW_HA1VvRIaObxP#Eh-xD{%^rqpC1D^cGYRuj_)}#vbc&_K!GhZbMprlJDDiocV(Y3h2N| zlToCw;EE^JKbX+QMp+_>jl}m__nu+$2J=F3d`OZQhAjaM-8R3Wfif!dmkZdpf23z0 zx5E(=hMCGl)?=84qAyWntVw=%RW$}VZ4>Jt|AqBR>CX6ol9FaL>8A>p|^{~?3B(@K}kX+ zk1=dL^ph}1I@E`8cjx%J&1^?~MkO%Yy}KL7lkJUNkUObL#QTfl&e~|5#+R)@)V^Bu z7~zI-E8z_(a4(Y|uR>dw2x(+hkz$m~N!Pxgima;nw48{6y!;h(7YeW^qtMF-ey_tw zacUUh<%Ck%-WjU13DME!m#mdwB=PKr%nRK%(Y(F;D9xi7F}xzZd9(9Tyin2oM{w69hqU0|9UWM2ZqcK@?Y6k|mWLY9-}ZqGYn7 zN)(q=jvUL8E2^YYwz z0W)%fL5RE{wO}cu0)^r{hZsK03k*`UI-Pz5?z2UvK-py#I_S4nTE1?cOj>}S3be0D z*yBH{)Eu;Iz{Ji7Pz(oKclhtnXqsxfno{1VVW}|PqrFQ$wv8_EeI-lRx5wUT$e^tQ z2{>HKDpvT=C8cl&)XsR`5*_ny)aEXt0l7*eGTo&`+}ff{!h+_r^sCjE%}odG8$@7+ zU>=^OBH{OmKM_=5-)Ay2udqT?)3dJcYbC7@0)#fm^P@csA&WquE+IvB%7|&Bts78e z%=18&Jq2q)v&O6YE}ab5t>)CyDLX zr`tp7Wj$ntj{C_}$XyK4gMI+i_Vxp)Sb}9BQl>@K5h%;5nMfU07ffeR4Lq7Qd%au0 zgs0DuKn>2puBQg?S@JMtIN=RoxpanEerl8Q7sk4V&Q9^GlCswRqZgT{owV02#uQ$; z9!^^)j0rt}xEgmGWN#fw&_T7PR4{LJ{r-@uR3>!G8Xyh=tfbrOlHM{m#J3Uy_F)sSH6#VZUJ*`-4 zyDUb0@8B`+u~8Ha57=9l^3bjDZwX670g6 z>w`oJ%b1oT%Ka@NMOD`ydmMo=;`W74NiI^=2P{Jx(zv6S+ZtrY-myU#wU-6{?0zo- z_vNB#yV+KL+FWvpwz$qM=F0X~>M?85c;x*YA3O3+_Rr(^Pyqt;K1^rYM_u=I#(y$} zA@KJZp~k&34Hv~_^{`rpK)j`$!At#YM*2S|QX%_EGnDv|fx*d1FHI=J>X5*H{6I3F zObMC%|AgPVkISb1=y&69;ZKMZE0QfO??|p5YaOvs$=lFo%_f%EmcyDi;WFsTQINmp z@M!+l80*DD0#TLJ*-BxSeMa0gcD1%7HQFtYfo`89$VV||I`R*>$5ZB_OCSI(&XG5p zZ;$&%Q=P}fD`mf1bsy;v%?)2O&kXZCSu7lwMT~=n27q6^EdgBz+6NEWpeW794?~nI zc(7RS!ib>aYU7vtb7HRU&SreJHyZUQaZo?NpV|72J6VKBSc<1?m5Zf<=peS>!FPD6 z*-H?N5+3}{_2ydh+Oo2As5lx@LNdrv>lxqSHv99%r9%K)#Bgpkw>#(1I={ig*Ngy7 zt|IkL*C0@b%pjrGfJr#=CTu!J61-n59H7iinx|VgVKVanrq$2i=Vh)+Mp8vAZTvO~ zraNfzrR1}SKEivD);tRy9nc#^vZZpmRUJs2$klJNIAzo+6pflniJ`-GWpy@qRR5lR zx3-S8@9g^5;uWZ5<3@U-+dlEIdTq(QLyPbvudVl;Hm6SE5XiK6H?6&NDrhhZfuV4k zlisFwtiMFC@6)uQuL}fTtPYQuO%$|RLoZQ34@1@3nmRx#hJ-p>@>#nr*ctr%byMvw zk)`w0*KDatv9NBg{~EQ*@%jyUBK z$1_h})?38Rk|fsbg(j9^HDA4qntcSRj%mVO>c){iVj69~Yn#t<$pW%MSm=rsTkt2%h zU=o~R9pw=WFd1a1JcAIwV-d&u+aa^UUN?_rXqOCAg(cY4;ZVBEG_C z(616z&}_lQRbhw}CMsoZH^p0%At6Di&}R)b2?jyzU}g$hjF+-#NJe)Cml7jWozp6r8Zpw|#((NyRX}6TdNz3C#+jnE80LgM5cnKPdi9enDbKgH2SzGD9>g z?lvOLu3hcNkpM2`*p1?{mu|UtbjMqFBa>N>mrsv#>e=0Z+PW?FcnX>XEft+pv$hJ; z$?Z-2-Y38{OcCq;{1o%PtBOp9F!cTuOZj^Z+QD^X{p;u~T8U0;dBsv#%9j<=x<<=a z&2lx;O~RGG{D+srH~VohTMVi2U-k!BpOYG5`0Qr@j5 zv5C4wnIe8^n{sLb`g$k;!u<8=5>^mhgQUZ-!oar%8CobB2{Q-;grq-ATWuh!jm2oE zEU6EKI}J~X=g-fGr(0MS|H1qT!sUaOr`N`UXvhYR>KeX-PkAmXT8&dk4!bxP^@T%4MiO^^Q+Y(< zdm=tADXcj#DytXnT18#O2qTqN*d3q;X~^z7-QHQJ*y2scQ!ya9N3%D=gN3D?qL)n( zf=8RE3W`qgx0Rs?K%BNd?4N={^<6%ABLk^K)qU1WXcktMDo_YwS;|?OL5PMxP`Du@ z1hTtZ~|_u;9dApxwXt*}IQemtjI zohj8Fy5F5%3$UXs-hQt-OZnQzy^=(U@ZeQp-FWX!h4o9auWHK|4G)Qt*2Xqe;10!7 zmLezVV)+S zvF9H+f;elDXQmpDp64#vVmw_HD?mwQQ-k=RowNjjO!-{!VRXSu>@e>Ur2ik2P+@FI zl+&d_TrDwQ9JxI((|Z^WZ*sNHXhBr%R`X(*M;~KYFZgvM0RTzWa4mY`7vtNzXDV~h znu0bBgm2_XCg19WTP;)&e4~u2Dq!xUBH_4Ku9k=^qcst@)n+?t@94glYu9EW{a~5r zBxC87GAb8hA?wrV9D8EKPs!&Zp>mX!lS!m0HPV$NI1@euPP^5~wnF$KSBKv8U0Lk|Y0xCOTf2y4XRt${ z{S971R=HTMa?vdMJcKY^Uc)|SBe~Kk{fs;W5Mggmm zLpb%{gJ$=jyI)`FUUTZMYO|!#b=Mq2(|RSn9x& z;W`m?-Ugs{6(&~`AEvdLfMOGwAOY@B9HlQlsN)K;H=$Fe;9U%VKa2VMzfZGRctAje zQPyUYu~2xql=t)jQF_AfwZ@%r)b4^vPwKSO`lfh^&_oa^A36^5?4t}7O9Tz+I{I7I zZbQ|iQE}SLf@!dW=6=;YNQZJXJA?S@w$cw{Gm?z~?tO5|v?mqq8Mm`67iU@6r6`2L ze`+OxUTk*qU)cU&`PCVgl040qMPb>ejg5Lugh8H$Q?C&ovdt@KFZx;`rel`Xnw3vH z6;n13v330i1gi9p(`5s_HimEkgY-JPNn#O^H= z+qQ~P3Wj@-|EL1Px;`n#loNQWLQ$o29^)NF#qP1s)p_)%c<4VM{_`0kjAR0>0$nx| z5Dw+5(TP|Y+#bIo^q0*ZUe=37?%N-teRt<@;N1)neW&i8_e^ z0=@YpR9duD83RJob{}-RKn*|Uo^IjH5kjO@K)x4{Ord|u>uxc7m-5>0$~ZyJ95Q5% z7@5?3Fdw8{Hy_MB3Nye$?GYzzVV<;u!B$YU8KgI+YY~$MpOE^dM=)Npebq5z66t*U zyG0Ikg@Q@5P#8iEh3(F5jHD=ivvYRMTv zENQ0ZTeCLR0#j{7cinC@pGg+DuZGo-G(yx0Wsa1Wpz^s4x4rh;_6Yj}K02n0z!pwf{raM{1!kcYV;0U(pDF}8icmBYK&EsU@x~{W#VEIr)5qu?(mieT`$TG$9(-p$e zr`Yvhw(_#MArXW9h%$%4EQ^TObaUG3tL-ih_$Q3DR@C zxTq_B5k)I5&nuF??77Xi^12;U05K|14F%&ZYk5VVIw8U!!h#wU8px>d=0p4L*jG(_Ub5j=E~ctj&|b_sW0N6FVwg@fTK8gZ zQabTVVn_15;K)#SXx_i!IFpQC6VfQ^pdAGv7(T7(K~}Vhf@(UYdZ3Ug@G)&XEEcsW z^r3^jlzrSh)+6p5_=l1MB&lfY4;`DoQ)n;_yR2F{YmFv3MvO(j42k3HR73!+-JnTI z(rquBx9uubTA#?WpIGqZgY{tDw1AeTE6R$xtR%8|y?pbv)z0g4EhQJx^75@*L|V?{ zW#--WCAm!b&-t*1#~fm7>bB~4hW5F<_MR=4f)I1%T=;%S{6jgI8(7aYKff4&HPZw1 zmu6XwgrSsynLcq83{4IAJk26`a()m&QA&r>iqt8V3qrBk4}FgQC9aFV*#2CXw=y0% zf4;*{hA`kLNem&!LpC`kEN?ak^{AfXV`KZ}Eg&j;RmEuQc1Yit9I0Xs5L>1z2^(Zy?9y7##4-Qp{ zWk5VrIrtU@M_7v^`q|nvN6Dq{6oY;XvtvLqg|<4yRQMBUUX6$OJdj|}sRIZJWr%s)pac*&q~1g1ln1~pbWEySQMr6>%WYRlMBZ!; z2FxV_ud&CugUzV7UG13eJ*E};h$aPVBVgqrmwO6A6c2-{5rfZE#H)FmR%nO9lc+lrSuyUpA_ElC^gn|{`%*(DxMT5O+wOA{xMfPLb%V2y*~Oj<0R(yeei zNJ+&-GJF|1w~JS=O3IHB2GHCvrSCEJfDW_Mut3UD)wC|gd|F;pE#Yva@t=~KEEu1L zenNhk4~iVbdavDWe}bW5%%T*v^Hg>@PJ;2j(ivGPIByt1>n5*!&6KtvsAl_K*R0Ezu-h8Y8i1a*_aYv z`U3mKeo-~5{up}c8&*83zEkRn z3*|f_?9%_uq6am&%Gc^1M56j6F`*N$K)!~x8X~QzwX7?>2VZd-uklsYk$&fKB%7TQ zwiTbj9kB{wzebCIGtN7pS)fu0Y!E`ii5kD3k0%LqW|Qdo)F5biuxIr3MPBDNPzGUR z3`Qvd6e{@4<%_4YVE2Gz4Z+9{n@8nL&Yl!K`TA%4v9Cg}53xAlL}W9mG1PKQtWlFU zuc1ocVRbQg(y$5NYq;Z>E8r6DvtE zDdgCQq>}op#jdsp8r-MAE&nfn(|oi1wD~mIBTwxDLL>}6wN#uq+XH6B5ELnFFoP(Y2UTL)Iq%^tyzWDf+?uA>{ZC5NI z%c^G)Z)sr{b(cETv{^{W$%1K|m{R0`B3#sbq(0g$T>U_GcKYIf?-^D=9>UbT;xd2M ztRe{%$O}>zg;+9*gsH~b;nVZxKAP#r+}VST(PU;+PMcRZ%tP*myGUE={ws8{TCFxf$J`6%5zYLCbr5l^U9exhXY+HXq~e)-^5M zRT?hHlorE7b8GizYCeRfp#HTa=?+n|DWJb}^%Cq(e3!CB+UJ1Q9=0?=_PDQWggrw6 zHWsGp{V$qt0{F)hgrI5@I!yaO3!|B-QXt8r5^~0`0ENVSc|ZUqYeuMOragI1Cw|Mk zw`vu3MmIvrD)1;#(tPBM+Q}P4{FqYSlQ-%U9r#ahJ~#^)%Ma2rM`UHbScFnAq8RiE zd00Z}7yenIh?aVwc^XaKd|#WO3r=4)r2ZQuXf*%N_82}LOfG;WS>1PtjLZQkI`SMK z$z5gDhE`d-w~{jj=-qW6F|+mtgH=rc!EGqTU|0obldSOQdEWSyeh&j=7u zhr;;5>W9p8G^%!HN34!i8WX|@gb|8}(@~Bata^UcP|1FjC;FhpCThqQy<^W^lP0hf zw1T^?;P5io#m!)%k+*c$N%}T01_*rE7RndsXLB-7 zw1%h&Er5MZk?oS05cJ?43-&$vO?*_ClmKZ~MOQS@hk*Z1xYRx8($LI8(ayw)h$~F{WjI{u8U@j zVg{R^mdmB~8Y+Q&fgOtI{uC!X?e?FtX9n?u$u3R#V63SG;-;Oftj-;7X4&?GamCCS z5+rUudfwbc$exBzw5M%f2LT!YEKE_#x)niUjjna@PQl;RR9FLG+Yv!@Yizs2J)NV^P* z21Ag>qDkHkx}J(FXd!A%sN;Ei68KXW{Djykf~!b@3hNbxll_|A<0}HQt<-UfUgf!aT|th-??Di^?B5Lv9I7aLRNanwz;M z8tV(T#{Ot3cwaN0Ghc#F#fJ3>@}YSw{VXF!C*Bj~O4YtZkg{P${e;8yf*j0i{3(8& zi@G(F?D<^w+%(Vmr2u*k$c)wL48PA6}gevduOsA4bL zfQr*i56Cp|Z+{ZXT00N81DUI|vbHE#7bZ-ng(=xEdw>POyyrG9UkK0>f!!o0WQK@W zfx0qfWDEU-fmywz)ph_2pfyKBX>eB4*6ZfsJZ`0@d<+osP6#IgaTH*lBUmXhi7TS2 zBw2|6!bWN?P~_80uYr9lcroJVif50xR*Mv|4pqfMz`ObZ&+1#X&@;}g|5xm!_fR6L zk|JQLC6PlxY;9rsQU7})snZV9TY3AbF5j40^Z+>i zf=`^P^A=IrBZN0cMgkH|6pm`MJ_wNs#)~}B$eBUF(jiX4Z^Sn2t8kuR0LlUNBV%Sa zR|9JJHgYB>(u;}NirYW{5!X^Blu0^Fo<=y|q8>dJeW>zkRaY$!l;{Wn-m_#35d(CW zcSqHPJ{v9qYfahrGUadMEPm(n3dQdtDr*op7=@;_vopw;5tX{ZAO%9P1MpL82UCs@ z8+)&r$66Hl?4F*Z2D&3YK7PxTA}WHDs>c4;WD0)34ZgR@+-Q5E>(`rGw1r-c!neOj z?KBi;U9K_U@p@TzjB7yR^}D(xj!nek9orG>WwU>e3yP7;UuN=N4BnHL;uLkL;K^f) z-2*?~0Ueo8DE1Z5M_QBsF_0xAho=R^1ZHFE8HM|%jSiE6)srdV%<=dgcLZV*;xTb( z^O_vtLANf41y%4q&5<8=qfeSAA|k_i zx~ozwNd}ZD#@T^==93l2&ZNAAj(76`YfSic7Izud(|(B_592Xq;|POeI2@NC8MpFN z=t+li4DpI&K#mMhChczeG+(6T?KO6ckPS+Bxzv_M;MV-M)Nk79$7>=n-KX9EB#8vioDjV$SzRMn&9&K=xH?DeH7^MEkyqATcs0uq#M;7Bvd-hUD3zNRtZ zVb+TOgO9qO>XVgoN#Ujhz|D{L9AF@$Hj&f!(A|z%_GH>0dPl41w-yy3$^$dpxIo~{ zJL(fCn({YQJ(-WpO!gyJ7%aXgaWd+bR9b^CaQ$RkbF5x%D;zQ2g?-_)(F z=wOKeEvzbpR*+THwM3KZ6BV0dv@p$5NI0JmH=NCZjq2oZkyt3yE9SV3 zV`<2p+D*tl<=(_PqQvTMbzrlD(R{EN1ZX6yy$-)|U|B6IUCmylsyJ#9{;lnlxw5az z>FTUPT?6xChVhQG+1ZADW>h4GNTu7+8apfyu>FWn5JRw5pdywLak2588(F@YwXnCq zETxPT|1*qGar~phuABc)@w6XOgko!ZB%$IN@@;D>fZ4VJD&w5)Ct`-`lfm5NdrNT# zare}4;)tfGNUfQ2dLeM5w;BD_Q*u;)hP&YJ$R?^@gE3?KJq?EL4b zNg}E*rr;Y}&C+f~qK3%P^_&*1cA*%IK-o%aTE>Eg_FztLXk13nHk$u3)N!bI8^2}T zExNrX$PqQ+Nwk3{Y4@t)7)+@%Klk$>XlWQqxr4%tPMh$Y6Ab*C9eH|%TH)M4d09eQ zq!|BLnI%*lMB3ip%vx!qsD z&3wwdGV&0W8K3D*%e>0KGR7iRDMQ(II;~EdJ{M$}{Ldf2gYQG>d{}%4#g?#E2^qNG zs)TkSf@;NN&{3~yBi3v^RKtoUA}Xw=qpM06sks0DNvLPV((G%1D$P4(hV37BKT3Qy zQj6!7_*QW)WPd{a8{8WA9@8!$eOg99fxhjH#sj*0K}(aIU?;0C?JtpPYHPWJfa%Lt zqOIv6Qb3Tk2C%I*nIeTX5`g8v_ zGwDSE9TWZWpa-&%km@u1aW?KYh$&gRNrvO?^9*~Y>C)1PeA=^Mnyv)Gp(16h>?X%`?jcI^D56dk!r*L)sf@RcG29_T_D6)4{Ue(>xUE5un_sacfuiDhnTS zK`dfP-E{XNHMnD@iEj|POw3K6g_mN~GB6%bv`8w=*}q}j$KqD`pY2tq@nnpG1(^j@ z>!KKT8E|YpyuZNO{vI@%6L!A|9(&VLNpw1~=T7oc#SL4(s1i?!X`oq1fTIqphV9tr z5RPyBT1L=Hk7IRX8T6Phxv~yzu{--KrW5PO1F*k&EeYa$Bl^;SnCS@d?3qI*w&DXl zv#_ydlit}Kq5mK7b^)?>03-BhS@YQ|fT-N=I`1}n#TJl^2rF8Wx6}4^2gJJ|pLDky zjAOVE{VONC8*G8={t5F)PV2?~DatHjJS)1W2w(v!?ju)q;YU$_jm5mIn!Bzck_dGjSt^mG zS{(w3`Be`n%!?skI^+1kvjue-ICU$|EY05mE$qk5uMlCkHVbWUW%M-b-fgBD84i{m zEfG%A+XkF5EYz{C<(IAa6NN67F)rR?X9`A{=jId0ccB1J~SRn)Wr`LWO_r@JbP+fOt>_3SuZ9Xf$xY5Q7 zvxkbWpxm`%EIUD>6>06UFe2AzzFR(Bl-1vf4uV@ul>-FfO)*e~wsD1$k}1l7y0|nC z_BsVKv|BVtby)w<2Rs?1%$U2PLx|FLp}UM}4zfMb+&|HTwt1Q8WY{OSMujheM?lu}tEaWIB|2`vGFS=|Z!a_qp{CPEuIU z*V=apb?bL3WY}&^&&nDz5VNYS8DoFi_nRY{YyB(}i?=hcxQL1s@UXrvU|!L3M&}BC z7-JXGJV8|Q5^?ct1W+9XG^^qdmA+IdqwQ6Ys4vx|J%C%k?x7LN)YSYg_4UjxSGB$v zwRtF0e!CmfI!mU_Y=)gavu|EAPg1Ot&BeY_=PFslaIen#lt%j#O80h%Cr^1iq-%+n zRpl_UA6yws&C>hc%0m1YyH`whozQ|Dkgefeo~#b2j-{IT&-%KOeEfnTSgvWVi>(D> zY1xxS;DX}wdS3*z&skg&gr@WxwLW}%Vnzv>fUQ7orekN!c^4TJQ63QPc`&W z2xGamL@-3hn|!$@F02@>#b8-QbB?gVHOryz zjX7zb)yo=Lfh_rHq?*2ZWMt!4&5fQ%4AXILH2(mW)S!=~RgsZpt||t&7(((A(*=7Z zzJb{+Z1qnZmF|?$RG=3(cMEee zd5C^X$EODecYO0IH>+ZPO1~*1RJ10}N73ll5SYXeW8#W*m;@OBZ|)&Hdx;gepLN(o zmHjH-C;@e}kic*^=<>(g4B`}w;2_Le8c;>6`JE2zmz#G@LFDtRso^eZ%hZVU=Tquh zijSFh7fF^M%*{So1t`wAV5Tf0PROc;A79irKr9^mtAE|M3RPE^@5IvUC{FgmGFAo_S*a zK4PT+=7u5)&PR)p-=V*gX3P|nKA2OJ=2hjSh*;Y^jSER56)MgBw0X7++wn}e1!wsq zLOj#zgqWiA6BWgHjDfYwV^3~U!@>U+tDxyCS9DSJ_jX?|8)`J9tLthho`YeLrj}(J zUT)-TBW!tvx5T2*@2_yNc-B(0mh=#p*QHIyYuu_hS9TDMl6M;lR1b;K;jU~uA(9oa z3TE)YzsOpwZvx^dc<=?>V3X+!E?~DdcOf|P>W@EfKL3)CRQUe}h~^bSAfOuOi%>){ zaPh0cK@47q%wtJUA)PlmBuJPEn}XFR`!sTAi7@vHVveBP5(#%mCQXf65Cc&EA4#&P zv%5hnKAB>(g+6;KkHJO+m6@TsHp=m*WPtyKY=AHfACpWdD-jYdgvofS_)xRkdEPvM zdb|klHBXk;uL81}x9UhVgcX1O!1Zo6UuQcq)5djw+5{IIzlSAQnY-kTJO%qvS%+$Y z;lzPOG9t;yMz?teg|csU?tk69KEuCmbKdv7v_WNJ4mw8ed8ioW6(mO`MO7Cby-X~OWM}anwybQblzy4r(?f+{CT( zixiL4&#^Q_dqW~ivqqzE;K~}c$JRR7@}t#QJk|bu7@%lx15p=-B_4%>Q4^rlXIF?I z6uT}T133GDhOW(^g8$M_t!^K3?Tci}sr&_z+V5j?-i(1PL>}gnRtw3hIofx%yN>z9z5p#yC(tW| zGx&nT@Vaa5GBF%11Jm#;^opc+plG#P0nxwuKkl3kX&}UmrB{d^47P%rF$FpmXF`jk z#Ca86EQ!;)^LvxvSGQZycJUg0z#m4BbSYhY4-~|v^u0Z{kRKjkVB7)kO<_@|i>=-Z zoKC`!gW!CTN3WO%1BMNx>8>PIQ&gb#t_}0t46-HvU3)ZYPv!34D#n_G#aW);^ey^A zNkKb7hpp8GN+XtWgHFTpmL7gaJ8iC8x3{@sG%?%y0eM6&m`cJ;9CwoTL7$}ouuoIt9}&7rTluFJp6IJ%sfg>8sKK1I>#0)h)-Rkh_BwWYaelMGCt9ZG{iY$mh! zt}ISdfIyF{0YX`j6Ck`*R-@D5CFMO7A#7}uPvM__RrG;0d{uBsvkxu1@U$^6#5GXI zilVSN7JgYsm#%5Hu*X2h)eBq_ik~1_UDf&z(IMed&-iO_8f;fBn*#y1J+eDw(1P`R z=Vk*^9F`rmQ0jaILE9ZtmH^}+qS;9i&H(mw{oakBg;vudyP5EJpRtAj65`SXMLhAP zJ<}d@4A|EyBkHn71G5dil{Dx%Th#xcWZ0A1`p7387`*rbkhK^t+O6RHV`ai#nCnt7 zNY-G&yjGQ@(}6d@G&NLf`2HUJT+X&Dt7(bRg0bFz74tG`rw3Yy8@LEUF;o(8GtO^Y zSuf{86gw_s4>L*7@Dk7jNEj^uuc-S)m2&?IYw}4r*;XF1QkJq}U%O@3(op1t{_7Pu z76=Vn*Zf-%niDIoVHcfeR!&L^RC>RxDz?ia{HQrV-Iav+y-VgixP9hSe-jM82*#e` zK`<>B!LUtRT1M}tycuF+9coS?KI3F8C9RkUl3fup!eP7x0dNl!;B4QgvNR-Vl8-!t zhDTe|XN`)26zW@x2h23&?@XDPL%uvIn3)zZ5%5jt6jO%r< ziy*pd6Rq~j-12$F=@9tZDW|mS(-pd{MF7!=%^&BJejC0lu+1!h2kFs`pMa)qIsn9x zlml*XqXZ)k&3PLn1FJ8KCJ9~MWLXo)!~+lKqfDD>nD`6qcm<8HZM*}XPeNfVp*yrC zu7IT*<^-6#?52Z_4eGBUB>m(!kH`qIj^N)zQmQY+*-lx2qCo5EM}Qo=AlNbfKT9No zc!=jcW9@I*Ho^kDYV)X1HZlcn3gM=;_=W34C6RSSTF6?hNOnx%Ma?NTQ^S$9Bu`zg z>gdlFKmVX7dfl;e8BwC+jon|wdD`dg#EUFFSHLE#(D>z z@!m0`S%N_+c&e;QPF{+o?4w@sVr}Ut@^Y~K1`Vw=fO(hi*-VPf=waDD{C^4V2dRrd zxQB;Ku_ekGhnu`!MawYR&DHLeR{Ao?tRLhaJpV>;kk@YO8rJ2jgw)LfX_3NfAtUL->kad&s+ZD; z@b>y|z`dN!D_oPqIfAoTJ1sgwrHT}XTDHgutRlu0K3AKnKt;qmQPgKb;t+PkA7r#d z-|lAWdOZNW3y;yxJ-iFbIKv_C2x=+v@*Lz?id)#i;5xh2Pq9?GR*l`;YK;8Cyu#W; zOqIKN7+#oXL3}$9fvTtQVw;ffeWMYrwAas&oBR69xH%=%&A|1A=;dTG0b!g{Ah4)U zZ&0T~rscBhPX@@Uz+n^(oP2!tnAFr0T$$Am2YX z7atuTML_T4v}|-TG&G7o5drtvL$i7iodYT7szN|03d4F0{12=@kk0QX97BIDTKU zj$u`?-m5*gs6W3)eA)#hjj3W-2%1Dj1E_z zIK2Jem~4PvM#G&jRZE z>i0-e7k;Sq9IdVZZ06bVXb0YR=)Id#1zHb-#G^$&Zz&Jl4>5S|y1cA_>W8{&egmRi<`o(*%%u(ya9ci*l-cHQbF>S~ z3FCJytJGvNB8IbLb|JtF;t`0qa?8iILZK^x#H%yjMVZ0B2|j>+UVDbJX~onK#DjLY zOY0(3z0AU@Ghv-C`wvt&e;#e}Ez7CPYFVxJz6goPK?hW8#oMrDqbt^~R9Q(p=`cwo zdy;r}b=F!q9Xp)Op;koM6SXS*!Kj4HHQ#aT?f0d$mws9QHLZ>PY~QE=*QL>%&>@uB z1^Y7?(f^@5Bh96x4{V!024x3TOvea~r9=qX`E=E3HxN?Y4!XCwlK;h5`M07UBTF<^kACEXMNkU%6K8;=h~r3%W$&p}lH!A`=J zae*Xendlbn?J|wYmWeXxTfq;i3vDLq`<77~4Cn@T9dg&}RpTk-Z?+5@f~{pAEB??g zS|-|SC&7AwgL!xMG6SS)y30f2Rku1f^vg84FgMBUt{c*wb=zKf~eB!yH3 z0bERL5`2ih+SBa2tFZiOtiCJz?5Fp;kKs8-^x&3V_p$VC^Y&MoxJxhbq0u%N)zm z&4Xj^mi-BPQ^Ce)3#vmErh?n$ix%A^D`L91p1Oj7e;RQ#M>K4N#a0_+O&!~~7pP}+ z9%B?dyeyjK`0#>oxP{;_D znSM-R&C;51%Hm^ftKSiM--$TDY7dN98=Mr~GRtLua;zhf*>D1P$&PPsy4FpLY3#kP z6dHVGxoZJ|L|rQYAXsH7$>C5D0bSQG-Qe$2_;-d0-Kd;X4A1~tVnDIN1(yC+mP_IC zbJVg>FNp=xuK;GzSZ7Ph(rkyF`HfLGJfZ>B@c$37BJt~KCZX0qMJ>QeyJ(x~yfh4IO(|O2XQ9zY1{}Il)PHSDeA=w3zinR#C zzxAD7+k`91Sejig7MtyNLT!nbQ3Z8)sDv^Zif5#M@g>pqfs!k`(j3^$4nnYRGCA=) zn`0~}xO3H9?kH zHOR>FW*7#e0G3itLb><#GqKX+Jm?DWdYxjno3{&wONy-Y03yk=PnpL$OljXc1VEe! ziitNZB^C4dGwYq-MeO)7;vO%UFR%}LTA`6oo@c z5an~!!r4U?7_T79w#=okKt8$uf>ITSjzR#m%zk5cZa4~ z7)!bseUhyD+7#b=nXda+@nt^MSi#4lan0iqdmlRg%{*Q&8ll*j5$~{ySt+fUE@qco z7vf2zZ#<_cs0FgDn7V~-m%LPmTEp&xcJt0Ig6$l>*9~U8NfXt6r+sGNgxOX%%C`qX z7qQVcL`E8?Gk@zVh}ZiewoKfN=mAKqXo}1Hya*MJEjOGEAvsH1!|ym1N@z-~GTfAB zdMAZE{VeQkB^cQl;Jp;ov7R|nnlH&;HP3YbB05c*F+CFZ^f{b7Xc%G+;93(%WS!`C zY9cf0`2Rk(PZJ3cW9c}1rBa_ZR@5>$ETH=rL{S1~`hjQAZ}0Y5@P5_DVAPmosFV{;wi zXFrV`N?02a>o6q~AnpHBl4Kt<4@TrT4~38??Z%Q~T91vUJxZFW66d>U^K(${3+AWH z&#$-@immyxA&7XUOQcnx`Anwvj4a zx0VLre7hoA5M4`NJja2HnA7dvuy32N=MV}~Jj>KTS$I^*V-ZKxmu%dS1g7=+4w@(> zn(8}OkVIucK43rvAw8}Xh5LQlE$BIP{3p#mD%;s=3Fh4Q#>Mm;rnJ+g`+Xy3zMh-< z3vv+T19v}Ul;(Q3`P!J^O_Y8^q?E}?DUX1OUck4x4=`Nd4zOcCg+w8261TT6Q8Gac z_hktW!dXPRaw(pnW>=}^S@s!)!Zso<`6HIC8f${(u!LR<@v4TW z?K(C;IZkV! z@Vn}N^f=fkq6tZX)8p8ixSLbm>}DKvF2a%$@2a>sOIQemiKxHb_B#bx760@Gt;_Bv z3b{M+T@_J(1v{oU$Vk&X4c<_P+O&~^+p>dmzieC0Rw5kQ1RYdrl|tQfUpHZ)Rl@ z%&4~aDJ`#I$v(1u&jc6UXyTg%<%4co*7RdMMGy<9e~ShVv&Sh80gJR&-7@{#Y@!3G zf9OYBg#F;T3{zu3U@~@b&60Z{kMU%F`~m&=EqpJRzK{w_@1s1BUIV9-qel#Y22oG1 z#EgE$H;vkO;{kqPn<{H$5X*BMJDC9cf44n71pWR3*3OWHkBm3S4gPz805CX2=ZVIz zGC!In@s`bb{xnkS>rfur)XNH~Q$a2018ubgsYmXI6iwimI9gx68?2;_|wNUSp+}jZ6P^$h+eFVdhhbN*SSGedLp; zJs{uN`oL^uc@Lb=ypsg%cnA?Oz#}K@SkU_$Pj)6bcFp18J|n8Zg_mELghR}9P~ujY zXd31vEKlipBF-!!C>;==u!u)lTrSj!t4x^9_o!xYobMzoF*XdXePmxL0L!R5hNlPp zE;B;28;~-c(4Az(Mk`?~eZSl94}Ehtb##n=U?q;!P)W5oHXl-Wn*sG+-#h{wT|8G^ zV`GX5q;VB;W*hcLFvp!jx1-6oZ)JIMijq^r zb5QK0etVFN#tFgf&h{-HHJ8I~)t-e|w*;OSWXmXmQQeAWcmIO-0jWQ}tk};{_-$w>7-ct!7#fdTkWlrj;H4A{r9H7j zIpcP}lIAKhMozLGJvIFQvrji-M&**&hI83b;w>% zmmN41Zn8@=rw@z+7>WFCQ-t0Q#$ad23yI!PY>&fioesZeK-I;VL>?HTGE#JM%8kS> zr5D(c-lqwQG6kZQ9VjHkR>dp|f+;H$pwl@Pm$P%sD-8<mAvddt!1^ao0gv?t95O6>L?zT z2`bk8yiA@K8sE>cPl>~0U2RiPxk)_y?z=IEHGb{EHu=G49be?+U$+WC5ush}sGvO_1UY#^%qrza3P9W_59*s8!muCfI&@}I9BfVp zPH-E|!<|igL8pV6N9K`|%e4^!jSuB(s+M zx|9=X19es1{IUqEs>T4|fW_N8=57Z#LnK4eR|#I>`b9jLbnrO}%0tFEQ?$>RUo(dp z;caq@K9)Y19Jy^;hN)@Cj|YV3(HKkw*M$_SRR9AL_))o&`N6USrxt#&`>rs&F-WkM zx7(YMxBDFg5rdXEI7+ChV>)mgCdH`N1yZ;Zp<3A8O8=6LkIXqqkN`CjlbtTe?}EA9 z1xj#Z$yI<<<6T6ePgRq}xs8~V(q#}Oh<+bA0A-q^FtV9>-bpk)^D##yUMG*GdFwu$2t%^!c>UK5| zSJHPDB4mmcA6P;QVtvzm#S}Ej_-(+~LGl6aSS@{28Wdy`a2GMjW>V1x6h1~IXA{7F z1$Cl>qOCL^Crtk&r>DzB$RFk_=Pfr!Gl0;C#wQVciG;lAeU*jI+;3V>gtAiHAl2^> zWyFC;rfia??@)j|Bn3eD{|u|j-=@WFgZO`Su$#17<6f0SqZ~ znbA3>*V78N;c3=UxS6LL#0Xi3Xw!?g{rpm#o!jyH^Ef@*cL&4|cWBxS=?4Y3s|Xzs z2H6m>bE2X^yERw~Z4H2J^SLm9r&FfF1OtL90h42U-ai3EfM7WB50EzV7Jj!mKW!mWP$#u_8}PP zTf4wF`QCyovL;FcOA$%ZvZodMR!98vsHTrwsid6kvRa-bl@&n|D+1{j4aZ+cT9{re z9xfJhHch>(*JN*~uNNV?E-5*t1uQFGkmjhDQB~V3zXska@H3WD6ecsOHzCYdcP6-FAV(wQ3fev#wrEaBan=m6s%)q0G2Ipzj|4lH84jl7NAflz z(gOYC(vBFtA|8@Nlm0I)qe zcwIT9c*uEj6n9Wt_B`H%&6=-y)e@(nBfM?NzUFCuiJ+{gSTFRfS(?l8o0&00(l~;+2sYAozdMI2v&QShz|Mu%{R(Jo2jV5YJ<# zQecLU;74!M08Oe-i0#zSfSC)Z8_^SFRmPgk$PIW`$+QEoi*;8LC{!A}1yq~%1f|Dn z9tg@`!|b7|%IajfXs=$FQ&zhN!paBC{c65!#izhQ$E>~4r&1oNPi3AL3y0J5=tk!= zQy0yEZ0ffo3`wxgv5@_H%su9l3{n}6fg)GdexbFdICjAE4{W;{d8X)8gE)Jh57D5B z-D5i^tgYB6U`Ssz>{Gv7CMS`|`gYP+!XZ+{+;+waI#U7Pn z0%&v=dF#o)3jd65r;+>e$Kf1VQ;%ip_1 zkIfl`am@6k1TuSYAdatwVSuY04~Y}VV(gBKXg+j0ZNdqD>kuO+7+^Ml{X^wcAG8=U zDJuvx(wAY3kO+xDFZm>rOA)V+4^iwE0kD6sKwg|Lw0Pzr$Pq!GQ8sK@Q z6PZjepo#$2DiyH1Q*oEgo-RAQrlc^O|3544oA#S;acy*N8pAQdWA4L$$hGp<3LHz)`?E%qLVu(5gmBvbAUw z=^)6H(SPNB_9pX7<~D^kdIRScb!1Tatq}z`n=hH-TjpDzK&a~LgL^7yNCvbSlh zY%LUi)of2hl|YUF$`1wr!uhH9CJRj^IvAjo(A|E{oLd;`_}LJPC(V-|Vx2DY9H%2% zuxjYfMuvZX)qnXz)~4t7U|blnt}GRhz1&c<$j*g?DTQ%j?I)tD7xQ zR$K)!A1U^u6QCEz@Pkbd)m)B0_X3l*z#9=?A#Ym)@-qmE!s%qgBEjVb^B@o0+{|HF z>%HSS4Iy=yGiZ-y8!B~H>1K5V0ThGZ&lNFFC&UU4XhNeYA~yF^vxaQwnfu#JVttDu z-@xp+|Cmx1X$ewkw_cdJUe==!YhNthf-mu`pVn(h?6+i%%hJqX7}qWfid`mX$^2x{*_VMPP9WPGkXK z_SNOIwyX;4&tEGm)`SZn4Hu0CRKWvWUDs}|zkI>WIskB>Zg)>nj?~2$&!a?Tc~JLZ zBMePFz3ks%f^&ctBB+vZ;7%q1wy6ds)c$2Wd$kI)M_}M|0`LHFw^gY1?v}tFn#&bw zr*|LNejea&OcbEdFMqF3NH-(E)+TB*M07FHjq3ZPU{obG)i;aD98-W=ta%3yoRJ7H zkBocN^cY`3ZdVW_FH7}1rHDLa1Y!#70g(^Cj zvW&95_{XPV;>Ct~miTbaFbd~k@lhD9?K~T_!9rrD1wkK}2DMHWJfhy$%A~&_!}>q- zr>=l3_JoaNe1J%XEZMaeA$r%9;uU|x3hGUkYn|QG@tnb~Y@FvcC)j<)&MU+Pne zJhaL+SNQci!v0ya(<8$+kto;&u8B7CG)l&HZ*^D8VhaJOMBz?cXWrSyXo=3BN#<>O zqrp~(A7sju1^e?fcuRH zNz^s(?E`SX*k|wAC^}xYcGO1L&fnE!=z1iCWdUINC`qScP%7&9jW5J4ox>Ngi%0lt z@#Auvu}mdKDRz`t&}l?m)rX-BM(o6 zGoU2@QSqFr^P=X3Me}n3aw4sMtDe9Y&*+GcSY;AR1orZt! zv~>KisAnZd1)r5Q62|hb2q+e_#9ZlEv_~ZB*dyv=F0JY%60D(=E}}O$clAD3XqM(b z-@{Zvo^LChukENYbpk+UNUBlO6|IyJBSWTa@wf3xZgWXjKMqVz+}gTr$Lu^wYk%MQ z2n%uH{pP;S^J#F)Cg*Nn4BO`?nyv~$K0Etgg2Bu#*63}5+eEFQFOeB#8dlG!bW!02 zf_^IaRve96%!t~*yb>5WVd27rH)5~Qr$KQkD8oC9SS<&wf_4PkX^6NW>@3usKd1Ki zPsqo74!`9q$C960w^TYQcdu#T3Uyj7`5smrbsf3ZwoE9>TXkSpV10N6C0A$aRA`Jk zE)fi6wXCBBf3!qP*Y!`S-!kdrJ1ymkb~-uZeB1pv@3k4P%QhqxgFo1!3tSYVO7)(> zvheE-$hmowwCUyXeR#W6z1~F#Gaupg^VPSVZRmy$OC=kTrz&&OkZwlTe1M6MzW1KX z(M7-*F0+BZ-aEa|GL!aXdz5{~=5>+|(SkH-YX&-HLzu988D5#z30sSNQc!e@32-iD zkCs1xY24N)f!8VNM18#!B5&a-)8D+^fQrcln5)O zn1kj=Ua%h5@nlmi3>yG?!rRM8%VLSkYplR^oD9iX56BLU?MBeP;UJb_ozAY-T+gu_ z_&nqF9Dm?FEB8+y!ec&%a>4@DoU&KZI~#`w?*f?*{21XN$&k=;#;QRQtz1wL>i? zNRj<#l*R?5$S$bzCjNlbK}-y7(8n5@4joX-BVI|T1u?*{qSsLMm|Lmwkh+==k@0KA z-n+-V0-n;R;rFkuX^F(NyjU$GMJJaKOf;({HN@+1Ek`fqqpd`QUa2h| zA=sLH_3>I%_EqwZ{0(R=GsmvW%Hq)<34dn7y}e>$n$X?*ag(6=yBQ4Vbig|z_s+b` zZqzqdf&=e1luGCxa}((1?)?0sx7vN9};B#1~0 zAF~FHP{MM=_F&yab)Y5Ji?doI@|k*e{i1P^B^L=Rwg}JG&$YxHsDt^ZUw8&Kh(Ffe zS9TrE7_-QhVl1&DD+yw-Nw|P2>E~uj3EM`G`Vd4+A z;%K+OV6U~n=!9A=5JpDPrK$qrPTsK|lzxCU?*p4Ck1uh?k;Vd&mu*L^7Hg$|hOd6bR06K52)V!#$C&<_zl z9P0Z)@rHSP10ad{k=au(4F6ydoL@cH=i%C#5H0DXkjq)gJSvK{1p(W{!_Zu-ig&Gr z8CG^*iTKTa5WVXq-^$g>t(NS=pH)CA*p22$zErT3?HgN(UO2Rdo^ZEEyAGF~u`w1gn6VFxrR?mO-Wojh`zLWTOr=3=7Ck|(z zZ+v#vi>Jv8WFm0v*jVP_ZhX1hzg)x*e3nq*AZi6}YXW52Z<_f&)o)IZ=>Wqdym-kW zFI&0Y?Xokxyamaz$l~mdNzolI_BVPVz*p|F^*jAr(y&+cHfmb8MT8;9(j{0-m`0_U&@lz@X&WXu)d0-IwowJ?%bk@Gq%BL(x z6cxH(5XFOOYF@90ru6ELFv{w#?5vNmEOzd3~q3*RgX|`dr=UFDc zYOMn-rF;HsR;$+jZ8&SSY`SqcZ)Hr2Sk>}2Oonzmq05F(ij#FO8kw+F5FM(k4A>3r zzMGR`)@dIg3{%W%<93VQz?fV6RK((!v^uT($Qp5@L0gGVbN)AJwmN-D2@zNTU};tk zKu_cB8)CYwoD+rJOY?L%S?uqCZx@o)*|_~w@vDnj0p=XLUULVM7UeCO? zuN4#;Rq_&Tz3f}h@mkk zO4b8lp0~KS^?VxaeD522V^n~F;ZDBI_JAr#CTiFA2s(8;<53*$14$rxg+q4tf#c`- zWN&}7OS_Td3{o$1uOf=ZlgX5W2uu1*@_~JJZYE{a%6`rVB224D9zr|5f?BG15q|e3 zHGa*Gk05}((}tHq836OBs_SNBTVhElKqy{A_G=&MSTWB^nd<^IFLID2;_uu`Lv9+L zVzGl^REF-1VvWxNr0Fq+^oNaeQ(kPhySu&G z*hSc)Q|fg>W`R1+x6KH}ffpKA#2+r->ck9cxb*0tN^UF6Q|0-+q(9o*r4(2V!)(_7 z9(qto=oM+70V46f=M1(xP%#KvZA9Si#hDf6SfJ2HQ(Q!!7qE~%$z+d4T1RtBp#`_f z{;0V}?wcF8Oay~yTgmW&p`en8qxTvjHH2Ni&bu&@*h*i`vCVU?)r1Zp`|n<5k2tMf zFb^WCt;l5~Tq@)opR{fzdwD(&NSO$(l*p``#b>(#86~oWUNj&#PJAGs^FM7zU8*~Y znt9&7TA>kP?zegX5pyIP3gaVc@7%OWMGV*aZQ~EAnDS<(vk9w>qdOPau~NRR^M|d@ z_WtgaR91>*`)<_?<>~f0s!Jd-2e*8ur->Ma;}fvX0mM&takc5sMcz@JxiLJXdWWKJ zG-fb}lN-(0?e9*_R5VvMQL{^)B>wh8=4&gSTtH#AtG21OAmrs6RJN4nspZ8L&GlPD z;T833**xnNU>$f~FUshcIV(67Ru3;n`{C^ zz-&Y+PtFr$xn1#P1`!B@fGH_}w5a)z(NILZ33=;SZb7v`tbY=W$0Qe=_A@9~L9+1? zm2NQi9UZE*=M;Fi?%vExCNFkUfOT=%C6RE#2L&)xtXFPj$oKifFB=C<5meo>}uk2=6NnE={pf>bgFX8&Ix?+E6)sP^oCDR2P#jG=sJHLAe!XLU=upRe+ zfv1HzaFD)m8nJg`o_W!!x+9OinyB*p4G$UDb<#04K?^ffQ4fbPeX_-LB43mDK!-0Ln5DuDhSj|sni z@hH@1VzDO3YU&^Rf>H$l#tMbz%ROsXOuftx=_;MMI?pmWj9#yn;>0r+38vSBeegEs z6CyJX4rn82G3&-`!6Q<%&J{j?<%9>3ogBw&H!y<0ObQu5^spjV`j_GY?N%kN?d*_S zRtRei)Vgy#EwoFpl^Bq|`2Y3iIM9iJ%X@G{MC0%Z^PE6&b{IHMIXi&`h2t!O%lN`P zK}U@CcD6}3(HzMtHt@vkz#Z% z$wDn~zba1bUt;>a_M9U=gc={kkGb^8519|$a3>!h^JX6-i2%zWL^8O+@3c~Iqv-sF zT^}7}0TU>nHO}Q$R&{eAtZm)ZP)+LI+f*jJjX)tQNJk(2$gcnU&_E%DAP_66J5SLs zp<&)`W?PQa!8>s`83%TB6Q!O(_78hwSHOEiMgtvW9agvZM7}&KTAS0^1W~e4o&lg& z7yRG>7aXIFaL2&p(6&%6C4<8M5&QcJ?EN_M;iICiZrjp_y={pmp>R#M+pWE*Et5lc zXm?C&NE-iU85u%MtsaO0cATlOz6fh*i zC#VMeB{MvlX=_9=I7EXEEwT=Ij-%aHXRF#7GX+F7mgaMK^bAB&U2O+_S*SuyLf)KK|#$cIE6r}BaRrHfQWc{TVdm?5>xUr8G>cCqh=;F-P|9r6tzx$LozsXMGpuh z%2_puC=e+dfv|-7rR3_OtQrP~Xm&-!vE@Rtm4mCL_5q6(g)c13gpp3(kV?=UO38wI zXsmFlzwnN-&>=fRymaQL;LjgYIm=B=fIM?{hG8%(-2N2B&ew;Gx6JdM)^JK;FE4Ci zRxMnrwym`Ohp-O_2cbECQx#vSDokg_ATBT5%0yG5xGR9GE-72B}J&D zl1fskc2|{aaqVT73%hJrdAG}UdB7`XG1z5;_q9yZv;hM{gKZAIz|aN{n@wZp^qezi z`t&f(HqFv>Hw|uPj^}s37a_?8g(5TJy%&-1yZ3(gyWd^@ck?td$_!(Z!6E4$DH(er zkvEeZ`-pm6$9byRa-o4TB9t;}J;kAjCPG!)4|1@6x=E#iZkV(spc#Xt8(X-0#WY#7{6Y0dUydame0lfZ0)X7AWihAl6>~Le_ zAP>5p)$O)%u~X|P_$}=iUE{SWMGryLW~F0U6AXg?4`1zrXn+@M8{t)~YT{jA)QSLl zA!eHL3oVeB-@ytIS|m~?HKHu%5nHH^h{|)tfLawGwhNJSVFzT_{~^3)k9_lDE`J3k zRVzO5r$^9E5<_WzYC93FQD}^SpJ}2BuSo+#*SrSq5YJ*z6C0bBk|FU;7h%-I=#p$M z;M&|MXcFS?z>W=m3N&WV-eUAZfkSv`4{@DTnwz1zJ{G^REU5cY-V4)7Bc9vpD|C+c zsY!srK2Clyq|pWm;D7WfA%_7D4OrKZilK`8NP!NDY>~*&jGV*jMjjg(E27k!@G(*C zCBI1vSwndp!-|n`H<W$Fx#RenY_ zUuk3Lr%AuSMqa?KZzrm-3QB98BYc7Z9-Ldi9C<6RgexD#GT4L?cHGF_b;rXfV#V8V zak#O07I{3DM7<=b5dIB<3ntzF9#(HbbKFh2%$qL~dc(Llf=d^rs?!Oc>Z-do=Oe4( zI>!!yNvzh1oC!8GY`~bXlKH5Sw`Wtp;!{IER)jh!esEITj_v(yus&2+MdqO$lhoH4yBI z5TavnJn&8OT`MQ8NIuuH;AslV_wh!q`O;Ycrl>MoZ&>|^15}K951`0w_6#M^R#N^1 zb{feoV_bbtG$vxRVO{1#-&ttrk|+wtFpoMpP-`tejBu2*zPJH?b9}Ji@EUQ(M%-$V z$xeAY)jzlc3uy{Q&^`RTcs&Vzs2xA3*8PxjI`XU4j5e)3N(;o_N;}#Hip-V7cbplv zeG=7imK-{D+uCt*G7LLPcXs{eXs|Z$aZ5%GGxWp=Pv~PE#b(BiRM~|Uut2*V2}_R# zwkJ3z5`ZEF^IQKFU*&Hy^Wa8J&I$>W=RyuF54}}wFw5XRvV#8kV~7BJyG%ar|CjZ8 zo*l&qcmdA=pj_fJp%=jGc#(bUZ}HOpOEH=FMiF8C?cebi?wjD@`wBUA7kE6R{%`a~ zkIfNt*k}T~Lx`7H@PN>)eE+NXTJ9g@M?6*OxBddp-S40+Zq|QcdB;~&Aq$7Q5C?(q zd^U5rg{uZC!X;8D7CwTpI`u4l)cGUm-Ka?)XA&w6a~De`p&W*)DUVE@LuUl)TvJ6t zeH03rH*J%@k7wJ1(2`z&YI43Rv1@9#FZd+D$5`~Z!W*Xx8~1Z)uAzIBbsQI!Fxxr7 z_gtb6W12Cg#zJxPhvgKpESx5SqFf^`N)yL3jJA>+_O#Nt!nEa)%R{M0DDuucs0E)F z_hTa$%qcfN~qYU%|0N+g@KsG2B|q#Js8*Qi`i) zb-N6xth7$7;1G&%I;#ao_yo%|8&`~6h`i?NZ6-n^vH|TUQ7Z`u6cYUzs0$WF!!}z- zTF+tExo>b}Ep_`bKw0Vr7qC0i0khZkA&Jl*fM;_@CA9hoON$P;eCW(1!U^r- zaXw}ki_x4z#D@tT8^bUf+0Wy1SfhTtXFhnFNGl_biBw3v$t^hJzOy<}1|>Gpm4%dn zqM#NohZr}by-F^H;nkAinnLqW2{dPk!$CMnOE@fu#M_}QU8DbOlVBovol>!Xi!w7Eii?HW+}_^wQhqZ z6*x#)WetPu8nlVye;4%&M0QA4AczN1s!Y$&@LT_x8TxA^c^nshqvTnEeS zEXSyb<*HCEgettL=&RszC&Ts6BQ%oq@v!>$?C)~P0)^LI2n+T>bAR`a_ayrR`URW2 zzsBDW7HYF6o&&)`Xmg;)UJkhhYGM;rLP&*p%C_3*m8k=|JDCxxk8J*>`d5%c^QoF~ zpY`obXWUL%%@-U(N*}+GmFy+1_X6`%jcBoz<^zWgf~kM5HI7;*Kd1E+Nha?eVB3_v zq6N}-Oas1N9}gcA5q;~=h`av^3#H8CS}O{pVJ(l9!Vi<9|H>p$@8F7W$F(Pvuqy?iYW!}lEl83j(Fe>)hi}F(q)kXpa*|a`flU#KaOXOx=Q*~DDYWCeKIKqY+;^K zH;o!W((6Q2-dIs%`#1t|54h`02tWw1a7f7@AL5&=hYyiO`YMsu1w1cVJ%sudi-&Nd zVyHaJiXZg@<%C8;M07r=-XL<|%Ax6Oc~)~;K28<@d|n8Vs>PiDi&^=-+zqo4s&{3l zIs>vy(1?uUUV|tVy^qB6EAVH%ayX&DQq3wn(QNi&D#4uilr-*Mqjg(AB^NzX`(W3< zTx~nfuF8)!iEQHP7Bpe|MI@N5d7qyEr_0orMJhnEk#pkjsc1}b!HHokxzX&SNL*2I zT7(8@_Eui4LowEUYuG$F#iF4m8~A^2AqdThbS}gslZm16log-Za!N@#v{v(DzF=ILq>jkAz{~ z&w%k_qXuBa#$uu-*RTa)GYD8#JK037t~@b+k0zh+rH2@S=yU$bJ(UOuBVjC}w(9Mz zjDvx3yZl4%iLA@8JdX>OCy^@TK~g{Ts9y(d=>3cwuo~@RlAn%`$BpeAG}JJ(_JPDW z$+ly}_T%jYZYb_Wok{&I@tm$RKr@bQdsA5#6mg@x)4JEG7KxlC_KcN-Z2oa_;UTUf=-+NciOm_zANkuFKbm3@S+bK;- zJZD97i-h<~7M9pJu_IPtk{5c<+iK(ghWYF|z=>D7EV9nS>s`pupkO`UB3{VCsOqYiYQp9@d%}|v{%mSK; zZ17^nbyv$nO+K#v<$>R}?4e_y84@2M&J)m(3=R@2cj!dE#l|z3 zgaX*rr`#IySl9dQ^_VWuWXSYLwS9~(Le{9=w8_PGpCF=EI_@uH4gfDb?5UlzIu#Yb zQvVo$hUBA#R`-P3p~)t>-D9KUSZly8UCO$~_O=~$4!qp~N64$i%T&_g39W59PvCDsG0-A3+EB)IUfxMPpo<*WA^C@p z{)YVq65V$BuBX(`ty!RfG@(hqmz~kMMusp}vDHplHOa6ru?Dtd?gce9ir(sINq%o+UEa>gq`#lo36F zC@iY^vs9Ybp?*P>J%;kxiKi*^ zDE6GjR!*(0bz=d5Qt19TI#$%9?O?2S)jH43eol11B6aqbjWJGaqeozsGvbgA)Lqv` zep)r!*v@O(ElM+XE!(20(Oe|M({}33)@K#jC?W-(yl?RpwnZ{2G&W# z+=->yxMey~>e64$8dyQzlpTw>=EIvw`$LV#j}&=?gG5l=Yvf`9@0#K;xkQLdw2W3V zt9enAWd_+$oHG0pTJURLaUE~m*%WU+lMY#wpYBYPNbENKQ6`tro7bwdt_Jj&p3XLlQi^v!F97!Afu_ZiE&q!)E3Jd z`lX><0Lsl{FW8E#DDg1oPMD-FgUE}+KrAWozJC=h(}zYgd`35E`YaF+hR<|akqHHh z5}88<)>(a$1qXtlY-ExmLy$vES&<)(a_t{t`rgyUxY{-CUGsTC+QA2oZK&L|^CleS zf;Im%%gy^pJ7~J*D?y#a5hOB$GTw;XZhH{#Me+4tJ+ID7iw;KAP%k;%@UyOA6=7=l z(Z*rcnA@+%%D#_%SU2SocO)@2@#=U1fytI1bQscPD*j8YBWe2h6+_p{n>Vr9%uaR}@8s@dc(XDli3&)PaE%knS zr#l1Z=pgX>-W%u%Ms(M?XRmPLejF2ei6@{c@<4|Ky)&|Rfe7Y)lX|T!z*%#;He|#M zU9V_UzvE2EJi@yWvUtg-iiR^Tg5ES(lc-Fj`%iqG~<>#%To^- zp;!^DCPb}igkGXzxNZi?G|?)=MMOqE{7KQiUG1GS4S@@uvH<;r+ECLsbYRZVvJMf$ zE2s~MyTny-b+U!4J`4Qjn?RGMo-(#>!Ax4V6xsg_w<}w3?QG$7g8xt)|38F`$TExc zOxDJ|qS^3@ev)9{vD=usTxVmfl17}SL|x)_tm1Wiq^s!Ef2W!QBo}6f)N?PW;L=vv zGCWmtUC03MA%Z-ojF%$}lu;uIb9v2wh{PHsi?Le?g=(6;b&cwt((~4&drwkldYQ?mcldEAT1!M#CR31xX?gAzsnHRlmXg zTp*|MHf(g=*_>OKnXmm#dP<-qYw;Itd0845HdK+PmW6ukNCjgTlE^QS3|>{dfij;h zE~)nnXy-viCq;`C8W1USwjZK4`K09x?6>sD7#S0UM_QzOkPKq~gk?v5r(nBf199~j zo5-7pmRIUcRI^ja`wU@Wa+^Lay_Gje30z-qgZv5PB4N1FKu(x44J&!8e#N%mMQyoI z>k;*$14P8mr;!gdxW6quCl1F1n-aWT4KIwn2@}+kK1MKyeorUaCUdD!W7FDD=7lUM6DRP=T^-mR?(dj&(&AQk-V{0tL)f)m&gg&F zBoma4A{qw-CnToNL7Q}{An!)_y&7EsO3wtY>K?uvJrmz|BC+#!9EYH?ZSM0C(vJ?= zbUaYUo0LP)$-^;ajhFh6|3rM?YcTBy2G?oqySw4!V=|W(D~+`|&)YY%*YGmm>%%TH2`332gGBT}A>tviX z3u$QRkPu&%uAtu7>ixH?+s|yNH>eH)S-c{fKqnl+IpQLD>*NBjnWsO*w0T7J{v~u4 ztpgZ`tA$b$Z0LET1qwIDV<#ggU3Y23!EQJjQ##V1`6l{6MnWB;*BNs-^%P@ik9k7kK`WIR6Rr3c;aFZR_n*sK<+5@X1%5LlQ1U$l;ZiQEkg(rm33 z^~%XlSSJ_M=UFW(VXwZ7wPU75pBH*)??Yk@w?*10xj9Va)EM1wfF9UOonBRTz*vhO zVgGtN<`BI$9V=?$umsz%k#s}MNE=xvw9`zP%+ybrzFR&7CXZ`}KiIdT@Mr1mO_GEO zb~`St=8if{h~enCVK*C5Ocns9zxr)Nxr5bi+vKJBU?!2rRt>UFj1I*^MN2p@uA~*H zVMcBq-cgVqoE=dmLLk0-p_N44B@* zm+vtxkEoL__0)R19MkcIP_q3ee~gEk096Lo@R#-w=4Xn|Qj zZL39zC#4LV2A&hs0Ae{K*Mv^#g2>sy1}5V?q1VH<8snAZ>j-37AGPR-N;0)reWv*$ zG%HIlsgqDks%yaGV%?tgf*L|C9zugk&dgDg5RG4)YA=?f)KgZqm)TqFxcjh?>vChv>*}}*`}8!etvPCJskhPx1wb3Fy??G z@$m_<@Z9L#<2Q4huBp{+w%dd<+%6N3ifO0OzW*ud|BOCmtO4qeMlpqy`6a~Y1R2Y5 z)S+SGZa+m*$Pgs}c21-5!?jcr+chEb9zxo0Faz4Ou_oPz{DdIu3IaS14ZT_mX5v>7 z^XKsg?qk3B>Uvf}l7%K+dDRO93NltQ-yl$}Gp3M~w<3?VN4=8w{1?KCUe@Xc`tnIp zH~f~BNmIAdYN*HGyqh7wRK~>%m*&R$1m`I|TLFm4n#u-i!u zqwkF4&~`(L&4+mF%|tA*DS5DumcTLXu);b++dz6HH8uss{-IZ4nSggH3Ye{v$T^#E zTRKtD2@n+TU~r)JM={_}Ebc%Zgg!9$F}Y=plIjzZs|co7#C8N-@ZU-DVxe7F=gehMA{aWrmVNrc`OlA4kD&pGKGpW zP20IwaV3}YAqc(@!CcI%c?H4iFR0|mM`VACp6Bil_nR6}G>*1+P05qNQAOPQVZs4mvC#wCR&;7d=HO?>HE#;TtN)!`k@g zXjAQELh=u>jIRR_xT(It8Vd13Ajlx!5vhtZ53j{uOp8}~8kxXEv~*aM(IUT1WL!`( zLaQRCSQ`9IsvapZVSj6289Nqj3Aj5qTf>XbEweFD-N0{Jk6y0grMae5?utnQ9wYsD zbzJJ}TslT-J}4Zi=_s;U)}+$J7dfnDSP04l7XcNe;A$p8%~~h$nfkKQWBt-{z0|l@ zSS;TqlE1Ry;ILd>AA-|zrqoNCe0Mb?S%XyL9J>gVNA=3rsoYA`VN%#=z~dP9tr9_h zjahb((I)6r7MVnAgo;N*Fr>~F#8CV};MKE;^(1AE^Z;5q;)hi0*bSMH-{iD|G9ZJj z+iq1++Am4blWd)gm=C!Jp)z)D55&`aC=tHxFJYH40Yq_w0mq!U9mY`;3>sFzI7qQ3 zO(XMMR?~=?ZeFGKKg|3>{f{NL9841zBU=#K(n!YqH( zgymh$D`DV*Nj0y8k)FJg7Yl55^HZj|PMFG|0V`=k8)mp=?Y7SV<{0cW_Z@TgPpL+UWeiI zC=8)P0-GWBc(WOYx6DxW@R1Ky1>j!GIU13zlVjb0L<-7;z&)~`VlOBiBBZ~;c|`9n z8CeCbg)j1yRZ`C-h9Ml2LCAX^GIMyR$E1%`j9CwL`4Q-&4?Olm>NDZ{4cf;TSmxFN zWwcJu_--43<~^j$3CR8Fm(=rhDXS%i(Ox&DA{D0+)mfXMXk1V03%o$?nmyk#wgM;k z*Nix3YbKc*1GSE(VgC7QM5Aa%OSO#CaE3EU`@q}kS~pNt&opDE>J1*T^b72>0i3cG zslpQq$t25KGWGrjS`2lB?;>`|%8MjpMFCXMWA$7xv;|ax5LeO46qP3|`%iIdB0J`~Spb#Bun9qB8VD<~Be_1v=1jc1*u-yv1-9?!cS| zXGca54qv#7vv7QFV5|k!PcgkE62U)0){-C!vLH%Wph8;e%_!EE_ER;{tCW9{?DlMvw(Y&EVxzOX-(`o_>RnaJ{FgBV^*L)%PtfzjC<*gLpP``BtGO-^QoU9|I4B zQ09$nT>-ww38+k#NMNeb!VtGj)z}bhK2M!B(RbK%ZdOHEZh<%LkXd+CU4wfd*s{HL z(5J9G%BI9Mu@wAAjD}+uwhI!{Z7L%FS-uaG7{>$4DO(gUIqA*aXg)>uglB<#8Ph@c zmoP}kWHa$V%6^2nKP?(&+mePsMp1rr6k@C7f#BAVg-cRx+YL6S1Q-tY;fWSX5)A+p z^Ri$JW+Va)DlLobkop$7jDqK=*51#bWYDhjU_r5^yz)*os26f*MWBq+_-ZNYin$V* zrY_)Hf5puHUs+^HzSQ)DP4G&y#lsGUuEGmw3r%5UeHu=2iCm;lLT}!^6O?1DP7?=k zv+axqN0k|M5+fy_#ve}BA0&zjva!Kw@eufF3Lcb6XgxF#EgY8sQ!pYNUZ;`?-65tY zfkGe)(A;t%i8}F|oaWL1ctv$HHJWxrtpoKb2Ia9PytS~-{)`Uyzk~DQ2)$7Cjuhib zL~V8JG6qH=L#)T(>cQ#zuT~ey@b%ah?iCV1fM>~neH_NUh({?^@`j1!y2|yGL2Z!3 zI2tFUd2vS%Dl+V#ITNM!eG#7ed<*y&SlnS%*(&SjvwI_I*S$k`XyIa zJZ0n_8umXhhZ%L#SvNxQH0r7K01XwwVJODu0<)H;5oae_o#6_ z#j4EdnC6U(F?w$qDUDp5-sbv4I2ELRh&dyTEPFlkJ{Dz&_Mu^u#&f4>0ZN{M=st>D z>|>K%&u-D(*cl&VP9zE0S)#%P{-BjV*az#&==b0FppM9fH0HLNbcIRrt5e_%$U6}# zWo}_43xRQ{V!{j^rvehbgs3+soigq2w{eFNC8lCB+l(wgvW;F~jHN=Cj)>GGviYZF zGZ74=yq_AWEDX5CK5+t1cre5 zUIex;-ZeDfF3;;hENQ=#cT_X0pWDNf5gkE-%!2Arqh$EEFo&_~Bza^eCVd2MS5E-2 ze-4f?x&1HwEA=I;_~z3XIg00ljr?A99TAIt9ksBTg@1$$eof0@-Oc3+B}9Tm{#GNURE?BYx2o*QC3>%@JW>Yl*0?XN#{Eur`|-(E57DkiUL*) zB~|nbcVnHM!k7|1_(!C_+8f_l>5T9YV^K zGYT1a?$Fz}eRNDK7{UKPV!V)GraKCK@WDy^YYeJpV7})TJgby%q1kCx4bU!P3}lXv z7XT~6+B>M{H#T#JBunBwIQEF}xaU|KD3JGQt(M|wqgoa{X$?`|MqfnP8r;r(Fl+9R zJwJdn6mMbuhe6VyCo*3ef9wBI{{?TV*vyPx=qyC$H?KsG&!C#787u2tgs=Wt(^}3= ze?V<+np=PnSDm(*jVGAo{eH)2rq1wY@+o$9t-U=po>=P>%12{9g{X0bYBTf1>5fx6yKcS>|XaTal22vP%OgcZ4 zL~ysB48-Q8JK<10F4JX``7zw#(vj7*`W!H5Mw2IWn{aOx9C5G%modm~brIdHs;kGK zMIJT?yJ|9Az4p|)cP3}`)L7J4mL5}SIeC`USuJ=FLX%|1gz?;e_x`cLW)eHt9I<5i z2R*`#mV+zA9O!`?#cRgM2(Di8-<2m>rZEx7K%wHnD494HECw6gSZ^ zHP*{l2dg*--GHxRK6OyryH?L!GrQ)x8x&3JhzkTj6S@vuyVkWqys!4sB{XccO;- z6m{Kr1f@xY`aHTugmD8U1R#BjzP;@HO>7!A$$*bqzD=#DOFbTHi4tXOo4;qAFQ*TH zV20{ZiWG=Z&27&aD$}GA?O6-Q(jB~5DgrG|q9bb&;$klMu3TPLrB)ADO)938e5F_b z^{bWq@dxUBfHyS3=_Iq*b!olXHBS&MV-*r-jxiij5@@sstxXGLUQlxJQX+iT_@#l7 z4$El}UCVrOSZk0d!x#)$z-3iC_BbW?GJV%fa5|~Sfx3mGv>@}Q|Kbw?_xxaQO!{Y?c>F*eh?8T z!ll7cM6D6#84DjOY8P~_ttkRKL0|`z4y8T~g}q&B>CKGI6PwO3e~4$pY-G8YCmuCz zHMZY3iHAH6m%c~6`-(=>9D%@#@0{LRXF*J@3E&(h+q1>Db3i^;E@ZL0d>npoOumi< z56Oj#@)FLvvs!`?ZEq%wpSkZ>&ol2-FENLCNO>)}Dn?9|)gg0N&5Z?{yD&6dH+8Je zVK}#A&Bh>>8TbWeH3NX%Tg<@IG7ct}NSS}Yd`R7F-l~#QruVMnKr)jX9bDRP7#G=$ zdP9PK5mBX)F$TJKS8bX*s#zGtmyl(;@w5!jz}bU6F9ITMazd+3AstHrE1o4&LFFah zX|jCS2T+R_nFX;5!;OhPk$+5(!DtI|wQm*76`-tfFp^^p125v2H^Y-01X~>&DUfgH z^R(*SPH?iB=n4<(_`id_C|PHMM<*OwEgY4H^m~g6!mae?w=t_+EMy54$=A%1%k&z` zyo1WTo5Be_^RU{=N;t4OR`VV1>hm1cub6y1cz1E^k;y~~v(s}))Z0gk6^?(lvJB#N z0p)2k6Ca3q1S<|}!3NILswR~}`?}3FCfHhIlWbtAYQXZ#t1cQOK2XDUiwufq4B}j) zitqzFFZQg5PmBuV1imoSz3~tX5B=uG9^1&Dq_US5;#k))37=H=nY55-xCQP;VV1ql zL|C&r)|9=N-6sLwID#?NT$qVlRNcHqt7NGNWlf={xUnOOJh+!lCauaxH-fliM6@as zzFQ_8B8Is+BHVBF;|cH~gf`N|WD_V|%Y;M!me}hHS!Jcu&(maHk{>A2juH|ENKCMn za&)!3U~*h$3g?98r8X%SvTKofAY_(hQP?XN$f}@uT$L;ioUJ&rREK=?qLNR^Z&r-* z<*rAoSLZbF$w&u03kyn-)!C90!8%zL2%r@m5sxd9uO@Y0B98j#v5~HZ$Twv=?aN~|s z<7ODWG5jS&7gH0qgSKd45YiBw-~>B1p3Dlo+_pgnWHmT2D|6E<&5`2)*#=JPL28dd zYuM;gzl|f_pYa)5l;Q>owsV6hnAx`}wcV=fb> zWV*n>s)S2S6+S56w}AEXrB%gg`0D9Dve19Vt7iPcYVI-d#0e;~lApq6J|}xLr;e89xld>xbWM?I77`rDEL$P|Gu-p0&-8k>#Yw{*0i{U+6)PL+GIAcmD7$bH z%;ke5OTM94(9u0mg+1$4K`?<)VYR%_L}yaMEE|(1*b%b`z*~ zklN4IQ8w>_8vOTU?VZzEMuJ28sCo>~>&rEF#RjPP2Y)NgWtm%W)`eM2CRiuy7VkXX z=x03{S-(j`|RE5@XFM z-sGVhUW4Fz{r6AI%bShL_71Q4(J&z4z`+-aGl9Mo08I%0X`Z8|4M8PoJ)f1It@sK4 ze>Lv9GzkfDZxV?jrJo26nQ@nQ4@LwPZt~43&b85%twsZgRB*0{M3IkRV!?nS(ZHS~ zu#si5V*!UHW%=^`<8T~s0<4$6L$6{ps5lEbw^`Slz@w=CF@3s&Rtj^cNkRc-4b~JY(Ro%s%H{7{dE0<# zItc<@Bb1YMK{9|IS5L63t-CYHnq5;2YPk?ev_ZKf6r+cVt0xks)rY3%jH@8FEcIL< zawk+qx`hXPMvn0d0?HdtAE;j=s@3XSsX;S0vy!4<8%4jjaK1&wM(U^7juCc!n*vJg+m9QBKm@Xn z)*bm4Ap(|bodx)(>d(33+12-4YKf7%miv|gAnS6=3%Ot3E$_CH*Bt-It?FjK2@Deb zYV4}$ZidI%j|T@mdS#iio4It1zP`tdJLwo|_$1H(ndepC1IuP5ch&Q)vzAd(y>aa* zPB$>TN2H=ZM@PB|)@fPa?e~X0+i8OfLxjZ(p|d8m{=uE=TdJuoiepJ> zQ~?C$u}*d6C1u{L?o7rY=CthAEgkYXJBB;%(sLH8I+(mhy~a>SWgQ#-B<=-_fxbH8 znM2PxZbf&|z?n{n%zvw55eeSK^gn_9Nn2X>I1--}@2kU|9n*+o++SIFQ<*D>gZ`n3 zc!j!}zE^~TTb3NkaeB&>}qE~fvNoftiU9(3-CgTDABIKFb+$1UU707 z!P>Rz+C6ZSPz+Nwxg_behWfQe)(Nu@|19Il8tAO8&}jMQ8OO|eN7P=7F=V!ws8&b? zfefk#n)z$s(15vi2Y-U`iG&9_1Lqsep^aL?MMtlwjC_kd!Y^S117sL?KdV0JKdU|+ z8gWWj7@wqc)522D$b@b?&C`~8i~1M*HSy$;x98^V)<{sX?Yp;+`z8W?!mu9}h*SC7 ze~5MU4RpupD}S56@78}04J9;%X3!E6!+ccPyqfE~s%1e-!#zKuKIOe%eIocIn{m1` zNvB!g0en}n<~NG9Yzxc6qOB92AF*YOJYJKQ-=i@874EcwZi>~RaW7nRohkOcGS&xU zQZ-#~T~O6b`<k$l0j-1 zgx1|`k{H_@13`rPo*z}8a-UV7a6g5aLKY6SWBV4{0$?Ju^`HmvlTl37+whHJe)TJh zAS(8+jUqf1#{2&Z>w0Yt+_+OlS2Sz`&zaUVtcZneuY~P z;Zmqh4yttI8EwdKjt5hA2B0(ArgTgYd{py;)0$I`)7c*jOnA8^$S^S7@n2kXOz>fU zpNVwKKQ>A&akb1bm^osvhj>})s>PL;thATk-18yzS?5{AkbwfOmd19jTXrFE@1a?G zG-+%QHZu#FpRZs;T35z5B4w{0tf79Du}XuuQ0*ORhk$jRCg(Uwn}acBlxg5j52&p- z%`a0AE90V3#5t@Ic}bk)UNXTRSsllNR`+?78FmdyQewDQ__~~B@bU^@Wxy^1dwE=X z_%(_BCd!osTP zZuv%5xQ-OQ8Rj1L=#tgHs<|wqzm^pGPG}t`M3}XT<|f^OJ%95!xys7?*j_zG$M3iD zqOg-V3Xe(mr1EmBHPAmCsW;Mb^} zYrMvu+rq11vdLLz2C}0eQfjO<@Ea28idw~SQYV7u`Rwc=@=TTbT|ps}Y*oa6LBl4; zIO2qN0)DX5$NNJHmQmZ_SvNDL#)kMHH=M+JM-UgDa}%`_%2SG$-p;nXqLB< z$j;^{Qkx)m0M<#P%Y^({0t!t4DgcMY+!G|5M5R<0;m~oM9Wug56tv7oI7)4liug~O z2rlf15SN~7{}-C&4_HnlZt_B?$kt|oZMDz>G($+LTBRUtmua?qp~-ZWWL}w^^*Xom zGKiJAB={F!)^pB&p9$* zKf_#g!16E)P*_Y#^v9OpZX2Gn3+$KC9*KK*{2H(URX1yppBR9L>D$&zBKqU{L4GFy zVQjj4(1*e}f)Hm&pp!%%(g`41pe_!Zjjrt+H;nV_zww6i9fSiU{mCJLmc|TBVkA-! zQ2riWe37~N?J_slGfW1GxF9gdnFyC0(1Ir9D61)l^bvWZ^)wdu13$tnM6wvA%t97Z z@{Tvr9V~6<)Q_{c9YQl%(ebr&>fKS{CNbz+-%rYAIw&l36M_E5oq3i08$BE;)46FI z(N0V*nNknAA5ouU+@EsM zJ}60?YMIkz0faB#kJ}qxfjv&fq*(qSiud_drkZSj(~InaTMU5m;1k<)AEQtD^{V)7 zDaVjxwm_ZfcY?NOog#v>EA7Rmh<}2o$J#vV{zs7Y-iB5>$Mi}8YBCo5Vqpd{hc&Fx z2nxFBBAgP*5q#utsO#~2-d!X1R(ceSL@Uolt%j$J5)T0SLo<5n)q!Y{dPYB;)nq|B zgx%Fl_|E9%`o+AGU-FQn@&)ym@b2D^svmQHRDIg{ENMhy|HUyK&*LE}88q4`%RM{U z>a+x#$HGn!m-`WQgK5q1az*(hV&%5X$F9W_Y@9mTk=RYkImbk?B=grzNTjria)0bL zUNj@^Y9%+mx_h1Q9UDsHC}1AllcG+#RHyrih4qD1qiG|aX_}%?VuRPt-rK{W28JwN zZ6Yis@NTe=0Jx|^w%(*kmgGoiYJCx&_1CYnPI>)vreQjhyI!T3a^u$&Ok$bP*h= z(*|)7)*LI&I!!QI!F2Bc2IqW5PfbjAN8LI}&9*1uMsK}ao;WRmrVXSF9}US@LZ`r| zNw|Y#B?R$eB9jOg;>)R!W=LF&;Ncep#mMWPCsb>iKc>in#}JoJ3Su|?K0BKWL|j1O zTRC-O*7g4lo8w+>KVCH~8T3CO3Jy#Np(!xeqjf8;(a&|z?ZyaPx~xR`u=h!D@l^lnF{*}o=tGcZV)*S z8skQ5J*qHhVz$<=#j`}xo!LK29xW_pBMG~b8+bygweG0Fgu-rS1|d8$E$Q|O z1*m#Z1-o4ZT<}^IhBzn=tDujuCDe(Qn*BVh+SC7tj0iDgZV9Pm;vo|CusO{8YW@$z zgd?uUarul~QA^h9Lzq9D5h+^{*R5O>{AJ4qsYye#L$ci(g)n5_31)XX7;TKeJElVv zv5J(a{T`+fAR0qj1RzVa0dw1=i4wjA8`TAlNcN6v!}7QvPMT?G=hW2T3LspLpzu%j z7qzC>2G4qKkl%L7O>a0MGKwum(+rAYlP;C}j!&;3%K97tCa{>8Z5t=h4z}?M3z&_@ z&EPK69w#9CiRP=02{cJeT82+SRZ0sG>Ar!9kETb(VQ^@g*XYa-5o!}_U2F8qGZV@& z8)Ys+_HrRgO$f;mk}JlvB!`j}m~W!szC$%sfr*2xIu3B- z9%d{l{SS}S(2?^pYhlhKTlmpzL<2yz`hvq0k9yjA|zAb5Ak#U z0aN?xKHvX{jf!y17-l7eS%@N^%6PqcDdZ@lh8_!X&t86gzspFZ_$eKUM4pjct_TzMzI-nge;|70 zbT4#_>=+4hYz&tklHbQCyQL|jDX~)7@&}d_5V@}Jf<3KByd+q0Lm#F|Wi#ckw^OeN zwjW)G+|#s$cCa1BmNVKXr%lZcj;VXi8ngaZko8(z>M?xS%SEA}lx!-Co zRN_EYnqwA%xf9GC1Ef)J_BT{#7HiGh~YM$z0xtZxR=qOoH(e15Vax=lQ zwVk5dC^F1K$?pC$a6x_tjU;_mH$@&rSIhK5uZT;kMDp|@&5=sRHy`%8Nw4{uYneNg zeq3)vhrACKR4M|Uo3=3px_DTdzu0NzRS8ZfkB_ror9|>^TJQDpPQyOcOa$|kGu%U= z>jZz7I~ZV3)pKG=xU#C`K3Kx_-{nSX3PXHe)jv7%Fq{UaN0vo;$njWLw-#O3^}Ipa z7`5|CXiXPXjkYmXAKM-$Cg_)iNa_xLEdjilnf}&d#(|1lK z-r0@WxqxDh>%o31*>$3lXirI!9CnU3D350TaU?YGCze0C_ZIU~n4faCz9=qwzW`J$ zr5j?_JaIAy!P97d@Aq(Aq`XRf+G8VHWG)Y*W?t^>=a`f9IeuK-vDFBMQ<1m~ssGRF zx6p3Ve_>sZPYcsh?pZzSpyG8lsU8~4{JnyyhU<7bEoni7g#}dh0WB2XOM(Ge0%Aw_D8$#9yLQKA>CDaqZ5gx9yZ5)N)uL_?2(3zzg1vssSSqQtd&;MbWG z8kpE2vKm&d`aW-CFtO~|?r!#W!gw~GUF!gE;)Nu^MU5A_34t4Y)kuoxA8G2jnnwPQ zo_9vwkDCKBDjh$gP#G7ldSu>>Y(QRx((KxX1cajk^##)$V=*)Yjfd~l$(qr|e`Zv}{J;3_%&)wmT z`WMo8XM%DJI(?k>aMk7 zXEs<@>#c160{+mrhn@-to&5p2Tn)2VRu{oq!1I2z$!el2M+C=+az|$F?Q+)@_o?rN zy$Tan->^GFz(vd$#pPk?xeTl1=!#8x$Xu~J`jPw9OFZvU7X=0UbT%sNxJ9OEf8!)r z&LIuza9gp(@bf86B&2MvRZ^{OCxh^O)hGgA0;J<0Xtppn1DC#ZisYA&w9yNo7%SR` zS+s{>miK^v07Zff8Nh0t=+Nnq?T0^Wk?qHxyyrc)y%$@pog#3)KZ(i5qk2=k;3;)8 ze+~=|^^vS3=VbJH@j_9F=*dca zdYs()QX<^}>v21O9QE=}lnjYPi1Ar62C>Z zM4{=sg7y&is*Al^&ZhSfwa1-Dpcv0p5Ym7vjDwI?9V0Z3BzsZJP3J7C#p9?^+{WQ& z@*dTrmYac#>V$iQR-Cq<|9qm}R8Tm8kC;LWo6aV*((}q=LlVTFLfM|g(bM3MsCE!z z?6cXqK9jMyoKv|;_Fy&WSy{{4zIF#Fvi&=YffEg?#_>KjQ`$^_fobGs zMHaN5`$aMV&oK&nGcbt1T0ej+UoUxFjVyg~`v|F%r`R>gO7h24um2Wy^I^6k=T?#P z?_4m1BXePgW)l2xYiU8)(G09SOExgcg+Eiye)1u;fwTBf9H(o;V_tkfb>%1_b;{vy z1@6#;J0stTcZykQu~!RXf&H;zZqksv!!&6 zvMIPFV>Tmj$>-~)S`p)=g1sQCvf8d-pyB^HSwWBx683=x`5=WED- zmJ?txuj`V6~~gJ0;xUyql-|T>kyP zMW#JIb0e9Nm-lrQe@N(7RuvPrL()(QJMCg8^zoMtam5f-QKd&#&=`pehU41n2$R~Yik`RzRaW)&Gz54mL)37TtBFJbD1+*)?5$b zKpuw3pc%3rIdo&(Q(@V#n|G^XJFBW@_eFc^Id!*f+>9w|Ik%YJaUJ`))q4fnmmU^* zR^IR~^{)T97q)uYUN1`eR3u9G9|}T)XuDmSfOcddi=XPWegPX0fX}+`xFalV<9ePuy z0(U@OUmF0M4_BdC(F~3zLj&c9;Mf3|62;WiM$&>?rg{| zA(2))BF#!qy5~l^nWUsT znc3*W(Bd97`C`>~SbL~&uid{;;*_o8PhlFuEB%7yiM1l+I)gk;(<59Ihl&j>xFi)~kE-2F1Ly3OhjdXMfDvC^n*aaYmSWmsa|#(&J$nevLXBGYqpypGmhUu0CZ>stxAwqdb2(-mUMo+ zMyb|5_*1-YrE&bvJI%DyI*(R9g5x+z_J+-!VcZxdPeggEzxx?wPS%upVMrNq6;z!d z0eL01&)rj~FB4sKjOt>-wnDF8f5N`~-(m@`u_HUi7#V>G8aFJ{T4MCDOm1I(GdRsu z{c8FC7ut8DFuOZAdND0An(UP3uCF6PX~zgC-Oj+8Ksz^$<5?>YT0!*Bd<1SgJ<%Ri zuT-Dpb<_*3!N^U3feFH_di*`TmK;Y%FLz;AXstK$ zqIJ1B#PRZtFC|Xzi@oI=8P69ksx`Oj?c{!U`%o38v%!djE_$((idlH}X-Wb|*3)Sh zkSJu*fAfyrOg@n}WA?tl+PlH$5sOpXbT?{+YXcG~vfk!d)z4cEiU~89F0>RM<&Q=5 z_DfhW!74jww;vcSLa%)&XO}Fw$PrrLFSHie2Px>Hj#@)7wStwJ8|7#_~-DE&eD1xl!2!KX84q(wH-L&AVbyWNQ6oDi0Q zmpNA0K$(Sp?$vs*&qXH-eJA~f%elZK@nxB@dutn2Bi%BV?=+PAICrw z?5VrD!>x7CEBoDEL~{JmBePQjCkX9c^kj7|B5bx-CPx7bYrC$5=KRu;Xs6Ia&{=+u zS3PcVLGi$Hw^`3DQ8g9wOp74ofB@dK5+P-rRdt0Z44vVxNW{s0r`PCIPZF|uk$Qz? zKcZenQc%(JRnL8Q(NA0HJMq7~O6S&4Ylce7GON8-G~OURvG76V0Kgi?m%C-!>5f<% zQ8CmUNHoH7Hm_yBc?Vsed&${~6J?Z8HfJg#37&D_7#)%(K~)%C6L{?dX;$Vq#*ToF`vFm+WnTu$OySDP(}# z0QqD45!w&BxAfnfHEAy7G=u0+E5g-6;Gb@TLHk3Mmr-1n`BaA4?%XoZ4FO*C*e_zB z4ALR{1EdLI%ILkS?&}Ly9#xq%-pY1}<#HeVF=Gc`DdwKE8p5#_F-$cCA!jO-Cdv|#G|&5fn#$*9^^r&!4G-I!p|u!HcT{mJ%gV53YYU- zDDtCKxxAmhcPu!UYsFmvjAvm=QtY*5E5YXy+zV0^fjMRsk*WYst8rx9ziAW`zKnhQ zyGJfj2hZ37ve1br!OwoRVcFZwXpe+CB1UPWYK*Hq?%<1g8NLbvPoDcCENC^tiO8&Y zZ#3BuOS^qwA0NA|17|Iw$nGHXgBg;PB1!)h%S?Q(N6;a`yi$tyo#JufWx6kE2kE;5#Wqp4~vT0LprNC>Fe9q`F;@HAOw^97p?wV z_?G1ESr))MtWzo2Q~A%5Q9}!t65H{*R?-~qZB61} zQ(_uyuS$z_aFFl7gD%X zh9W{(i{XNCGBFor%_gR@j1Y?f+0;X24Mqr8%3$8Fda+mJUwDgp%hyGLMqN9|&VEKL zNRO0TP>3_?`^ygg7aFuG`wTs|!;^;E7)Mz54Z^aOTl``LmOa)!e7n>!ts#K0zF)wu5_h7r(Ew^IpS%yeRXnT855m zzSN7b9*Y(_W*v56$%BEqt6^T{EtyS!=A8PpEJ-2#m|WJRQx z4VKKLX%D*;mr^@=O%|Pcq6_X%BWEAcvc3SXnps}ph{g{{G_TM}ui^c9*bIuGwRTdy zjD|}SPo1VDr~9Z{Ke>_mWovscaMurkH;Oxw(KVP`;;&*|!iv7X)+PuV%o8>;QvS__ zH&`3ILse__veGIHQ-oO$RO=9UJV&%w58aP_GhD%fMF&hC zuD`Q_ekeXv>72_exG!~7%avNFBDA1}K3M;Py2 zuW0*0<`y8j{WB>C7ROu~8tZMM^kha|6E_x?I@@dzk^`mK{>4t|b<$0ob!QpVF1~yW z4Zv56*8*&84EP4)6ia&X3e~%L5QpXB#D^Q<*5SaJZczQNXR5?&#j~$@%$?Rutr$op z9A3V?+JB>&DmkjFOBZ6LiKar%SHI!D9ML1Z^NbYX*BhQ2Fl<0a*C}7{bPXA%=Q2R5 znb|wK>0m=&F4C@`EOtXIaDGKQZP6asA@3;wL7VzRT2y=il`Y?Dx}eR{dDb{qzxDh} zB+P>&p=bbS9N<&v92j@%a~QK@;|5hkev59Fo|8QiXA++6I@vQ(uyznx*%0(vZKeDr zx>>peNw3it2#)U8S;=khz`U_zcX}<~_<19&PDb|b z5oUlBys64@a~1ojkVgC&JGaSV01~fyO!Z&4EB#mNoycFK7sh1jN#t%xmCJOQ3B&dF zNq*_os}=(}UQ}JMak5`XcoJC}+Qe4-oS!EJ`4pZTFQZqFB9}U__%3B&^LQ zZnj2ZRjS?T;}8R{fQ%!gTJke$KcB$4N>=mA`j*?S*}*GrSQg&Zv4xCcCA$oFarMkU zo0Msg=iolad1>WMilLl0QvddJk^ns7mT|T7NmfUE>@?#vy*-P_$z^3wsxzOA6Y}2( zyE+%s*dZtmXPS_t8#!)#yb6QKPryqeG+mMsip**E)MJ{<)QTNv1A)~mS(}1uDR}!5 zU6o8I@#)v|O^>Udo0S|A3wX}h__;i~8u;S!{QgSV!xS*Kp75jBe5mXeRr`DUaoe(n z*-NdF47d4$cHX5Rzzkbiju-h3T_G;~z2A-`_wo7`d;QOMv!dIK(iXkXvUMso&e0cf zkFwEbzwti-Be8Kba7WD#%S@#>_B|qdg5)JgeYGtwb(q|p9?9z7r--2NW~y)Z%ES{E z%@Dj=9_tl)c4xb2RDNomZ%+m-^<|xx%#NK3PK-r zH5LK2Yvaj1PU=M2iHxjjQRUO^nCccE$cH>wOB}qd?i;#k(JzNh)5`MF9pp(PYmnJq zeO`4B=h+1>H50NP$YdEtF5aRIbu*TGcS?zX+t>$yB9joHedL&AKnApR08(kcgFh?o zIgbtIfj1@pq7W~d;9|?#8W5S;Wlwgku2_^grUwA`unp!5nPe_}gPpSR;{0lW)#_Tv zwV0uKW?H>qK5ClD+38J5*8u9BHk#7G){IjyW@+6Lg#nx#D09$AJ1-9XUMnCkm2@Dp z_{d9UBLv-G-By~7wzda<+9n@qw+XS@A@j8Zg8jLMLLk)wjK>q#{?5~^A=l}>UT z7DuMGyt z02a#kQ2iC@W8m2-=DnyEFx0^cpPuc~V8-4$Es+p8{bWpQ{*MdqQ1S&gss`pl8Q-1N z=}2KM9oCt}7y3HMmYqc@xY7a^c~TGkx;*)#)V{x4`|%gGIXg$xFp-;CrC^1cmG>s< zYD3p{*MYwyoxt#MCeG8*9*0HN{ANw~yOO*A43vDLpXP1#j_rLxA3fEQB}%N1Wftea zXiR%25kJFP$wIHLhDqer!*!u4p`ZG1R7Cg$xvY72+7V@JJECr^BJ?ODG?yh)_pd~{ zBbigJt88wk|HmV0)%xinQyJa?V@t+IABf7%fEUlielcHDN^LhxIVYlQD5Sr26knzl>E6f~zfQk3aF6b2YZWjID!~0} z?k4Z<50gPPZ4yc#bJJp)UxG0cgVaV9F6KFZO> zv3j(f_^KA>wcIrgOh>n9qd}GS%2~@W=lE&Q8SIDlJt@jA!6#iwvsA$RSN7ID6iQ+g zqQ7dNVIi?s$n8ux<;>(ni?XuraI1m-j(x&BB`0F$6<20AEcmxHu= zO+V%8>JbR?PIcBbwq!pIt}z%kF}_s0rRy~LJ(sE^e;*kGl(6qrU<1k%k4)b-tc*quih+tJ&w$RzfAn1uQN?%A z&08^9s0%+``%n*dWfuU2g2AI7F%_uqSZmoFYaZ zxh?YpSL}#>2ZYokTn@tANF(tAx`O;emg6uEuWZWA7!2}+ags&Kz`U~BmyRBaUnj&c z%{)4{8iXsSkZEIjilf!8iVEfIhkwRCP@(IBjdB9MqCrTNPmDpBS3Gwfdiu-79Gz6VLd{ zmgmjxzMZftC1Xu-Y6N_XHOMDB+RpjRyT4R5oDxeE>T+gk&3-1t6nGWLMg&vpAjIqusgEM8V*c zdi57#Z}U`W?XE^hvcJe0NtNX}^0)U3$06b-8Gnlex%HVMc0s~|7`aF!TV9pND8iD= z`z|s$YH@74rd=AG%>0#_J+B^;i8oHPXW}-oiCTwr2zohVz!58u4+8yJikT?aAqh!s zW%wg;o@H53|2W4jVUg{cdysQswFt*lV?S}CXVXNscBeKX+Cw77t!d-FkcKIZ%8V{b z^_P({C7oINh@2Mw129|S@sD6L33z9xR5T^Pkzli zO6F%*wN=2By+J~G65v<%`iaQ8h0;I93zC5}xx2r_SNOK_jUSi05>04ttdMYA7{1tW zU_Y|vutwq=@d#y+MdM3On`(uYE5nD>ddX!imwiQIUXL$MUhF!93B$8=dkmaHFaznD z_61^p^=*XSMg(2hdT8dLnuTfab7BBmk?Y@+mtn-z9?x2@m=TEk3my>w=U>9T?^7Bf zD`$GaFd7j<1!Z)&A|;p`l*VXV^r&fi`(AC^r$61cK@MXcEB{iEvVR%&o09}p0TRJ_ za^);>R;_=GqlRyzve8mY^KCrIko6N#>DLOU+_u3ez@Wv(D~}+0@k^F=CeJ$#u}Sf` z{aeD{y$i!T?#}r9Ol@Lf$Xlf&--N3AldBbgNusbB%+#%7i>9Yx0sy>grS~AUQ~(g(F~JP+_~kwn0B;~4<{!+9+X-usrC8I>*e46T z+_7ixv*)iIxdX2|r;$XGn3kYn{{dWNv=13?sT7A_4Sd0(35TRV1JPPKFffOAc!4XF zIKi`a+9&8>TG}tLKe9J$Y0;ho7;6!3RdKJbpO{b;B9qkk|9jJdk%+{lh{kdVHDXr$ zv&1WmoZ6iq(X1lcVh`_^kI_r_4o*$i_qF|JMrVEJLe3O=>O(^O&i{a4b{@a%+M=`V zF_kmqjuwm5wsQA#<&;dt9M5FckGX5n5)l9)k|$h0he)}Yci48s1k9!_kA=XNzaXFG z)1okQ(JGkpNy_RM^Aa@jG*Zi@&rBk-5E(hA;&d07)?G65E!gCgb%@i@bn_KxiI4W! zPkz15a=;}6#&2?E1QWp4{ZN3k6KkR^cf{~D+wuRt)p@WSE*K{CBKUWj0InH2C#XL; z93^&6(4{ZBYY3@+|7zSC8ut>KuIU@MM`ZR=KHsbG>UC7G|FcY@mqN1=MO}xMV~gbzYn`2 z?Q20w(kDr?%ammYo<-YHEL$Ppk4_GVm9O;Tti<$c@;~+>!lnu)Qh#yozD#r*szf9@ z6M>eyDhA8y%4(~%mbaFd$c5eWDbyof5DUdWb`*F~wo0ffa=hvOgj2U4h#AkAazR_a zT~*;mpIU>ua*vn{N(~h?YL55hDri;f?D+iu0|ZuWHhWwtpmcP1O`jG6%&%GX!Z4&C zH|JPhdJvgJZ`nMQN}$bSI+!C>MxAO`a9Yr0$*}zedI3Ts`G*CCa?{8zcf2@+K{0B8 zO%w|Fc4km0^e$M@QK>jEJC-F~>p3xTp7KF*nrsPYOb6$j1zEKY--+eDg{TmfXT{kU zStiY4Ucc~sn|csK+J$T8%RWh2`15_bD(pU>KkRX{z7f>GN&5gJ&WF$d295ScYTnX} z=@nF%G0-xkWQ6pveR`ESMAk4wMW9e3m46L|GJS4@XLOx4T;95?b~?30-SQ!NP^}ae z{cfRGz7@?Ps7j|5)vWA2wPlv%%GOR&+z^SXIT%^0i#`LQOS_e?Q>>dL zRt~gFbTm`AVlh$(Uu5=Px|=emueTr6_4Oly1$tQw!9sMdqe&kZ%Svbpr+W++rWC?u z(ET_l^RTS{?lZ<|r zzBO+DPQEA`K=@aSY#@P;K}P!eQd3nxAqIuh2R6ntTi5teu6Y6rtQ61YmPg3gJGkLg z`vQoGBu7ZO#rAlZrc~Lv(c5Hhbq@1EyRJV_a{1&TG)UaClQQ%O$-;3t zmSw=OI&z~bOQi0d1zi4S#nh_F1$S1NTSOVV+L&;!<~6`{5UEJmYSuMlN|W&`?W`(8 zPDpVRQ)U!Du}abZ8q9<0pQuAW^)p+K^bPGIt_PEWXcp5f#!iJ>t5#0U8_57aZ{FTq z^xg9-xH)g21OQ}trp4iDNM*HD!b^tZE}H57mQ|d;&_F6N>u$RfvraZy!}+l*yG?s@ z-C%@-)y1?3CyqZ(wfMq$2E;-=#4{7e@j(RUo#X>+Qag?j4hZ!dgr+ESW_y>_y_L)d zJqBw=@p?vGz8grKl&U_)!ZjbgDhr8U;GJS!)kDXT2EF_FdNtPm{lMd}e7GeRRT`Ae z&yiI*S4?97IVnDE-TakEFaYFyumTG^!^nwU{VVM+RSZbZEGG!EDZ8p{4l8yH#n1+2 z-SMBzRNlHFpe*zp26Rl4V8C>y*w)Vab=20q&(n=4L#r0^*H|snEPk`>C1u6Lb%%^N z$r?X+fXgTdaR91v0rlMc6gKH)+W4!zuxYB-zFK?t6R7Si(q^_tl(%9CpLh3V zwn~8u8)|9hWi0dgt(4!aTcURQZ>ybt73n^ZJL)t|G;TqhkS3zZit(GZf);*u@3LsD z?(FkdP_XMP{+8U&3~$$YZa}%R-zzrDXj1onm5}SF38-mtkH!Mqevs#%*ZvWDm1w^W za3FbHtYWOUt{=F)^3=eqd&L;L_inZey}p!~^DN!K6X{}(e@S=Hzfk%0JIPMJlDl?A z&W=UO)E9RuOjfto$dei7MX{aRRrW`TpS&-ED61$R6#s5PHVY@Obni^R!5HMRKuOa^ z0+X#6%qK*z0IIj5K9+LMgIcQ?R=P&thF_;~`a>b@v2+w@-ZnVyR*z9ozTG^O5t@}* z6U1Er7t>$aMuc3F=F_=-*WLrbP2klNJuaO5&~_)i6DtUZ46|b-5(AYSKZ<)#Gn_o| zE0@pJu7DgcJ1I8>ax!$w+Zk0@mPEk#n3nEDhqHsg**Ps!Ql%>8Z#XSoWuaa|d#`Yf zMQ&l*%xPQ17pug^F_&l*i>xd$Tjksp2J#HPAr^{d!lZWE&ga5*cqCj}aFD-)E5QXk z{}hM?>Li2lBB*29I4txYaIj;XBoL8rau9Vk!!&l zu|TG{AM|1xoZT5O{@_ZPM~U}YL_q8qsnZp0?b7)HgXqD=SYO|w@avAVzPoqZL@PIB zko$}Vo6Nma`(J4W)Y8NSY>yW(e)GaN#owkS7yvlB369yY-_~0_El}fv=+*VmUZQU9 z5wM@75=)7S(+Y)1$ZR2KH+YBY%x65~{rS9|xv)$)q`0);m3&U*uH%|89p>`lzlI#p z=ZQ)7bJ7qbxK~={@CGu4mhs8Nb+_n?+O3=s2`b_?Gh@nO8>Z5hXm0+V%rPaA4e~^u zHz6o1UKYEF`vuO=1a7}ck!!S{csdBt4GudSbL}J$buc?2$(hOiNq|ryjF?rWmdGRHC$>` zr+tcN5UX@h_y>UDA#>_`ejuj=*P1v!+d9xFB+Hq!U=(2zwt!1| z*Cm<5*9txm?`y*-YHApr3^yMqEo7J8z{m`pXrP z=?#dQi`_Yg@Ao2hWU)G8PC8=(OXfFLTdcQG-2LQN_dqx|mme6Vxnjr-Yco?Pa$Zw% z^^5!i)~?~O$i0bRei3frl%jJVSuys?!w{=&O3WEk5?A7JgJiHa^e##f#5Wz8DrGm+ zbg}a?dxLX`Q_xnx$ltF8+NWC}e6DK0Yub;S_KTD>;3r($ramo*i!ItkLo@g;j_X!h zQg!C!Nnzwf0N$+ww=Vme1zfR_6O4?%k4_zXe8#iGmYL;P=D*hd3jay)U8LgkBJm8x zrB3pfY-n0xRy&`u<%)S0=DOGxn%ht1xyI8*>g;D%PhKLY6cv}P`oz9l<(MhDe@ z<1ccm!`ZyV&IH}c$ylr?x+2dpy4*{HL_jBBHv~gyMmOXo^*Oiu+;p`j5tQxSzR&3E z3wdS^H^8O1ODm3v?>`)w>qo6ifY@ec6!q15G94!mX{SjBy`y6HtWwr4tnHQG=*Mv% z-2iJr!0e;SZ2=TDrn{ci#`Hod+_1zoXc{EvpN|Qq&|?+`qj3_C(x)e9LhF`ExA)2< z>_31`xnkO#<%CXk*9}rERET^l%1DMnjaql1t$|2cP%dDpXX9Z~wDC?eA@|}2??J(T zNsd*aw{H6DKO9JRX~-^k>J}8Cs&EfA{VZprhqRU7XtTPEHW>BP;Ap=53imS79!SAV ztI5?T*8^|7Sy<+8(*q$nR-blIc31%cRZ{vVtkrjLAU8P62{y^2tQO`=ZcQ1swsYP) z)7}VaLd0TaxObM17Zx^+&nPNoQCYqluPVB~iku{Umsumv{+Z|Fe=;OR z3mBL++}~YA%B_vd7)wA&sL2N=br&qyUN)ED*LrI88A?e)!m_=1Z*QN&Jo8E^wSS_( z#bUq%b(Xku!kqwLy6e%9>|mdrKS;QL(NFf^ciTPuRpxX zoDR3#N`h|GsBOGdvko!f-#tv3rFDHkioJQ&L!2Y&!n@0?Fc05nIkC1yCL+DlxLezx zP}J->ln842+RH(UJ9#L+D?2{}QQtSlYyeE=vj6>w%8*Mva7wg7(3J#%TM@40dpgHR zxsXrA!h9wR-%$uZFkbUxk@~jn1d2Z>x2>Z7}jlwxxfemq&x}&S4%8 zn=O!*uW0*gPTX#4MU&hYJMG2DuA0$TWD`?oU>rsYmx!*i3!Yw$XfO=u`psR5f`snM zgGxjGoC>XPVNnY{)>Vgg_DnRFg9d`oiGn;;YYcHtCm#?ghbkrh%hx`(>FNE4v`;ac zwcwZ$ z(v-v(k1KsYxQusXnB$Gx{DW=(=qYeV^~n)))+Pesk zSAHA6NxTSE0#QdJ27HzznS(6U=_nbU>;u75qMg6dP^)P)#ihrPIsc*kz}bEy zB%c`4$>0s5H_=2y(Fh=eQ8pw61=ItXCv)f-Cy)^41oV#scYT`Zm;}kW2?EBqRkZD@ z>_iZ`_!ctNcPEbBO1T)V<(hS*@w~l3=4|@8JBSlW!O<1%S1{8Oik^dY%M5Nx)9o@G zo5xfLX{*?__%nXgFg3Z($O##KFDOb50{JgN3~=3iOicA$J!6Krt@p8LUg3^Rtp#No ze7nj%MY$n$z@@Lhhp5nX-#r9|-)9AL*78r;eFTN5^I1E))Z9z@Bb1U zD@stmj{Chk6i1*ha3kaUSI+oeHo^uSOI%HGpu~&*eL|BDsZ$oWB&?pxJv1%Wp!;fs zV0DTUi+V8Vq*q zUS!0jP57R3mX~`VA?YAXXVgWU$wSI-aKk{RJ3~)-iNi-|p8-v-6_pwox9moSRbK6t z%*LQoBXytMJVhsvZiyycEK+W9kSZ6 zhjr~32;Ua`<&p4GF%}j*a^YspoJ38fEMb*2+coV%FRTE(ZUF4OIPx+A6>qX}<~T)i z`{gG~21|p0mU%xxCbI1N1`|T#XE_v!Nd|UQCa#f;;-0Un-)Cv2jC>|QQ#9BcFi-F- zH4XS#a+oQ`BMxYW-i)lDA_y5yPw_Vm$#DdWSlk)T6xTRoz64!u=SYl*O7}|yL@1Z9 zSu5nq$|Ez!^SS(1Qo(0tH<%$pevCRVwjM4xv#I^Cge`P9a7KDpE9#G}B=g+R*<#SQ zz&m;FDn*ZCt5P@au@~HPk9N;najxt(jlJ+Cs0y)|*N15q>zVKNzO&iN8HI*rIMJ`e ziA;WAPz&uOR7g^D9&9UnM1G_VF=1a64Bz!-LC-tTzR89UKIY=ly& zrEoQHlPlj~-ie1}R)t~Qr@h#`M|;qI25i$kTKB-EoJb+NP2q}pDAT*Oq}`xEow0}^ zp&dF=0y~ILROhsN?YZ`*jVN~AB$H{ym~9=y%vlMwv9q7`vC(Eu_hi6>ZdwSl7=t`_ zVvyMgYD7UwOSoBkK$z2d%jiCeNAPH*nv*@Y!MqwD-St^b2d}&Q*2oj&dqK>Lwgr|N) z?qzWfJ%a(hQk==%-ClA_ke)3sW`QSAffA7_@2~J~g2sA3QLz%CqT@yTMpJRr&^Z{Y z_=5##_5;Yy3|n8#)`xLa>}oqZHr8bQ$o6w>V~|IEX1X#Y?<@y9D;A(t$qP#S`i}^J zNY~x{oX(JwZq+;85K2%I^aD>6S@|C&Wu~M=-V+H}$Pqioyj7ln5)*lqzx1m6;$8eK zimZvnbLurPelCMTOq~$C>1?E%p%e$#nlrb&HA_2MDOjH-j4$f~t`Ry+wNCFP@v9l< zQt#v|h5-%MP8r&b`AZsA&A=N_Y{C>(m}0o32|)GHNqw8f%KA`%ftnLn8$C^p_%qURYSd(mCC?ZLe{gD56oT4nJe2hN{l&p7e{^)*LnXiYY?7nymw85H|O zQ4fu1lf+RU+egF`SVMq^IJ5fW>O^7P@(XEBxYjIdhS&{SNB8KkW`fMwZqH!a6X_c1 zDS16U5g`Y1dTn-Cm_^}~uM+EFFikp)6DqGfHu0kL84(IUI;;fA95;BKPqVhNY(mcR zH{^*ugnShESh&M?Bb=G@#+=n%z6=}W+Rnk{O3bNj9`g6*N(JN(-}tlq(MNmu1fDN0 z!it~@+D;Xiu66MQuGm1OW|2SsKM|JIhVQHqDZ9}O6C)@s6(0e(t0XKVZMxQ{Tp+44 zEjUNxw?8V2dkJN@jT0wckbb@)-5~zNlTr`olANaHnt>g#YZ1nDd}6+gW+2+(|Bkv*I zCQ(GVjZ&lJYECeu_{?qEZC?S!2*f_hgN)+xb)wf|F4+&HPPHQV1>DlMZ!lr$b%grE z5bhBoSnsF7fK%*5yK8e#W>M^)p!BedW&eA0=lA(o7nka$PAtSl@_h65ri>^GMU|AM z%%=PnJ>vqX6Gc))DgwD?@#;-&n_eMYYM{w2xVxv&`GIP9V|}DW0mPjROs1o4h9RL= z?nuk#r}}2Iy8iKsUY4RN$smz)no|EvjUjDuZ;aEdipuCybod%%jacdkK!g1SPl7%? zxu1>LEK@7K#?i+OLfyeTV`P$aOYaThqL;pITT8(&@kbh@FT;czDVWS zS2My_at30@2h;{vpw=FTZs`C>4z=w)Z4lzmGDiH>rSDSa=(;hX9`9A7xk*^?T$aNT zb6-4G*+FFnp5)ISpeygys@60U%FT8M#YAq>)a)R|2Y62w8#tRCKwC?zM| zhq{kB;?Ev;CZ+lO-P!}z^{|Qe3VW?T1pa!fcKpFg6foE#$Hr9|I&rekbaf(?wl!kj zBoRwHx7-P)6uEg*PFo;xL8A=_;J}0u^W$1Mxf1WgYYcHa81W;^J_VO@aIj*Jy4$K| zxJ^_zy*=V5CBp&?eS9^vR#rFfCn$(Z7xg&JO3?t*g23bAU&hsy*%J`~(SoAeU``U- z5iHG!dkJzdc(d2A)ms22O62=b;OV!JX-P~^DDZg*t1NP`;K5vYfWRzXXyV|i;)I@|~Ryp@i66;6%0BaN; z^*_eo`o|gYlvaCIxHeH|cQHTf_=J~Lc4=Iu=6JxA(!Vq06i%kLqT6_+5u7;P5|fL8 zN@tFQtG{iB6q|2c1|u^3BjoQeXK;OOCw=IYw4==S8Y-%LG*yLGil-_uh(P7g1hZW{ zQ58KBIyw~**;-K9Q7F=*^hz-Wa+kl?`bn#Oe}WztLFkXy+m-il`r@fN+ryr2^yxqTB^>QHmE)*X6%czY_)pig=eO8#b59(k$F=cq(j*98 zZ}l^u)IRy9K^69^JG3XYmT1wtHcv9L`wsGO{F7{2%z#2Ef zJt6;mAJ2ua^NypAVre6HDcT_4+&aG?WX5eTZ+$j>8QoSZc!~1W!&$9~EGf=%1jmSG zck+4=I8-`DZ|V&>fPvRl=RsKSR9T#~O!hO{|6BXNNTg*iey8@K;S_#S@gX5&-wt@< z^k)1a3{T$V{@Fy zS+OwQE}Ymlf_Qi*I3b;e{gcYFYQL`EMS3)3chNtD14>Yf{vfbV+~2AyAaQ@}>#Vs9 zr1^TQHNN$WaAlySu{OLu^MO>9`6bz=6S@E_}wle_MDRZn_FwA1WV;?=dL=;iptJsOG$5K zH{pe+$W!Qswo28!VV_qf{x$U=Zpt6S)_LiUC(xYZ$y%B+Izlpa4^`|aYFWq6f2Gvik9Y*$*#M7CecUp#rLxptBNt{#qP1eW+ z9&^T265eo2EefpEn5E{17dHwKVs%8ZS%1-R;#ji!tth(0;TMK=HXS#d{C<(c-VXoT z!+g)Q9g@-c+wg&YqM10o`l*0!r+XVbLcF4ch#JYCM`)+OtNap`_;EsceemTGz85z* zA#p6wj6aVew^WGmYh}ORw|f-AUQEYxa=yn}vB8<1t*?&+pU`H`)#=H=#*dbehn%_o zy~=zFM)?D$j?84Y;}3~7`);Pr zfwqNAvJ*(0{W99kxzW?(njuLj8^v)K)8LE_ONc_^5b2Y|X0yK3Fg45vnc2U@w2n$A zcUUKS;QD#ueGVZLpINH1G8R`B^$H0|utTg9n5y~#Exfb=?(zZkp}dRhX!$Esu&@Sz ze`P-9F~JEM39)_d8^*`X&$JG91U+0Pvq)Fzp*mgMyX49Xw?HAwK~|9mQQTu?)I}x~ z4|q-SU?CeK4NKlQ-$OKjfDy8dhN$`u2Ah)<8&vE!<&IMvR%cm_K|pU6*wsVLdR^V* zb-r1Q!=jgS3QrOs!-2FmjL#uSV#2W{&_97nP)BJ0YgZWUxH%5v38z;|J?Kl^*pJ46)&w8#J9r~INcS0boW;pYEInExl=H1*M6pmk zQi8OQ6Jg`x;ask8XG_UZ=h>flQP$Mkp_4-48NNd&+6FWky6h~S#BEA3)qC5z>gC_N zmAJuYOXfCYk6lm8;*~g34417^Q2wsLq2Hu|Jav=CeGCJVY7g5vIQ7!`7dXDPeu_j8 zk%WFm85gK%Rx}z{;fR86rj)*xD4uPGYlpEriC4J^mpIm6P#+`J6Ov&TbdoJJT=`?j zgOZ9lme7TE)_>`ZiG(PAEVfU1+;0YMldaWFRX1OFKzracyuK3w{+YapNS_ku_(^u+ zt3R#TXLWzo;t)E1zSsD@{Ny-E$E8G}-;olTd6||@dKUw0{k)dib3Dh7Y5%xqSLaccg5^sJ#LhdsU z+tDKg3V*gP@~VE0N1p?ck4{ zbj@wRUhdHz27yzcczq9f83|MrGrt_KT5Wa#;I!(XS6`}!0D8U!+5B=LBTRyVj~G4s zSuXx{tx753k+Tj^GP?GI3`5e3&>$aoPJ3O1LG15nDO2hyx0hc7Uw)A5G(kMQeg;Gh z^I}15W@6qWC4p+?|CE)N$q<5Vaw|Hj?7P^m_Qv8ukJ`JSf4RU|L6wP7+)=CC(LNX2 zmBl;ePr#DNpv(v9<(nWas~m!eRLIsR3bUd8s?1m=$f291AlPlQZ{Jb&s%qs~-ab9* z&zyYr+^88hYhNBD#UQiTEBQEilL4ngWr|$J9}ZYC#{8V>Gm0$GoZa1silSp}urpz< zOH~6p{czDAdr80T58HN#rb-s~zo;{ypaV-U_byym)Pg`gqQ5XlLbXV;utg~3|JiKT zE|nMS|4<7;MH8O@IMbTY1!U@1k>BUF@=m<8y7%28XB>%cWj^(r3qbA|e5tu#=reUF zN6?w{U~S{%}(fJb(%?h2%oWs`kO?PT(K*{1j*&v}Q}C9W|p zdui3bcj$Q&|CA=ssuBl|oj#>^0f6)z$31{UH3O%F_BZ^T!FKWEV13!c)XH>ybh1Kb zbvGu78eT?hl_Xdf<9tr*84Zc}&+XuAeNwFTRc}=K^+*4?tTE@B(=`Qp)Hr&s>9cQD zL2(jD2$L2jR|k(td(N;D7e|OGw)Otqp#+6}XXDWSKIIhH-kYy%#Qt~&9-&72o#D$2 zpRTX^Tk6~_Q2?2=cS8bL^>*HhrFO-V!PFNBxiCbrj(28{7ERsjx!Pwj_+vw6dp&JR zd&z0-ixdKt=_`2jgEV%>IpfuO_p>ekN?9g@+zpZ2cN;_Vly)MR7$4BF&L@XqItZ8v z(f=s9NN0S(@$TL;aSFu~`!n{I-)F_|V9lkXjhi}d7fU6#sqR%)PA%Ko=Nehj z#f2~UP$$zJS#9?rMB{5216!A2U1qriXcjMNp+5|h25(z>SM)wLE|$5xkaGhwgBPj8 zpKhAGSFRU9zlgW!bj(XeVR#>L22Uv6rMBe{v^O~$@6(=eCizaU>EqVc<<{72a>qYU zWC^!dl$_Jnp*>_sh&%?@tSQr`-tT#3KV02E;rlzgY`>jG{5dGh(n;9$$4}TPZ|q`G9anjRC>s_*kG!Qy ze?nm`$Afn?W!)zC@a9M9r4zO1^pZTu^RH=Nqsm(^eItBM1Lpnxq_ZpSH8vqt+S?H9 zwF|iCB>x6+HAs($+q}JhB{tW}O*-|xdn9z@;X(b?Vo#!TAL?a}F~UrdNKBSKj(L?Q_pJ zann#UHzex#tTyO1*dG#Y7G!(AUzE&oy=o7D8fOsIV4Zy53)C|9)`}ePqgnI zHalpLlih!T27%%@;%rZ$6nA_qWVAQP5EA6BA)*!D{|^_;mdrn%Er?@yD4>;crW0@N z0=wD;EbHS9SY}E77WLu+992EOh7Zt&1^p4U4`ozwdZp9UUm^rSb&-ROloXKci~PK0 zME7P9f7dF8lOQz7dWzV2EYAmbdG4*CLF)D3XZwyzV=K{Ci9!Ck%7v^zw5(L8Ei8^K z%XGG|lnecUaz(0;q9~S=$3jnFfLc>N%9{Oif?t&G`b_NVGl1B#o9blK1Mz@K7Kc#~ zeWM+xg*ANmY#Kx#9>lrN5nHc+?wDJBmQw)^$?G{~hQ1jJ5K=&Hi0pWMm*gdwBG!hj z`|z+xD;vNv4m!`RABNV>BsVC9Pqf$ZbuVh6*6`1i7n379cj32_eVVg?vN_F{_swc@ zu0TT+QILi9U<%Z_-Mmt)hr?pRiH<4FT)j!iX13VtT<4vdvF_DlT|0eOt&K;3&Ob50 zn=2XyAI&6t0^W5%s0Apys4lQu6lHHlWcH{9awI;H{ZLsqL9pv%QM6v4NFk^LHBQ3Jc3YU>jK_?+dCt=~o}rk6 zexCz^2TJE;fBMgyq@;&HqB?hx8D02QVoSsV{&$wdaj~17>UI1Ru3~!-S{M#Lh5HMM zZRIHf>^#~O0K8o+ZMy}@=IrTi9vyZ^Y^Sc@tz9nn!+b9-PP_Tp81P28ccvgz6uW+w zWc@Uek*0y=y>&*ZWyKEHAS-DFw_|2;GYF>H1QH(^e%vw{p8T+1TkbQDBFs zRn=&By#_o1%U-zQM)}*Phh{X{28-%ndme~B7IN2R zV!hazd%Ma9+@e#>?s zueGXjO8z<@`jy*B0NiB-O_~sUsivuQmYVk?!yRD1csb;dVpHJHPTex*DltYpAl9K) z1h5>BiYsFF_K&Ps-pKofJ=p|gvN83#@w*SSM;QuqEl5v3k7i#V(eV!&t5;`k6Xt8H zBX)YjzfWT%Ie*3ne#o3_+c|BjxgS-;z4=Gr<6bEx6||C*+rc-RL>%61lOYgf-!0RP zpTcX<^mDXe5E&2;^N-cOa)FH9UC8ZwWM6@iN(E;P9Do%I@#``>!bZgy7=+4pf~$la zKDz3o$D;gfqutw`yduMBKHAI&ctssc(R*R5{EgZC-&q5bh;~XRe_zidy*JqG4H<85 ztfrn>)n-(cjRypmRbV=W!jxik>>Z`f>)BK`hw@kJHK#5Db`3zG0%|YWk#ysCaI!R; zb1FtFGW&b%Gm&$P^xW>->)LPkZT1}9;nleB>3}a+31LpO!$Vu>V92AP6VY=<@*t3b z8vNq~7Cj)o?4culC*g41TEpZ6l>afIt51u=$z53dN^A(}1~wf}0`^+woGKh0k-`;z2_4 zt4ydLF#=B0dg|TQCN-xJ;7`>K!ZzGGxe6X8hCVHtXBSIr$bBqYJv)S?j-k!H}`G3aF z(+Qs9)a|u2$<;u&yT{$G%7UDOR{Tv?lUz6Z8pv<>b=Jc*JzkVc=-~wDcWts+0L$sd z$;dF1%kl!B`8jGcfH!Y2tmcaT+<-09sDc4VNFr;})lsnlc$#RqYtXECf+1Ma&_X(H+cWz3M@CJ8Yad}1>lTJ&C^H`^Jr};+} z8s(SC4>3zZNsIP7Ib9+#+bO`G0NGi_=m{2;pcZqLaAX*(6C}s8@8UIf%$S%nl3}~Q zIWmd=e3d$~G-%Tg{;=9-oL#V9#UJzsn`;`7K40?G$G!#atU+KA2f}lBB;a7vWV#C zq%tNNRF~50IK4(gC}F$_fR6#Hc)+%iQ&h|$Rm<^L^o0E{UR2TEihkYQ%|cKNXgW%k z)We>R^kYSQ=eEMJj_~PBdBL!w5tr=vrqPB;@+bIu@Ure~;|1vFnN(TUJF!dczl{ts z(}D4*H2-rfHIDq8)T4}za-&(3F#|B3gf%!yuic`s;ivOngU}cRek&$_0H9^+U*k+A z)W&0d*LpP>#C@lKkkgDw!isZdw%$UvW z`>D>hHV}pLihiUq1X_UM zy>Nrm(=z}|@Im%7cdmPr&*>FY9@v`+pKeuYU1$FUY-7R@-67e3JEqcPlANFWKKN6p z;V=)way%?3egdb2fF8SkYB#MHX+dTGx~hC&eE8QJlQwfEC0OR_*}%CT+t0NWR4N}p z@5LDs?dSUdeRCvjj)#VwaK_G_Ik6jCYg5eFzaiBFHX;P}>A6tp zA_SLyRfiWO!?MShY)=xBWGs(_AsF94MhP(#+au>3$(%_5LXZfhA`qfc5D4scp}CR_ zUW9Od@{Io#*-Or~igPby&{7j&-<-$a-8bEh0AyeSZG>SKZZ2z)EXPC9kp7|t6Nj0%(CIi(;H$hc9jKmomO4mQQ97h%0n~;bGfoCs%%E>(tsi= z&udq>6)IIVeJu`*dcrwq4G<9N%A)X{rW9(lxK(P;u>&UPQG9W;lsO3c*7k^iJ<*Nm z|LCPflR5-g=#!`2*v;IMNp^vk|B8%O`LO;2T6JxQUNzL4a7ns@t4Fs6;Oh8fn_SUB z_UJBUheSG%Svne1SR3rwQ1lVa5=2WGuj+s>*l-w?h zo3Vki+T>I!&KnG90VRRElB(E#4dnmkkhvgqtt1vsgNz|0e2lkFq+H--@;B(ygTy)6 zj~zWC%dG>wj|VMh4yoU?vHk*YESM%YG_`H#ohG84BDM>WMP0>Osb!n<3qN`(ys&wV zHissAkglBxf9;piud6ersC=iQkfZnkZC$%<)ayC@mEfT^U+a}WVURE-jG1J%35G}3 zmw`6|wu2jzZTeyYH+C}!x65>;r2xzc?B3PDWXPTDMv2<5r4L@v z(PUOh=i_j57}fMaM__wk2i zyIlnf)jEBY)4FG*ehnin3hoIqGHTLh_|L7{J4*mBSn{}U8k6SvHU`|osIDm^CD4p? z2pTDw+F?qaWnhA2LTjj;F^D0TnfnfCr6M_M!1=N6OEf_@mwIzK?femcM=I z8p2qZ`Eh%!B%U=}*iG3^A^roUVO zn@n8qA?-;gqS#m^N0CMbZ|-X@UPsGfm(ayNXoCvop)vq217Fq8sQ)p=vkOal%8A(M z=2q$#>kPv3ydGX}@k`ApY%ZV0hlbj#z{mQfPd z9=7*iP>_Y-H8^Tp1r9U=6QKqOOvZ_?0D03(Py5_GGq|x-*4WbzXe_C(YA)rHVd!n{ z$L5tD)qUuN)O^TXqAm+`orvtiomVU3uoNFr3t4^P!Ti6MCFm5UG+eP1juyVa5h?{b z5fh=}sr>&a6J?l%&Ke>tExF@RgMQ(zLm{4GNl`bMN%-&I5)O5@g zPw~cigz9?+VuNL_M*0?BdI?FBU&mDOAHgk?*tEsGjSwU(-b}S0seu_YBl=?aI_AKc za&iqT-RgPwkK=p*_9@k|dCs?=_Rk8IQtXfLSvYXu_NzEdms46H#Uv-{i)_bO5_r@u zd8AmQoR&_BAYE9tP?#=2FWgXO2bRH$579we3#Oj%;()F7vi2*47RR(c7cpt)H}pqd zkBPlw&iKK4P9)WH{0COqHP;w*3_94aO4d@;0h}lHd4ydS9rv6L#len4sJZ9$tD{lj zjiV3LjA^#|z10M-<|&Rz(v&B4iRt2mER`OD@Omf8q`Y?VRJ)Cn`&MGlJ@b+*s>n40 z0t3|V#%()I5Q=#?bCvLLCA)Rg9xLgYe)S}kO%5=TamFACQ{TvIH^NI{2Xg>$K;jLm ztwEmE>7_Fyi~l8#v<&Dfo&dx5tqkI2N@)@lzqVm{*{`(WsGmMhBdBZ9&*-OCKs_w8 zpLVrlU&kHcY~u&g=0v@`hsR3jZ4b3u8%cO&Ol?N4z31c%FfsGsg!?ka)FjXL-68NP z@I)&61)JW3Pc$|hjJ%8pKwf)Wol@FG0Z;rfW<>|tR`OFlCW-*7 zKEiZ;6y=l}UY`)oCANGq5%Gm6Fn@KGqBtPB%lMYNt0enik@_haJ3aXnw(Y0n5J(|! z8myEPpZHs>=PUF}8WZrb{1-opG^g6*j-Eu#E%^1oH0%(aGS+ZObbQP_X|!n6f7Rfe z=T54bZm&o*K`^2O|Li+(6M5>Vuq;*Nxplxpy?<%`o#yh3}cZNG(aZp8KqPWwi%N4YlU;`N?hVI1k0 zl@=IAZ=($>oRU^a&{^*xLCKo8;}WP7yKbH-2B5bTD_TugrQ@6c*xRImdX41B$~M(@ zI^YApg)GpuKNLGERV1;K>p4ex_;4!F_V=2VIfbQJjsv25!RQp#v=r&t(IAxxa?N4i z1w*ATvmquL$q}^9V^2DdPsFi|TV61TZKt|1na4@2AP`RS5mdTYHH3 zSyt}>)a0|A?UM#M-081PooELTx|fw;Td=jzD^@@)A+|@bA*$#fcNNqjT(7=ooaE?SuWdC2}zMx{jm!RV2Gp zJK@iac&jp-2ua7BDZ7ubr87i|Azg5P!JQ>f;FIE^u(i{_>F-1S6>)GpcU5rPRU>JGu!agF3$m<*#e-8<;Fne_H2 z&q$x#K)V&yp@B^g4|q~BV9F1om0O7!5ool`GoUrP5BB`FU(YlFDeq;Y+8!kDJiF~% zG& z18b+NO;$8?16*VSJ0L)D#P8GiqMv6w$gXNv-(KXS#-A8(=kYV_ndBtsJ=XH)+a&8{ zq4`N^RDUO5(t9f1ZX>PtE_Cb^y+lK|qS?CCKA<`AHJ^bqq0aKFs$22G1$|JeZugYO z@gOw3&~z?@yS2FkG=CcApH|@>O~FAX0YqEqKX3Ao$}}o zKiY69x3+t4zNTG!YZC%4oDW`yH3I3X1=}YI!(+}PB;>GKN1As|xAD}kakHPW-DW81 z<**JJ6&gh}hh&6GvH=AnWZVHR*WR$b&v5mN*x9l~tDC z?UFN#YhBEyyu{OwB8FK8Wkxp%<^umFFdZ$$Dg>D98m#nIIB2?wGPk{4BkjAyAfV$_A zk>AhjC>+5c$L%#iKRZc5N#Qa*yj}ymm)d@Z8>u|+lpcE9CnecM&85hV$o(H8G24i0 zhp2T&mmNoPSa`QH3@p4@OH_TzqfVw8@$Zk_jtA3LIL8lVFuDtPCa=Ck`)oVj(cH6m zj^^TU#+(2Fj>&cdro_cj`ph=NpDB1QuaW zd#)vm%XDV!*$(#XbAovQY=@r|6`05s-i^CXA4`+~Uck!mf3+6c>(kKo!V@bzlh|e# zhZU5=Z*la06)EI*iN>>>&AgdI6f(iS2)!LKve-hZaxK&q&P_(h=b*K-5F%xW725^W zi?A%z?gfwK&n{kVou_-69+zt?3HcJ7Dhh%Qw|Z12lj>!i9Oh9Kr)QPzS5`A4A@BL^We)#sKRjsg}}qM+dZ9~RqSq;T!CwI zB*%q;uIMA4OUEuA&yU@Xw;i`d0jDCHiqCO9z&ilwg?)yuHDdb|)PI2WKEg0YKzB;` zB#w}oS}ko~=88VAD?3GGdscJF%z6(#9`nSV$JaAnp*hGC5;JHM`dwMU__4OFRi4^O``BGY6K<1ISDepq`~LXAbs zD3Ax}uz6x{Cj_}^Mq?Z)4He%K+bR(sK^I?4L75+8SCz!`s9PV=1NCUOAV_JFtfN}a zdDHEmLS&~SEH$LzWp%poFeS_)mNGD`!GRWE2IpOJxWqMY86HS#;Gk~y**c<={X?Kz zi?+I0#iP1>?q2PEb(vIoICdtlOz3dd-NGUA{bd$|AhyMXfddunv4fGeCW>R&&aSo= znADUtlW|W6urJ)wHk%^pXV*qvJ<1+nanDZhQ_q=Wt2$j$DaQ=M^?4v%$vD0K4RU=M z$&fRjny=8A3};~(8t4))3yM2}F)wN%c`6oxtJ_ALti{Jzc6ki<=BUH0bI|3QTalXi84t95H#8~HCyRfb&sfGLYsCI3ODZ|YM3$eDr zI|Wm~^%~IV67WXGD*!%&ZkZ1;RmG0df@wYZ29d=*;$v^g+|@G%s4-_s21+Z>^gj`Q z?&j${)S(|J`b6yK?QHq2SSSoUzOnywhCz%&$4yZpm?J!N;MIJ=DtJ3zIA@QXGi%D! zi1F!+jpIyp$$AjF1?<8&z;~gPHQn;_(=mO%#0^dvb1ebJ0T7>ts79bAr}*#GPr+ z#YOE?^XvGp#>EFrrv5saGc14svKNL?`XB`kAQwZ~P}`%0cyZ&z-`eIC>5hywKzqwD z$IQQ!pgx&aKeJY0(CfT-`$S}})swhSEmWG4mzO-mA7eFT+OEXd9wYw7UInQgu`LgI z(y5&?8zN&$%h;}wmW8G%(VMr*q;k249sG6RsXUu2{k*ZE&tThQ>og;AJQ2sHW&)Pz z9$F~-?wA+Gcnu+AHoY1_xuaTh%Hr>FYZLA7YHwz8oMEntebx0dnn6sTIVC7?bly)- zKb@0y1rw8EpOvp-JmoUM*@iiylro)xSEXT9zG9;C5lb3d7l$o_7Kcb2Wd?ieTwYMn zDO-@E-B%kNyeQe8Xva;$B#{33$l5<4TU0~NRpQkDFJ~Z^v&d~|=&~mbx;sPFw4ItF zLT$$wWw&nbEie?_gq_G1aw+20-q29jd08*dg%9o-b{P3rWvtsR+63$&;%&CMs+~%= zQhPIpKgC{| z$I|)W!JuiG#_fq0Yxiysau39nq1Ki`TYFr!Iw*mB{(d4I8YnW>dehT;gASK=>@`s5-MR*^5M*8qD!;cLb)VAp_C4Gh@v4|$0Abm&O>r} zQyeHn2_b`P-PMh7_Pvw>nEKczfQo?JO5R1IeZCX06?nAH*9u34BaLvPrIW%5yk@UX z3%#b+eiisOX5OSmkMdLV96dRHexRB2Et%pT82kI|{Z4|}XMD6)*5J1q1(0E>Yk!3~ z_CD!kpdL(Alt7;v4^CmVC80ezb4`$Jc|<0Zc$yx7U{c4K-k_o{5d_8?|L&X4I%oB3 z+RG*+r`VIEzR0l(GX|*_Wbum{(`*fWZ_gKWT=?(d0|-L66dB2^W7#Pdr_9cFHK^)h zix<&q=P)0om0xZ5-N462UgLW%wy*nMte9L296qpct3}iJUfMU$wTukJj1%RJ&ZC$z zZ117~46N}r)$C2(=0qa!76MU%=Z(0Hv_j2I(NEG*_qAc349im^O2sLYHoklNL~PAD z?a+Ch|6A?f5t8tJgIt%)U=6jcEjNj&D?`L&_G|Yd5ecQ?x)qY2Km)}W`VUw$Nyd$_ zCHpM${cvI-9qmGvZkTZOd?`Ch&Svd#3$buQai&4acr5#Xe8U{rau3|CVH$f1Qmdcl`lv{OGp zJ9QAydC5V|3knh?_cEg}v7Ll;RP?MxyY==7-)TpiFVl8&e_eCipMt7Vdun9Wo)wUL ziJ6$;`up1ZuwPwVMrwP$gCs1c;|T%~5+P<8%7pIa`9qPUw*I-&RP|mvKNhRagb2 zDJymh_seJikxt5DUopwNi1Rg3s&b6&AV%WToxMIqD-_htQMxjtG+8ra!vipZKUQi1 zbx=mw8;0e;4ecEO0;-fljQ{$2ch9$Pi?NZ?nJ9=L{}PGYga;k^?wy=wu+A_+cBm!& zA{#=f(8Y_2x;Y#=?r3*Aa;J)D-o9~((i`De=X)U-b1`nsF9ml5};;CNB;T> zLL#_D=5RBgJPh((oD7neuYvab^UWx3usac_i7@?g!R)E1AH6Qf2ca z(Za<2yQDFN6?y+%Vz=wQ*7KdTcC)}LbP7YHh&>yh^v)GYl!nqkg5NzHQqP<{vw0NR zr}q6@^PwM9L+7mTl>;MKyHBv955V5wNTx^YJfU@n@QW#VMX8pPIk*`dT*vHRA;uuQ z6GPIp=mBK&MC^nL;>^(!5f$|U#zJY25-pT%!9pzjf_u#)mQO>tY-JNcDeu=G##3X? z-Vv^M{7)Lc->=>?B-tkkl0J9#FyB3`|G_YdQZK~fesJuBxlDxq0v3`ehHZRV`-f>s zwdH4?_c_~T6agk*QA(^Hhn4fdnmgE-#-}$)Fw#Q<$HK`5xt?1N4%PU>em!4 z1Xbnt<4=5&yZs$Jbex^sci&6*Eon2x1g(333Tp=QX zZp;<=ZL2=wisEp=34lgOaSKEuXv1;lwP3=Sht$Mfq_>%%j$r@-=gy2OX3hqdG0EvZGST}|FEom;LyIsX%^De+4rgr}H25co(q8)0i0*# z6#kP*iT6Q&W|7atN%vP07wwV0=&qh{i2V_)iU*exB;0^>#Tk*2j*U{Er}!xvMrd#u z^yTmlTjg8vP}tVC!p)XPqkc)k^fgD?|IgN&MoV^8cb@0Y^B8xC;mt!tX1>h#a*W71 zmCBSdB{U$VBqS1qKp+qZ5Ex-5GZ?VVWYgHiXj5Ry24e}X zy{G~%L%Kg{4f>zifv&*;lEE;q{AbuQCWbPfSJ4e(VTdU!AIQi>cwmPXI%o>$_pK(& z1MDsBC7{SpveZ6A?0-#Uf_0w_wJQ2`{4tI_0ZfBKDO39--kYDyhSD*f`W9tX!Xd3$G*tZHC1X)i;MF&{*>gpEaCdS1S*;;46&H5_H z_Wz9xeUClRE%>GG(b+kYiNKeiE5m84*|lM!P#QAg8Ar4gC4&}z*Gq3Z5O~Q8ooZ1{G3LsSNg(H(}MHx5&eCp4YTF0khv8d?|7V!(Kz)&yu3l8WRbN z-CV{UNCBa@T+#%PMy)kRE>MDCHo4hs_EB~q;xvy+?$8#U?aWVZkn*0h>;kU?0v2?9 zE)8C&`J~v^{st7o=}u2gbsGT$3TCOuqM?AgPCUl(ta`NN(tdR(NqlSN7#TD{owNph zc^ua#Gt1k>9gkKDwzi8r35o&OyYzQ2yt?!gFfU2;q+~GPoVhve<&b=IvE-3RkC#7% z<`UPw1@D{0YoGXsYZFA#i#5_WmtdieOIXiI!%&bYkOha{^=UWj5t z=x6LNG3y8+z2hGBPwE{?stnK~sm25uST92>>cR!-pe6~#?0HQ9R#f^C@JpKB{fdGl zKw=+Jb@qE%4yp$68}zl~gJNs0u-S;Peh_e&%WJ<;HE9o2U-H10Mow;0X<{2xV-VZ& zyq^WA()<+vg=FMW7jIDkwe9W$+P5wI16CHhPP)BQ=l8bfBXi?m+HA2;{cyOshdr`Hh&2ZATv= zxjwPg24tW5JSisp0)9*6l%JxIl0)e&CGvB-db(K(>$V+&oneS8A%8t8<=V&4W7pNv zcN!qc=yUM7PpeNqC|9$lGgyJ&kasj{9}d7Sqc*M>9<%w>Tsp{&-wMiZ%wixBEXkSr zJ9dy_3HOL$&F$ZA(#4gGC?Rg`T&6@s7lJCEw0y{XGb&+@NtXey*EBA;;fQaikb$Qg zQpkyue%&MedX)t1x_C8q3)5#D|EM|}Wk4aYSz;rZsBsi;nmA!he3)mH2TTC{e?g;M zmu4L{2vqEcdZg@`aS)YR2{6CclH(rQmJ{HCchYhH$hU}1412r7BpYNqbnl}#sr3$c zCW*r`8xkTmob32Y+}k+k`d;ae$27JDJ0QxJdvPd8mXtTpIVcLIV6(!=?)tGg%WU+^?uJlDApYxJ~_fTNX|E3>Me>;LAhoWiH`HXpdLq`%`tZO(<`O6Z1_h`s^>4Ff77ytjxD&Rd2UX5F0q)D6C$S3o5oEqh8bYsN4oAMddkn(~ zP#DW7M%%j~so^J$Qe0coNONPdx>1X%(zVAiUC%V!=+G zk$CeA5g0^8q{ZV&zqomY?Cd$$gMNq}bo_@mgmw?v6%AjMRkt4uYS0smKGmIJ0C#;o zDag&rt2#|{DamK2ju2i!Q7>Zyo|L~luI2&ZBfK++9`T6SEjHfFR`D8w+JtQbw+?7k z5(oI^v*7bK{(Q%9^6I{9jmGOVjsQxbC{t$;!;Ee($$CHO0R_EwAapMz!HXff(EWhm zEAjKXAvuz4D+az_vPJZ*(Gq!53HI9CRWsO^P>^h!eo?goa)pA^ax0!#K>`rZSEqX5 z7bafwRD&Ysr$HO(145?G?;#|HV)CbxQSGmuc8aRw%ojAQ>cCZs{iIb%NGZHhhn85* z1;<1BGZV^N53|O_QEst(;t->zR8RxclG4}uG`hKN2YIh3s<**Mr?d~+aVNa4-K=+K zRhjV$u6n6>`e}Z8x9xr=eTFa$JUXeg~`jZ(7*ig+r7>P&-99SPesZO4nkQKI04E(qWZ;hXSA zpTb``(S^D*VaG23X5rXS9+WVGs19ttOfevvM)s#euSjUqw$vU_Gd5=#3k1^wEo5LrlZ^JO~`Hj}ju z!go~E#D?H=NtMrLTqET3I$}2M81ZfaG^Y<9>r<^QRhB-Tc%(wbS5JTdBz=#(sZ9HguPjZd?{CYuWN5SD|2Yg6b|;{`@t%=+c_lrbK0-DW_`vS+9^#wD1oW=4n@l-NUT&rdi?iz z@g-Zk!|K1HBj3`E07}6koi=L_!A_hPLMVSV2XO)~A*B%WS;uBjn02E&NAuWym}>?0 zHnDr@izC~~p@rFXtmqk4-sA@>T6zO)lhFL>dK(8zz}J5^qe6=0TY?$!ONVR@$-a7T znv;rm1;>CeCG0HzOQMEq=5w z;V{Pih8eVP6QPvudwrJ$VaIj>T#$O^jB-ICteCBm{UgQw_gQ_ys8LMXG1Y_ASoN#u zp8^mcnh=H7=2!Z@IW*tOjwyHhX~)w-jccIqBUj zOApFILOPmY&@H3MJX@;5?>n;^0CT`PMDYNTlzesNuH`fIL+tIRkk;)vr|H(Ny)}Qy z9`uI@!v+yx$ymGP#_GvZ>9#P=jR!0wL=%F`y4VqZ*3M=ghheS-3ywd00>_Wb_Jo07 zhEHbLVUjenjsZ9L;Wgli+$t=Wd4BG2ULm0dsy%ALgm*qG>x>7t2-D;WvKE^4gX zQ~xcT)8StNXTZXI%OYYRT%)-~Gm1AB5_P83gx63@#8r#tocxGd_X-lugsR^7{rfB! zr^T3Q)M@jL4RB@I9nVwGd!kqND!2513d8HO>Y{Q_8UEV)a3qNJ>Id6PXduQ&#GjMSA8o%3}vlXunwD$P-?)eActiQI3bk2-wm6J(jiulbnY9U39S<1{3=%HLDjQ z@$la?JTY)4-8hlEnJd#QOS%laokE0G?jwTqEKwB^9k(rkqx_guo8$<$$O|4#Yb62R zl_E^^myNG8;;>1gRh-bbuX(y}j+1Ee_A>89ZvQ@vK0F8@5w1Afq)G$O=q5CL_EWG5 zBKLb01;E8Yrj|r?!U?uFR^`U3duigXI6?bDbu~fQ4*6^{S;Cgjll#8>Hg(H#TpqDo zHcozlw3DWEB3xSs;!yVBOLnxk>KN4?xQ`~ZBe0LhPwJTjb5CORQqd~l7dJd72#vM} z;f%SwKv3bA2}BSUgET@y7)T447NRMV)~`rXD8Bb0^`X~5q9qp2f7V+8cI^3J?;Pjd zXNnxh80ljSJn)Zvh2V_fks7D6WNNAd-)@Vv&7Q-;I*__czS^GPvXWjdZtqgPXJtxL zGUGg*7^ua0h%4{m$J-k=PB6wWWjxYlNOoZ2IcZplw&4#!V-UT|6wjJDt25biK9>V9 zzzvH7fKG@BpXrWvXLoc{s}N{FOANgx8|YV^xf@2vo1W87Coddogaq_g6Cz|VLEvF4Tc9)|g+v(*@IiY-qS%-0vjO7@ zK|R^&=cNOHc7BwiTK5E__8SZV?_bySqo*75x2iR|i>-t9_eEj}^p0sF=hNlt1`^W%Kshvn_Mqe$WetA&(6M%bS`C0`ND7>z>GRu| zbQ{b}@5DB>Py2Qqhr&g~mjCQiHIsRvA7!EXP<=qQTOh4aLY0q+tpWBBOb)^<`Z1^qF zG2N~bW}UsS*xx^aOv6pWU9ihkKa03_x@pcph^UC=oOD7lVLJ%rPV`lfWPT?1kz?I^ zybRD;Un;z-Uw1be|4+3Mo;t8lm~qvtoj5popY|7yzV1 zdH-OUn}a_nzNfP!9+E%UH{!!yK?`L+CsEfGJ605fboA-+Hsl!yBU3VW!7egLeI+N) z0xc5@4xuM`j2azK_b|L-kony5C#a3SM8dSOw$(R0bZCcp(D_X_iB-HDibE7(JgBYt z3=R|x3UhH}L32F|&{O`(v4+`!y86A$7O%BHckHO=L2k-zWo~4f-n@5gIA^K)p|xD? z4U1BpGT&K`@_w0_VNFlzgr?uql!6Zdk#!>qHvJY(VZVdM0w&qcf{2duqWuonjh`?P;_6 zWG!Jw2x_@NSW-w3V@xwscy<79$2=9Nr{;kB5{v<<4`Y8XU&_=v^Di~l?;;X^4$Ucb z60L~ooDV%A!?PbE)2@d*UlVyUCpOOgcGmf9gu8`7c|QRS#PXeO7i8JUYffRH0}rBq zj!@Nsj|C6>aQku%wguM4N?p?-vN7MlCxV3ZTEIeMIvQ0k=G~8C(;)++pciXN0oDLb z&^;uRr&4b*NO-8u_6Ibcqus&LVVsPh!jK5ZVIEYJEUi*wOU$0g9AlSA&EM*Xb%y_0 zdg9$n{9H#GXUw~>P^Y07$W#c@3Kc}+#=;izX9{z8H>47JEw15GNYI_aF<#vL35N3m zwQ{L+{K_qQuLAWNSC%%|ZdKEEUuth-daH6A6#H92kTQVkQz7$&Vdk<8?FW}^EBPG;<}I0ZoWr_tBfyjD~djK`}8wQC=z&=y06Kb zetw;OM14(tG~GM{ZxTP*Fr~-A?QEKrn>}q7Id1ukF0lU`_!QFZrGSZ!JSZGI@q^G$ z;=E60$8tZy5Cm!`y#(6;oj|=K?GC6VMnrfcZEUYmfwcc{k-w<%sHsb&2$eCRP= zyo1Pv;Eg;Ehae6zQkmY)QHg?RI~I`<<9_3_xup&*=FGFu-KZW}2iXxpmxX#7&t_c8 zO=Tm*ZGWGQ#&6fjC??A5KE-ffp{Q;WIvHx6A1WA)Eu8G6uUp;~6}KHH#ni>yqlDF( zDmRn`Q3wwP8pvEfxWggY%~^3iA*I#TZ5d zx%i=dI%VSXB!G5Je0-!X`+f%eLh6xohbgw~8HaHrw$=H_IaPuo`w|j)AErtlP`=Qn ztSds!{#w_K?~+_{6$ztJDU$zsaAe=2-YxPr)6CR4=O6;Cgm!^(^pVNLMT-b;K`qXd z2V~+DP8zqJ{Qwp9Tlr9b4D~htP22gY(3DTwnfy+?N%w+Dp0Qv{Mb6p#}NY`4pG~^>nilkUWpe1HJZO!4VG!))$E{HM}{on>ONAsU8A?YWKgo7B%sNm$g?BBz%_*H*t}VEQi>$(XsMtw*tl1u zU&+=C2l!F}2&#E-k7<#aS;KdfBr2g-JEeSzZVgf=^Vj&j{)}Ci^dsmzio)hXSXh4M zLNO*uIGjIPj6MDceP!vK3B}#EyJUCT@xUHsX?-a2SW(gAtb0}N3?00TL|6=mjMxguo&D52 z0B)!r1W*ZN3eSv}{KG|t!-MRL@XTs29#tRnJuW&kQ)kiei1oG z<8a>~tXApV%Xgst^uS#mxOKY^|AA5YR&rO5Zvm<$iGrzdg=}q4ddN6!{MywMzGD>I zoA%wo;Q|x^qV-tM{}0yl>q$0y4}8CHiFBlqkoV$<5YdB(&`@Y5beX}iqDlVYX&zPy z^jpw!VOh^F{)dOfyn+6**O8lYS6=)}W$!b6GSHp<><0muAz9j-V1tovG501UJqt)G zg}=^>dMpDOE4I-mfneM8Y0sIKObuYY;!GsXWHx~idM%*)eExIX}Y(2cxaS`;hjH?hmVEJ^u2@Zv_V!!*^16_wg}$W)O*pI z!>Y)s(TkkQmdE4~8aPbx+u3H6he1pWZQ7NGQANEDiJ#|C z`Bw%(n7}n+H2&Wcr;)r@iAmp0yaq2aGo!f_27T5>g$dE~1s{uk>Lj7# zY&}zY5@sw1^9Ki^I;Zk0kF#_JA@66&P95`15DkiiNbul(RHAp>kb)AtS9b%xZv!mk zXKr=;6i^m{1f02OU@_V>8;H;&FS$&H@WvcLw+;3 zd~mU^wq6CqY;ruOG{M>VC__c*K;te?uEFstDIvrfSOQ;8sBa1H9zPz|(toAf+(mXe z4^VUXa&-7JtkPP43$wzfnx|l6VOdcIni?YWttN)>BQIN+@a6$|+3A-~Z{R=Xt;Zeo z3vMQ~=U$Ll$S~`tO+l7WizZ^WQ(Bc zDS+0Nm!OXVVD^!SsFssORqzzYC~>!=_)pa-tZkw(k$X{{q2rQM;(JzV-<0Yn;z`(K_yI_-b-g{Tbrg!d z7B<-KmbFAXVzxT|Fj!924v`TWqEQARdB>i+4e&uw(*>P1gJNlV)d82}7!N9U?QrOw z0W&4mJ0t0pBmDr+VI0kS;EEcC;GMv`-mGP{gMLtbCgjwV6*Wz6j?7w@nl;tu&pK;v zGSf9y-JEhRt&7ZUJ^NGXgMuQX0%4l*X*! zi@n_VQXLIzzi+=`5X7VSo(wGhBFbF%8_mdR!(P|c5g?NorHY#;NN9B{nOsFp4rRJA zCL5qM>B^8|!dAAmnuxoOoxWEO+}t`*09Bbk76q%**gV|eoYEDI;*amJlFlPBkHNKb zu3~gEhyqjH=Gark*QxyiDyKIiiM?5!jUqfZE;N#dyVt^#$w zj@-P4kdyRN6G=OJitq*@b_Ry_Jj;)4%x+g-M1=SFIknbj?;iVono5Qb0932(f?^;2 zy4-57I^@Q;f72^sskowG;a)Vs33aluf_>w}IfeT>{MVQiqJc5z(0m9qAksVpaJ+kU zrNqtGbF&Nw+%XIXkl&M#ltIvy@Qx+FHdNB7utx(Yodsl&n9}g z?`R`dtT*nMr=4jz6+&tfafJu(i993b`k6Bzsl1izx@lppdf^Gxm%I|zcX9gM;&`}b zu958vIPenucH-7*L|Mze3M|z0QD8|~pQ*}3aM=BvRu`;nGxQ>GMz?$Y!xrAzW9?c=tgv85ZdvoeCB)=o@0A z5sH$)A})38I+mQ;rKSJ?W2?_)*yMKOrO(+om6(?Zh_lZV1kBE|k{&W|f{xfq{6Gy& z8Q7?WAi{UgqHcG_l%tcI3Qx||EZfPX$Lj?pwFtZVTp_DWO(QcQGtzd;n0uE68iQpH zr5`y1k(`HdK$H{@7yJml#mg-jYx1=rs4@=KsSmh7gTqK_7}1>#u-vWy7!*Y9f!LwQ zE5nyh2+SoZ39GUw+VpT``>uRt}4DuqIKk!IHIO00n8wmFe$iz()CsX z$YusO?BjtXaE%ew4#jqWY0s%0N-l#( z5xH&p&cq%a^UcHJg_nv{v1=tIMsQ*!FH;b##M=RZAdeR9PSj^;Nsdln+sTAiLT)~v z^E9vI$-cbd)u>30Cw4uI97s+798g zq{lX~UVhb!_a95FyTHk1iMWVuuYVYS!uUlCuImawsk)G!&SK#(e)x_N&Sg?~NtkWi zYVK^|PkjWb6>)}1U5}yidxHdWB}AGDrCRRv@mq{~6L<#@W${7Tp^ZO~q%UiEqfhA$ z;^Vw9>-B;*%=X5vwSlu$3S^hiPM@x!geU1qPX1OXa~y?rRef1~8$%WE>V4Qq4jv;4 zbV`#gmA%wI3p*kG?!k)wp?%T@0PG?o*Ig#ADWT0b?%xaCrWumC7d%(AA_osjT$56H zA~S*sAd%VyPuzkAzA7})`bfyag%tApytAe~F^sbi z{`qR{%&3e9y_3_00dfKcsrfFoT7RhN$8G!=YI;b1)31>d7}o@x{bx9G8%Ms2AIQl9 zxJpKKsP2{ZaKFe4{EzZ_6QhtdBvEf@DjK_(*b4lrR}4?Z=4m_u&bj#!v2=a*B2o=0 zd0UcWFP*JKCoyV0ZmmyXec_8vTk~4jVgd<7+lZMqS4zSwnk=1o%!Nerj=rdcVYusJ z3#r-3(-(1J)9Ty5Zy!8>$9XfN)Y_4_)LrUGIgad;rMEWmvbFv`IMy1GhlJgvl@dA@ zN2jv_1mSyu8g7d%X>Z${-Cpx?XKii;M}W2?gGO@d&mY@wlK^|*BnWvlVyvsBeuZ+o zpuN?S&!LV0H)v-S-Y+_={OJy#yY(~F)xjPm7A79qM_V1QmL%S>jzDn z9vWoPu$(0;9x33Y4y@N_=^;~sMJ4I@1ggzp8o>27t#qTJ$9%2HhEl5JyGp3j>K1LW zbqJ2L1(%7m33c==bRsH>NG5`VtxN}sYbxiUXIH!=7##Hh&ls$x3-5ho~O`m0aX*5&>v7!>aZ|JD1oW)wHsOS#}U zOY-kvWV3RDYZg)bfLgCSaij$y%bTQ{T@3L}9E&`%fDRmv%+$x_;LDO(gRF$Nw<5V% z1;wa}M%f|!a>uwvR2+LS$upOni4N29x<)u@;TyQ9nMfp#4T8&yM%YRY30XYNY(f%w zG+xKH9g%pg9YwAF#BGsihy>~MNwan~`!Q>Tw`@8?_6C0NAbu`D)$B1oc6tbD5p`mA z6S12W$&r@bE%_n%R6d{90gcdb{LeQ0(C-Ig9YE#&783iqf_hAN=nB_A{S4{UBw3i{ z6PW!>KJ52Kkh46HV55Mnws+Wc?yCc@%);%%lCi!&u46UMs({R4Y3T-KnJ(5kwh^)| z&DH%|I4jR=c)B5Y*Uv&^+R^pRfRV(Ek9pxagh zG+su|hidnCUAeAEA2b#q1$@LP*h>*lqdcdWG-f#zXyh*8M#sIq|7;l|DMFMGjtO&v=h=mkt{$GS5&l?mvbvbce^fBqiF! zJ$?+n()abs_@s{LP8gu38#HrUXeMizkV&haIR^>}TRiz7!oIK^5CEygu8J7>V-gvF8YYF>4}vDNrZssHpNw zM4MaXm!Zf@656XhBcp3OVPrVN3&X=p7d-E1zeK3II9yjbT4L%fG11~<(z;8e7Am$k z#as(B2O**n!GP?0K@mOzjPpszx}!W~%1QyWZ|h&~<+QzYSO&i?{S>^WxcoA)n4OgI>HglKCV^ zb&~(sWt>6-Buo$16FoL(D=0F5eA6RrCVTn z1$O?0xQ7e2#I;zcUu62;%0wQ9??Db$-z_$sq`gU zo9FY&6Y**pB*Nf{uIa8qJYCem?`Z}oOy zq~ltHc742XR+Abi+%2^#UjnSY1mB%yXux*VpDg>)YV^HCt!rjx>k3FFhs zBiUg8LFa4>I-hh%A2Hv8huIfD(s<#Ql|R6u`nv)$YQ(DD?opN6yD0%Wz*gJ+$zdsX+c=H3y#?--nvhS6Zw<>W9zC=#>&Qkw;Kph(O zGpFZ43L`oinq>8Do|#xGp;VBfX&XH9f{2k5W<)&qBc&_fuIjM%d@Q_ONekltQXs&m z>U@)98r~^3vgB¶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

    ^SXbDKBsQ1XA*)qi2H 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

    ^CQo4_4}AmejKBGFmFAO&Abo0!5(&&~ltX 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 z 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�}ATq8*lvF&xo8oF6E9$Y=E)i$n%`e^<@k*Wk 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