]> git.mxchange.org Git - friendica.git/blob - util/composer.phar
added curly braces
[friendica.git] / util / composer.phar
1 #!/usr/bin/env php
2 <?php
3 /*
4  * This file is part of Composer.
5  *
6  * (c) Nils Adermann <naderman@naderman.de>
7  *     Jordi Boggiano <j.boggiano@seld.be>
8  *
9  * For the full copyright and license information, please view
10  * the license that is located at the bottom of this file.
11  */
12
13 // Avoid APC causing random fatal errors per https://github.com/composer/composer/issues/264
14 if (extension_loaded('apc') && ini_get('apc.enable_cli') && ini_get('apc.cache_by_default')) {
15     if (version_compare(phpversion('apc'), '3.0.12', '>=')) {
16         ini_set('apc.cache_by_default', 0);
17     } else {
18         fwrite(STDERR, 'Warning: APC <= 3.0.12 may cause fatal errors when running composer commands.'.PHP_EOL);
19         fwrite(STDERR, 'Update APC, or set apc.enable_cli or apc.cache_by_default to 0 in your php.ini.'.PHP_EOL);
20     }
21 }
22
23 Phar::mapPhar('composer.phar');
24 require 'phar://composer.phar/bin/composer';
25
26 __HALT_COMPILER(); ?>\r
27 ·\90\0\0ç\ 1\0\0\11\0\0\0\ 1\0\r\0\0\0composer.phar\0\0\0\0+\0\0\0src/Composer/Autoload/AutoloadGenerator.phpfa\0\0ùcÂXfa\0\01\8fé4¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Autoload/ClassMapGenerator.php\95\11\0\0ùcÂX\95\11\0\0î$»'¶\ 1\0\0\0\0\0\0\16\0\0\0src/Composer/Cache.phpø\12\0\0ùcÂXø\12\0\0.f\97ݶ\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Command/AboutCommand.phpÁ\ 2\0\0ùcÂXÁ\ 2\0\0\1c¾þò¶\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/ArchiveCommand.php¸\13\0\0ùcÂX¸\13\0\0ÖN¨\r\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/BaseCommand.phpÉ        \0\0ùcÂXÉ \0\0\97P!£¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Command/BaseDependencyCommand.phpÉ\18\0\0ùcÂXÉ\18\0\0D{²Ð¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Command/ClearCacheCommand.php^\ 5\0\0ùcÂX^\ 5\0\0\83÷\8d\ f\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/ConfigCommand.phpªG\0\0ùcÂXªG\0\0Ð5$4¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Command/CreateProjectCommand.phpë4\0\0ùcÂXë4\0\0\87&ªö¶\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/DependsCommand.php·\ 2\0\0ùcÂX·\ 2\0\0o±¹ú¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/DiagnoseCommand.phpÍF\0\0ùcÂXÍF\0\0²E>F¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Command/DumpAutoloadCommand.php¨       \0\0ùcÂX¨ \0\0g/\94\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/ExecCommand.phph\a\0\0ùcÂXh\a\0\0í\bB=¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/GlobalCommand.phpü\a\0\0ùcÂXü\a\0\0ÝH\8f\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/HomeCommand.php\1f\ e\0\0ùcÂX\1f\ e\0\0\16±¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/InitCommand.phpµ=\0\0ùcÂXµ=\0\0*µÍ\14\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/InstallCommand.phpý\13\0\0ùcÂXý\13\0\00ö:\89\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/LicensesCommand.php%\ e\0\0ùcÂX%\ e\0\0nx
28\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/OutdatedCommand.php°
29 \0\0ùcÂX°
30 \0\07àzk¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Command/ProhibitsCommand.phpË\ 2\0\0ùcÂXË\ 2\0\0\1ag\8fð¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/RemoveCommand.phpç\15\0\0ùcÂXç\15\0\0º\ 3\v\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Command/RequireCommand.php£\1f\0\0ùcÂX£\1f\0\0\ 4\9a@p¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Command/RunScriptCommand.php\9f\f\0\0ùcÂX\9f\f\0\0ÎÀñ˶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Command/ScriptAliasCommand.php\ 2\ 5\0\0ùcÂX\ 2\ 5\0\0®%þ\9b\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/SearchCommand.phpá\b\0\0ùcÂXá\b\0\0\ 3\88\fª¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Command/SelfUpdateCommand.phpï0\0\0ùcÂXï0\0\0û­\ 3\f\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Command/ShowCommand.phpcd\0\0ùcÂXcd\0\0\91Òba¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/StatusCommand.php.\15\0\0ùcÂX.\15\0\0\8d\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/SuggestsCommand.php¨\r\0\0ùcÂX¨\r\0\0£\16.¿¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Command/UpdateCommand.php["\0\0ùcÂX["\0\0IyYì¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Command/ValidateCommand.php\18\14\0\0ùcÂX\18\14\0\0lp\9c\ 1\0\0\0\0\0\0\19\0\0\0src/Composer/Composer.phpÿ\b\0\0ùcÂXÿ\b\0\0Ï\85YJ¶\ 1\0\0\0\0\0\0\17\0\0\0src/Composer/Config.php\90"\0\0ùcÂX\90"\0\0Þ4Jö¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Config/ConfigSourceInterface.php\ e\ 2\0\0ùcÂX\ e\ 2\0\0³\f[/¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Config/JsonConfigSource.phpÅ\11\0\0ùcÂXÅ\11\0\0Â4\87\e\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Console/Application.php$0\0\0ùcÂX$0\0\0íf\12û¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Console/HtmlOutputFormatter.php3\ 6\0\0ùcÂX3\ 6\0\0Ú\81Eu¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/DependencyResolver/Decisions.phpQ\ f\0\0ùcÂXQ\ f\0\0?\98¬$¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/DependencyResolver/DefaultPolicy.php\ 2\17\0\0ùcÂX\ 2\17\0\0õÝv\7f\ 1\0\0\0\0\0\0/\0\0\0src/Composer/DependencyResolver/GenericRule.php·\ 3\0\0ùcÂX·\ 3\0\0Ì~¯³¶\ 1\0\0\0\0\0\0>\0\0\0src/Composer/DependencyResolver/Operation/InstallOperation.phpC\ 2\0\0ùcÂXC\ 2\0\0´\õ*¶\ 1\0\0\0\0\0\0I\0\0\0src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php÷\ 2\0\0ùcÂX÷\ 2\0\0ïÎà÷¶\ 1\0\0\0\0\0\0K\0\0\0src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.phpý\ 2\0\0ùcÂXý\ 2\0\0\193#\86\ 1\0\0\0\0\0\0@\0\0\0src/Composer/DependencyResolver/Operation/OperationInterface.phpÓ\0\0\0ùcÂXÓ\0\0\0Ùâ&ä¶\ 1\0\0\0\0\0\0=\0\0\0src/Composer/DependencyResolver/Operation/SolverOperation.php¹\ 1\0\0ùcÂX¹\ 1\0\0&¢e
31\ 1\0\0\0\0\0\0@\0\0\0src/Composer/DependencyResolver/Operation/UninstallOperation.phpI\ 2\0\0ùcÂXI\ 2\0\0FûÂɶ\ 1\0\0\0\0\0\0=\0\0\0src/Composer/DependencyResolver/Operation/UpdateOperation.phph\ 3\0\0ùcÂXh\ 3\0\0öSÕ]¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/DependencyResolver/PolicyInterface.php­\ 1\0\0ùcÂX­\ 1\0\0\18\9f\8b\ 1\0\0\0\0\0\0(\0\0\0src/Composer/DependencyResolver/Pool.php°"\0\0ùcÂX°"\0\0\1d   \8e\ 1\0\0\0\0\0\0+\0\0\0src/Composer/DependencyResolver/Problem.php\99\16\0\0ùcÂX\99\16\0\0\ 3´\87Ķ\ 1\0\0\0\0\0\0+\0\0\0src/Composer/DependencyResolver/Request.php\83\ 4\0\0ùcÂX\83\ 4\0\0åVP\84\ 1\0\0\0\0\0\0(\0\0\0src/Composer/DependencyResolver/Rule.phpn\18\0\0ùcÂXn\18\0\0\973"u¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/DependencyResolver/Rule2Literals.php§\ 4\0\0ùcÂX§\ 4\0\0~Ð'ò¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/DependencyResolver/RuleSet.phpª
32 \0\0ùcÂXª
33 \0\0\82\e\ 1\0\0\0\0\0\04\0\0\0src/Composer/DependencyResolver/RuleSetGenerator.phpO\e\0\0ùcÂXO\e\0\0³Q[â¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/DependencyResolver/RuleSetIterator.php\14\ 6\0\0ùcÂX\14\ 6\0\0}õÇù¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/DependencyResolver/RuleWatchChain.phpi\ 1\0\0ùcÂXi\ 1\0\0\9a\ 1\0\0\0\0\0\02\0\0\0src/Composer/DependencyResolver/RuleWatchGraph.phpá\ 6\0\0ùcÂXá\ 6\0\0\89rôv¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/DependencyResolver/RuleWatchNode.phpñ\ 3\0\0ùcÂXñ\ 3\0\0ë\95\e\93\ 1\0\0\0\0\0\0*\0\0\0src/Composer/DependencyResolver/Solver.php\9f8\0\0ùcÂX\9f8\0\0\1epöb¶\ 1\0\0\0\0\0\06\0\0\0src/Composer/DependencyResolver/SolverBugException.php\98\ 1\0\0ùcÂX\98\ 1\0\0\7f"qN¶\ 1\0\0\0\0\0\0;\0\0\0src/Composer/DependencyResolver/SolverProblemsException.php¤\a\0\0ùcÂX¤\a\0\0Ä\1d~\a\ 1\0\0\0\0\0\0/\0\0\0src/Composer/DependencyResolver/Transaction.phpô\13\0\0ùcÂXô\13\0\0cïTܶ\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Downloader/ArchiveDownloader.phpå\ e\0\0ùcÂXå\ e\0\0\15\83dø¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/Downloader/ChangeReportInterface.phpÌ\0\0\0ùcÂXÌ\0\0\0¯à¨¿¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Downloader/DownloadManager.phpG\15\0\0ùcÂXG\15\0\0\8a(í»¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Downloader/DownloaderInterface.phpÊ\ 1\0\0ùcÂXÊ\ 1\0\0gs!l¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/Downloader/DvcsDownloaderInterface.phpÑ\0\0\0ùcÂXÑ\0\0\0\9c¿¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Downloader/FileDownloader.phpÍ\17\0\0ùcÂXÍ\17\0\0\81Õ\90\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Downloader/FilesystemException.php
34 \ 1\0\0ùcÂX
35 \ 1\0\0.-\1e\8b\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Downloader/FossilDownloader.php`\v\0\0ùcÂX`\v\0\0ÿI©u¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/GitDownloader.php\9d3\0\0ùcÂX\9d3\0\01mU¥¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Downloader/GzipDownloader.phpó\ 6\0\0ùcÂXó\ 6\0\0}Úo¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Downloader/HgDownloader.php8 \0\0ùcÂX8 \0\0ëyàn¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Downloader/PathDownloader.phpS\10\0\0ùcÂXS\10\0\0Êfý|¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/Downloader/PearPackageExtractor.phpu\e\0\0ùcÂXu\e\0\0z\84\15\87\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Downloader/PerforceDownloader.phpÃ\a\0\0ùcÂXÃ\a\0\0\1c\91Èý¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Downloader/PharDownloader.phpå\0\0\0ùcÂXå\0\0\0ÞÉ\1fç¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/RarDownloader.php\9e\a\0\0ùcÂX\9e\a\0\06      3U¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/SvnDownloader.phpG\11\0\0ùcÂXG\11\0\0\86íV\96\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/TarDownloader.phpã\0\0\0ùcÂXã\0\0\0Í\92X?¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Downloader/TransportException.php=\ 2\0\0ùcÂX=\ 2\0\0ZÎÈÞ¶\ 1\0\0\0\0\0\09\0\0\0src/Composer/Downloader/VcsCapableDownloaderInterface.phpÔ\0\0\0ùcÂXÔ\0\0\0`§ôö¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/VcsDownloader.php"\16\0\0ùcÂX"\16\0\0\9c\1a\9f\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Downloader/XzDownloader.php§\ 4\0\0ùcÂX§\ 4\0\0W$;á¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Downloader/ZipDownloader.phpù\f\0\0ùcÂXù\f\0\0>Å¡\13\ 1\0\0\0\0\0\0&\0\0\0src/Composer/EventDispatcher/Event.php \ 2\0\0ùcÂX \ 2\0\0±\99jï¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/EventDispatcher/EventDispatcher.phpÀ/\0\0ùcÂXÀ/\0\0dw\0\ e\ 1\0\0\0\0\0\09\0\0\0src/Composer/EventDispatcher/EventSubscriberInterface.php©\0\0\0ùcÂX©\0\0\0\ 1\ 1\0\0\0\0\0\09\0\0\0src/Composer/EventDispatcher/ScriptExecutionException.phpv\0\0\0ùcÂXv\0\0\0wZ8S¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Exception/NoSslException.phpf\0\0\0ùcÂXf\0\0\0ËíM\9d\ 1\0\0\0\0\0\0\18\0\0\0src/Composer/Factory.php¦<\0\0ùcÂX¦<\0\0i\87@˶\ 1\0\0\0\0\0\0\1a\0\0\0src/Composer/IO/BaseIO.php\8c\10\0\0ùcÂX\8c\10\0\0(\82l\91\ 1\0\0\0\0\0\0\1c\0\0\0src/Composer/IO/BufferIO.php*\ 4\0\0ùcÂX*\ 4\0\0¢®hT¶\ 1\0\0\0\0\0\0\1d\0\0\0src/Composer/IO/ConsoleIO.php@\15\0\0ùcÂX@\15\0\0\ 6¤ñâ¶\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/IO/IOInterface.phpì\ 5\0\0ùcÂXì\ 5\0\0\0Õ\9d\ e\ 1\0\0\0\0\0\0\1a\0\0\0src/Composer/IO/NullIO.phpÀ\ 4\0\0ùcÂXÀ\ 4\0\0F`sʶ\ 1\0\0\0\0\0\0\1a\0\0\0src/Composer/Installer.php \97\0\0ùcÂX \97\0\0Ô©ül¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Installer/BinaryInstaller.php\ 4\13\0\0ùcÂX\ 4\13\0\0³\v\1c\ 1\0\0\0\0\0\02\0\0\0src/Composer/Installer/BinaryPresenceInterface.phpË\0\0\0ùcÂXË\0\0\0À5\9a¨¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Installer/InstallationManager.php-\17\0\0ùcÂX-\17\0\0¾}\8c\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Installer/InstallerEvent.php\ e\ 6\0\0ùcÂX\ e\ 6\0\0lÔzi¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Installer/InstallerEvents.phpÞ\0\0\0ùcÂXÞ\0\0\0ì\9f@G¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Installer/InstallerInterface.phpã\ 2\0\0ùcÂXã\ 2\0\0^\83\93ʶ\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Installer/LibraryInstaller.php^\13\0\0ùcÂX^\13\0\0\10\1aÍr¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Installer/MetapackageInstaller.php\9c\ 4\0\0ùcÂX\9c\ 4\0\0Æ\12Å!¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Installer/NoopInstaller.php+\ 5\0\0ùcÂX+\ 5\0\0À·M}¶\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Installer/PackageEvent.phpe\ 3\0\0ùcÂXe\ 3\0\0;° \1a\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Installer/PackageEvents.php¸\ 1\0\0ùcÂX¸\ 1\0\0dbØs¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Installer/PearBinaryInstaller.phpâ\f\0\0ùcÂXâ\f\0\0;øiU¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Installer/PearInstaller.php¢\a\0\0ùcÂX¢\a\0\0È\82¶Ñ¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Installer/PluginInstaller.php\9f\ 6\0\0ùcÂX\9f\ 6\0\0<tú,¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Installer/ProjectInstaller.php\1d\ 6\0\0ùcÂX\1d\ 6\0\0*0@P¶\ 1\0\0\0\0\0\04\0\0\0src/Composer/Installer/SuggestedPackagesReporter.phpª\ 5\0\0ùcÂXª\ 5\0\0àGö\ 1\0\0\0\0\0\0\1e\0\0\0src/Composer/Json/JsonFile.php\ 3\14\0\0ùcÂX\ 3\14\0\0VVN\15\ 1\0\0\0\0\0\0#\0\0\0src/Composer/Json/JsonFormatter.php\ 6\ 6\0\0ùcÂX\ 6\ 6\0\0\1eÐqu¶\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Json/JsonManipulator.phpþ0\0\0ùcÂXþ0\0\0\0kÌc¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Json/JsonValidationException.php\\ 1\0\0ùcÂX\\ 1\0\0.Xóܶ\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Package/AliasPackage.php\ 5\17\0\0ùcÂX\ 5\17\0\0¹\97~\9a\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/Archiver/ArchivableFilesFilter.php       \ 2\0\0ùcÂX \ 2\0\0yY+¦¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/Archiver/ArchivableFilesFinder.phpÞ\ 5\0\0ùcÂXÞ\ 5\0\0\f²²¹¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/Package/Archiver/ArchiveManager.php°\f\0\0ùcÂX°\f\0\0gþÒ)¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/Package/Archiver/ArchiverInterface.php\a\ 1\0\0ùcÂX\a\ 1\0\0ñ´>\v\ 1\0\0\0\0\0\03\0\0\0src/Composer/Package/Archiver/BaseExcludeFilter.php\96\ 6\0\0ùcÂX\96\ 6\0\0y¶=ƶ\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/Archiver/ComposerExcludeFilter.php\1f\ 1\0\0ùcÂX\1f\ 1\0\0\8bSZ0¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/Package/Archiver/GitExcludeFilter.phpq\ 3\0\0ùcÂXq\ 3\0\05¾i&¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/Package/Archiver/HgExcludeFilter.php\13\ 5\0\0ùcÂX\13\ 5\0\0~\94\ e¸¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Package/Archiver/PharArchiver.php>\ 6\0\0ùcÂX>\ 6\0\0 5\89í¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Package/Archiver/ZipArchiver.php¼\ 4\0\0ùcÂX¼\ 4\0\0\91XÝë¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Package/BasePackage.php&\r\0\0ùcÂX&\r\0\0\e'\1fݶ\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Package/CompletePackage.phpü\ 6\0\0ùcÂXü\ 6\0\0þM˶¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/Package/CompletePackageInterface.phpõ\ 1\0\0ùcÂXõ\ 1\0\0¦Ê\81ò¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Package/Dumper/ArrayDumper.phpë\v\0\0ùcÂXë\v\0\0Ó8WE¶\ 1\0\0\0\0\0\0\1d\0\0\0src/Composer/Package/Link.php\88\ 5\0\0ùcÂX\88\ 5\0\0å¶Y«¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/LinkConstraint/EmptyConstraint.php\82\ 1\0\0ùcÂX\82\ 1\0\0\ eé~\8b\ 1\0\0\0\0\0\0?\0\0\0src/Composer/Package/LinkConstraint/LinkConstraintInterface.phpd\ 1\0\0ùcÂXd\ 1\0\0¤ôLn¶\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/LinkConstraint/MultiConstraint.php\82\ 1\0\0ùcÂX\82\ 1\0\0ób`ý¶\ 1\0\0\0\0\0\0:\0\0\0src/Composer/Package/LinkConstraint/SpecificConstraint.phpi\ 1\0\0ùcÂXi\ 1\0\0Þ\94\9a\ 1\0\0\0\0\0\09\0\0\0src/Composer/Package/LinkConstraint/VersionConstraint.phpX\ 1\0\0ùcÂXX\ 1\0\0\ 2}`y¶\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Package/Loader/ArrayLoader.php¸\1e\0\0ùcÂX¸\1e\0\06\r¤\1d\ 1\0\0\0\0\0\07\0\0\0src/Composer/Package/Loader/InvalidPackageException.phpE\ 2\0\0ùcÂXE\ 2\0\0xb\13¾¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Package/Loader/JsonLoader.phpù\ 1\0\0ùcÂXù\ 1\0\0!~\88\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Package/Loader/LoaderInterface.php²\0\0\0ùcÂX²\0\0\0¦}úζ\ 1\0\0\0\0\0\01\0\0\0src/Composer/Package/Loader/RootPackageLoader.php½\16\0\0ùcÂX½\16\0\0\8d\ 1\0\0\0\0\0\05\0\0\0src/Composer/Package/Loader/ValidatingArrayLoader.php½1\0\0ùcÂX½1\0\0ÅnÚѶ\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/Package/Locker.phpª!\0\0ùcÂXª!\0\0\8f7e¾¶\ 1\0\0\0\0\0\0 \0\0\0src/Composer/Package/Package.phpÉ\1a\0\0ùcÂXÉ\1a\0\0\8f\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Package/PackageInterface.php \a\0\0ùcÂX \a\0\0ûÇ^ƶ\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Package/RootAliasPackage.php\1f   \0\0ùcÂX\1f \0\0      _\80ø¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Package/RootPackage.php\11\ 5\0\0ùcÂX\11\ 5\0\0\ 2\8eÎ_¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Package/RootPackageInterface.php¹\ 3\0\0ùcÂX¹\ 3\0\0"maV¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Package/Version/VersionGuesser.phpµ\1c\0\0ùcÂXµ\1c\0\0.â_  ¶\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Package/Version/VersionParser.phpø\ 3\0\0ùcÂXø\ 3\0\0\1e¾3l¶\ 1\0\0\0\0\0\00\0\0\0src/Composer/Package/Version/VersionSelector.phpK\f\0\0ùcÂXK\f\0\0²<\ fȶ\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Plugin/Capability/Capability.phpW\0\0\0ùcÂXW\0\0\0æ_¨1¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/Plugin/Capability/CommandProvider.php\97\0\0\0ùcÂX\97\0\0\0ûOâ>¶\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/Plugin/Capable.php\7f\0\0\0ùcÂX\7f\0\0\0Æq\15\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Plugin/CommandEvent.phpâ\ 2\0\0ùcÂXâ\ 2\0\0³ÆÇW¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Plugin/PluginEvents.phpÂ\0\0\0ùcÂXÂ\0\0\0^Íþ\ 6\ 1\0\0\0\0\0\0'\0\0\0src/Composer/Plugin/PluginInterface.phpô\0\0\0ùcÂXô\0\0\0)'*ض\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Plugin/PluginManager.php\1f$\0\0ùcÂX\1f$\0\0ë\8e"»¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Plugin/PreFileDownloadEvent.php`\ 2\0\0ùcÂX`\ 2\0\0\09-ζ\ 1\0\0\0\0\0\0+\0\0\0src/Composer/Repository/ArrayRepository.php\13\ e\0\0ùcÂX\13\ e\0\0éÌt\0\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/ArtifactRepository.php»\f\0\0ùcÂX»\f\0\0\88Ý÷<¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Repository/BaseRepository.php_\r\0\0ùcÂX_\r\0\0\96ûß\ e\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/ComposerRepository.phpAT\0\0ùcÂXAT\0\0u\0`\1e\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Repository/CompositeRepository.php;\b\0\0ùcÂX;\b\0\0¤¯S\1f\ 1\0\0\0\0\0\0;\0\0\0src/Composer/Repository/ConfigurableRepositoryInterface.php\85\0\0\0ùcÂX\85\0\0\0±\9f_\1c\ 1\0\0\0\0\0\00\0\0\0src/Composer/Repository/FilesystemRepository.php×\ 4\0\0ùcÂX×\ 4\0\0I\9cª\13\ 1\0\0\0\0\0\04\0\0\0src/Composer/Repository/InstalledArrayRepository.php£\0\0\0ùcÂX£\0\0\0/ö~>¶\ 1\0\0\0\0\0\09\0\0\0src/Composer/Repository/InstalledFilesystemRepository.php£\0\0\0ùcÂX£\0\0\0V
36 \95\ 1\0\0\0\0\0\08\0\0\0src/Composer/Repository/InstalledRepositoryInterface.php\87\0\0\0ùcÂX\87\0\0\0\18£9p¶\ 1\0\0\0\0\0\06\0\0\0src/Composer/Repository/InvalidRepositoryException.phpn\0\0\0ùcÂXn\0\0\0à\93ë\98\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Repository/PackageRepository.phpj\ 3\0\0ùcÂXj\ 3\0\0¥ôò̶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Repository/PathRepository.phpY        \0\0ùcÂXY \0\0(\97¾3¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/Repository/Pear/BaseChannelReader.phpI\ 5\0\0ùcÂXI\ 5\0\0c\b6³¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Pear/ChannelInfo.phpÄ\ 1\0\0ùcÂXÄ\ 1\0\0:T*ɶ\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/Pear/ChannelReader.phpí\ 6\0\0ùcÂXí\ 6\0\0?ÈYT¶\ 1\0\0\0\0\0\04\0\0\0src/Composer/Repository/Pear/ChannelRest10Reader.phpÁ \0\0ùcÂXÁ \0\0\ 4O\80ë¶\ 1\0\0\0\0\0\04\0\0\0src/Composer/Repository/Pear/ChannelRest11Reader.php& \0\0ùcÂX& \0\0òUb\b\ 1\0\0\0\0\0\05\0\0\0src/Composer/Repository/Pear/DependencyConstraint.phpq\ 2\0\0ùcÂXq\ 2\0\09\ e\17\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Repository/Pear/DependencyInfo.phpq\ 1\0\0ùcÂXq\ 1\0\0fºTò¶\ 1\0\0\0\0\0\08\0\0\0src/Composer/Repository/Pear/PackageDependencyParser.php\85\16\0\0ùcÂX\85\16\0\0÷$Li¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Pear/PackageInfo.php°\ 3\0\0ùcÂX°\ 3\0\0\9f\r¸\f\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Pear/ReleaseInfo.php\92\ 1\0\0ùcÂX\92\ 1\0\0o\93\8aö\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Repository/PearRepository.phpª\16\0\0ùcÂXª\16\0\0)\9f\83\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/PlatformRepository.php\ 1\e\0\0ùcÂX\ 1\e\0\0\ 3_Mì¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Repository/RepositoryFactory.phpM\11\0\0ùcÂXM\11\0\0^ Æä¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Repository/RepositoryInterface.phpÛ\ 1\0\0ùcÂXÛ\ 1\0\0\92\11âÁ¶\ 1\0\0\0\0\0\0-\0\0\0src/Composer/Repository/RepositoryManager.php,
37 \0\0ùcÂX,
38 \0\0¾\85\\95\ 1\0\0\0\0\0\07\0\0\0src/Composer/Repository/RepositorySecurityException.phpo\0\0\0ùcÂXo\0\0\0pÕ«ª¶\ 1\0\0\0\0\0\0/\0\0\0src/Composer/Repository/Vcs/BitbucketDriver.php \1e\0\0ùcÂX \1e\0\0¶tpX¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Vcs/FossilDriver.php \12\0\0ùcÂX \12\0\0]\8bÉQ¶\ 1\0\0\0\0\0\02\0\0\0src/Composer/Repository/Vcs/GitBitbucketDriver.phpê\ 5\0\0ùcÂXê\ 5\0\0Ã\8e»\14\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/Vcs/GitDriver.phpØ\11\0\0ùcÂXØ\11\0\0Ý"T̶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Vcs/GitHubDriver.phpz+\0\0ùcÂXz+\0\0\13\1fÚb¶\ 1\0\0\0\0\0\0,\0\0\0src/Composer/Repository/Vcs/GitLabDriver.php\92\1d\0\0ùcÂX\92\1d\0\0\17î i¶\ 1\0\0\0\0\0\01\0\0\0src/Composer/Repository/Vcs/HgBitbucketDriver.phpä\ 5\0\0ùcÂXä\ 5\0\0i\9büà¶\ 1\0\0\0\0\0\0(\0\0\0src/Composer/Repository/Vcs/HgDriver.php¥\12\0\0ùcÂX¥\12\0\0uߣȶ\ 1\0\0\0\0\0\0.\0\0\0src/Composer/Repository/Vcs/PerforceDriver.phpO     \0\0ùcÂXO \0\0@ËóN¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/Vcs/SvnDriver.php\15\e\0\0ùcÂX\15\e\0\0\1dÕzï¶\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/Vcs/VcsDriver.php\83
39 \0\0ùcÂX\83
40 \0\0\9e\9f\11\87\ 1\0\0\0\0\0\02\0\0\0src/Composer/Repository/Vcs/VcsDriverInterface.php÷\ 2\0\0ùcÂX÷\ 2\0\0ÇX[\89\ 1\0\0\0\0\0\0)\0\0\0src/Composer/Repository/VcsRepository.php´\1e\0\0ùcÂX´\1e\0\0\ 1ªÖG¶\ 1\0\0\0\0\0\03\0\0\0src/Composer/Repository/WritableArrayRepository.php\ f\ 3\0\0ùcÂX\ f\ 3\0\0¾G\17\ 1\0\0\0\0\0\07\0\0\0src/Composer/Repository/WritableRepositoryInterface.php\89\ 1\0\0ùcÂX\89\ 1\0\0\91/sï¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Script/CommandEvent.phpW\0\0\0ùcÂXW\0\0\0£VZt¶\ 1\0\0\0\0\0\0\1d\0\0\0src/Composer/Script/Event.phpµ\ 2\0\0ùcÂXµ\ 2\0\0lt¦M¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Script/PackageEvent.php\9c\0\0\0ùcÂX\9c\0\0\0§ÿÉ\r\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Script/ScriptEvents.phpP\ 4\0\0ùcÂXP\ 4\0\0\87\8f\ 4¶¶\ 1\0\0\0\0\0\0 \0\0\0src/Composer/SelfUpdate/Keys.php\9d\ 1\0\0ùcÂX\9d\ 1\0\0\vîÊN¶\ 1\0\0\0\0\0\0$\0\0\0src/Composer/SelfUpdate/Versions.phpì\ 5\0\0ùcÂXì\ 5\0\0͵\91\83\ 1\0\0\0\0\0\0 \0\0\0src/Composer/Util/AuthHelper.phpË\ 3\0\0ùcÂXË\ 3\0\0>zx\96\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/Util/Bitbucket.phpõ\14\0\0ùcÂXõ\14\0\0\92q9\85\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Util/ComposerMirror.php±\ 4\0\0ùcÂX±\ 4\0\0­½øض\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Util/ConfigValidator.php&\11\0\0ùcÂX&\11\0\0î:äü¶\ 1\0\0\0\0\0\0"\0\0\0src/Composer/Util/ErrorHandler.php\87\ 4\0\0ùcÂX\87\ 4\0\0He\1c\ 1\0\0\0\0\0\0 \0\0\0src/Composer/Util/Filesystem.phps.\0\0ùcÂXs.\0\0\9bÍ®à¶\ 1\0\0\0\0\0\0\19\0\0\0src/Composer/Util/Git.phpT$\0\0ùcÂXT$\0\0çz¢\81\ 1\0\0\0\0\0\0\1c\0\0\0src/Composer/Util/GitHub.php¯
41 \0\0ùcÂX¯
42 \0\0\1dàÏ   ¶\ 1\0\0\0\0\0\0\1c\0\0\0src/Composer/Util/GitLab.php\7f\f\0\0ùcÂX\7f\f\0\0\83\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/Util/IniHelper.php\9d\ 2\0\0ùcÂX\9d\ 2\0\0Çþ\82\ 1\0\0\0\0\0\0$\0\0\0src/Composer/Util/NoProxyPattern.php¾\ 6\0\0ùcÂX¾\ 6\0\0Z+°m¶\ 1\0\0\0\0\0\0\1e\0\0\0src/Composer/Util/Perforce.php\1e2\0\0ùcÂX\1e2\0\0­\ 65P¶\ 1\0\0\0\0\0\0\1e\0\0\0src/Composer/Util/Platform.phpü\ 4\0\0ùcÂXü\ 4\0\0s­fç¶\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Util/ProcessExecutor.php\f\b\0\0ùcÂX\f\b\0\0\88)sw¶\ 1\0\0\0\0\0\0&\0\0\0src/Composer/Util/RemoteFilesystem.php$b\0\0ùcÂX$b\0\0÷7Mp¶\ 1\0\0\0\0\0\0\1e\0\0\0src/Composer/Util/Silencer.phpò\ 2\0\0ùcÂXò\ 2\0\0.\8e\7fܶ\ 1\0\0\0\0\0\0!\0\0\0src/Composer/Util/SpdxLicense.php\ 3\ 1\0\0ùcÂX\ 3\ 1\0\0¾7
43 ñ¶\ 1\0\0\0\0\0\0*\0\0\0src/Composer/Util/StreamContextFactory.phpw\ f\0\0ùcÂXw\ f\0\0Ó;Ã\91\ 1\0\0\0\0\0\0\19\0\0\0src/Composer/Util/Svn.php¾\11\0\0ùcÂX¾\11\0\0Ík\93ܶ\ 1\0\0\0\0\0\0\1f\0\0\0src/Composer/Util/TlsHelper.phpp
44 \0\0ùcÂXp
45 \0\0¤eÞæ¶\ 1\0\0\0\0\0\0\1e\0\0\0src/Composer/XdebugHandler.php\ 4\ f\0\0ùcÂX\ 4\ f\0\0ë\1d\88½¶\ 1\0\0\0\0\0\0\11\0\0\0src/bootstrap.php¹\ 1\0\0ùcÂX¹\ 1\0\0\15I}\9c\ 1\0\0\0\0\0\0%\0\0\0src/Composer/Autoload/ClassLoader.php\8b4\0\0ùcÂX\8b4\0\0Q\9f\94¼¶\ 1\0\0\0\0\0\0#\0\0\0res/composer-repository-schema.jsonð\ f\0\0ùcÂXð\ f\0\0\81GÐà¶\ 1\0\0\0\0\0\0\18\0\0\0res/composer-schema.json[\92\0\0ùcÂX[\92\0\0ák¥\ f\ 1\0\0\0\0\0\06\0\0\0vendor/composer/spdx-licenses/res/spdx-exceptions.jsoní\ 6\0\0ùcÂXí\ 6\0\0ÆÅz±¶\ 1\0\0\0\0\0\04\0\0\0vendor/composer/spdx-licenses/res/spdx-licenses.json\ve\0\0ùcÂX\ve\0\0ùe!\89\ 1\0\0\0\0\0\0*\0\0\0vendor/seld/cli-prompt/res/hiddeninput.exe\0$\0\0ùcÂX\0$\0\0\95\8d¥v¶\ 1\0\0\0\0\0\0&\0\0\0vendor/symfony/console/Application.php.W\0\0ùcÂX.W\0\0´'\8fð¶\ 1\0\0\0\0\0\0*\0\0\0vendor/symfony/console/Command/Command.php\95#\0\0ùcÂX\95#\0\0Ìí+!¶\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/console/Command/HelpCommand.phpÝ\a\0\0ùcÂXÝ\a\0\0\99\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/console/Command/ListCommand.phpZ\b\0\0ùcÂXZ\b\0\0É£ \16\ 1\0\0\0\0\0\0(\0\0\0vendor/symfony/console/ConsoleEvents.phpï\0\0\0ùcÂXï\0\0\0\rÕH¸¶\ 1\0\0\0\0\0\0<\0\0\0vendor/symfony/console/Descriptor/ApplicationDescription.phpß\b\0\0ùcÂXß\b\0\0µ\8c°7¶\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/console/Descriptor/Descriptor.php\9d\a\0\0ùcÂX\9d\a\0\0\b;~Ķ\ 1\0\0\0\0\0\09\0\0\0vendor/symfony/console/Descriptor/DescriptorInterface.phpü\0\0\0ùcÂXü\0\0\0±Q\aµ¶\ 1\0\0\0\0\0\04\0\0\0vendor/symfony/console/Descriptor/JsonDescriptor.php\9a\r\0\0ùcÂX\9a\r\0\0\14\ 5\ 1\0\0\0\0\0\08\0\0\0vendor/symfony/console/Descriptor/MarkdownDescriptor.php¹\ e\0\0ùcÂX¹\ e\0\0k\9f.a¶\ 1\0\0\0\0\0\04\0\0\0vendor/symfony/console/Descriptor/TextDescriptor.phpi\1e\0\0ùcÂXi\1e\0\0 Îòÿ¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/console/Descriptor/XmlDescriptor.php\ f\1c\0\0ùcÂX\ f\1c\0\0\ 4\8bP$¶\ 1\0\0\0\0\0\04\0\0\0vendor/symfony/console/Event/ConsoleCommandEvent.php²\ 1\0\0ùcÂX²\ 1\0\0Zk\89\ 1\0\0\0\0\0\0-\0\0\0vendor/symfony/console/Event/ConsoleEvent.phpÅ\ 2\0\0ùcÂXÅ\ 2\0\0ÒxÛ\¶\ 1\0\0\0\0\0\06\0\0\0vendor/symfony/console/Event/ConsoleExceptionEvent.php\12\ 3\0\0ùcÂX\12\ 3\0\0á\162é¶\ 1\0\0\0\0\0\06\0\0\0vendor/symfony/console/Event/ConsoleTerminateEvent.phpz\ 2\0\0ùcÂXz\ 2\0\0³,îL¶\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/console/Exception/CommandNotFoundException.phpÔ\ 1\0\0ùcÂXÔ\ 1\0\0È÷ L¶\ 1\0\0\0\0\0\07\0\0\0vendor/symfony/console/Exception/ExceptionInterface.phpf\0\0\0ùcÂXf\0\0\0¡ABª¶\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/console/Exception/InvalidArgumentException.php¦\0\0\0ùcÂX¦\0\0\0Ö̽Z¶\ 1\0\0\0\0\0\0;\0\0\0vendor/symfony/console/Exception/InvalidOptionException.php¦\0\0\0ùcÂX¦\0\0\0\13Ë×H¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/console/Exception/LogicException.php\92\0\0\0ùcÂX\92\0\0\0ÍO\e¶\ 1\0\0\0\0\0\05\0\0\0vendor/symfony/console/Exception/RuntimeException.php\96\0\0\0ùcÂX\96\0\0\0Ùí,6¶\ 1\0\0\0\0\0\04\0\0\0vendor/symfony/console/Formatter/OutputFormatter.php!\ e\0\0ùcÂX!\ e\0\0§îwx¶\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/console/Formatter/OutputFormatterInterface.php\8a\ 1\0\0ùcÂX\8a\ 1\0\0\ 5\a\ 1\0\0\0\0\0\09\0\0\0vendor/symfony/console/Formatter/OutputFormatterStyle.phpL\10\0\0ùcÂXL\10\0\0\8a\908<¶\ 1\0\0\0\0\0\0B\0\0\0vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php\86\ 1\0\0ùcÂX\86\ 1\0\0ÝRÚ­¶\ 1\0\0\0\0\0\0>\0\0\0vendor/symfony/console/Formatter/OutputFormatterStyleStack.phpL\ 5\0\0ùcÂXL\ 5\0\0.=\16\ 1\0\0\0\0\0\06\0\0\0vendor/symfony/console/Helper/DebugFormatterHelper.phpx\b\0\0ùcÂXx\b\0\0N©Ø¼¶\ 1\0\0\0\0\0\02\0\0\0vendor/symfony/console/Helper/DescriptorHelper.phpz\ 5\0\0ùcÂXz\ 5\0\0fÉÚý¶\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/console/Helper/DialogHelper.phpú\1e\0\0ùcÂXú\1e\0\0hX\8fö\ 1\0\0\0\0\0\01\0\0\0vendor/symfony/console/Helper/FormatterHelper.phpc\ 4\0\0ùcÂXc\ 4\0\0\93ý«N¶\ 1\0\0\0\0\0\0(\0\0\0vendor/symfony/console/Helper/Helper.php\1d\a\0\0ùcÂX\1d\a\0\0\87Â<£¶\ 1\0\0\0\0\0\01\0\0\0vendor/symfony/console/Helper/HelperInterface.phpç\0\0\0ùcÂXç\0\0\0 \18Çã¶\ 1\0\0\0\0\0\0+\0\0\0vendor/symfony/console/Helper/HelperSet.phpÐ\a\0\0ùcÂXÐ\a\0\0a\88~\r\ 1\0\0\0\0\0\02\0\0\0vendor/symfony/console/Helper/InputAwareHelper.phpc\ 1\0\0ùcÂXc\ 1\0\0ñø\90\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/console/Helper/ProcessHelper.phpÑ   \0\0ùcÂXÑ \0\0@±ã\81\ 1\0\0\0\0\0\0-\0\0\0vendor/symfony/console/Helper/ProgressBar.phps%\0\0ùcÂXs%\0\0鯦\81\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/console/Helper/ProgressHelper.php\\e\0\0ùcÂX\\e\0\0\12?\8bá¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/console/Helper/ProgressIndicator.phpK\14\0\0ùcÂXK\14\0\0í\1cÍ°¶\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/console/Helper/QuestionHelper.php\81\e\0\0ùcÂX\81\e\0\0Ô\1ab£¶\ 1\0\0\0\0\0\07\0\0\0vendor/symfony/console/Helper/SymfonyQuestionHelper.phpl
46 \0\0ùcÂXl
47 \0\0\1e÷ÞL¶\ 1\0\0\0\0\0\0'\0\0\0vendor/symfony/console/Helper/Table.php\11*\0\0ùcÂX\11*\0\0\ 1¢¸}¶\ 1\0\0\0\0\0\0+\0\0\0vendor/symfony/console/Helper/TableCell.php\87\ 3\0\0ùcÂX\87\ 3\0\0¨*æ\18\ 1\0\0\0\0\0\0-\0\0\0vendor/symfony/console/Helper/TableHelper.php\13\f\0\0ùcÂX\13\f\0\0¦pm\87\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/console/Helper/TableSeparator.phpÍ\0\0\0ùcÂXÍ\0\0\0Qßa²¶\ 1\0\0\0\0\0\0,\0\0\0vendor/symfony/console/Helper/TableStyle.php\1f
48 \0\0ùcÂX\1f
49 \0\0PÞµ¦¶\ 1\0\0\0\0\0\0*\0\0\0vendor/symfony/console/Input/ArgvInput.php\14\15\0\0ùcÂX\14\15\0\0¯Ü\10\9c\ 1\0\0\0\0\0\0+\0\0\0vendor/symfony/console/Input/ArrayInput.php_
50 \0\0ùcÂX_
51 \0\0[µðɶ\ 1\0\0\0\0\0\0&\0\0\0vendor/symfony/console/Input/Input.phpª\v\0\0ùcÂXª\v\0\0\ 3\1a\1f¶¶\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/console/Input/InputArgument.php\12\ 6\0\0ùcÂX\12\ 6\0\0ÁÜ\17\90\ 1\0\0\0\0\0\04\0\0\0vendor/symfony/console/Input/InputAwareInterface.php\9a\0\0\0ùcÂX\9a\0\0\0\87jT\9f\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/console/Input/InputDefinition.php\96\19\0\0ùcÂX\96\19\0\00Oly¶\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/console/Input/InputInterface.php\9f\ 3\0\0ùcÂX\9f\ 3\0\0¥R6Û¶\ 1\0\0\0\0\0\0,\0\0\0vendor/symfony/console/Input/InputOption.php\1c\f\0\0ùcÂX\1c\f\0\0\87¹§\7f\ 1\0\0\0\0\0\0,\0\0\0vendor/symfony/console/Input/StringInput.php\98\ 6\0\0ùcÂX\98\ 6\0\0 \1dÚ¤¶\ 1\0\0\0\0\0\0\1e\0\0\0vendor/symfony/console/LICENSE)\ 4\0\0ùcÂX)\ 4\0\0·)E`¶\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/console/Logger/ConsoleLogger.php< \0\0ùcÂX< \0\0:âÇl¶\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/console/Output/BufferedOutput.php_\ 1\0\0ùcÂX_\ 1\0\0ûBÍ·¶\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/console/Output/ConsoleOutput.phpµ\a\0\0ùcÂXµ\a\0\0
52 ¢S\¶\ 1\0\0\0\0\0\08\0\0\0vendor/symfony/console/Output/ConsoleOutputInterface.phpå\0\0\0ùcÂXå\0\0\0rNô\0\ 1\0\0\0\0\0\0,\0\0\0vendor/symfony/console/Output/NullOutput.phpÏ\ 3\0\0ùcÂXÏ\ 3\0\0®\98\8b\ 1\0\0\0\0\0\0(\0\0\0vendor/symfony/console/Output/Output.php\9a    \0\0ùcÂX\9a \0\001 ý¶\ 1\0\0\0\0\0\01\0\0\0vendor/symfony/console/Output/OutputInterface.php\1c\ 3\0\0ùcÂX\1c\ 3\0\0\1aÓÚ>¶\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/console/Output/StreamOutput.phpÄ\ 5\0\0ùcÂXÄ\ 5\0\0õ\1aí\95\ 1\0\0\0\0\0\02\0\0\0vendor/symfony/console/Question/ChoiceQuestion.php"
53 \0\0ùcÂX"
54 \0\0_౶\ 1\0\0\0\0\0\08\0\0\0vendor/symfony/console/Question/ConfirmationQuestion.phpé\ 2\0\0ùcÂXé\ 2\0\0\83\17Q@¶\ 1\0\0\0\0\0\0,\0\0\0vendor/symfony/console/Question/Question.php#
55 \0\0ùcÂX#
56 \0\0e¯ \ e\ 1\0\0\0\0\0\0 \0\0\0vendor/symfony/console/Shell.phpé\ f\0\0ùcÂXé\ f\0\0½fü\91\ 1\0\0\0\0\0\0,\0\0\0vendor/symfony/console/Style/OutputStyle.php_\ 5\0\0ùcÂX_\ 5\0\0\ 4û\ 5µ¶\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/console/Style/StyleInterface.phpÔ\ 3\0\0ùcÂXÔ\ 3\0\0 ßÊj¶\ 1\0\0\0\0\0\0-\0\0\0vendor/symfony/console/Style/SymfonyStyle.php¼\1f\0\0ùcÂX¼\1f\0\0öÅPg¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/console/Tester/ApplicationTester.phpÔ\ 5\0\0ùcÂXÔ\ 5\0\0¬ì¤d¶\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/console/Tester/CommandTester.php®\ 6\0\0ùcÂX®\ 6\0\0\9a\ 1\0\0\0\0\0\0(\0\0\0vendor/symfony/debug/BufferingLogger.phpt\ 1\0\0ùcÂXt\ 1\0\0=\0hܶ\ 1\0\0\0\0\0\0\1e\0\0\0vendor/symfony/debug/Debug.phpé\ 2\0\0ùcÂXé\ 2\0\0Àxa?¶\ 1\0\0\0\0\0\0)\0\0\0vendor/symfony/debug/DebugClassLoader.phpå\1d\0\0ùcÂXå\1d\0\0¦ù3\¶\ 1\0\0\0\0\0\0%\0\0\0vendor/symfony/debug/ErrorHandler.phpqB\0\0ùcÂXqB\0\0\9f\/r¶\ 1\0\0\0\0\0\09\0\0\0vendor/symfony/debug/Exception/ClassNotFoundException.php\84\ 1\0\0ùcÂX\84\ 1\0\0n\90¡\85\ 1\0\0\0\0\0\08\0\0\0vendor/symfony/debug/Exception/ContextErrorException.php\98\ 1\0\0ùcÂX\98\ 1\0\0-
57 d2¶\ 1\0\0\0\0\0\01\0\0\0vendor/symfony/debug/Exception/DummyException.php\ 2\ 1\0\0ùcÂX\ 2\ 1\0\0-"ûd¶\ 1\0\0\0\0\0\06\0\0\0vendor/symfony/debug/Exception/FatalErrorException.phpï\ 6\0\0ùcÂXï\ 6\0\0æ\ffz¶\ 1\0\0\0\0\0\06\0\0\0vendor/symfony/debug/Exception/FatalThrowableError.phpD\ 2\0\0ùcÂXD\ 2\0\0¡\fÂí¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/debug/Exception/FlattenException.php²\16\0\0ùcÂX²\16\0\0HòÑ\ f\ 1\0\0\0\0\0\07\0\0\0vendor/symfony/debug/Exception/OutOfMemoryException.php~\0\0\0ùcÂX~\0\0\0ë¨oâ¶\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/debug/Exception/UndefinedFunctionException.php\88\ 1\0\0ùcÂX\88\ 1\0\0¢G\82\ 1\0\0\0\0\0\0;\0\0\0vendor/symfony/debug/Exception/UndefinedMethodException.php\86\ 1\0\0ùcÂX\86\ 1\0\0¨LÚ:¶\ 1\0\0\0\0\0\0)\0\0\0vendor/symfony/debug/ExceptionHandler.php
58 3\0\0ùcÂX
59 3\0\0¹¨È£¶\ 1\0\0\0\0\0\0I\0\0\0vendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php7\12\0\0ùcÂX7\12\0\0Ñj/=¶\ 1\0\0\0\0\0\0E\0\0\0vendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php\ 3\ 1\0\0ùcÂX\ 3\ 1\0\0ĹBV¶\ 1\0\0\0\0\0\0M\0\0\0vendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.phpu\b\0\0ùcÂXu\b\0\0éj\ 3\19\ 1\0\0\0\0\0\0K\0\0\0vendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.phpN\ 5\0\0ùcÂXN\ 5\0\0Ço-ç¶\ 1\0\0\0\0\0\0\1c\0\0\0vendor/symfony/debug/LICENSE)\ 4\0\0ùcÂX)\ 4\0\0·)E`¶\ 1\0\0\0\0\0\0:\0\0\0vendor/symfony/filesystem/Exception/ExceptionInterface.phpi\0\0\0ùcÂXi\0\0\0$ ÿ\9b\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/filesystem/Exception/FileNotFoundException.php¼\ 1\0\0ùcÂX¼\ 1\0\0pí\¶¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/filesystem/Exception/IOException.php\87\ 1\0\0ùcÂX\87\ 1\0\0\80ü#Ѷ\ 1\0\0\0\0\0\0<\0\0\0vendor/symfony/filesystem/Exception/IOExceptionInterface.php¦\0\0\0ùcÂX¦\0\0\0jÙwM¶\ 1\0\0\0\0\0\0(\0\0\0vendor/symfony/filesystem/Filesystem.phpÔ.\0\0ùcÂXÔ.\0\0\ fÏL{¶\ 1\0\0\0\0\0\0!\0\0\0vendor/symfony/filesystem/LICENSE)\ 4\0\0ùcÂX)\ 4\0\0·)E`¶\ 1\0\0\0\0\0\0)\0\0\0vendor/symfony/filesystem/LockHandler.php\8e\ 5\0\0ùcÂX\8e\ 5\0\0ü\ 2 Å¶\ 1\0\0\0\0\0\01\0\0\0vendor/symfony/finder/Adapter/AbstractAdapter.php\\v\0\0ùcÂX\\v\0\0Æ\93É\80\ 1\0\0\0\0\0\05\0\0\0vendor/symfony/finder/Adapter/AbstractFindAdapter.php\91\19\0\0ùcÂX\91\19\0\0ao¦È¶\ 1\0\0\0\0\0\02\0\0\0vendor/symfony/finder/Adapter/AdapterInterface.php±\ 3\0\0ùcÂX±\ 3\0\0ä»Ê&¶\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/finder/Adapter/BsdFindAdapter.php2\a\0\0ùcÂX2\a\0\0Q/ÇC¶\ 1\0\0\0\0\0\00\0\0\0vendor/symfony/finder/Adapter/GnuFindAdapter.php\15\a\0\0ùcÂX\15\a\0\0\r\17¡¾¶\ 1\0\0\0\0\0\0,\0\0\0vendor/symfony/finder/Adapter/PhpAdapter.phpô\a\0\0ùcÂXô\a\0\0\16\1d:?¶\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/finder/Comparator/Comparator.php\8c\ 3\0\0ùcÂX\8c\ 3\0\0\16wþT¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/finder/Comparator/DateComparator.php%\ 3\0\0ùcÂX%\ 3\0\0L¿EǶ\ 1\0\0\0\0\0\05\0\0\0vendor/symfony/finder/Comparator/NumberComparator.php~\ 3\0\0ùcÂX~\ 3\0\0\94\87 x¶\ 1\0\0\0\0\0\09\0\0\0vendor/symfony/finder/Exception/AccessDeniedException.php\84\0\0\0ùcÂX\84\0\0\0½¾s\9c\ 1\0\0\0\0\0\0;\0\0\0vendor/symfony/finder/Exception/AdapterFailureException.php¯\ 2\0\0ùcÂX¯\ 2\0\0\9côÔÁ¶\ 1\0\0\0\0\0\06\0\0\0vendor/symfony/finder/Exception/ExceptionInterface.php\84\0\0\0ùcÂX\84\0\0\0\1cGz-¶\ 1\0\0\0\0\0\0A\0\0\0vendor/symfony/finder/Exception/OperationNotPermitedException.php)\ 1\0\0ùcÂX)\ 1\0\0ìcj=¶\ 1\0\0\0\0\0\0@\0\0\0vendor/symfony/finder/Exception/ShellCommandFailureException.phpÂ\ 2\0\0ùcÂXÂ\ 2\0\0\19v\82ȶ\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/finder/Expression/Expression.php\a\ 6\0\0ùcÂX\a\ 6\0\0µoÔ\ 6\ 1\0\0\0\0\0\0)\0\0\0vendor/symfony/finder/Expression/Glob.phpi\ 4\0\0ùcÂXi\ 4\0\0@\8a\eº¶\ 1\0\0\0\0\0\0*\0\0\0vendor/symfony/finder/Expression/Regex.php\ 6\ f\0\0ùcÂX\ 6\ f\0\0p8\0\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/finder/Expression/ValueInterface.phpÍ\ 1\0\0ùcÂXÍ\ 1\0\0²~øb¶\ 1\0\0\0\0\0\0 \0\0\0vendor/symfony/finder/Finder.phpÂ-\0\0ùcÂXÂ-\0\0\1e\98f´¶\ 1\0\0\0\0\0\0\1e\0\0\0vendor/symfony/finder/Glob.phpK\ 5\0\0ùcÂXK\ 5\0\0já±n¶\ 1\0\0\0\0\0\07\0\0\0vendor/symfony/finder/Iterator/CustomFilterIterator.php]\ 2\0\0ùcÂX]\ 2\0\0tà±µ¶\ 1\0\0\0\0\0\0:\0\0\0vendor/symfony/finder/Iterator/DateRangeFilterIterator.phpz\ 2\0\0ùcÂXz\ 2\0\0ÂT-\ 5\ 1\0\0\0\0\0\0;\0\0\0vendor/symfony/finder/Iterator/DepthRangeFilterIterator.phpð\ 1\0\0ùcÂXð\ 1\0\0ß0\99\ 4\ 1\0\0\0\0\0\0A\0\0\0vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.phpï\ 5\0\0ùcÂXï\ 5\0\0¾\8dÒâ¶\ 1\0\0\0\0\0\04\0\0\0vendor/symfony/finder/Iterator/FilePathsIterator.php \ 6\0\0ùcÂX \ 6\0\0fQCe¶\ 1\0\0\0\0\0\09\0\0\0vendor/symfony/finder/Iterator/FileTypeFilterIterator.php\\ 2\0\0ùcÂX\\ 2\0\0p\91'\98\ 1\0\0\0\0\0\0<\0\0\0vendor/symfony/finder/Iterator/FilecontentFilterIterator.php5\ 2\0\0ùcÂX5\ 2\0\0\9aí\1f\14\ 1\0\0\0\0\0\09\0\0\0vendor/symfony/finder/Iterator/FilenameFilterIterator.phpr\ 1\0\0ùcÂXr\ 1\0\0t\b\1a\ 1\0\0\0\0\0\01\0\0\0vendor/symfony/finder/Iterator/FilterIterator.phpÀ\ 2\0\0ùcÂXÀ\ 2\0\0E\99½\8c\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php/\ 5\0\0ùcÂX/\ 5\0\0»Ç\1f\ 1\0\0\0\0\0\05\0\0\0vendor/symfony/finder/Iterator/PathFilterIterator.phpÏ\ 1\0\0ùcÂXÏ\ 1\0\0º\1cªÇ¶\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php\12      \0\0ùcÂX\12 \0\0eÚ¹ü¶\ 1\0\0\0\0\0\0:\0\0\0vendor/symfony/finder/Iterator/SizeRangeFilterIterator.phpg\ 2\0\0ùcÂXg\ 2\0\0\97é¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/finder/Iterator/SortableIterator.php,\ 6\0\0ùcÂX,\ 6\0\0\96\1c\ 1\0\0\0\0\0\0\1d\0\0\0vendor/symfony/finder/LICENSE)\ 4\0\0ùcÂX)\ 4\0\0·)E`¶\ 1\0\0\0\0\0\0'\0\0\0vendor/symfony/finder/Shell/Command.phpS\v\0\0ùcÂXS\v\0\0cC\85\99\ 1\0\0\0\0\0\0%\0\0\0vendor/symfony/finder/Shell/Shell.phpp\ 4\0\0ùcÂXp\ 4\0\0\18Ó}g¶\ 1\0\0\0\0\0\0%\0\0\0vendor/symfony/finder/SplFileInfo.phpÿ\ 2\0\0ùcÂXÿ\ 2\0\0Ë\rOÀ¶\ 1\0\0\0\0\0\0(\0\0\0vendor/symfony/polyfill-mbstring/LICENSE)\ 4\0\0ùcÂX)\ 4\0\0î*L\14\ 1\0\0\0\0\0\0-\0\0\0vendor/symfony/polyfill-mbstring/Mbstring.phpÁ4\0\0ùcÂXÁ4\0\0^i\a\ 1\0\0\0\0\0\0@\0\0\0vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php2A\0\0ùcÂX2A\0\0½\11=¨¶\ 1\0\0\0\0\0\0@\0\0\0vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php¡A\0\0ùcÂX¡A\0\0\ eÚ    Í¶\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/polyfill-mbstring/bootstrap.php±\ f\0\0ùcÂX±\ f\0\0|\8a©Ò¶\ 1\0\0\0\0\0\07\0\0\0vendor/symfony/process/Exception/ExceptionInterface.phpf\0\0\0ùcÂXf\0\0\0]ö>T¶\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/process/Exception/InvalidArgumentException.php¨\0\0\0ùcÂX¨\0\0\0ÐÀ+_¶\ 1\0\0\0\0\0\03\0\0\0vendor/symfony/process/Exception/LogicException.php\94\0\0\0ùcÂX\94\0\0\0 ³ãñ¶\ 1\0\0\0\0\0\0;\0\0\0vendor/symfony/process/Exception/ProcessFailedException.phpx\ 3\0\0ùcÂXx\ 3\0\0¨Ìzy¶\ 1\0\0\0\0\0\0=\0\0\0vendor/symfony/process/Exception/ProcessTimedOutException.php\1f\ 4\0\0ùcÂX\1f\ 4\0\0.     Ãá¶\ 1\0\0\0\0\0\05\0\0\0vendor/symfony/process/Exception/RuntimeException.php\98\0\0\0ùcÂX\98\0\0\0¢\eØ:¶\ 1\0\0\0\0\0\0+\0\0\0vendor/symfony/process/ExecutableFinder.php\9b\ 4\0\0ùcÂX\9b\ 4\0\0ý\82m\9b\ 1\0\0\0\0\0\0\1e\0\0\0vendor/symfony/process/LICENSE)\ 4\0\0ùcÂX)\ 4\0\0·)E`¶\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/process/PhpExecutableFinder.phpg\ 4\0\0ùcÂXg\ 4\0\0\8dçµ\ 6\ 1\0\0\0\0\0\0%\0\0\0vendor/symfony/process/PhpProcess.phpü\ 3\0\0ùcÂXü\ 3\0\0_\17\97\ 1\0\0\0\0\0\0.\0\0\0vendor/symfony/process/Pipes/AbstractPipes.php^\a\0\0ùcÂX^\a\0\0%s\85ï¶\ 1\0\0\0\0\0\0/\0\0\0vendor/symfony/process/Pipes/PipesInterface.phpD\ 1\0\0ùcÂXD\ 1\0\0vØ\ 1\0\0\0\0\0\0*\0\0\0vendor/symfony/process/Pipes/UnixPipes.phpå\a\0\0ùcÂXå\a\0\0\ 1È¥\ 4\ 1\0\0\0\0\0\0-\0\0\0vendor/symfony/process/Pipes/WindowsPipes.php\8d\v\0\0ùcÂX\8d\v\0\0\85®\1e\ 1\0\0\0\0\0\0"\0\0\0vendor/symfony/process/Process.php§R\0\0ùcÂX§R\0\0+Á¥\1f\ 1\0\0\0\0\0\0)\0\0\0vendor/symfony/process/ProcessBuilder.phpã
60 \0\0ùcÂXã
61 \0\0ʧ°\88\ 1\0\0\0\0\0\0'\0\0\0vendor/symfony/process/ProcessUtils.phpK\ 6\0\0ùcÂXK\ 6\0\0µ½~ò¶\ 1\0\0\0\0\0\0\1c\0\0\0vendor/seld/jsonlint/LICENSE"\ 4\0\0ùcÂX"\ 4\0\0a\83sy¶\ 1\0\0\0\0\0\0@\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/DuplicateKeyException.php*\ 1\0\0ùcÂX*\ 1\0\0\19\95pñ¶\ 1\0\0\0\0\0\05\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.php/2\0\0ùcÂX/2\0\0­ß\98ö¶\ 1\0\0\0\0\0\00\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/Lexer.php\0\ f\0\0ùcÂX\0\ f\0\0\8e\8f\ 1\0\0\0\0\0\0;\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/ParsingException.php\1e\ 1\0\0ùcÂX\1e\ 1\0\0\89²\10ñ¶\ 1\0\0\0\0\0\04\0\0\0vendor/seld/jsonlint/src/Seld/JsonLint/Undefined.php>\0\0\0ùcÂX>\0\0\0ÿq\9f\9f\ 1\0\0\0\0\0\0\1e\0\0\0vendor/seld/cli-prompt/LICENSE"\ 4\0\0ùcÂX"\ 4\0\0\88ñ?e¶\ 1\0\0\0\0\0\0&\0\0\0vendor/seld/cli-prompt/res/example.php'\ 1\0\0ùcÂX'\ 1\0\0I\1c\ 5£¶\ 1\0\0\0\0\0\0(\0\0\0vendor/seld/cli-prompt/src/CliPrompt.php\r\ 6\0\0ùcÂX\r\ 6\0\0l½`߶\ 1\0\0\0\0\0\0(\0\0\0vendor/justinrainbow/json-schema/LICENSE \ 4\0\0ùcÂX \ 4\0\0ºç\ 6©¶\ 1\0\0\0\0\0\0.\0\0\0vendor/justinrainbow/json-schema/demo/demo.phpñ\ 1\0\0ùcÂXñ\ 1\0\0f\e\12\ 1\0\0\0\0\0\0N\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php°\ 4\0\0ùcÂX°\ 4\0\0Ãÿ¦'¶\ 1\0\0\0\0\0\0T\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php.\r\0\0ùcÂX.\r\0\0[÷3í¶\ 1\0\0\0\0\0\0J\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.phpß\f\0\0ùcÂXß\f\0\0\97\ 4>/¶\ 1\0\0\0\0\0\0S\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php¼\ 1\0\0ùcÂX¼\ 1\0\0ÿ Q\9c\ 1\0\0\0\0\0\0N\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php]\ 3\0\0ùcÂX]\ 3\0\0V\8eU<¶\ 1\0\0\0\0\0\0G\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php7\f\0\0ùcÂX7\f\0\0³\8d3%¶\ 1\0\0\0\0\0\0P\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php\9f\10\0\0ùcÂX\9f\10\0\0x&÷o¶\ 1\0\0\0\0\0\0P\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php\9a
62 \0\0ùcÂX\9a
63 \0\0\15\1ez&¶\ 1\0\0\0\0\0\0P\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.phpµ\10\0\0ùcÂXµ\10\0\0üø¦É¶\ 1\0\0\0\0\0\0P\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php\b\ 3\0\0ùcÂX\b\ 3\0\0N_»\19\ 1\0\0\0\0\0\0P\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php{\ 4\0\0ùcÂX{\ 4\0\0\r\9f\7f\ 1\0\0\0\0\0\0X\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.phpa\ 4\0\0ùcÂXa\ 4\0\0\v     qö\ 1\0\0\0\0\0\0Y\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.phpp\ 2\0\0ùcÂXp\ 2\0\0\12r\1fë¶\ 1\0\0\0\0\0\0\\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php\89\ 1\0\0ùcÂX\89\ 1\0\0\93µ+j¶\ 1\0\0\0\0\0\0N\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php&\ f\0\0ùcÂX&\ f\0\04\98©T¶\ 1\0\0\0\0\0\0S\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php\12\1c\0\0ùcÂX\12\1c\0\0/4\ 5˶\ 1\0\0\0\0\0\0F\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php\f\ 6\0\0ùcÂX\f\ 6\0\0û}fa¶\ 1\0\0\0\0\0\0P\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.phpI\0\0\0ùcÂXI\0\0\0%|\19°¶\ 1\0\0\0\0\0\0V\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php\95\0\0\0ùcÂX\95\0\0\0\8bàG\ 5\ 1\0\0\0\0\0\0T\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.phpl\0\0\0ùcÂXl\0\0\0A!L׶\ 1\0\0\0\0\0\0]\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.phpu\0\0\0ùcÂXu\0\0\0=hç\a\ 1\0\0\0\0\0\0W\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.phpw\0\0\0ùcÂXw\0\0\0N-ò[¶\ 1\0\0\0\0\0\0S\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.phpÞ\ 2\0\0ùcÂXÞ\ 2\0\0\r
64\ 1\0\0\0\0\0\0W\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.phpo\0\0\0ùcÂXo\0\0\0píÛù¶\ 1\0\0\0\0\0\0N\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php\85\0\0\0ùcÂX\85\0\0\0\b%\85\97\ 1\0\0\0\0\0\0^\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php\80\0\0\0ùcÂX\80\0\0\0u-#1¶\ 1\0\0\0\0\0\0R\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.phpj\0\0\0ùcÂXj\0\0\0å\1a>\8f\ 1\0\0\0\0\0\0Q\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.phpf\0\0\0ùcÂXf\0\0\0¬¤\84þ¶\ 1\0\0\0\0\0\0K\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.phpþ\ 5\0\0ùcÂXþ\ 5\0\0M\8f\84õ¶\ 1\0\0\0\0\0\0;\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.phpG\ 2\0\0ùcÂXG\ 2\0\0\9c?IǶ\ 1\0\0\0\0\0\0A\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.phpN  \0\0ùcÂXN \0\0ZÈó¬¶\ 1\0\0\0\0\0\0J\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php\ 1\ 1\0\0ùcÂX\ 1\ 1\0\0o\8a+}¶\ 1\0\0\0\0\0\0T\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.phpá\0\0\0ùcÂXá\0\0\0[þA\81\ 1\0\0\0\0\0\0G\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.phpw\ 4\0\0ùcÂXw\ 4\0\0\80¯¶\ 1\0\0\0\0\0\0R\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php\1d\ 5\0\0ùcÂX\1d\ 5\0\0äZ\9a\ 1\0\0\0\0\0\0R\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php,\ 2\0\0ùcÂX,\ 2\0\01\955þ¶\ 1\0\0\0\0\0\0X\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php®\0\0\0ùcÂX®\0\0\0ÿ\8bÁå¶\ 1\0\0\0\0\0\0C\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php\96 \0\0ùcÂX\96 \0\0=&ßͶ\ 1\0\0\0\0\0\0D\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.phpî\10\0\0ùcÂXî\10\0\0Ý¿\81   ¶\ 1\0\0\0\0\0\0H\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php\83\0\0\0ùcÂX\83\0\0\0\12J\80\1f\ 1\0\0\0\0\0\0I\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php\85\0\0\0ùcÂX\85\0\0\0íæ\e\ 1\0\0\0\0\0\0=\0\0\0vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php\86\ 3\0\0ùcÂX\86\ 3\0\0yÐSR¶\ 1\0\0\0\0\0\0%\0\0\0vendor/composer/spdx-licenses/LICENSE\1c\ 4\0\0ùcÂX\1c\ 4\0\0\ 6Bhí¶\ 1\0\0\0\0\0\02\0\0\0vendor/composer/spdx-licenses/src/SpdxLicenses.phpç\11\0\0ùcÂXç\11\0\0·\96U ¶\ 1\0\0\0\0\0\0\1e\0\0\0vendor/composer/semver/LICENSE\1c\ 4\0\0ùcÂX\1c\ 4\0\0\ 6Bhí¶\ 1\0\0\0\0\0\0)\0\0\0vendor/composer/semver/src/Comparator.php\ 2\ 4\0\0ùcÂX\ 2\ 4\0\0wl\83ï¶\ 1\0\0\0\0\0\0<\0\0\0vendor/composer/semver/src/Constraint/AbstractConstraint.php×\ 2\0\0ùcÂX×\ 2\0\0õî>\8e\ 1\0\0\0\0\0\04\0\0\0vendor/composer/semver/src/Constraint/Constraint.phpª\f\0\0ùcÂXª\f\0\0ÇO7²¶\ 1\0\0\0\0\0\0=\0\0\0vendor/composer/semver/src/Constraint/ConstraintInterface.phpß\0\0\0ùcÂXß\0\0\00C,\87\ 1\0\0\0\0\0\09\0\0\0vendor/composer/semver/src/Constraint/EmptyConstraint.phpé\ 1\0\0ùcÂXé\ 1\0\0!-Ø\99\ 1\0\0\0\0\0\09\0\0\0vendor/composer/semver/src/Constraint/MultiConstraint.php1\ 5\0\0ùcÂX1\ 5\0\0í xU¶\ 1\0\0\0\0\0\0%\0\0\0vendor/composer/semver/src/Semver.phpv\ 6\0\0ùcÂXv\ 6\0\0\8b×È\9b\ 1\0\0\0\0\0\0,\0\0\0vendor/composer/semver/src/VersionParser.php¿*\0\0ùcÂX¿*\0\0\13)mƶ\ 1\0\0\0\0\0\0!\0\0\0vendor/composer/ca-bundle/LICENSE\1c\ 4\0\0ùcÂX\1c\ 4\0\0*!^`¶\ 1\0\0\0\0\0\0*\0\0\0vendor/composer/ca-bundle/src/CaBundle.php½\e\0\0ùcÂX½\e\0\0e\1c\e\1e\ 1\0\0\0\0\0\0\16\0\0\0vendor/psr/log/LICENSE=\ 4\0\0ùcÂX=\ 4\0\0\8e\ 1\0\0\0\0\0\0)\0\0\0vendor/psr/log/Psr/Log/AbstractLogger.php;\ 4\0\0ùcÂX;\ 4\0\0ñ>3[¶\ 1\0\0\0\0\0\03\0\0\0vendor/psr/log/Psr/Log/InvalidArgumentException.php`\0\0\0ùcÂX`\0\0\0 \88X1¶\ 1\0\0\0\0\0\0#\0\0\0vendor/psr/log/Psr/Log/LogLevel.phpû\0\0\0ùcÂXû\0\0\0jðñ8¶\ 1\0\0\0\0\0\0/\0\0\0vendor/psr/log/Psr/Log/LoggerAwareInterface.php|\0\0\0ùcÂX|\0\0\0$\13£\88\ 1\0\0\0\0\0\0+\0\0\0vendor/psr/log/Psr/Log/LoggerAwareTrait.php§\0\0\0ùcÂX§\0\0\0T½úB¶\ 1\0\0\0\0\0\0*\0\0\0vendor/psr/log/Psr/Log/LoggerInterface.phpÆ\ 2\0\0ùcÂXÆ\ 2\0\0»\12sg¶\ 1\0\0\0\0\0\0&\0\0\0vendor/psr/log/Psr/Log/LoggerTrait.phpi\ 4\0\0ùcÂXi\ 4\0\035§Þ¶\ 1\0\0\0\0\0\0%\0\0\0vendor/psr/log/Psr/Log/NullLogger.php\9e\0\0\0ùcÂX\9e\0\0\0Ç\ 2Ã\1f\ 1\0\0\0\0\0\03\0\0\0vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.phpü\f\0\0ùcÂXü\f\0\0iq0ض\ 1\0\0\0\0\0\0\13\0\0\0vendor/autoload.php\82\0\0\0ùcÂX\82\0\0\0·\8e¯\8e\ 1\0\0\0\0\0\0'\0\0\0vendor/composer/autoload_namespaces.phpd\0\0\0ùcÂXd\0\0\0Z¡¦H¶\ 1\0\0\0\0\0\0!\0\0\0vendor/composer/autoload_psr4.php\98\ 4\0\0ùcÂX\98\ 4\0\0\9e\1c{¢¶\ 1\0\0\0\0\0\0%\0\0\0vendor/composer/autoload_classmap.phpd\0\0\0ùcÂXd\0\0\0Z¡¦H¶\ 1\0\0\0\0\0\0"\0\0\0vendor/composer/autoload_files.phpÃ\0\0\0ùcÂXÃ\0\0\0ÒÂür¶\ 1\0\0\0\0\0\0!\0\0\0vendor/composer/autoload_real.phpI\a\0\0ùcÂXI\a\0\0)±¸\88\ 1\0\0\0\0\0\0#\0\0\0vendor/composer/autoload_static.php¬       \0\0ùcÂX¬ \0\0Ú[@.¶\ 1\0\0\0\0\0\0\1f\0\0\0vendor/composer/ClassLoader.php\9c\18\0\0ùcÂX\9c\18\0\0¥ÂåN¶\ 1\0\0\0\0\0\0(\0\0\0vendor/composer/ca-bundle/res/cacert.pem\ 1ÿ\ 3\0ùcÂX\ 1ÿ\ 3\0-=Jn¶\ 1\0\0\0\0\0\0\f\0\0\0bin/composer\8b\ 5\0\0ùcÂX\8b\ 5\0\0íeG\9a\ 1\0\0\0\0\0\0\a\0\0\0LICENSE.\ 4\0\0ùcÂX.\ 4\0\0 Õ\b\ 3\ 1\0\0\0\0\0\0<?php
65
66
67
68
69
70
71
72
73
74
75
76 namespace Composer\Autoload;
77
78 use Composer\Config;
79 use Composer\EventDispatcher\EventDispatcher;
80 use Composer\Installer\InstallationManager;
81 use Composer\IO\IOInterface;
82 use Composer\Package\AliasPackage;
83 use Composer\Package\PackageInterface;
84 use Composer\Repository\InstalledRepositoryInterface;
85 use Composer\Util\Filesystem;
86 use Composer\Script\ScriptEvents;
87
88
89
90
91
92 class AutoloadGenerator
93 {
94
95
96
97 private $eventDispatcher;
98
99
100
101
102 private $io;
103
104
105
106
107 private $devMode = false;
108
109
110
111
112 private $classMapAuthoritative = false;
113
114
115
116
117 private $apcu = false;
118
119
120
121
122 private $runScripts = false;
123
124 public function __construct(EventDispatcher $eventDispatcher, IOInterface $io = null)
125 {
126 $this->eventDispatcher = $eventDispatcher;
127 $this->io = $io;
128 }
129
130 public function setDevMode($devMode = true)
131 {
132 $this->devMode = (bool) $devMode;
133 }
134
135
136
137
138
139
140
141 public function setClassMapAuthoritative($classMapAuthoritative)
142 {
143 $this->classMapAuthoritative = (bool) $classMapAuthoritative;
144 }
145
146
147
148
149
150
151 public function setApcu($apcu)
152 {
153 $this->apcu = (bool) $apcu;
154 }
155
156
157
158
159
160
161 public function setRunScripts($runScripts = true)
162 {
163 $this->runScripts = (bool) $runScripts;
164 }
165
166 public function dump(Config $config, InstalledRepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $scanPsr0Packages = false, $suffix = '')
167 {
168 if ($this->classMapAuthoritative) {
169
170  $scanPsr0Packages = true;
171 }
172 if ($this->runScripts) {
173 $this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode, array(), array(
174 'optimize' => (bool) $scanPsr0Packages,
175 ));
176 }
177
178 $filesystem = new Filesystem();
179 $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
180
181  
182  
183  $basePath = $filesystem->normalizePath(realpath(realpath(getcwd())));
184 $vendorPath = $filesystem->normalizePath(realpath(realpath($config->get('vendor-dir'))));
185 $useGlobalIncludePath = (bool) $config->get('use-include-path');
186 $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true';
187 $targetDir = $vendorPath.'/'.$targetDir;
188 $filesystem->ensureDirectoryExists($targetDir);
189
190 $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
191 $vendorPathCode52 = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode);
192 $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
193
194 $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true);
195 $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
196
197 $namespacesFile = <<<EOF
198 <?php
199
200 // autoload_namespaces.php @generated by Composer
201
202 \$vendorDir = $vendorPathCode52;
203 \$baseDir = $appBaseDirCode;
204
205 return array(
206
207 EOF;
208
209 $psr4File = <<<EOF
210 <?php
211
212 // autoload_psr4.php @generated by Composer
213
214 \$vendorDir = $vendorPathCode52;
215 \$baseDir = $appBaseDirCode;
216
217 return array(
218
219 EOF;
220
221
222  $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages());
223 $autoloads = $this->parseAutoloads($packageMap, $mainPackage);
224
225
226  foreach ($autoloads['psr-0'] as $namespace => $paths) {
227 $exportedPaths = array();
228 foreach ($paths as $path) {
229 $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
230 }
231 $exportedPrefix = var_export($namespace, true);
232 $namespacesFile .= "    $exportedPrefix => ";
233 $namespacesFile .= "array(".implode(', ', $exportedPaths)."),\n";
234 }
235 $namespacesFile .= ");\n";
236
237
238  foreach ($autoloads['psr-4'] as $namespace => $paths) {
239 $exportedPaths = array();
240 foreach ($paths as $path) {
241 $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
242 }
243 $exportedPrefix = var_export($namespace, true);
244 $psr4File .= "    $exportedPrefix => ";
245 $psr4File .= "array(".implode(', ', $exportedPaths)."),\n";
246 }
247 $psr4File .= ");\n";
248
249 $classmapFile = <<<EOF
250 <?php
251
252 // autoload_classmap.php @generated by Composer
253
254 \$vendorDir = $vendorPathCode52;
255 \$baseDir = $appBaseDirCode;
256
257 return array(
258
259 EOF;
260
261
262  $targetDirLoader = null;
263 $mainAutoload = $mainPackage->getAutoload();
264 if ($mainPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
265 $levels = count(explode('/', $filesystem->normalizePath($mainPackage->getTargetDir())));
266 $prefixes = implode(', ', array_map(function ($prefix) {
267 return var_export($prefix, true);
268 }, array_keys($mainAutoload['psr-0'])));
269 $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
270
271 $targetDirLoader = <<<EOF
272
273     public static function autoload(\$class)
274     {
275         \$dir = $baseDirFromTargetDirCode . '/';
276         \$prefixes = array($prefixes);
277         foreach (\$prefixes as \$prefix) {
278             if (0 !== strpos(\$class, \$prefix)) {
279                 continue;
280             }
281             \$path = \$dir . implode('/', array_slice(explode('\\\\', \$class), $levels)).'.php';
282             if (!\$path = stream_resolve_include_path(\$path)) {
283                 return false;
284             }
285             require \$path;
286
287             return true;
288         }
289     }
290
291 EOF;
292 }
293
294 $blacklist = null;
295 if (!empty($autoloads['exclude-from-classmap'])) {
296 $blacklist = '{(' . implode('|', $autoloads['exclude-from-classmap']) . ')}';
297 }
298
299
300  $classMap = array();
301 if ($scanPsr0Packages) {
302 $namespacesToScan = array();
303
304
305  foreach (array('psr-0', 'psr-4') as $psrType) {
306 foreach ($autoloads[$psrType] as $namespace => $paths) {
307 $namespacesToScan[$namespace][] = array('paths' => $paths, 'type' => $psrType);
308 }
309 }
310
311 krsort($namespacesToScan);
312
313 foreach ($namespacesToScan as $namespace => $groups) {
314 foreach ($groups as $group) {
315 foreach ($group['paths'] as $dir) {
316 $dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath.'/'.$dir);
317 if (!is_dir($dir)) {
318 continue;
319 }
320
321 $namespaceFilter = $namespace === '' ? null : $namespace;
322 $classMap = $this->addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $blacklist, $namespaceFilter, $classMap);
323 }
324 }
325 }
326 }
327
328 foreach ($autoloads['classmap'] as $dir) {
329 $classMap = $this->addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $blacklist, null, $classMap);
330 }
331
332 ksort($classMap);
333 foreach ($classMap as $class => $code) {
334 $classmapFile .= '    '.var_export($class, true).' => '.$code;
335 }
336 $classmapFile .= ");\n";
337
338 if (!$suffix) {
339 if (!$config->get('autoloader-suffix') && is_readable($vendorPath.'/autoload.php')) {
340 $content = file_get_contents($vendorPath.'/autoload.php');
341 if (preg_match('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) {
342 $suffix = $match[1];
343 }
344 }
345
346 if (!$suffix) {
347 $suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true));
348 }
349 }
350
351 file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
352 file_put_contents($targetDir.'/autoload_psr4.php', $psr4File);
353 file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile);
354 $includePathFilePath = $targetDir.'/include_paths.php';
355 if ($includePathFileContents = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
356 file_put_contents($includePathFilePath, $includePathFileContents);
357 } elseif (file_exists($includePathFilePath)) {
358 unlink($includePathFilePath);
359 }
360 $includeFilesFilePath = $targetDir.'/autoload_files.php';
361 if ($includeFilesFileContents = $this->getIncludeFilesFile($autoloads['files'], $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
362 file_put_contents($includeFilesFilePath, $includeFilesFileContents);
363 } elseif (file_exists($includeFilesFilePath)) {
364 unlink($includeFilesFilePath);
365 }
366 file_put_contents($targetDir.'/autoload_static.php', $this->getStaticFile($suffix, $targetDir, $vendorPath, $basePath, $staticPhpVersion));
367 file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
368 file_put_contents($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFileContents, $targetDirLoader, (bool) $includeFilesFileContents, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion));
369
370 $this->safeCopy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
371 $this->safeCopy(__DIR__.'/../../../LICENSE', $targetDir.'/LICENSE');
372
373 if ($this->runScripts) {
374 $this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, array(), array(
375 'optimize' => (bool) $scanPsr0Packages,
376 ));
377 }
378 }
379
380 private function addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $blacklist = null, $namespaceFilter = null, array $classMap = array())
381 {
382 foreach ($this->generateClassMap($dir, $blacklist, $namespaceFilter) as $class => $path) {
383 $pathCode = $this->getPathCode($filesystem, $basePath, $vendorPath, $path).",\n";
384 if (!isset($classMap[$class])) {
385 $classMap[$class] = $pathCode;
386 } elseif ($this->io && $classMap[$class] !== $pathCode && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($classMap[$class].' '.$path, '\\', '/'))) {
387 $this->io->writeError(
388 '<warning>Warning: Ambiguous class resolution, "'.$class.'"'.
389 ' was found in both "'.str_replace(array('$vendorDir . \'', "',\n"), array($vendorPath, ''), $classMap[$class]).'" and "'.$path.'", the first will be used.</warning>'
390 );
391 }
392 }
393
394 return $classMap;
395 }
396
397 private function generateClassMap($dir, $blacklist = null, $namespaceFilter = null, $showAmbiguousWarning = true)
398 {
399 return ClassMapGenerator::createMap($dir, $blacklist, $showAmbiguousWarning ? $this->io : null, $namespaceFilter);
400 }
401
402 public function buildPackageMap(InstallationManager $installationManager, PackageInterface $mainPackage, array $packages)
403 {
404
405  $packageMap = array(array($mainPackage, ''));
406
407 foreach ($packages as $package) {
408 if ($package instanceof AliasPackage) {
409 continue;
410 }
411 $this->validatePackage($package);
412
413 $packageMap[] = array(
414 $package,
415 $installationManager->getInstallPath($package),
416 );
417 }
418
419 return $packageMap;
420 }
421
422
423
424
425
426
427 protected function validatePackage(PackageInterface $package)
428 {
429 $autoload = $package->getAutoload();
430 if (!empty($autoload['psr-4']) && null !== $package->getTargetDir()) {
431 $name = $package->getName();
432 $package->getTargetDir();
433 throw new \InvalidArgumentException("PSR-4 autoloading is incompatible with the target-dir property, remove the target-dir in package '$name'.");
434 }
435 if (!empty($autoload['psr-4'])) {
436 foreach ($autoload['psr-4'] as $namespace => $dirs) {
437 if ($namespace !== '' && '\\' !== substr($namespace, -1)) {
438 throw new \InvalidArgumentException("psr-4 namespaces must end with a namespace separator, '$namespace' does not, use '$namespace\\'.");
439 }
440 }
441 }
442 }
443
444
445
446
447
448
449
450
451 public function parseAutoloads(array $packageMap, PackageInterface $mainPackage)
452 {
453 $mainPackageMap = array_shift($packageMap);
454 $sortedPackageMap = $this->sortPackageMap($packageMap);
455 $sortedPackageMap[] = $mainPackageMap;
456 array_unshift($packageMap, $mainPackageMap);
457
458 $psr0 = $this->parseAutoloadsType($packageMap, 'psr-0', $mainPackage);
459 $psr4 = $this->parseAutoloadsType($packageMap, 'psr-4', $mainPackage);
460 $classmap = $this->parseAutoloadsType(array_reverse($sortedPackageMap), 'classmap', $mainPackage);
461 $files = $this->parseAutoloadsType($sortedPackageMap, 'files', $mainPackage);
462 $exclude = $this->parseAutoloadsType($sortedPackageMap, 'exclude-from-classmap', $mainPackage);
463
464 krsort($psr0);
465 krsort($psr4);
466
467 return array(
468 'psr-0' => $psr0,
469 'psr-4' => $psr4,
470 'classmap' => $classmap,
471 'files' => $files,
472 'exclude-from-classmap' => $exclude,
473 );
474 }
475
476
477
478
479
480
481
482 public function createLoader(array $autoloads)
483 {
484 $loader = new ClassLoader();
485
486 if (isset($autoloads['psr-0'])) {
487 foreach ($autoloads['psr-0'] as $namespace => $path) {
488 $loader->add($namespace, $path);
489 }
490 }
491
492 if (isset($autoloads['psr-4'])) {
493 foreach ($autoloads['psr-4'] as $namespace => $path) {
494 $loader->addPsr4($namespace, $path);
495 }
496 }
497
498 if (isset($autoloads['classmap'])) {
499 foreach ($autoloads['classmap'] as $dir) {
500 try {
501 $loader->addClassMap($this->generateClassMap($dir, null, null, false));
502 } catch (\RuntimeException $e) {
503 $this->io->writeError('<warning>'.$e->getMessage().'</warning>');
504 }
505 }
506 }
507
508 return $loader;
509 }
510
511 protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode)
512 {
513 $includePaths = array();
514
515 foreach ($packageMap as $item) {
516 list($package, $installPath) = $item;
517
518 if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
519 $installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
520 }
521
522 foreach ($package->getIncludePaths() as $includePath) {
523 $includePath = trim($includePath, '/');
524 $includePaths[] = empty($installPath) ? $includePath : $installPath.'/'.$includePath;
525 }
526 }
527
528 if (!$includePaths) {
529 return;
530 }
531
532 $includePathsCode = '';
533 foreach ($includePaths as $path) {
534 $includePathsCode .= "    " . $this->getPathCode($filesystem, $basePath, $vendorPath, $path) . ",\n";
535 }
536
537 return <<<EOF
538 <?php
539
540 // include_paths.php @generated by Composer
541
542 \$vendorDir = $vendorPathCode;
543 \$baseDir = $appBaseDirCode;
544
545 return array(
546 $includePathsCode);
547
548 EOF;
549 }
550
551 protected function getIncludeFilesFile(array $files, Filesystem $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode)
552 {
553 $filesCode = '';
554 foreach ($files as $fileIdentifier => $functionFile) {
555 $filesCode .= '    ' . var_export($fileIdentifier, true) . ' => '
556 . $this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile) . ",\n";
557 }
558
559 if (!$filesCode) {
560 return false;
561 }
562
563 return <<<EOF
564 <?php
565
566 // autoload_files.php @generated by Composer
567
568 \$vendorDir = $vendorPathCode;
569 \$baseDir = $appBaseDirCode;
570
571 return array(
572 $filesCode);
573
574 EOF;
575 }
576
577 protected function getPathCode(Filesystem $filesystem, $basePath, $vendorPath, $path)
578 {
579 if (!$filesystem->isAbsolutePath($path)) {
580 $path = $basePath . '/' . $path;
581 }
582 $path = $filesystem->normalizePath($path);
583
584 $baseDir = '';
585 if (strpos($path.'/', $vendorPath.'/') === 0) {
586 $path = substr($path, strlen($vendorPath));
587 $baseDir = '$vendorDir';
588
589 if ($path !== false) {
590 $baseDir .= " . ";
591 }
592 } else {
593 $path = $filesystem->normalizePath($filesystem->findShortestPath($basePath, $path, true));
594 if (!$filesystem->isAbsolutePath($path)) {
595 $baseDir = '$baseDir . ';
596 $path = '/' . $path;
597 }
598 }
599
600 if (preg_match('/\.phar$/', $path)) {
601 $baseDir = "'phar://' . " . $baseDir;
602 }
603
604 return $baseDir . (($path !== false) ? var_export($path, true) : "");
605 }
606
607 protected function getAutoloadFile($vendorPathToTargetDirCode, $suffix)
608 {
609 $lastChar = $vendorPathToTargetDirCode[strlen($vendorPathToTargetDirCode) - 1];
610 if ("'" === $lastChar || '"' === $lastChar) {
611 $vendorPathToTargetDirCode = substr($vendorPathToTargetDirCode, 0, -1).'/autoload_real.php'.$lastChar;
612 } else {
613 $vendorPathToTargetDirCode .= " . '/autoload_real.php'";
614 }
615
616 return <<<AUTOLOAD
617 <?php
618
619 // autoload.php @generated by Composer
620
621 require_once $vendorPathToTargetDirCode;
622
623 return ComposerAutoloaderInit$suffix::getLoader();
624
625 AUTOLOAD;
626 }
627
628 protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion = 70000)
629 {
630 $file = <<<HEADER
631 <?php
632
633 // autoload_real.php @generated by Composer
634
635 class ComposerAutoloaderInit$suffix
636 {
637     private static \$loader;
638
639     public static function loadClassLoader(\$class)
640     {
641         if ('Composer\\Autoload\\ClassLoader' === \$class) {
642             require __DIR__ . '/ClassLoader.php';
643         }
644     }
645
646     public static function getLoader()
647     {
648         if (null !== self::\$loader) {
649             return self::\$loader;
650         }
651
652         spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'), true, $prependAutoloader);
653         self::\$loader = \$loader = new \\Composer\\Autoload\\ClassLoader();
654         spl_autoload_unregister(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));
655
656
657 HEADER;
658
659 if ($useIncludePath) {
660 $file .= <<<'INCLUDE_PATH'
661         $includePaths = require __DIR__ . '/include_paths.php';
662         array_push($includePaths, get_include_path());
663         set_include_path(implode(PATH_SEPARATOR, $includePaths));
664
665
666 INCLUDE_PATH;
667 }
668
669 $file .= <<<STATIC_INIT
670         \$useStaticLoader = PHP_VERSION_ID >= $staticPhpVersion && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
671         if (\$useStaticLoader) {
672             require_once __DIR__ . '/autoload_static.php';
673
674             call_user_func(\Composer\Autoload\ComposerStaticInit$suffix::getInitializer(\$loader));
675         } else {
676
677 STATIC_INIT;
678
679 if (!$this->classMapAuthoritative) {
680 $file .= <<<'PSR04'
681             $map = require __DIR__ . '/autoload_namespaces.php';
682             foreach ($map as $namespace => $path) {
683                 $loader->set($namespace, $path);
684             }
685
686             $map = require __DIR__ . '/autoload_psr4.php';
687             foreach ($map as $namespace => $path) {
688                 $loader->setPsr4($namespace, $path);
689             }
690
691
692 PSR04;
693 }
694
695 if ($useClassMap) {
696 $file .= <<<'CLASSMAP'
697             $classMap = require __DIR__ . '/autoload_classmap.php';
698             if ($classMap) {
699                 $loader->addClassMap($classMap);
700             }
701
702 CLASSMAP;
703 }
704
705 $file .= "        }\n\n";
706
707 if ($this->classMapAuthoritative) {
708 $file .= <<<'CLASSMAPAUTHORITATIVE'
709         $loader->setClassMapAuthoritative(true);
710
711 CLASSMAPAUTHORITATIVE;
712 }
713
714 if ($this->apcu) {
715 $apcuPrefix = substr(base64_encode(md5(uniqid('', true), true)), 0, -3);
716 $file .= <<<APCU
717         \$loader->setApcuPrefix('$apcuPrefix');
718
719 APCU;
720 }
721
722 if ($useGlobalIncludePath) {
723 $file .= <<<'INCLUDEPATH'
724         $loader->setUseIncludePath(true);
725
726 INCLUDEPATH;
727 }
728
729 if ($targetDirLoader) {
730 $file .= <<<REGISTER_TARGET_DIR_AUTOLOAD
731         spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'autoload'), true, true);
732
733
734 REGISTER_TARGET_DIR_AUTOLOAD;
735 }
736
737 $file .= <<<REGISTER_LOADER
738         \$loader->register($prependAutoloader);
739
740
741 REGISTER_LOADER;
742
743 if ($useIncludeFiles) {
744 $file .= <<<INCLUDE_FILES
745         if (\$useStaticLoader) {
746             \$includeFiles = Composer\Autoload\ComposerStaticInit$suffix::\$files;
747         } else {
748             \$includeFiles = require __DIR__ . '/autoload_files.php';
749         }
750         foreach (\$includeFiles as \$fileIdentifier => \$file) {
751             composerRequire$suffix(\$fileIdentifier, \$file);
752         }
753
754
755 INCLUDE_FILES;
756 }
757
758 $file .= <<<METHOD_FOOTER
759         return \$loader;
760     }
761
762 METHOD_FOOTER;
763
764 $file .= $targetDirLoader;
765
766 if ($useIncludeFiles) {
767 return $file . <<<FOOTER
768 }
769
770 function composerRequire$suffix(\$fileIdentifier, \$file)
771 {
772     if (empty(\$GLOBALS['__composer_autoload_files'][\$fileIdentifier])) {
773         require \$file;
774
775         \$GLOBALS['__composer_autoload_files'][\$fileIdentifier] = true;
776     }
777 }
778
779 FOOTER;
780 }
781
782 return $file . <<<FOOTER
783 }
784
785 FOOTER;
786 }
787
788 protected function getStaticFile($suffix, $targetDir, $vendorPath, $basePath, &$staticPhpVersion)
789 {
790 $staticPhpVersion = 50600;
791
792 $file = <<<HEADER
793 <?php
794
795 // autoload_static.php @generated by Composer
796
797 namespace Composer\Autoload;
798
799 class ComposerStaticInit$suffix
800 {
801
802 HEADER;
803
804 $loader = new ClassLoader();
805
806 $map = require $targetDir . '/autoload_namespaces.php';
807 foreach ($map as $namespace => $path) {
808 $loader->set($namespace, $path);
809 }
810
811 $map = require $targetDir . '/autoload_psr4.php';
812 foreach ($map as $namespace => $path) {
813 $loader->setPsr4($namespace, $path);
814 }
815
816 $classMap = require $targetDir . '/autoload_classmap.php';
817 if ($classMap) {
818 $loader->addClassMap($classMap);
819 }
820
821 $filesystem = new Filesystem();
822
823 $vendorPathCode = ' => ' . $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true, true) . " . '/";
824 $appBaseDirCode = ' => ' . $filesystem->findShortestPathCode(realpath($targetDir), $basePath, true, true) . " . '/";
825
826 $absoluteVendorPathCode = ' => ' . substr(var_export(rtrim($vendorDir, '\\/') . '/', true), 0, -1);
827 $absoluteAppBaseDirCode = ' => ' . substr(var_export(rtrim($baseDir, '\\/') . '/', true), 0, -1);
828
829 $initializer = '';
830 $prefix = "\0Composer\Autoload\ClassLoader\0";
831 $prefixLen = strlen($prefix);
832 if (file_exists($targetDir . '/autoload_files.php')) {
833 $maps = array('files' => require $targetDir . '/autoload_files.php');
834 } else {
835 $maps = array();
836 }
837
838 foreach ((array) $loader as $prop => $value) {
839 if ($value && 0 === strpos($prop, $prefix)) {
840 $maps[substr($prop, $prefixLen)] = $value;
841 }
842 }
843
844 foreach ($maps as $prop => $value) {
845 if (count($value) > 32767) {
846
847  
848  $staticPhpVersion = 70000;
849 }
850 $value = var_export($value, true);
851 $value = str_replace($absoluteVendorPathCode, $vendorPathCode, $value);
852 $value = str_replace($absoluteAppBaseDirCode, $appBaseDirCode, $value);
853 $value = ltrim(preg_replace('/^ */m', '    $0$0', $value));
854
855 $file .= sprintf("    public static $%s = %s;\n\n", $prop, $value);
856 if ('files' !== $prop) {
857 $initializer .= "            \$loader->$prop = ComposerStaticInit$suffix::\$$prop;\n";
858 }
859 }
860
861 return $file . <<<INITIALIZER
862     public static function getInitializer(ClassLoader \$loader)
863     {
864         return \Closure::bind(function () use (\$loader) {
865 $initializer
866         }, null, ClassLoader::class);
867     }
868 }
869
870 INITIALIZER;
871 }
872
873 protected function parseAutoloadsType(array $packageMap, $type, PackageInterface $mainPackage)
874 {
875 $autoloads = array();
876
877 foreach ($packageMap as $item) {
878 list($package, $installPath) = $item;
879
880 $autoload = $package->getAutoload();
881 if ($this->devMode && $package === $mainPackage) {
882 $autoload = array_merge_recursive($autoload, $package->getDevAutoload());
883 }
884
885
886  if (!isset($autoload[$type]) || !is_array($autoload[$type])) {
887 continue;
888 }
889 if (null !== $package->getTargetDir() && $package !== $mainPackage) {
890 $installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
891 }
892
893 foreach ($autoload[$type] as $namespace => $paths) {
894 foreach ((array) $paths as $path) {
895 if (($type === 'files' || $type === 'classmap' || $type === 'exclude-from-classmap') && $package->getTargetDir() && !is_readable($installPath.'/'.$path)) {
896
897  if ($package === $mainPackage) {
898 $targetDir = str_replace('\\<dirsep\\>', '[\\\\/]', preg_quote(str_replace(array('/', '\\'), '<dirsep>', $package->getTargetDir())));
899 $path = ltrim(preg_replace('{^'.$targetDir.'}', '', ltrim($path, '\\/')), '\\/');
900 } else {
901
902  $path = $package->getTargetDir() . '/' . $path;
903 }
904 }
905
906 if ($type === 'exclude-from-classmap') {
907
908  $path = preg_replace('{/+}', '/', preg_quote(trim(strtr($path, '\\', '/'), '/')));
909
910
911  $path = str_replace('\\*\\*', '.+?', $path);
912 $path = str_replace('\\*', '[^/]+?', $path);
913
914
915  $updir = null;
916 $path = preg_replace_callback(
917 '{^((?:(?:\\\\\\.){1,2}+/)+)}',
918 function ($matches) use (&$updir) {
919 if (isset($matches[1])) {
920
921  $updir = str_replace('\\.', '.', $matches[1]);
922 }
923
924 return '';
925 },
926 $path
927 );
928 if (empty($installPath)) {
929 $installPath = strtr(getcwd(), '\\', '/');
930 }
931
932 $resolvedPath = realpath($installPath . '/' . $updir);
933 $autoloads[] = preg_quote(strtr($resolvedPath, '\\', '/')) . '/' . $path;
934 continue;
935 }
936
937 $relativePath = empty($installPath) ? (empty($path) ? '.' : $path) : $installPath.'/'.$path;
938
939 if ($type === 'files') {
940 $autoloads[$this->getFileIdentifier($package, $path)] = $relativePath;
941 continue;
942 } elseif ($type === 'classmap') {
943 $autoloads[] = $relativePath;
944 continue;
945 }
946
947 $autoloads[$namespace][] = $relativePath;
948 }
949 }
950 }
951
952 return $autoloads;
953 }
954
955 protected function getFileIdentifier(PackageInterface $package, $path)
956 {
957 return md5($package->getName() . ':' . $path);
958 }
959
960
961
962
963
964
965
966
967
968 protected function sortPackageMap(array $packageMap)
969 {
970 $packages = array();
971 $paths = array();
972 $usageList = array();
973
974 foreach ($packageMap as $item) {
975 list($package, $path) = $item;
976 $name = $package->getName();
977 $packages[$name] = $package;
978 $paths[$name] = $path;
979
980 foreach (array_merge($package->getRequires(), $package->getDevRequires()) as $link) {
981 $target = $link->getTarget();
982 $usageList[$target][] = $name;
983 }
984 }
985
986 $computing = array();
987 $computed = array();
988 $computeImportance = function ($name) use (&$computeImportance, &$computing, &$computed, $usageList) {
989
990  if (isset($computed[$name])) {
991 return $computed[$name];
992 }
993
994
995  if (isset($computing[$name])) {
996 return 0;
997 }
998
999 $computing[$name] = true;
1000 $weight = 0;
1001
1002 if (isset($usageList[$name])) {
1003 foreach ($usageList[$name] as $user) {
1004 $weight -= 1 - $computeImportance($user);
1005 }
1006 }
1007
1008 unset($computing[$name]);
1009 $computed[$name] = $weight;
1010
1011 return $weight;
1012 };
1013
1014 $weightList = array();
1015
1016 foreach ($packages as $name => $package) {
1017 $weight = $computeImportance($name);
1018 $weightList[$name] = $weight;
1019 }
1020
1021 $stable_sort = function (&$array) {
1022 static $transform, $restore;
1023
1024 $i = 0;
1025
1026 if (!$transform) {
1027 $transform = function (&$v, $k) use (&$i) {
1028 $v = array($v, ++$i, $k, $v);
1029 };
1030
1031 $restore = function (&$v, $k) {
1032 $v = $v[3];
1033 };
1034 }
1035
1036 array_walk($array, $transform);
1037 asort($array);
1038 array_walk($array, $restore);
1039 };
1040
1041 $stable_sort($weightList);
1042
1043 $sortedPackageMap = array();
1044
1045 foreach (array_keys($weightList) as $name) {
1046 $sortedPackageMap[] = array($packages[$name], $paths[$name]);
1047 }
1048
1049 return $sortedPackageMap;
1050 }
1051
1052
1053
1054
1055
1056
1057
1058 protected function safeCopy($source, $target)
1059 {
1060 $source = fopen($source, 'r');
1061 $target = fopen($target, 'w+');
1062
1063 stream_copy_to_stream($source, $target);
1064 fclose($source);
1065 fclose($target);
1066 }
1067 }
1068 <?php
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 namespace Composer\Autoload;
1087
1088 use Symfony\Component\Finder\Finder;
1089 use Composer\IO\IOInterface;
1090 use Composer\Util\Filesystem;
1091
1092
1093
1094
1095
1096
1097
1098 class ClassMapGenerator
1099 {
1100
1101
1102
1103
1104
1105
1106 public static function dump($dirs, $file)
1107 {
1108 $maps = array();
1109
1110 foreach ($dirs as $dir) {
1111 $maps = array_merge($maps, static::createMap($dir));
1112 }
1113
1114 file_put_contents($file, sprintf('<?php return %s;', var_export($maps, true)));
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128 public static function createMap($path, $blacklist = null, IOInterface $io = null, $namespace = null)
1129 {
1130 if (is_string($path)) {
1131 if (is_file($path)) {
1132 $path = array(new \SplFileInfo($path));
1133 } elseif (is_dir($path)) {
1134 $path = Finder::create()->files()->followLinks()->name('/\.(php|inc|hh)$/')->in($path);
1135 } else {
1136 throw new \RuntimeException(
1137 'Could not scan for classes inside "'.$path.
1138 '" which does not appear to be a file nor a folder'
1139 );
1140 }
1141 }
1142
1143 $map = array();
1144 $filesystem = new Filesystem();
1145 $cwd = getcwd();
1146
1147 foreach ($path as $file) {
1148 $filePath = $file->getPathname();
1149 if (!in_array(pathinfo($filePath, PATHINFO_EXTENSION), array('php', 'inc', 'hh'))) {
1150 continue;
1151 }
1152
1153 if (!$filesystem->isAbsolutePath($filePath)) {
1154 $filePath = $cwd . '/' . $filePath;
1155 $filePath = $filesystem->normalizePath($filePath);
1156 } else {
1157 $filePath = preg_replace('{[\\\\/]{2,}}', '/', $filePath);
1158 }
1159
1160 if ($blacklist && preg_match($blacklist, strtr($filePath, '\\', '/'))) {
1161 continue;
1162 }
1163
1164 $classes = self::findClasses($filePath);
1165
1166 foreach ($classes as $class) {
1167
1168  if (null !== $namespace && 0 !== strpos($class, $namespace)) {
1169 continue;
1170 }
1171
1172 if (!isset($map[$class])) {
1173 $map[$class] = $filePath;
1174 } elseif ($io && $map[$class] !== $filePath && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($map[$class].' '.$filePath, '\\', '/'))) {
1175 $io->writeError(
1176 '<warning>Warning: Ambiguous class resolution, "'.$class.'"'.
1177 ' was found in both "'.$map[$class].'" and "'.$filePath.'", the first will be used.</warning>'
1178 );
1179 }
1180 }
1181 }
1182
1183 return $map;
1184 }
1185
1186
1187
1188
1189
1190
1191
1192
1193 private static function findClasses($path)
1194 {
1195 $extraTypes = PHP_VERSION_ID < 50400 ? '' : '|trait';
1196 if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) {
1197 $extraTypes .= '|enum';
1198 }
1199
1200
1201  
1202  $contents = @php_strip_whitespace($path);
1203 if (!$contents) {
1204 if (!file_exists($path)) {
1205 $message = 'File at "%s" does not exist, check your classmap definitions';
1206 } elseif (!is_readable($path)) {
1207 $message = 'File at "%s" is not readable, check its permissions';
1208 } elseif ('' === trim(file_get_contents($path))) {
1209
1210  return array();
1211 } else {
1212 $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted';
1213 }
1214 $error = error_get_last();
1215 if (isset($error['message'])) {
1216 $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];
1217 }
1218 throw new \RuntimeException(sprintf($message, $path));
1219 }
1220
1221
1222  if (!preg_match('{\b(?:class|interface'.$extraTypes.')\s}i', $contents)) {
1223 return array();
1224 }
1225
1226
1227  $contents = preg_replace('{<<<\s*(\'?)(\w+)\\1(?:\r\n|\n|\r)(?:.*?)(?:\r\n|\n|\r)\\2(?=\r\n|\n|\r|;)}s', 'null', $contents);
1228
1229  $contents = preg_replace('{"[^"\\\\]*+(\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(\\\\.[^\'\\\\]*+)*+\'}s', 'null', $contents);
1230
1231  if (substr($contents, 0, 2) !== '<?') {
1232 $contents = preg_replace('{^.+?<\?}s', '<?', $contents, 1, $replacements);
1233 if ($replacements === 0) {
1234 return array();
1235 }
1236 }
1237
1238  $contents = preg_replace('{\?>.+<\?}s', '?><?', $contents);
1239
1240  $pos = strrpos($contents, '?>');
1241 if (false !== $pos && false === strpos(substr($contents, $pos), '<?')) {
1242 $contents = substr($contents, 0, $pos);
1243 }
1244
1245 preg_match_all('{
1246             (?:
1247                  \b(?<![\$:>])(?P<type>class|interface'.$extraTypes.') \s++ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+)
1248                | \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;]
1249             )
1250         }ix', $contents, $matches);
1251
1252 $classes = array();
1253 $namespace = '';
1254
1255 for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {
1256 if (!empty($matches['ns'][$i])) {
1257 $namespace = str_replace(array(' ', "\t", "\r", "\n"), '', $matches['nsname'][$i]) . '\\';
1258 } else {
1259 $name = $matches['name'][$i];
1260
1261  if ($name === 'extends' || $name === 'implements') {
1262 continue;
1263 }
1264 if ($name[0] === ':') {
1265
1266  $name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1);
1267 } elseif ($matches['type'][$i] === 'enum') {
1268
1269  
1270  
1271  
1272  $name = rtrim($name, ':');
1273 }
1274 $classes[] = ltrim($namespace . $name, '\\');
1275 }
1276 }
1277
1278 return $classes;
1279 }
1280 }
1281 <?php
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293 namespace Composer;
1294
1295 use Composer\IO\IOInterface;
1296 use Composer\Util\Filesystem;
1297 use Composer\Util\Silencer;
1298 use Symfony\Component\Finder\Finder;
1299
1300
1301
1302
1303
1304
1305 class Cache
1306 {
1307 private static $cacheCollected = false;
1308 private $io;
1309 private $root;
1310 private $enabled = true;
1311 private $whitelist;
1312 private $filesystem;
1313
1314
1315
1316
1317
1318
1319
1320 public function __construct(IOInterface $io, $cacheDir, $whitelist = 'a-z0-9.', Filesystem $filesystem = null)
1321 {
1322 $this->io = $io;
1323 $this->root = rtrim($cacheDir, '/\\') . '/';
1324 $this->whitelist = $whitelist;
1325 $this->filesystem = $filesystem ?: new Filesystem();
1326
1327 if (preg_match('{(^|[\\\\/])(\$null|NUL|/dev/null)([\\\\/]|$)}', $cacheDir)) {
1328 $this->enabled = false;
1329
1330 return;
1331 }
1332
1333 if (
1334 (!is_dir($this->root) && !Silencer::call('mkdir', $this->root, 0777, true))
1335 || !is_writable($this->root)
1336 ) {
1337 $this->io->writeError('<warning>Cannot create cache directory ' . $this->root . ', or directory is not writable. Proceeding without cache</warning>');
1338 $this->enabled = false;
1339 }
1340 }
1341
1342 public function isEnabled()
1343 {
1344 return $this->enabled;
1345 }
1346
1347 public function getRoot()
1348 {
1349 return $this->root;
1350 }
1351
1352 public function read($file)
1353 {
1354 $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
1355 if ($this->enabled && file_exists($this->root . $file)) {
1356 $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG);
1357
1358 return file_get_contents($this->root . $file);
1359 }
1360
1361 return false;
1362 }
1363
1364 public function write($file, $contents)
1365 {
1366 if ($this->enabled) {
1367 $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
1368
1369 $this->io->writeError('Writing '.$this->root . $file.' into cache', true, IOInterface::DEBUG);
1370
1371 try {
1372 return file_put_contents($this->root . $file, $contents);
1373 } catch (\ErrorException $e) {
1374 $this->io->writeError('<warning>Failed to write into cache: '.$e->getMessage().'</warning>', true, IOInterface::DEBUG);
1375 if (preg_match('{^file_put_contents\(\): Only ([0-9]+) of ([0-9]+) bytes written}', $e->getMessage(), $m)) {
1376
1377  unlink($this->root . $file);
1378
1379 $message = sprintf(
1380 '<warning>Writing %1$s into cache failed after %2$u of %3$u bytes written, only %4$u bytes of free space available</warning>',
1381 $this->root . $file,
1382 $m[1],
1383 $m[2],
1384 @disk_free_space($this->root . dirname($file))
1385 );
1386
1387 $this->io->writeError($message);
1388
1389 return false;
1390 }
1391
1392 throw $e;
1393 }
1394 }
1395
1396 return false;
1397 }
1398
1399
1400
1401
1402 public function copyFrom($file, $source)
1403 {
1404 if ($this->enabled) {
1405 $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
1406 $this->filesystem->ensureDirectoryExists(dirname($this->root . $file));
1407
1408 if (!file_exists($source)) {
1409 $this->io->writeError('<error>'.$source.' does not exist, can not write into cache</error>');
1410 } elseif ($this->io->isDebug()) {
1411 $this->io->writeError('Writing '.$this->root . $file.' into cache from '.$source);
1412 }
1413
1414 return copy($source, $this->root . $file);
1415 }
1416
1417 return false;
1418 }
1419
1420
1421
1422
1423 public function copyTo($file, $target)
1424 {
1425 $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
1426 if ($this->enabled && file_exists($this->root . $file)) {
1427 try {
1428 touch($this->root . $file, filemtime($this->root . $file), time());
1429 } catch (\ErrorException $e) {
1430
1431  
1432  Silencer::call('touch', $this->root . $file);
1433 }
1434
1435 $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG);
1436
1437 return copy($this->root . $file, $target);
1438 }
1439
1440 return false;
1441 }
1442
1443 public function gcIsNecessary()
1444 {
1445 return (!self::$cacheCollected && !mt_rand(0, 50));
1446 }
1447
1448 public function remove($file)
1449 {
1450 $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
1451 if ($this->enabled && file_exists($this->root . $file)) {
1452 return $this->filesystem->unlink($this->root . $file);
1453 }
1454
1455 return false;
1456 }
1457
1458 public function gc($ttl, $maxSize)
1459 {
1460 if ($this->enabled) {
1461 $expire = new \DateTime();
1462 $expire->modify('-'.$ttl.' seconds');
1463
1464 $finder = $this->getFinder()->date('until '.$expire->format('Y-m-d H:i:s'));
1465 foreach ($finder as $file) {
1466 $this->filesystem->unlink($file->getPathname());
1467 }
1468
1469 $totalSize = $this->filesystem->size($this->root);
1470 if ($totalSize > $maxSize) {
1471 $iterator = $this->getFinder()->sortByAccessedTime()->getIterator();
1472 while ($totalSize > $maxSize && $iterator->valid()) {
1473 $filepath = $iterator->current()->getPathname();
1474 $totalSize -= $this->filesystem->size($filepath);
1475 $this->filesystem->unlink($filepath);
1476 $iterator->next();
1477 }
1478 }
1479
1480 self::$cacheCollected = true;
1481
1482 return true;
1483 }
1484
1485 return false;
1486 }
1487
1488 public function sha1($file)
1489 {
1490 $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
1491 if ($this->enabled && file_exists($this->root . $file)) {
1492 return sha1_file($this->root . $file);
1493 }
1494
1495 return false;
1496 }
1497
1498 public function sha256($file)
1499 {
1500 $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
1501 if ($this->enabled && file_exists($this->root . $file)) {
1502 return hash_file('sha256', $this->root . $file);
1503 }
1504
1505 return false;
1506 }
1507
1508 protected function getFinder()
1509 {
1510 return Finder::create()->in($this->root)->files();
1511 }
1512 }
1513 <?php
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525 namespace Composer\Command;
1526
1527 use Symfony\Component\Console\Input\InputInterface;
1528 use Symfony\Component\Console\Output\OutputInterface;
1529
1530
1531
1532
1533 class AboutCommand extends BaseCommand
1534 {
1535 protected function configure()
1536 {
1537 $this
1538 ->setName('about')
1539 ->setDescription('Short information about Composer.')
1540 ->setHelp(<<<EOT
1541 <info>php composer.phar about</info>
1542 EOT
1543 )
1544 ;
1545 }
1546
1547 protected function execute(InputInterface $input, OutputInterface $output)
1548 {
1549 $this->getIO()->write(<<<EOT
1550 <info>Composer - Package Management for PHP</info>
1551 <comment>Composer is a dependency manager tracking local dependencies of your projects and libraries.
1552 See https://getcomposer.org/ for more information.</comment>
1553 EOT
1554 );
1555 }
1556 }
1557 <?php
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569 namespace Composer\Command;
1570
1571 use Composer\Factory;
1572 use Composer\IO\IOInterface;
1573 use Composer\Config;
1574 use Composer\Repository\CompositeRepository;
1575 use Composer\Repository\RepositoryFactory;
1576 use Composer\Script\ScriptEvents;
1577 use Composer\Plugin\CommandEvent;
1578 use Composer\Plugin\PluginEvents;
1579 use Composer\Util\Filesystem;
1580 use Symfony\Component\Console\Input\InputArgument;
1581 use Symfony\Component\Console\Input\InputInterface;
1582 use Symfony\Component\Console\Input\InputOption;
1583 use Symfony\Component\Console\Output\OutputInterface;
1584
1585
1586
1587
1588
1589
1590 class ArchiveCommand extends BaseCommand
1591 {
1592 protected function configure()
1593 {
1594 $this
1595 ->setName('archive')
1596 ->setDescription('Create an archive of this composer package.')
1597 ->setDefinition(array(
1598 new InputArgument('package', InputArgument::OPTIONAL, 'The package to archive instead of the current project'),
1599 new InputArgument('version', InputArgument::OPTIONAL, 'A version constraint to find the package to archive'),
1600 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the resulting archive: tar or zip'),
1601 new InputOption('dir', null, InputOption::VALUE_REQUIRED, 'Write the archive to this directory'),
1602 new InputOption('file', null, InputOption::VALUE_REQUIRED, 'Write the archive with the given file name.'
1603 .' Note that the format will be appended.'),
1604 new InputOption('ignore-filters', false, InputOption::VALUE_NONE, 'Ignore filters when saving package'),
1605 ))
1606 ->setHelp(<<<EOT
1607 The <info>archive</info> command creates an archive of the specified format
1608 containing the files and directories of the Composer project or the specified
1609 package in the specified version and writes it to the specified directory.
1610
1611 <info>php composer.phar archive [--format=zip] [--dir=/foo] [package [version]]</info>
1612
1613 EOT
1614 )
1615 ;
1616 }
1617
1618 protected function execute(InputInterface $input, OutputInterface $output)
1619 {
1620 $config = Factory::createConfig();
1621 $composer = $this->getComposer(false);
1622 if ($composer) {
1623 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'archive', $input, $output);
1624 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
1625 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::PRE_ARCHIVE_CMD);
1626 }
1627
1628 if (null === $input->getOption('format')) {
1629 $input->setOption('format', $config->get('archive-format'));
1630 }
1631 if (null === $input->getOption('dir')) {
1632 $input->setOption('dir', $config->get('archive-dir'));
1633 }
1634
1635 $returnCode = $this->archive(
1636 $this->getIO(),
1637 $config,
1638 $input->getArgument('package'),
1639 $input->getArgument('version'),
1640 $input->getOption('format'),
1641 $input->getOption('dir'),
1642 $input->getOption('file'),
1643 $input->getOption('ignore-filters')
1644 );
1645
1646 if (0 === $returnCode && $composer) {
1647 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_ARCHIVE_CMD);
1648 }
1649
1650 return $returnCode;
1651 }
1652
1653 protected function archive(IOInterface $io, Config $config, $packageName = null, $version = null, $format = 'tar', $dest = '.', $fileName = null, $ignoreFilters)
1654 {
1655 $factory = new Factory;
1656 $downloadManager = $factory->createDownloadManager($io, $config);
1657 $archiveManager = $factory->createArchiveManager($config, $downloadManager);
1658
1659 if ($packageName) {
1660 $package = $this->selectPackage($io, $packageName, $version);
1661
1662 if (!$package) {
1663 return 1;
1664 }
1665 } else {
1666 $package = $this->getComposer()->getPackage();
1667 }
1668
1669 $io->writeError('<info>Creating the archive into "'.$dest.'".</info>');
1670 $packagePath = $archiveManager->archive($package, $format, $dest, $fileName, $ignoreFilters);
1671 $fs = new Filesystem;
1672 $shortPath = $fs->findShortestPath(getcwd(), $packagePath, true);
1673
1674 $io->writeError('Created: ', false);
1675 $io->write(strlen($shortPath) < strlen($packagePath) ? $shortPath : $packagePath);
1676
1677 return 0;
1678 }
1679
1680 protected function selectPackage(IOInterface $io, $packageName, $version = null)
1681 {
1682 $io->writeError('<info>Searching for the specified package.</info>');
1683
1684 if ($composer = $this->getComposer(false)) {
1685 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
1686 $repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
1687 } else {
1688 $defaultRepos = RepositoryFactory::defaultRepos($this->getIO());
1689 $io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
1690 $repo = new CompositeRepository($defaultRepos);
1691 }
1692
1693 $packages = $repo->findPackages($packageName, $version);
1694
1695 if (count($packages) > 1) {
1696 $package = reset($packages);
1697 $io->writeError('<info>Found multiple matches, selected '.$package->getPrettyString().'.</info>');
1698 $io->writeError('Alternatives were '.implode(', ', array_map(function ($p) {
1699 return $p->getPrettyString();
1700 }, $packages)).'.');
1701 $io->writeError('<comment>Please use a more specific constraint to pick a different package.</comment>');
1702 } elseif ($packages) {
1703 $package = reset($packages);
1704 $io->writeError('<info>Found an exact match '.$package->getPrettyString().'.</info>');
1705 } else {
1706 $io->writeError('<error>Could not find a package matching '.$packageName.'.</error>');
1707
1708 return false;
1709 }
1710
1711 return $package;
1712 }
1713 }
1714 <?php
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726 namespace Composer\Command;
1727
1728 use Composer\Composer;
1729 use Composer\Config;
1730 use Composer\Console\Application;
1731 use Composer\IO\IOInterface;
1732 use Composer\IO\NullIO;
1733 use Symfony\Component\Console\Input\InputInterface;
1734 use Symfony\Component\Console\Output\OutputInterface;
1735 use Symfony\Component\Console\Command\Command;
1736
1737
1738
1739
1740
1741
1742
1743 abstract class BaseCommand extends Command
1744 {
1745
1746
1747
1748 private $composer;
1749
1750
1751
1752
1753 private $io;
1754
1755
1756
1757
1758
1759
1760
1761 public function getComposer($required = true, $disablePlugins = null)
1762 {
1763 if (null === $this->composer) {
1764 $application = $this->getApplication();
1765 if ($application instanceof Application) {
1766
1767 $this->composer = $application->getComposer($required, $disablePlugins);
1768 } elseif ($required) {
1769 throw new \RuntimeException(
1770 'Could not create a Composer\Composer instance, you must inject '.
1771 'one if this command is not used with a Composer\Console\Application instance'
1772 );
1773 }
1774 }
1775
1776 return $this->composer;
1777 }
1778
1779
1780
1781
1782 public function setComposer(Composer $composer)
1783 {
1784 $this->composer = $composer;
1785 }
1786
1787
1788
1789
1790 public function resetComposer()
1791 {
1792 $this->composer = null;
1793 $this->getApplication()->resetComposer();
1794 }
1795
1796
1797
1798
1799
1800
1801
1802
1803 public function isProxyCommand()
1804 {
1805 return false;
1806 }
1807
1808
1809
1810
1811 public function getIO()
1812 {
1813 if (null === $this->io) {
1814 $application = $this->getApplication();
1815 if ($application instanceof Application) {
1816
1817 $this->io = $application->getIO();
1818 } else {
1819 $this->io = new NullIO();
1820 }
1821 }
1822
1823 return $this->io;
1824 }
1825
1826
1827
1828
1829 public function setIO(IOInterface $io)
1830 {
1831 $this->io = $io;
1832 }
1833
1834
1835
1836
1837 protected function initialize(InputInterface $input, OutputInterface $output)
1838 {
1839 if (true === $input->hasParameterOption(array('--no-ansi')) && $input->hasOption('no-progress')) {
1840 $input->setOption('no-progress', true);
1841 }
1842
1843 parent::initialize($input, $output);
1844 }
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855 protected function getPreferredInstallOptions(Config $config, InputInterface $input, $keepVcsRequiresPreferSource = false)
1856 {
1857 $preferSource = false;
1858 $preferDist = false;
1859
1860 switch ($config->get('preferred-install')) {
1861 case 'source':
1862 $preferSource = true;
1863 break;
1864 case 'dist':
1865 $preferDist = true;
1866 break;
1867 case 'auto':
1868 default:
1869
1870  break;
1871 }
1872
1873 if ($input->getOption('prefer-source') || $input->getOption('prefer-dist') || ($keepVcsRequiresPreferSource && $input->hasOption('keep-vcs') && $input->getOption('keep-vcs'))) {
1874 $preferSource = $input->getOption('prefer-source') || ($keepVcsRequiresPreferSource && $input->hasOption('keep-vcs') && $input->getOption('keep-vcs'));
1875 $preferDist = $input->getOption('prefer-dist');
1876 }
1877
1878 return array($preferSource, $preferDist);
1879 }
1880 }
1881 <?php
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893 namespace Composer\Command;
1894
1895 use Composer\DependencyResolver\Pool;
1896 use Composer\Package\Link;
1897 use Composer\Package\PackageInterface;
1898 use Composer\Repository\ArrayRepository;
1899 use Composer\Repository\CompositeRepository;
1900 use Composer\Repository\PlatformRepository;
1901 use Composer\Repository\RepositoryFactory;
1902 use Composer\Plugin\CommandEvent;
1903 use Composer\Plugin\PluginEvents;
1904 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
1905 use Composer\Package\Version\VersionParser;
1906 use Symfony\Component\Console\Helper\Table;
1907 use Symfony\Component\Console\Input\InputArgument;
1908 use Symfony\Component\Console\Input\InputInterface;
1909 use Symfony\Component\Console\Input\InputOption;
1910 use Symfony\Component\Console\Output\OutputInterface;
1911
1912
1913
1914
1915
1916
1917 class BaseDependencyCommand extends BaseCommand
1918 {
1919 const ARGUMENT_PACKAGE = 'package';
1920 const ARGUMENT_CONSTRAINT = 'constraint';
1921 const OPTION_RECURSIVE = 'recursive';
1922 const OPTION_TREE = 'tree';
1923
1924 protected $colors;
1925
1926
1927
1928
1929 protected function configure()
1930 {
1931 $this->setDefinition(array(
1932 new InputArgument(self::ARGUMENT_PACKAGE, InputArgument::REQUIRED, 'Package to inspect'),
1933 new InputArgument(self::ARGUMENT_CONSTRAINT, InputArgument::OPTIONAL, 'Optional version constraint', '*'),
1934 new InputOption(self::OPTION_RECURSIVE, 'r', InputOption::VALUE_NONE, 'Recursively resolves up to the root package'),
1935 new InputOption(self::OPTION_TREE, 't', InputOption::VALUE_NONE, 'Prints the results as a nested tree'),
1936 ));
1937 }
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947 protected function doExecute(InputInterface $input, OutputInterface $output, $inverted = false)
1948 {
1949
1950  $composer = $this->getComposer();
1951 $commandEvent = new CommandEvent(PluginEvents::COMMAND, $this->getName(), $input, $output);
1952 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
1953
1954
1955  $platformOverrides = $composer->getConfig()->get('platform') ?: array();
1956 $repository = new CompositeRepository(array(
1957 new ArrayRepository(array($composer->getPackage())),
1958 $composer->getRepositoryManager()->getLocalRepository(),
1959 new PlatformRepository(array(), $platformOverrides),
1960 ));
1961 $pool = new Pool();
1962 $pool->addRepository($repository);
1963
1964
1965  list($needle, $textConstraint) = array_pad(
1966 explode(':', $input->getArgument(self::ARGUMENT_PACKAGE)),
1967 2,
1968 $input->getArgument(self::ARGUMENT_CONSTRAINT)
1969 );
1970
1971
1972  $packages = $pool->whatProvides($needle);
1973 if (empty($packages)) {
1974 throw new \InvalidArgumentException(sprintf('Could not find package "%s" in your project', $needle));
1975 }
1976
1977
1978  
1979  if (!$repository->findPackage($needle, $textConstraint)) {
1980 $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO()));
1981 if ($match = $defaultRepos->findPackage($needle, $textConstraint)) {
1982 $repository->addRepository(new ArrayRepository(array(clone $match)));
1983 }
1984 }
1985
1986
1987  $needles = array($needle);
1988 if ($inverted) {
1989 foreach ($packages as $package) {
1990 $needles = array_merge($needles, array_map(function (Link $link) {
1991 return $link->getTarget();
1992 }, $package->getReplaces()));
1993 }
1994 }
1995
1996
1997  if ('*' !== $textConstraint) {
1998 $versionParser = new VersionParser();
1999 $constraint = $versionParser->parseConstraints($textConstraint);
2000 } else {
2001 $constraint = null;
2002 }
2003
2004
2005  $renderTree = $input->getOption(self::OPTION_TREE);
2006 $recursive = $renderTree || $input->getOption(self::OPTION_RECURSIVE);
2007
2008
2009  $results = $repository->getDependents($needles, $constraint, $inverted, $recursive);
2010 if (empty($results)) {
2011 $extra = (null !== $constraint) ? sprintf(' in versions %smatching %s', $inverted ? 'not ' : '', $textConstraint) : '';
2012 $this->getIO()->writeError(sprintf('<info>There is no installed package depending on "%s"%s</info>',
2013 $needle, $extra));
2014 } elseif ($renderTree) {
2015 $this->initStyles($output);
2016 $root = $packages[0];
2017 $this->getIO()->write(sprintf('<info>%s</info> %s %s', $root->getPrettyName(), $root->getPrettyVersion(), $root->getDescription()));
2018 $this->printTree($results);
2019 } else {
2020 $this->printTable($output, $results);
2021 }
2022
2023 return 0;
2024 }
2025
2026
2027
2028
2029
2030
2031
2032 protected function printTable(OutputInterface $output, $results)
2033 {
2034 $table = array();
2035 $doubles = array();
2036 do {
2037 $queue = array();
2038 $rows = array();
2039 foreach ($results as $result) {
2040
2041
2042
2043
2044 list($package, $link, $children) = $result;
2045 $unique = (string) $link;
2046 if (isset($doubles[$unique])) {
2047 continue;
2048 }
2049 $doubles[$unique] = true;
2050 $version = (strpos($package->getPrettyVersion(), 'No version set') === 0) ? '-' : $package->getPrettyVersion();
2051 $rows[] = array($package->getPrettyName(), $version, $link->getDescription(), sprintf('%s (%s)', $link->getTarget(), $link->getPrettyConstraint()));
2052 if ($children) {
2053 $queue = array_merge($queue, $children);
2054 }
2055 }
2056 $results = $queue;
2057 $table = array_merge($rows, $table);
2058 } while (!empty($results));
2059
2060
2061  $renderer = new Table($output);
2062 $renderer->setStyle('compact');
2063 $renderer->getStyle()->setVerticalBorderChar('');
2064 $renderer->getStyle()->setCellRowContentFormat('%s  ');
2065 $renderer->setRows($table)->render();
2066 }
2067
2068
2069
2070
2071
2072
2073 protected function initStyles(OutputInterface $output)
2074 {
2075 $this->colors = array(
2076 'green',
2077 'yellow',
2078 'cyan',
2079 'magenta',
2080 'blue',
2081 );
2082
2083 foreach ($this->colors as $color) {
2084 $style = new OutputFormatterStyle($color);
2085 $output->getFormatter()->setStyle($color, $style);
2086 }
2087 }
2088
2089
2090
2091
2092
2093
2094
2095
2096 protected function printTree($results, $prefix = '', $level = 1)
2097 {
2098 $count = count($results);
2099 $idx = 0;
2100 foreach ($results as $result) {
2101
2102
2103
2104
2105
2106 list($package, $link, $children) = $result;
2107
2108 $color = $this->colors[$level % count($this->colors)];
2109 $prevColor = $this->colors[($level - 1) % count($this->colors)];
2110 $isLast = (++$idx == $count);
2111 $versionText = (strpos($package->getPrettyVersion(), 'No version set') === 0) ? '' : $package->getPrettyVersion();
2112 $packageText = rtrim(sprintf('<%s>%s</%1$s> %s', $color, $package->getPrettyName(), $versionText));
2113 $linkText = sprintf('%s <%s>%s</%2$s> %s', $link->getDescription(), $prevColor, $link->getTarget(), $link->getPrettyConstraint());
2114 $circularWarn = $children === false ? '(circular dependency aborted here)' : '';
2115 $this->writeTreeLine(rtrim(sprintf("%s%s%s (%s) %s", $prefix, $isLast ? '└──' : '├──', $packageText, $linkText, $circularWarn)));
2116 if ($children) {
2117 $this->printTree($children, $prefix . ($isLast ? '   ' : '│  '), $level + 1);
2118 }
2119 }
2120 }
2121
2122 private function writeTreeLine($line)
2123 {
2124 $io = $this->getIO();
2125 if (!$io->isDecorated()) {
2126 $line = str_replace(array('└', '├', '──', '│'), array('`-', '|-', '-', '|'), $line);
2127 }
2128
2129 $io->write($line);
2130 }
2131 }
2132 <?php
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144 namespace Composer\Command;
2145
2146 use Composer\Cache;
2147 use Composer\Factory;
2148 use Symfony\Component\Console\Input\InputInterface;
2149 use Symfony\Component\Console\Output\OutputInterface;
2150
2151
2152
2153
2154 class ClearCacheCommand extends BaseCommand
2155 {
2156 protected function configure()
2157 {
2158 $this
2159 ->setName('clear-cache')
2160 ->setAliases(array('clearcache'))
2161 ->setDescription('Clears composer\'s internal package cache.')
2162 ->setHelp(<<<EOT
2163 The <info>clear-cache</info> deletes all cached packages from composer's
2164 cache directory.
2165 EOT
2166 )
2167 ;
2168 }
2169
2170 protected function execute(InputInterface $input, OutputInterface $output)
2171 {
2172 $config = Factory::createConfig();
2173 $io = $this->getIO();
2174
2175 $cachePaths = array(
2176 'cache-dir' => $config->get('cache-dir'),
2177 'cache-files-dir' => $config->get('cache-files-dir'),
2178 'cache-repo-dir' => $config->get('cache-repo-dir'),
2179 'cache-vcs-dir' => $config->get('cache-vcs-dir'),
2180 );
2181
2182 foreach ($cachePaths as $key => $cachePath) {
2183 $cachePath = realpath($cachePath);
2184 if (!$cachePath) {
2185 $io->writeError("<info>Cache directory does not exist ($key): $cachePath</info>");
2186
2187 continue;
2188 }
2189 $cache = new Cache($io, $cachePath);
2190 if (!$cache->isEnabled()) {
2191 $io->writeError("<info>Cache is not enabled ($key): $cachePath</info>");
2192
2193 continue;
2194 }
2195
2196 $io->writeError("<info>Clearing cache ($key): $cachePath</info>");
2197 $cache->gc(0, 0);
2198 }
2199
2200 $io->writeError('<info>All caches cleared.</info>');
2201 }
2202 }
2203 <?php
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215 namespace Composer\Command;
2216
2217 use Composer\Util\Platform;
2218 use Composer\Util\Silencer;
2219 use Symfony\Component\Console\Input\InputInterface;
2220 use Symfony\Component\Console\Input\InputArgument;
2221 use Symfony\Component\Console\Input\InputOption;
2222 use Symfony\Component\Console\Output\OutputInterface;
2223 use Composer\Config;
2224 use Composer\Config\JsonConfigSource;
2225 use Composer\Factory;
2226 use Composer\Json\JsonFile;
2227 use Composer\Semver\VersionParser;
2228 use Composer\Package\BasePackage;
2229
2230
2231
2232
2233
2234 class ConfigCommand extends BaseCommand
2235 {
2236
2237
2238
2239 protected $config;
2240
2241
2242
2243
2244 protected $configFile;
2245
2246
2247
2248
2249 protected $configSource;
2250
2251
2252
2253
2254 protected $authConfigFile;
2255
2256
2257
2258
2259 protected $authConfigSource;
2260
2261
2262
2263
2264 protected function configure()
2265 {
2266 $this
2267 ->setName('config')
2268 ->setDescription('Set config options.')
2269 ->setDefinition(array(
2270 new InputOption('global', 'g', InputOption::VALUE_NONE, 'Apply command to the global config file'),
2271 new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'),
2272 new InputOption('auth', 'a', InputOption::VALUE_NONE, 'Affect auth config file (only used for --editor)'),
2273 new InputOption('unset', null, InputOption::VALUE_NONE, 'Unset the given setting-key'),
2274 new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'),
2275 new InputOption('file', 'f', InputOption::VALUE_REQUIRED, 'If you want to choose a different composer.json or config.json'),
2276 new InputOption('absolute', null, InputOption::VALUE_NONE, 'Returns absolute paths when fetching *-dir config values instead of relative'),
2277 new InputArgument('setting-key', null, 'Setting key'),
2278 new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
2279 ))
2280 ->setHelp(<<<EOT
2281 This command allows you to edit composer config settings and repositories
2282 in either the local composer.json file or the global config.json file.
2283
2284 Additionally it lets you edit most properties in the local composer.json.
2285
2286 To set a config setting:
2287
2288     <comment>%command.full_name% bin-dir bin/</comment>
2289
2290 To read a config setting:
2291
2292     <comment>%command.full_name% bin-dir</comment>
2293     Outputs: <info>bin</info>
2294
2295 To edit the global config.json file:
2296
2297     <comment>%command.full_name% --global</comment>
2298
2299 To add a repository:
2300
2301     <comment>%command.full_name% repositories.foo vcs https://bar.com</comment>
2302
2303 To remove a repository (repo is a short alias for repositories):
2304
2305     <comment>%command.full_name% --unset repo.foo</comment>
2306
2307 To disable packagist:
2308
2309     <comment>%command.full_name% repo.packagist false</comment>
2310
2311 You can alter repositories in the global config.json file by passing in the
2312 <info>--global</info> option.
2313
2314 To edit the file in an external editor:
2315
2316     <comment>%command.full_name% --editor</comment>
2317
2318 To choose your editor you can set the "EDITOR" env variable.
2319
2320 To get a list of configuration values in the file:
2321
2322     <comment>%command.full_name% --list</comment>
2323
2324 You can always pass more than one option. As an example, if you want to edit the
2325 global config.json file.
2326
2327     <comment>%command.full_name% --editor --global</comment>
2328 EOT
2329 )
2330 ;
2331 }
2332
2333
2334
2335
2336 protected function initialize(InputInterface $input, OutputInterface $output)
2337 {
2338 parent::initialize($input, $output);
2339
2340 if ($input->getOption('global') && null !== $input->getOption('file')) {
2341 throw new \RuntimeException('--file and --global can not be combined');
2342 }
2343
2344 $io = $this->getIO();
2345 $this->config = Factory::createConfig($io);
2346
2347
2348  
2349  $configFile = $input->getOption('global')
2350 ? ($this->config->get('home') . '/config.json')
2351 : ($input->getOption('file') ?: trim(getenv('COMPOSER')) ?: 'composer.json');
2352
2353
2354  if ($configFile === 'composer.json' && !file_exists($configFile) && realpath(getcwd()) === realpath($this->config->get('home'))) {
2355 file_put_contents($configFile, "{\n}\n");
2356 }
2357
2358 $this->configFile = new JsonFile($configFile, null, $io);
2359 $this->configSource = new JsonConfigSource($this->configFile);
2360
2361 $authConfigFile = $input->getOption('global')
2362 ? ($this->config->get('home') . '/auth.json')
2363 : dirname(realpath($configFile)) . '/auth.json';
2364
2365 $this->authConfigFile = new JsonFile($authConfigFile, null, $io);
2366 $this->authConfigSource = new JsonConfigSource($this->authConfigFile, true);
2367
2368
2369  if ($input->getOption('global') && !$this->configFile->exists()) {
2370 touch($this->configFile->getPath());
2371 $this->configFile->write(array('config' => new \ArrayObject));
2372 Silencer::call('chmod', $this->configFile->getPath(), 0600);
2373 }
2374 if ($input->getOption('global') && !$this->authConfigFile->exists()) {
2375 touch($this->authConfigFile->getPath());
2376 $this->authConfigFile->write(array('bitbucket-oauth' => new \ArrayObject, 'github-oauth' => new \ArrayObject, 'gitlab-oauth' => new \ArrayObject, 'gitlab-token' => new \ArrayObject, 'http-basic' => new \ArrayObject));
2377 Silencer::call('chmod', $this->authConfigFile->getPath(), 0600);
2378 }
2379
2380 if (!$this->configFile->exists()) {
2381 throw new \RuntimeException(sprintf('File "%s" cannot be found in the current directory', $configFile));
2382 }
2383 }
2384
2385
2386
2387
2388 protected function execute(InputInterface $input, OutputInterface $output)
2389 {
2390
2391  if ($input->getOption('editor')) {
2392 $editor = escapeshellcmd(getenv('EDITOR'));
2393 if (!$editor) {
2394 if (Platform::isWindows()) {
2395 $editor = 'notepad';
2396 } else {
2397 foreach (array('editor', 'vim', 'vi', 'nano', 'pico', 'ed') as $candidate) {
2398 if (exec('which '.$candidate)) {
2399 $editor = $candidate;
2400 break;
2401 }
2402 }
2403 }
2404 }
2405
2406 $file = $input->getOption('auth') ? $this->authConfigFile->getPath() : $this->configFile->getPath();
2407 system($editor . ' ' . $file . (Platform::isWindows() ? '' : ' > `tty`'));
2408
2409 return 0;
2410 }
2411
2412 if (!$input->getOption('global')) {
2413 $this->config->merge($this->configFile->read());
2414 $this->config->merge(array('config' => $this->authConfigFile->exists() ? $this->authConfigFile->read() : array()));
2415 }
2416
2417
2418  if ($input->getOption('list')) {
2419 $this->listConfiguration($this->config->all(), $this->config->raw(), $output);
2420
2421 return 0;
2422 }
2423
2424 $settingKey = $input->getArgument('setting-key');
2425 if (!$settingKey) {
2426 return 0;
2427 }
2428
2429
2430  if (array() !== $input->getArgument('setting-value') && $input->getOption('unset')) {
2431 throw new \RuntimeException('You can not combine a setting value with --unset');
2432 }
2433
2434
2435  if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
2436 $properties = array('name', 'type', 'description', 'homepage', 'version', 'minimum-stability', 'prefer-stable', 'keywords', 'license', 'extra');
2437 $rawData = $this->configFile->read();
2438 $data = $this->config->all();
2439 if (preg_match('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
2440 if (!isset($matches[1]) || $matches[1] === '') {
2441 $value = isset($data['repositories']) ? $data['repositories'] : array();
2442 } else {
2443 if (!isset($data['repositories'][$matches[1]])) {
2444 throw new \InvalidArgumentException('There is no '.$matches[1].' repository defined');
2445 }
2446
2447 $value = $data['repositories'][$matches[1]];
2448 }
2449 } elseif (strpos($settingKey, '.')) {
2450 $bits = explode('.', $settingKey);
2451 if ($bits[0] === 'extra') {
2452 $data = $rawData;
2453 } else {
2454 $data = $data['config'];
2455 }
2456 $match = false;
2457 foreach ($bits as $bit) {
2458 $key = isset($key) ? $key.'.'.$bit : $bit;
2459 $match = false;
2460 if (isset($data[$key])) {
2461 $match = true;
2462 $data = $data[$key];
2463 unset($key);
2464 }
2465 }
2466
2467 if (!$match) {
2468 throw new \RuntimeException($settingKey.' is not defined.');
2469 }
2470
2471 $value = $data;
2472 } elseif (isset($data['config'][$settingKey])) {
2473 $value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS);
2474 } elseif (in_array($settingKey, $properties, true) && isset($rawData[$settingKey])) {
2475 $value = $rawData[$settingKey];
2476 } else {
2477 throw new \RuntimeException($settingKey.' is not defined');
2478 }
2479
2480 if (is_array($value)) {
2481 $value = json_encode($value);
2482 }
2483
2484 $this->getIO()->write($value);
2485
2486 return 0;
2487 }
2488
2489 $values = $input->getArgument('setting-value'); 
2490
2491 $booleanValidator = function ($val) {
2492 return in_array($val, array('true', 'false', '1', '0'), true);
2493 };
2494 $booleanNormalizer = function ($val) {
2495 return $val !== 'false' && (bool) $val;
2496 };
2497
2498
2499  $uniqueConfigValues = array(
2500 'process-timeout' => array('is_numeric', 'intval'),
2501 'use-include-path' => array($booleanValidator, $booleanNormalizer),
2502 'preferred-install' => array(
2503 function ($val) {
2504 return in_array($val, array('auto', 'source', 'dist'), true);
2505 },
2506 function ($val) {
2507 return $val;
2508 },
2509 ),
2510 'store-auths' => array(
2511 function ($val) {
2512 return in_array($val, array('true', 'false', 'prompt'), true);
2513 },
2514 function ($val) {
2515 if ('prompt' === $val) {
2516 return 'prompt';
2517 }
2518
2519 return $val !== 'false' && (bool) $val;
2520 },
2521 ),
2522 'notify-on-install' => array($booleanValidator, $booleanNormalizer),
2523 'vendor-dir' => array('is_string', function ($val) {
2524 return $val;
2525 }),
2526 'bin-dir' => array('is_string', function ($val) {
2527 return $val;
2528 }),
2529 'archive-dir' => array('is_string', function ($val) {
2530 return $val;
2531 }),
2532 'archive-format' => array('is_string', function ($val) {
2533 return $val;
2534 }),
2535 'data-dir' => array('is_string', function ($val) {
2536 return $val;
2537 }),
2538 'cache-dir' => array('is_string', function ($val) {
2539 return $val;
2540 }),
2541 'cache-files-dir' => array('is_string', function ($val) {
2542 return $val;
2543 }),
2544 'cache-repo-dir' => array('is_string', function ($val) {
2545 return $val;
2546 }),
2547 'cache-vcs-dir' => array('is_string', function ($val) {
2548 return $val;
2549 }),
2550 'cache-ttl' => array('is_numeric', 'intval'),
2551 'cache-files-ttl' => array('is_numeric', 'intval'),
2552 'cache-files-maxsize' => array(
2553 function ($val) {
2554 return preg_match('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val) > 0;
2555 },
2556 function ($val) {
2557 return $val;
2558 },
2559 ),
2560 'bin-compat' => array(
2561 function ($val) {
2562 return in_array($val, array('auto', 'full'));
2563 },
2564 function ($val) {
2565 return $val;
2566 },
2567 ),
2568 'discard-changes' => array(
2569 function ($val) {
2570 return in_array($val, array('stash', 'true', 'false', '1', '0'), true);
2571 },
2572 function ($val) {
2573 if ('stash' === $val) {
2574 return 'stash';
2575 }
2576
2577 return $val !== 'false' && (bool) $val;
2578 },
2579 ),
2580 'autoloader-suffix' => array('is_string', function ($val) {
2581 return $val === 'null' ? null : $val;
2582 }),
2583 'sort-packages' => array($booleanValidator, $booleanNormalizer),
2584 'optimize-autoloader' => array($booleanValidator, $booleanNormalizer),
2585 'classmap-authoritative' => array($booleanValidator, $booleanNormalizer),
2586 'apcu-autoloader' => array($booleanValidator, $booleanNormalizer),
2587 'prepend-autoloader' => array($booleanValidator, $booleanNormalizer),
2588 'disable-tls' => array($booleanValidator, $booleanNormalizer),
2589 'secure-http' => array($booleanValidator, $booleanNormalizer),
2590 'cafile' => array(
2591 function ($val) {
2592 return file_exists($val) && is_readable($val);
2593 },
2594 function ($val) {
2595 return $val === 'null' ? null : $val;
2596 },
2597 ),
2598 'capath' => array(
2599 function ($val) {
2600 return is_dir($val) && is_readable($val);
2601 },
2602 function ($val) {
2603 return $val === 'null' ? null : $val;
2604 },
2605 ),
2606 'github-expose-hostname' => array($booleanValidator, $booleanNormalizer),
2607 );
2608 $multiConfigValues = array(
2609 'github-protocols' => array(
2610 function ($vals) {
2611 if (!is_array($vals)) {
2612 return 'array expected';
2613 }
2614
2615 foreach ($vals as $val) {
2616 if (!in_array($val, array('git', 'https', 'ssh'))) {
2617 return 'valid protocols include: git, https, ssh';
2618 }
2619 }
2620
2621 return true;
2622 },
2623 function ($vals) {
2624 return $vals;
2625 },
2626 ),
2627 'github-domains' => array(
2628 function ($vals) {
2629 if (!is_array($vals)) {
2630 return 'array expected';
2631 }
2632
2633 return true;
2634 },
2635 function ($vals) {
2636 return $vals;
2637 },
2638 ),
2639 'gitlab-domains' => array(
2640 function ($vals) {
2641 if (!is_array($vals)) {
2642 return 'array expected';
2643 }
2644
2645 return true;
2646 },
2647 function ($vals) {
2648 return $vals;
2649 },
2650 ),
2651 );
2652
2653 if ($input->getOption('unset') && (isset($uniqueConfigValues[$settingKey]) || isset($multiConfigValues[$settingKey]))) {
2654 return $this->configSource->removeConfigSetting($settingKey);
2655 }
2656 if (isset($uniqueConfigValues[$settingKey])) {
2657 return $this->handleSingleValue($settingKey, $uniqueConfigValues[$settingKey], $values, 'addConfigSetting');
2658 }
2659 if (isset($multiConfigValues[$settingKey])) {
2660 return $this->handleMultiValue($settingKey, $multiConfigValues[$settingKey], $values, 'addConfigSetting');
2661 }
2662
2663
2664  $uniqueProps = array(
2665 'name' => array('is_string', function ($val) {
2666 return $val;
2667 }),
2668 'type' => array('is_string', function ($val) {
2669 return $val;
2670 }),
2671 'description' => array('is_string', function ($val) {
2672 return $val;
2673 }),
2674 'homepage' => array('is_string', function ($val) {
2675 return $val;
2676 }),
2677 'version' => array('is_string', function ($val) {
2678 return $val;
2679 }),
2680 'minimum-stability' => array(
2681 function ($val) {
2682 return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]);
2683 },
2684 function ($val) {
2685 return VersionParser::normalizeStability($val);
2686 },
2687 ),
2688 'prefer-stable' => array($booleanValidator, $booleanNormalizer),
2689 );
2690 $multiProps = array(
2691 'keywords' => array(
2692 function ($vals) {
2693 if (!is_array($vals)) {
2694 return 'array expected';
2695 }
2696
2697 return true;
2698 },
2699 function ($vals) {
2700 return $vals;
2701 },
2702 ),
2703 'license' => array(
2704 function ($vals) {
2705 if (!is_array($vals)) {
2706 return 'array expected';
2707 }
2708
2709 return true;
2710 },
2711 function ($vals) {
2712 return $vals;
2713 },
2714 ),
2715 );
2716
2717 if ($input->getOption('global') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]) || substr($settingKey, 0, 6) === 'extra.')) {
2718 throw new \InvalidArgumentException('The '.$settingKey.' property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json');
2719 }
2720 if ($input->getOption('unset') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]))) {
2721 return $this->configSource->removeProperty($settingKey);
2722 }
2723 if (isset($uniqueProps[$settingKey])) {
2724 return $this->handleSingleValue($settingKey, $uniqueProps[$settingKey], $values, 'addProperty');
2725 }
2726 if (isset($multiProps[$settingKey])) {
2727 return $this->handleMultiValue($settingKey, $multiProps[$settingKey], $values, 'addProperty');
2728 }
2729
2730
2731  if (preg_match('/^repos?(?:itories)?\.(.+)/', $settingKey, $matches)) {
2732 if ($input->getOption('unset')) {
2733 return $this->configSource->removeRepository($matches[1]);
2734 }
2735
2736 if (2 === count($values)) {
2737 return $this->configSource->addRepository($matches[1], array(
2738 'type' => $values[0],
2739 'url' => $values[1],
2740 ));
2741 }
2742
2743 if (1 === count($values)) {
2744 $value = strtolower($values[0]);
2745 if (true === $booleanValidator($value)) {
2746 if (false === $booleanNormalizer($value)) {
2747 return $this->configSource->addRepository($matches[1], false);
2748 }
2749 } else {
2750 $value = JsonFile::parseJson($values[0]);
2751
2752 return $this->configSource->addRepository($matches[1], $value);
2753 }
2754 }
2755
2756 throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs https://bar.com');
2757 }
2758
2759
2760  if (preg_match('/^extra\.(.+)/', $settingKey, $matches)) {
2761 if ($input->getOption('unset')) {
2762 return $this->configSource->removeProperty($settingKey);
2763 }
2764
2765 return $this->configSource->addProperty($settingKey, $values[0]);
2766 }
2767
2768
2769  if (preg_match('/^platform\.(.+)/', $settingKey, $matches)) {
2770 if ($input->getOption('unset')) {
2771 return $this->configSource->removeConfigSetting($settingKey);
2772 }
2773
2774 return $this->configSource->addConfigSetting($settingKey, $values[0]);
2775 }
2776
2777
2778  if (preg_match('/^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|http-basic)\.(.+)/', $settingKey, $matches)) {
2779 if ($input->getOption('unset')) {
2780 $this->authConfigSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2781 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2782
2783 return;
2784 }
2785
2786 if ($matches[1] === 'bitbucket-oauth') {
2787 if (2 !== count($values)) {
2788 throw new \RuntimeException('Expected two arguments (consumer-key, consumer-secret), got '.count($values));
2789 }
2790 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2791 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('consumer-key' => $values[0], 'consumer-secret' => $values[1]));
2792 } elseif (in_array($matches[1], array('github-oauth', 'gitlab-oauth', 'gitlab-token'), true)) {
2793 if (1 !== count($values)) {
2794 throw new \RuntimeException('Too many arguments, expected only one token');
2795 }
2796 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2797 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], $values[0]);
2798 } elseif ($matches[1] === 'http-basic') {
2799 if (2 !== count($values)) {
2800 throw new \RuntimeException('Expected two arguments (username, password), got '.count($values));
2801 }
2802 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
2803 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'password' => $values[1]));
2804 }
2805
2806 return;
2807 }
2808
2809 throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command');
2810 }
2811
2812 protected function handleSingleValue($key, array $callbacks, array $values, $method)
2813 {
2814 list($validator, $normalizer) = $callbacks;
2815 if (1 !== count($values)) {
2816 throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
2817 }
2818
2819 if (true !== $validation = $validator($values[0])) {
2820 throw new \RuntimeException(sprintf(
2821 '"%s" is an invalid value'.($validation ? ' ('.$validation.')' : ''),
2822 $values[0]
2823 ));
2824 }
2825
2826 return call_user_func(array($this->configSource, $method), $key, $normalizer($values[0]));
2827 }
2828
2829 protected function handleMultiValue($key, array $callbacks, array $values, $method)
2830 {
2831 list($validator, $normalizer) = $callbacks;
2832 if (true !== $validation = $validator($values)) {
2833 throw new \RuntimeException(sprintf(
2834 '%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
2835 json_encode($values)
2836 ));
2837 }
2838
2839 return call_user_func(array($this->configSource, $method), $key, $normalizer($values));
2840 }
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850 protected function listConfiguration(array $contents, array $rawContents, OutputInterface $output, $k = null)
2851 {
2852 $origK = $k;
2853 $io = $this->getIO();
2854 foreach ($contents as $key => $value) {
2855 if ($k === null && !in_array($key, array('config', 'repositories'))) {
2856 continue;
2857 }
2858
2859 $rawVal = isset($rawContents[$key]) ? $rawContents[$key] : null;
2860
2861 if (is_array($value) && (!is_numeric(key($value)) || ($key === 'repositories' && null === $k))) {
2862 $k .= preg_replace('{^config\.}', '', $key . '.');
2863 $this->listConfiguration($value, $rawVal, $output, $k);
2864 $k = $origK;
2865
2866 continue;
2867 }
2868
2869 if (is_array($value)) {
2870 $value = array_map(function ($val) {
2871 return is_array($val) ? json_encode($val) : $val;
2872 }, $value);
2873
2874 $value = '['.implode(', ', $value).']';
2875 }
2876
2877 if (is_bool($value)) {
2878 $value = var_export($value, true);
2879 }
2880
2881 if (is_string($rawVal) && $rawVal != $value) {
2882 $io->write('[<comment>' . $k . $key . '</comment>] <info>' . $rawVal . ' (' . $value . ')</info>');
2883 } else {
2884 $io->write('[<comment>' . $k . $key . '</comment>] <info>' . $value . '</info>');
2885 }
2886 }
2887 }
2888 }
2889 <?php
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901 namespace Composer\Command;
2902
2903 use Composer\Config;
2904 use Composer\Factory;
2905 use Composer\Installer;
2906 use Composer\Installer\ProjectInstaller;
2907 use Composer\Installer\InstallationManager;
2908 use Composer\Installer\SuggestedPackagesReporter;
2909 use Composer\IO\IOInterface;
2910 use Composer\Package\BasePackage;
2911 use Composer\DependencyResolver\Pool;
2912 use Composer\DependencyResolver\Operation\InstallOperation;
2913 use Composer\Package\Version\VersionSelector;
2914 use Composer\Package\AliasPackage;
2915 use Composer\Repository\RepositoryFactory;
2916 use Composer\Repository\CompositeRepository;
2917 use Composer\Repository\PlatformRepository;
2918 use Composer\Repository\InstalledFilesystemRepository;
2919 use Composer\Script\ScriptEvents;
2920 use Composer\Util\Silencer;
2921 use Symfony\Component\Console\Input\InputArgument;
2922 use Symfony\Component\Console\Input\InputInterface;
2923 use Symfony\Component\Console\Input\InputOption;
2924 use Symfony\Component\Console\Output\OutputInterface;
2925 use Symfony\Component\Finder\Finder;
2926 use Composer\Json\JsonFile;
2927 use Composer\Config\JsonConfigSource;
2928 use Composer\Util\Filesystem;
2929 use Composer\Package\Version\VersionParser;
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939 class CreateProjectCommand extends BaseCommand
2940 {
2941
2942
2943
2944 protected $suggestedPackagesReporter;
2945
2946 protected function configure()
2947 {
2948 $this
2949 ->setName('create-project')
2950 ->setDescription('Create new project from a package into given directory.')
2951 ->setDefinition(array(
2952 new InputArgument('package', InputArgument::OPTIONAL, 'Package name to be installed'),
2953 new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
2954 new InputArgument('version', InputArgument::OPTIONAL, 'Version, will default to latest'),
2955 new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).'),
2956 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
2957 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
2958 new InputOption('repository', null, InputOption::VALUE_REQUIRED, 'Pick a different repository (as url or json config) to look for the package.'),
2959 new InputOption('repository-url', null, InputOption::VALUE_REQUIRED, 'DEPRECATED: Use --repository instead.'),
2960 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
2961 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
2962 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
2963 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Whether to prevent execution of all defined scripts in the root package.'),
2964 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
2965 new InputOption('no-secure-http', null, InputOption::VALUE_NONE, 'Disable the secure-http config option temporarily while installing the root package. Use at your own risk. Using this flag is a bad idea.'),
2966 new InputOption('keep-vcs', null, InputOption::VALUE_NONE, 'Whether to prevent deletion vcs folder.'),
2967 new InputOption('no-install', null, InputOption::VALUE_NONE, 'Whether to skip installation of the package dependencies.'),
2968 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
2969 ))
2970 ->setHelp(<<<EOT
2971 The <info>create-project</info> command creates a new project from a given
2972 package into a new directory. If executed without params and in a directory
2973 with a composer.json file it installs the packages for the current project.
2974
2975 You can use this command to bootstrap new projects or setup a clean
2976 version-controlled installation for developers of your project.
2977
2978 <info>php composer.phar create-project vendor/project target-directory [version]</info>
2979
2980 You can also specify the version with the package name using = or : as separator.
2981
2982 <info>php composer.phar create-project vendor/project:version target-directory</info>
2983
2984 To install unstable packages, either specify the version you want, or use the
2985 --stability=dev (where dev can be one of RC, beta, alpha or dev).
2986
2987 To setup a developer workable version you should create the project using the source
2988 controlled code by appending the <info>'--prefer-source'</info> flag.
2989
2990 To install a package from another repository than the default one you
2991 can pass the <info>'--repository=https://myrepository.org'</info> flag.
2992
2993 EOT
2994 )
2995 ;
2996 }
2997
2998 protected function execute(InputInterface $input, OutputInterface $output)
2999 {
3000 $config = Factory::createConfig();
3001 $io = $this->getIO();
3002
3003 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input, true);
3004
3005 if ($input->getOption('dev')) {
3006 $io->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
3007 }
3008 if ($input->getOption('no-custom-installers')) {
3009 $io->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
3010 $input->setOption('no-plugins', true);
3011 }
3012
3013 return $this->installProject(
3014 $io,
3015 $config,
3016 $input,
3017 $input->getArgument('package'),
3018 $input->getArgument('directory'),
3019 $input->getArgument('version'),
3020 $input->getOption('stability'),
3021 $preferSource,
3022 $preferDist,
3023 !$input->getOption('no-dev'),
3024 $input->getOption('repository') ?: $input->getOption('repository-url'),
3025 $input->getOption('no-plugins'),
3026 $input->getOption('no-scripts'),
3027 $input->getOption('keep-vcs'),
3028 $input->getOption('no-progress'),
3029 $input->getOption('no-install'),
3030 $input->getOption('ignore-platform-reqs'),
3031 !$input->getOption('no-secure-http')
3032 );
3033 }
3034
3035 public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false, $secureHttp = true)
3036 {
3037 $oldCwd = getcwd();
3038
3039
3040  $io->loadConfiguration($config);
3041
3042 $this->suggestedPackagesReporter = new SuggestedPackagesReporter($io);
3043
3044 if ($packageName !== null) {
3045 $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repository, $disablePlugins, $noScripts, $keepVcs, $noProgress, $ignorePlatformReqs, $secureHttp);
3046 } else {
3047 $installedFromVcs = false;
3048 }
3049
3050 $composer = Factory::create($io, null, $disablePlugins);
3051 $composer->getDownloadManager()->setOutputProgress(!$noProgress);
3052
3053 $fs = new Filesystem();
3054
3055 if ($noScripts === false) {
3056
3057  $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_ROOT_PACKAGE_INSTALL, $installDevPackages);
3058 }
3059
3060 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($composer->getConfig(), $input);
3061
3062
3063  if ($noInstall === false) {
3064 $installer = Installer::create($io, $composer);
3065 $installer->setPreferSource($preferSource)
3066 ->setPreferDist($preferDist)
3067 ->setDevMode($installDevPackages)
3068 ->setRunScripts(!$noScripts)
3069 ->setIgnorePlatformRequirements($ignorePlatformReqs)
3070 ->setSuggestedPackagesReporter($this->suggestedPackagesReporter);
3071
3072 if ($disablePlugins) {
3073 $installer->disablePlugins();
3074 }
3075
3076 $status = $installer->run();
3077 if (0 !== $status) {
3078 return $status;
3079 }
3080 }
3081
3082 $hasVcs = $installedFromVcs;
3083 if (!$keepVcs && $installedFromVcs
3084 && (
3085 !$io->isInteractive()
3086 || $io->askConfirmation('<info>Do you want to remove the existing VCS (.git, .svn..) history?</info> [<comment>Y,n</comment>]? ', true)
3087 )
3088 ) {
3089 $finder = new Finder();
3090 $finder->depth(0)->directories()->in(getcwd())->ignoreVCS(false)->ignoreDotFiles(false);
3091 foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg', '.fslckout', '_FOSSIL_') as $vcsName) {
3092 $finder->name($vcsName);
3093 }
3094
3095 try {
3096 $dirs = iterator_to_array($finder);
3097 unset($finder);
3098 foreach ($dirs as $dir) {
3099 if (!$fs->removeDirectory($dir)) {
3100 throw new \RuntimeException('Could not remove '.$dir);
3101 }
3102 }
3103 } catch (\Exception $e) {
3104 $io->writeError('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
3105 }
3106
3107 $hasVcs = false;
3108 }
3109
3110
3111  if (!$hasVcs) {
3112 $package = $composer->getPackage();
3113 $configSource = new JsonConfigSource(new JsonFile('composer.json'));
3114 foreach (BasePackage::$supportedLinkTypes as $type => $meta) {
3115 foreach ($package->{'get'.$meta['method']}() as $link) {
3116 if ($link->getPrettyConstraint() === 'self.version') {
3117 $configSource->addLink($type, $link->getTarget(), $package->getPrettyVersion());
3118 }
3119 }
3120 }
3121 }
3122
3123 if ($noScripts === false) {
3124
3125  $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages);
3126 }
3127
3128 chdir($oldCwd);
3129 $vendorComposerDir = $composer->getConfig()->get('vendor-dir').'/composer';
3130 if (is_dir($vendorComposerDir) && $fs->isDirEmpty($vendorComposerDir)) {
3131 Silencer::call('rmdir', $vendorComposerDir);
3132 $vendorDir = $composer->getConfig()->get('vendor-dir');
3133 if (is_dir($vendorDir) && $fs->isDirEmpty($vendorDir)) {
3134 Silencer::call('rmdir', $vendorDir);
3135 }
3136 }
3137
3138 return 0;
3139 }
3140
3141 protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $ignorePlatformReqs = false, $secureHttp = true)
3142 {
3143 if (!$secureHttp) {
3144 $config->merge(array('config' => array('secure-http' => false)));
3145 }
3146
3147 if (null === $repository) {
3148 $sourceRepo = new CompositeRepository(RepositoryFactory::defaultRepos($io, $config));
3149 } else {
3150 $sourceRepo = RepositoryFactory::fromString($io, $config, $repository, true);
3151 }
3152
3153 $parser = new VersionParser();
3154 $requirements = $parser->parseNameVersionPairs(array($packageName));
3155 $name = strtolower($requirements[0]['name']);
3156 if (!$packageVersion && isset($requirements[0]['version'])) {
3157 $packageVersion = $requirements[0]['version'];
3158 }
3159
3160 if (null === $stability) {
3161 if (preg_match('{^[^,\s]*?@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $packageVersion, $match)) {
3162 $stability = $match[1];
3163 } else {
3164 $stability = VersionParser::parseStability($packageVersion);
3165 }
3166 }
3167
3168 $stability = VersionParser::normalizeStability($stability);
3169
3170 if (!isset(BasePackage::$stabilities[$stability])) {
3171 throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::$stabilities)));
3172 }
3173
3174 $pool = new Pool($stability);
3175 $pool->addRepository($sourceRepo);
3176
3177 $phpVersion = null;
3178 $prettyPhpVersion = null;
3179 if (!$ignorePlatformReqs) {
3180 $platformOverrides = $config->get('platform') ?: array();
3181
3182  $platform = new PlatformRepository(array(), $platformOverrides);
3183 $phpPackage = $platform->findPackage('php', '*');
3184 $phpVersion = $phpPackage->getVersion();
3185 $prettyPhpVersion = $phpPackage->getPrettyVersion();
3186 }
3187
3188
3189  $versionSelector = new VersionSelector($pool);
3190 $package = $versionSelector->findBestCandidate($name, $packageVersion, $phpVersion, $stability);
3191
3192 if (!$package) {
3193 $errorMessage = "Could not find package $name with " . ($packageVersion ? "version $packageVersion" : "stability $stability");
3194 if ($phpVersion && $versionSelector->findBestCandidate($name, $packageVersion, null, $stability)) {
3195 throw new \InvalidArgumentException($errorMessage .' in a version installable using your PHP version '.$prettyPhpVersion.'.');
3196 }
3197
3198 throw new \InvalidArgumentException($errorMessage .'.');
3199 }
3200
3201 if (null === $directory) {
3202 $parts = explode("/", $name, 2);
3203 $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts);
3204 }
3205
3206
3207  if (function_exists('pcntl_signal')) {
3208 declare(ticks=100);
3209 pcntl_signal(SIGINT, function () use ($directory) {
3210 $fs = new Filesystem();
3211 $fs->removeDirectory($directory);
3212 exit(130);
3213 });
3214 }
3215
3216 $io->writeError('<info>Installing ' . $package->getName() . ' (' . $package->getFullPrettyVersion(false) . ')</info>');
3217
3218 if ($disablePlugins) {
3219 $io->writeError('<info>Plugins have been disabled.</info>');
3220 }
3221
3222 if ($package instanceof AliasPackage) {
3223 $package = $package->getAliasOf();
3224 }
3225
3226 if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) {
3227 $package->setSourceReference(substr($package->getPrettyVersion(), 4));
3228 }
3229
3230 $dm = $this->createDownloadManager($io, $config);
3231 $dm->setPreferSource($preferSource)
3232 ->setPreferDist($preferDist)
3233 ->setOutputProgress(!$noProgress);
3234
3235 $projectInstaller = new ProjectInstaller($directory, $dm);
3236 $im = $this->createInstallationManager();
3237 $im->addInstaller($projectInstaller);
3238 $im->install(new InstalledFilesystemRepository(new JsonFile('php://memory')), new InstallOperation($package));
3239 $im->notifyInstalls($io);
3240
3241
3242  $this->suggestedPackagesReporter->addSuggestionsFromPackage($package);
3243
3244 $installedFromVcs = 'source' === $package->getInstallationSource();
3245
3246 $io->writeError('<info>Created project in ' . $directory . '</info>');
3247 chdir($directory);
3248
3249 $_SERVER['COMPOSER_ROOT_VERSION'] = $package->getPrettyVersion();
3250 putenv('COMPOSER_ROOT_VERSION='.$_SERVER['COMPOSER_ROOT_VERSION']);
3251
3252 return $installedFromVcs;
3253 }
3254
3255 protected function createDownloadManager(IOInterface $io, Config $config)
3256 {
3257 $factory = new Factory();
3258
3259 return $factory->createDownloadManager($io, $config);
3260 }
3261
3262 protected function createInstallationManager()
3263 {
3264 return new InstallationManager();
3265 }
3266 }
3267 <?php
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279 namespace Composer\Command;
3280
3281 use Symfony\Component\Console\Input\InputInterface;
3282 use Symfony\Component\Console\Output\OutputInterface;
3283
3284
3285
3286
3287 class DependsCommand extends BaseDependencyCommand
3288 {
3289
3290
3291
3292 protected function configure()
3293 {
3294 parent::configure();
3295
3296 $this
3297 ->setName('depends')
3298 ->setAliases(array('why'))
3299 ->setDescription('Shows which packages cause the given package to be installed.')
3300 ->setHelp(<<<EOT
3301 Displays detailed information about where a package is referenced.
3302
3303 <info>php composer.phar depends composer/composer</info>
3304
3305 EOT
3306 )
3307 ;
3308 }
3309
3310
3311
3312
3313
3314
3315
3316
3317 protected function execute(InputInterface $input, OutputInterface $output)
3318 {
3319 return parent::doExecute($input, $output, false);
3320 }
3321 }
3322 <?php
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334 namespace Composer\Command;
3335
3336 use Composer\Composer;
3337 use Composer\Factory;
3338 use Composer\Config;
3339 use Composer\Downloader\TransportException;
3340 use Composer\Plugin\CommandEvent;
3341 use Composer\Plugin\PluginEvents;
3342 use Composer\Util\ConfigValidator;
3343 use Composer\Util\IniHelper;
3344 use Composer\Util\ProcessExecutor;
3345 use Composer\Util\RemoteFilesystem;
3346 use Composer\Util\StreamContextFactory;
3347 use Composer\SelfUpdate\Keys;
3348 use Composer\SelfUpdate\Versions;
3349 use Composer\IO\NullIO;
3350 use Symfony\Component\Console\Input\InputInterface;
3351 use Symfony\Component\Console\Output\OutputInterface;
3352
3353
3354
3355
3356 class DiagnoseCommand extends BaseCommand
3357 {
3358
3359 protected $rfs;
3360
3361
3362 protected $process;
3363
3364
3365 protected $exitCode = 0;
3366
3367 protected function configure()
3368 {
3369 $this
3370 ->setName('diagnose')
3371 ->setDescription('Diagnoses the system to identify common errors.')
3372 ->setHelp(<<<EOT
3373 The <info>diagnose</info> command checks common errors to help debugging problems.
3374
3375 The process exit code will be 1 in case of warnings and 2 for errors.
3376
3377 EOT
3378 )
3379 ;
3380 }
3381
3382
3383
3384
3385 protected function execute(InputInterface $input, OutputInterface $output)
3386 {
3387 $composer = $this->getComposer(false);
3388 $io = $this->getIO();
3389
3390 if ($composer) {
3391 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'diagnose', $input, $output);
3392 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
3393
3394 $io->write('Checking composer.json: ', false);
3395 $this->outputResult($this->checkComposerSchema());
3396 }
3397
3398 if ($composer) {
3399 $config = $composer->getConfig();
3400 } else {
3401 $config = Factory::createConfig();
3402 }
3403
3404 $config->merge(array('config' => array('secure-http' => false)));
3405 $config->prohibitUrlByConfig('http://packagist.org', new NullIO);
3406
3407 $this->rfs = Factory::createRemoteFilesystem($io, $config);
3408 $this->process = new ProcessExecutor($io);
3409
3410 $io->write('Checking platform settings: ', false);
3411 $this->outputResult($this->checkPlatform());
3412
3413 $io->write('Checking git settings: ', false);
3414 $this->outputResult($this->checkGit());
3415
3416 $io->write('Checking http connectivity to packagist: ', false);
3417 $this->outputResult($this->checkHttp('http', $config));
3418
3419 $io->write('Checking https connectivity to packagist: ', false);
3420 $this->outputResult($this->checkHttp('https', $config));
3421
3422 $opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org'));
3423 if (!empty($opts['http']['proxy'])) {
3424 $io->write('Checking HTTP proxy: ', false);
3425 $this->outputResult($this->checkHttpProxy());
3426 $io->write('Checking HTTP proxy support for request_fulluri: ', false);
3427 $this->outputResult($this->checkHttpProxyFullUriRequestParam());
3428 $io->write('Checking HTTPS proxy support for request_fulluri: ', false);
3429 $this->outputResult($this->checkHttpsProxyFullUriRequestParam());
3430 }
3431
3432 if ($oauth = $config->get('github-oauth')) {
3433 foreach ($oauth as $domain => $token) {
3434 $io->write('Checking '.$domain.' oauth access: ', false);
3435 $this->outputResult($this->checkGithubOauth($domain, $token));
3436 }
3437 } else {
3438 $io->write('Checking github.com rate limit: ', false);
3439 try {
3440 $rate = $this->getGithubRateLimit('github.com');
3441 $this->outputResult(true);
3442 if (10 > $rate['remaining']) {
3443 $io->write('<warning>WARNING</warning>');
3444 $io->write(sprintf(
3445 '<comment>Github has a rate limit on their API. '
3446 . 'You currently have <options=bold>%u</options=bold> '
3447 . 'out of <options=bold>%u</options=bold> requests left.' . PHP_EOL
3448 . 'See https://developer.github.com/v3/#rate-limiting and also' . PHP_EOL
3449 . '    https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens</comment>',
3450 $rate['remaining'],
3451 $rate['limit']
3452 ));
3453 }
3454 } catch (\Exception $e) {
3455 if ($e instanceof TransportException && $e->getCode() === 401) {
3456 $this->outputResult('<comment>The oauth token for github.com seems invalid, run "composer config --global --unset github-oauth.github.com" to remove it</comment>');
3457 } else {
3458 $this->outputResult($e);
3459 }
3460 }
3461 }
3462
3463 $io->write('Checking disk free space: ', false);
3464 $this->outputResult($this->checkDiskSpace($config));
3465
3466 if ('phar:' === substr(__FILE__, 0, 5)) {
3467 $io->write('Checking pubkeys: ', false);
3468 $this->outputResult($this->checkPubKeys($config));
3469
3470 $io->write('Checking composer version: ', false);
3471 $this->outputResult($this->checkVersion($config));
3472 }
3473
3474 return $this->exitCode;
3475 }
3476
3477 private function checkComposerSchema()
3478 {
3479 $validator = new ConfigValidator($this->getIO());
3480 list($errors, , $warnings) = $validator->validate(Factory::getComposerFile());
3481
3482 if ($errors || $warnings) {
3483 $messages = array(
3484 'error' => $errors,
3485 'warning' => $warnings,
3486 );
3487
3488 $output = '';
3489 foreach ($messages as $style => $msgs) {
3490 foreach ($msgs as $msg) {
3491 $output .= '<' . $style . '>' . $msg . '</' . $style . '>' . PHP_EOL;
3492 }
3493 }
3494
3495 return rtrim($output);
3496 }
3497
3498 return true;
3499 }
3500
3501 private function checkGit()
3502 {
3503 $this->process->execute('git config color.ui', $output);
3504 if (strtolower(trim($output)) === 'always') {
3505 return '<comment>Your git color.ui setting is set to always, this is known to create issues. Use "git config --global color.ui true" to set it correctly.</comment>';
3506 }
3507
3508 return true;
3509 }
3510
3511 private function checkHttp($proto, Config $config)
3512 {
3513 $disableTls = false;
3514 $result = array();
3515 if ($proto === 'https' && $config->get('disable-tls') === true) {
3516 $disableTls = true;
3517 $result[] = '<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>';
3518 }
3519 if ($proto === 'https' && !extension_loaded('openssl') && !$disableTls) {
3520 $result[] = '<error>Composer is configured to use SSL/TLS protection but the openssl extension is not available.</error>';
3521 }
3522
3523 try {
3524 $this->rfs->getContents('packagist.org', $proto . '://packagist.org/packages.json', false);
3525 } catch (TransportException $e) {
3526 if (false !== strpos($e->getMessage(), 'cafile')) {
3527 $result[] = '<error>[' . get_class($e) . '] ' . $e->getMessage() . '</error>';
3528 $result[] = '<error>Unable to locate a valid CA certificate file. You must set a valid \'cafile\' option.</error>';
3529 $result[] = '<error>You can alternatively disable this error, at your own risk, by enabling the \'disable-tls\' option.</error>';
3530 } else {
3531 array_unshift($result, '[' . get_class($e) . '] ' . $e->getMessage());
3532 }
3533 }
3534
3535 if (count($result) > 0) {
3536 return $result;
3537 }
3538
3539 return true;
3540 }
3541
3542 private function checkHttpProxy()
3543 {
3544 $protocol = extension_loaded('openssl') ? 'https' : 'http';
3545 try {
3546 $json = json_decode($this->rfs->getContents('packagist.org', $protocol . '://packagist.org/packages.json', false), true);
3547 $hash = reset($json['provider-includes']);
3548 $hash = $hash['sha256'];
3549 $path = str_replace('%hash%', $hash, key($json['provider-includes']));
3550 $provider = $this->rfs->getContents('packagist.org', $protocol . '://packagist.org/'.$path, false);
3551
3552 if (hash('sha256', $provider) !== $hash) {
3553 return 'It seems that your proxy is modifying http traffic on the fly';
3554 }
3555 } catch (\Exception $e) {
3556 return $e;
3557 }
3558
3559 return true;
3560 }
3561
3562
3563
3564
3565
3566
3567
3568
3569 private function checkHttpProxyFullUriRequestParam()
3570 {
3571 $url = 'http://packagist.org/packages.json';
3572 try {
3573 $this->rfs->getContents('packagist.org', $url, false);
3574 } catch (TransportException $e) {
3575 try {
3576 $this->rfs->getContents('packagist.org', $url, false, array('http' => array('request_fulluri' => false)));
3577 } catch (TransportException $e) {
3578 return 'Unable to assess the situation, maybe packagist.org is down ('.$e->getMessage().')';
3579 }
3580
3581 return 'It seems there is a problem with your proxy server, try setting the "HTTP_PROXY_REQUEST_FULLURI" and "HTTPS_PROXY_REQUEST_FULLURI" environment variables to "false"';
3582 }
3583
3584 return true;
3585 }
3586
3587
3588
3589
3590
3591
3592
3593
3594 private function checkHttpsProxyFullUriRequestParam()
3595 {
3596 if (!extension_loaded('openssl')) {
3597 return 'You need the openssl extension installed for this check';
3598 }
3599
3600 $url = 'https://api.github.com/repos/Seldaek/jsonlint/zipball/1.0.0';
3601 try {
3602 $this->rfs->getContents('github.com', $url, false);
3603 } catch (TransportException $e) {
3604 try {
3605 $this->rfs->getContents('github.com', $url, false, array('http' => array('request_fulluri' => false)));
3606 } catch (TransportException $e) {
3607 return 'Unable to assess the situation, maybe github is down ('.$e->getMessage().')';
3608 }
3609
3610 return 'It seems there is a problem with your proxy server, try setting the "HTTPS_PROXY_REQUEST_FULLURI" environment variable to "false"';
3611 }
3612
3613 return true;
3614 }
3615
3616 private function checkGithubOauth($domain, $token)
3617 {
3618 $this->getIO()->setAuthentication($domain, $token, 'x-oauth-basic');
3619 try {
3620 $url = $domain === 'github.com' ? 'https://api.'.$domain.'/' : 'https://'.$domain.'/api/v3/';
3621
3622 return $this->rfs->getContents($domain, $url, false, array(
3623 'retry-auth-failure' => false,
3624 )) ? true : 'Unexpected error';
3625 } catch (\Exception $e) {
3626 if ($e instanceof TransportException && $e->getCode() === 401) {
3627 return '<comment>The oauth token for '.$domain.' seems invalid, run "composer config --global --unset github-oauth.'.$domain.'" to remove it</comment>';
3628 }
3629
3630 return $e;
3631 }
3632 }
3633
3634
3635
3636
3637
3638
3639
3640 private function getGithubRateLimit($domain, $token = null)
3641 {
3642 if ($token) {
3643 $this->getIO()->setAuthentication($domain, $token, 'x-oauth-basic');
3644 }
3645
3646 $url = $domain === 'github.com' ? 'https://api.'.$domain.'/rate_limit' : 'https://'.$domain.'/api/rate_limit';
3647 $json = $this->rfs->getContents($domain, $url, false, array('retry-auth-failure' => false));
3648 $data = json_decode($json, true);
3649
3650 return $data['resources']['core'];
3651 }
3652
3653 private function checkDiskSpace($config)
3654 {
3655 $minSpaceFree = 1024 * 1024;
3656 if ((($df = @disk_free_space($dir = $config->get('home'))) !== false && $df < $minSpaceFree)
3657 || (($df = @disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree)
3658 ) {
3659 return '<error>The disk hosting '.$dir.' is full</error>';
3660 }
3661
3662 return true;
3663 }
3664
3665 private function checkPubKeys($config)
3666 {
3667 $home = $config->get('home');
3668 $errors = array();
3669 $io = $this->getIO();
3670
3671 if (file_exists($home.'/keys.tags.pub') && file_exists($home.'/keys.dev.pub')) {
3672 $io->write('');
3673 }
3674
3675 if (file_exists($home.'/keys.tags.pub')) {
3676 $io->write('Tags Public Key Fingerprint: ' . Keys::fingerprint($home.'/keys.tags.pub'));
3677 } else {
3678 $errors[] = '<error>Missing pubkey for tags verification</error>';
3679 }
3680
3681 if (file_exists($home.'/keys.dev.pub')) {
3682 $io->write('Dev Public Key Fingerprint: ' . Keys::fingerprint($home.'/keys.dev.pub'));
3683 } else {
3684 $errors[] = '<error>Missing pubkey for dev verification</error>';
3685 }
3686
3687 if ($errors) {
3688 $errors[] = '<error>Run composer self-update --update-keys to set them up</error>';
3689 }
3690
3691 return $errors ?: true;
3692 }
3693
3694 private function checkVersion($config)
3695 {
3696 $versionsUtil = new Versions($config, $this->rfs);
3697 $latest = $versionsUtil->getLatest();
3698
3699 if (Composer::VERSION !== $latest['version'] && Composer::VERSION !== '@package_version@') {
3700 return '<comment>You are not running the latest '.$versionsUtil->getChannel().' version, run `composer self-update` to update ('.Composer::VERSION.' => '.$latest['version'].')</comment>';
3701 }
3702
3703 return true;
3704 }
3705
3706
3707
3708
3709 private function outputResult($result)
3710 {
3711 $io = $this->getIO();
3712 if (true === $result) {
3713 $io->write('<info>OK</info>');
3714
3715 return;
3716 }
3717
3718 $hadError = false;
3719 if ($result instanceof \Exception) {
3720 $result = '<error>['.get_class($result).'] '.$result->getMessage().'</error>';
3721 }
3722
3723 if (!$result) {
3724
3725  $hadError = true;
3726 } else {
3727 if (!is_array($result)) {
3728 $result = array($result);
3729 }
3730 foreach ($result as $message) {
3731 if (false !== strpos($message, '<error>')) {
3732 $hadError = true;
3733 }
3734 }
3735 }
3736
3737 if ($hadError) {
3738 $io->write('<error>FAIL</error>');
3739 $this->exitCode = 2;
3740 } else {
3741 $io->write('<warning>WARNING</warning>');
3742 $this->exitCode = 1;
3743 }
3744
3745 if ($result) {
3746 foreach ($result as $message) {
3747 $io->write($message);
3748 }
3749 }
3750 }
3751
3752 private function checkPlatform()
3753 {
3754 $output = '';
3755 $out = function ($msg, $style) use (&$output) {
3756 $output .= '<'.$style.'>'.$msg.'</'.$style.'>'.PHP_EOL;
3757 };
3758
3759
3760  $errors = array();
3761 $warnings = array();
3762 $displayIniMessage = false;
3763
3764 $iniMessage = PHP_EOL.PHP_EOL.IniHelper::getMessage();
3765 $iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
3766
3767 if (!function_exists('json_decode')) {
3768 $errors['json'] = true;
3769 }
3770
3771 if (!extension_loaded('Phar')) {
3772 $errors['phar'] = true;
3773 }
3774
3775 if (!extension_loaded('filter')) {
3776 $errors['filter'] = true;
3777 }
3778
3779 if (!extension_loaded('hash')) {
3780 $errors['hash'] = true;
3781 }
3782
3783 if (!extension_loaded('iconv') && !extension_loaded('mbstring')) {
3784 $errors['iconv_mbstring'] = true;
3785 }
3786
3787 if (!ini_get('allow_url_fopen')) {
3788 $errors['allow_url_fopen'] = true;
3789 }
3790
3791 if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() < 40009) {
3792 $errors['ioncube'] = ioncube_loader_version();
3793 }
3794
3795 if (PHP_VERSION_ID < 50302) {
3796 $errors['php'] = PHP_VERSION;
3797 }
3798
3799 if (!isset($errors['php']) && PHP_VERSION_ID < 50304) {
3800 $warnings['php'] = PHP_VERSION;
3801 }
3802
3803 if (!extension_loaded('openssl')) {
3804 $errors['openssl'] = true;
3805 }
3806
3807 if (extension_loaded('openssl') && OPENSSL_VERSION_NUMBER < 0x1000100f) {
3808 $warnings['openssl_version'] = true;
3809 }
3810
3811 if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
3812 $warnings['apc_cli'] = true;
3813 }
3814
3815 if (!extension_loaded('zlib')) {
3816 $warnings['zlib'] = true;
3817 }
3818
3819 ob_start();
3820 phpinfo(INFO_GENERAL);
3821 $phpinfo = ob_get_clean();
3822 if (preg_match('{Configure Command(?: *</td><td class="v">| *=> *)(.*?)(?:</td>|$)}m', $phpinfo, $match)) {
3823 $configure = $match[1];
3824
3825 if (false !== strpos($configure, '--enable-sigchild')) {
3826 $warnings['sigchild'] = true;
3827 }
3828
3829 if (false !== strpos($configure, '--with-curlwrappers')) {
3830 $warnings['curlwrappers'] = true;
3831 }
3832 }
3833
3834 if (ini_get('xdebug.profiler_enabled')) {
3835 $warnings['xdebug_profile'] = true;
3836 } elseif (extension_loaded('xdebug')) {
3837 $warnings['xdebug_loaded'] = true;
3838 }
3839
3840 if (!empty($errors)) {
3841 foreach ($errors as $error => $current) {
3842 switch ($error) {
3843 case 'json':
3844 $text = PHP_EOL."The json extension is missing.".PHP_EOL;
3845 $text .= "Install it or recompile php without --disable-json";
3846 break;
3847
3848 case 'phar':
3849 $text = PHP_EOL."The phar extension is missing.".PHP_EOL;
3850 $text .= "Install it or recompile php without --disable-phar";
3851 break;
3852
3853 case 'filter':
3854 $text = PHP_EOL."The filter extension is missing.".PHP_EOL;
3855 $text .= "Install it or recompile php without --disable-filter";
3856 break;
3857
3858 case 'hash':
3859 $text = PHP_EOL."The hash extension is missing.".PHP_EOL;
3860 $text .= "Install it or recompile php without --disable-hash";
3861 break;
3862
3863 case 'iconv_mbstring':
3864 $text = PHP_EOL."The iconv OR mbstring extension is required and both are missing.".PHP_EOL;
3865 $text .= "Install either of them or recompile php without --disable-iconv";
3866 break;
3867
3868 case 'unicode':
3869 $text = PHP_EOL."The detect_unicode setting must be disabled.".PHP_EOL;
3870 $text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
3871 $text .= "    detect_unicode = Off";
3872 $displayIniMessage = true;
3873 break;
3874
3875 case 'suhosin':
3876 $text = PHP_EOL."The suhosin.executor.include.whitelist setting is incorrect.".PHP_EOL;
3877 $text .= "Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):".PHP_EOL;
3878 $text .= "    suhosin.executor.include.whitelist = phar ".$current;
3879 $displayIniMessage = true;
3880 break;
3881
3882 case 'php':
3883 $text = PHP_EOL."Your PHP ({$current}) is too old, you must upgrade to PHP 5.3.2 or higher.";
3884 break;
3885
3886 case 'allow_url_fopen':
3887 $text = PHP_EOL."The allow_url_fopen setting is incorrect.".PHP_EOL;
3888 $text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
3889 $text .= "    allow_url_fopen = On";
3890 $displayIniMessage = true;
3891 break;
3892
3893 case 'ioncube':
3894 $text = PHP_EOL."Your ionCube Loader extension ($current) is incompatible with Phar files.".PHP_EOL;
3895 $text .= "Upgrade to ionCube 4.0.9 or higher or remove this line (path may be different) from your `php.ini` to disable it:".PHP_EOL;
3896 $text .= "    zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so";
3897 $displayIniMessage = true;
3898 break;
3899
3900 case 'openssl':
3901 $text = PHP_EOL."The openssl extension is missing, which means that secure HTTPS transfers are impossible.".PHP_EOL;
3902 $text .= "If possible you should enable it or recompile php with --with-openssl";
3903 break;
3904 }
3905 $out($text, 'error');
3906 }
3907
3908 $output .= PHP_EOL;
3909 }
3910
3911 if (!empty($warnings)) {
3912 foreach ($warnings as $warning => $current) {
3913 switch ($warning) {
3914 case 'apc_cli':
3915 $text = "The apc.enable_cli setting is incorrect.".PHP_EOL;
3916 $text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
3917 $text .= "  apc.enable_cli = Off";
3918 $displayIniMessage = true;
3919 break;
3920
3921 case 'zlib':
3922 $text = 'The zlib extension is not loaded, this can slow down Composer a lot.'.PHP_EOL;
3923 $text .= 'If possible, enable it or recompile php with --with-zlib'.PHP_EOL;
3924 $displayIniMessage = true;
3925 break;
3926
3927 case 'sigchild':
3928 $text = "PHP was compiled with --enable-sigchild which can cause issues on some platforms.".PHP_EOL;
3929 $text .= "Recompile it without this flag if possible, see also:".PHP_EOL;
3930 $text .= "  https://bugs.php.net/bug.php?id=22999";
3931 break;
3932
3933 case 'curlwrappers':
3934 $text = "PHP was compiled with --with-curlwrappers which will cause issues with HTTP authentication and GitHub.".PHP_EOL;
3935 $text .= " Recompile it without this flag if possible";
3936 break;
3937
3938 case 'php':
3939 $text = "Your PHP ({$current}) is quite old, upgrading to PHP 5.3.4 or higher is recommended.".PHP_EOL;
3940 $text .= " Composer works with 5.3.2+ for most people, but there might be edge case issues.";
3941 break;
3942
3943 case 'openssl_version':
3944
3945  $opensslVersion = strstr(trim(strstr(OPENSSL_VERSION_TEXT, ' ')), ' ', true);
3946 $opensslVersion = $opensslVersion ?: OPENSSL_VERSION_TEXT;
3947
3948 $text = "The OpenSSL library ({$opensslVersion}) used by PHP does not support TLSv1.2 or TLSv1.1.".PHP_EOL;
3949 $text .= "If possible you should upgrade OpenSSL to version 1.0.1 or above.";
3950 break;
3951
3952 case 'xdebug_loaded':
3953 $text = "The xdebug extension is loaded, this can slow down Composer a little.".PHP_EOL;
3954 $text .= " Disabling it when using Composer is recommended.";
3955 break;
3956
3957 case 'xdebug_profile':
3958 $text = "The xdebug.profiler_enabled setting is enabled, this can slow down Composer a lot.".PHP_EOL;
3959 $text .= "Add the following to the end of your `php.ini` to disable it:".PHP_EOL;
3960 $text .= "  xdebug.profiler_enabled = 0";
3961 $displayIniMessage = true;
3962 break;
3963 }
3964 $out($text, 'comment');
3965 }
3966 }
3967
3968 if ($displayIniMessage) {
3969 $out($iniMessage, 'comment');
3970 }
3971
3972 return !$warnings && !$errors ? true : $output;
3973 }
3974 }
3975 <?php
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987 namespace Composer\Command;
3988
3989 use Composer\Plugin\CommandEvent;
3990 use Composer\Plugin\PluginEvents;
3991 use Symfony\Component\Console\Input\InputInterface;
3992 use Symfony\Component\Console\Input\InputOption;
3993 use Symfony\Component\Console\Output\OutputInterface;
3994
3995
3996
3997
3998 class DumpAutoloadCommand extends BaseCommand
3999 {
4000 protected function configure()
4001 {
4002 $this
4003 ->setName('dump-autoload')
4004 ->setAliases(array('dumpautoload'))
4005 ->setDescription('Dumps the autoloader.')
4006 ->setDefinition(array(
4007 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
4008 new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'),
4009 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize`.'),
4010 new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
4011 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables autoload-dev rules.'),
4012 ))
4013 ->setHelp(<<<EOT
4014 <info>php composer.phar dump-autoload</info>
4015 EOT
4016 )
4017 ;
4018 }
4019
4020 protected function execute(InputInterface $input, OutputInterface $output)
4021 {
4022 $composer = $this->getComposer();
4023
4024 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'dump-autoload', $input, $output);
4025 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
4026
4027 $installationManager = $composer->getInstallationManager();
4028 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
4029 $package = $composer->getPackage();
4030 $config = $composer->getConfig();
4031
4032 $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader');
4033 $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
4034 $apcu = $input->getOption('apcu') || $config->get('apcu-autoloader');
4035
4036 if ($optimize || $authoritative) {
4037 $this->getIO()->writeError('<info>Generating optimized autoload files</info>');
4038 } else {
4039 $this->getIO()->writeError('<info>Generating autoload files</info>');
4040 }
4041
4042 $generator = $composer->getAutoloadGenerator();
4043 $generator->setDevMode(!$input->getOption('no-dev'));
4044 $generator->setClassMapAuthoritative($authoritative);
4045 $generator->setApcu($apcu);
4046 $generator->setRunScripts(!$input->getOption('no-scripts'));
4047 $generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize);
4048 }
4049 }
4050 <?php
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062 namespace Composer\Command;
4063
4064 use Symfony\Component\Console\Input\InputInterface;
4065 use Symfony\Component\Console\Input\InputOption;
4066 use Symfony\Component\Console\Output\OutputInterface;
4067 use Symfony\Component\Console\Input\InputArgument;
4068
4069
4070
4071
4072 class ExecCommand extends BaseCommand
4073 {
4074 protected function configure()
4075 {
4076 $this
4077 ->setName('exec')
4078 ->setDescription('Execute a vendored binary/script.')
4079 ->setDefinition(array(
4080 new InputOption('list', 'l', InputOption::VALUE_NONE),
4081 new InputArgument('binary', InputArgument::OPTIONAL, 'The binary to run, e.g. phpunit'),
4082 new InputArgument(
4083 'args',
4084 InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
4085 'Arguments to pass to the binary. Use <info>--</info> to separate from composer arguments'
4086 ),
4087 ))
4088 ;
4089 }
4090
4091 protected function execute(InputInterface $input, OutputInterface $output)
4092 {
4093 $composer = $this->getComposer();
4094 $binDir = $composer->getConfig()->get('bin-dir');
4095 if ($input->getOption('list') || !$input->getArgument('binary')) {
4096 $bins = glob($binDir . '/*');
4097 $bins = array_merge($bins, array_map(function ($e) {
4098 return "$e (local)";
4099 }, $composer->getPackage()->getBinaries()));
4100
4101 if (!$bins) {
4102 throw new \RuntimeException("No binaries found in composer.json or in bin-dir ($binDir)");
4103 }
4104
4105 $this->getIO()->write(<<<EOT
4106 <comment>Available binaries:</comment>
4107 EOT
4108 );
4109
4110 foreach ($bins as $bin) {
4111
4112  if (isset($previousBin) && $bin === $previousBin.'.bat') {
4113 continue;
4114 }
4115
4116 $previousBin = $bin;
4117 $bin = basename($bin);
4118 $this->getIO()->write(<<<EOT
4119 <info>- $bin</info>
4120 EOT
4121 );
4122 }
4123
4124 return 0;
4125 }
4126
4127 $binary = $input->getArgument('binary');
4128
4129 $dispatcher = $composer->getEventDispatcher();
4130 $dispatcher->addListener('__exec_command', $binary);
4131 if ($output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL) {
4132 $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
4133 }
4134
4135 return $dispatcher->dispatchScript('__exec_command', true, $input->getArgument('args'));
4136 }
4137 }
4138 <?php
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150 namespace Composer\Command;
4151
4152 use Composer\Factory;
4153 use Symfony\Component\Console\Input\InputInterface;
4154 use Symfony\Component\Console\Input\InputArgument;
4155 use Symfony\Component\Console\Input\StringInput;
4156 use Symfony\Component\Console\Output\OutputInterface;
4157
4158
4159
4160
4161 class GlobalCommand extends BaseCommand
4162 {
4163 protected function configure()
4164 {
4165 $this
4166 ->setName('global')
4167 ->setDescription('Allows running commands in the global composer dir ($COMPOSER_HOME).')
4168 ->setDefinition(array(
4169 new InputArgument('command-name', InputArgument::REQUIRED, ''),
4170 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
4171 ))
4172 ->setHelp(<<<EOT
4173 Use this command as a wrapper to run other Composer commands
4174 within the global context of COMPOSER_HOME.
4175
4176 You can use this to install CLI utilities globally, all you need
4177 is to add the COMPOSER_HOME/vendor/bin dir to your PATH env var.
4178
4179 COMPOSER_HOME is c:\Users\<user>\AppData\Roaming\Composer on Windows
4180 and /home/<user>/.composer on unix systems.
4181
4182 If your system uses freedesktop.org standards, then it will first check
4183 XDG_CONFIG_HOME or default to /home/<user>/.config/composer
4184
4185 Note: This path may vary depending on customizations to bin-dir in
4186 composer.json or the environmental variable COMPOSER_BIN_DIR.
4187
4188 EOT
4189 )
4190 ;
4191 }
4192
4193 public function run(InputInterface $input, OutputInterface $output)
4194 {
4195
4196  $tokens = preg_split('{\s+}', $input->__toString());
4197 $args = array();
4198 foreach ($tokens as $token) {
4199 if ($token && $token[0] !== '-') {
4200 $args[] = $token;
4201 if (count($args) >= 2) {
4202 break;
4203 }
4204 }
4205 }
4206
4207
4208  if (count($args) < 2) {
4209 return parent::run($input, $output);
4210 }
4211
4212
4213  $config = Factory::createConfig();
4214 chdir($config->get('home'));
4215 $this->getIO()->writeError('<info>Changed current directory to '.$config->get('home').'</info>');
4216
4217
4218  $input = new StringInput(preg_replace('{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}', '', $input->__toString(), 1));
4219 $this->getApplication()->resetComposer();
4220
4221 return $this->getApplication()->run($input, $output);
4222 }
4223
4224
4225
4226
4227 public function isProxyCommand()
4228 {
4229 return true;
4230 }
4231 }
4232 <?php
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244 namespace Composer\Command;
4245
4246 use Composer\Package\CompletePackageInterface;
4247 use Composer\Repository\RepositoryInterface;
4248 use Composer\Repository\ArrayRepository;
4249 use Composer\Repository\RepositoryFactory;
4250 use Composer\Util\Platform;
4251 use Composer\Util\ProcessExecutor;
4252 use Symfony\Component\Console\Input\InputArgument;
4253 use Symfony\Component\Console\Input\InputOption;
4254 use Symfony\Component\Console\Input\InputInterface;
4255 use Symfony\Component\Console\Output\OutputInterface;
4256
4257
4258
4259
4260 class HomeCommand extends BaseCommand
4261 {
4262
4263
4264
4265 protected function configure()
4266 {
4267 $this
4268 ->setName('browse')
4269 ->setAliases(array('home'))
4270 ->setDescription('Opens the package\'s repository URL or homepage in your browser.')
4271 ->setDefinition(array(
4272 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Package(s) to browse to.'),
4273 new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'),
4274 new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'),
4275 ))
4276 ->setHelp(<<<EOT
4277 The home command opens or shows a package's repository URL or
4278 homepage in your default browser.
4279
4280 To open the homepage by default, use -H or --homepage.
4281 To show instead of open the repository or homepage URL, use -s or --show.
4282 EOT
4283 );
4284 }
4285
4286
4287
4288
4289 protected function execute(InputInterface $input, OutputInterface $output)
4290 {
4291 $repos = $this->initializeRepos();
4292 $io = $this->getIO();
4293 $return = 0;
4294
4295 foreach ($input->getArgument('packages') as $packageName) {
4296 $handled = false;
4297 $packageExists = false;
4298 foreach ($repos as $repo) {
4299 foreach ($repo->findPackages($packageName) as $package) {
4300 $packageExists = true;
4301 if ($package instanceof CompletePackageInterface && $this->handlePackage($package, $input->getOption('homepage'), $input->getOption('show'))) {
4302 $handled = true;
4303 break 2;
4304 }
4305 }
4306 }
4307
4308 if (!$packageExists) {
4309 $return = 1;
4310 $io->writeError('<warning>Package '.$packageName.' not found</warning>');
4311 }
4312
4313 if (!$handled) {
4314 $return = 1;
4315 $io->writeError('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
4316 }
4317 }
4318
4319 return $return;
4320 }
4321
4322 private function handlePackage(CompletePackageInterface $package, $showHomepage, $showOnly)
4323 {
4324 $support = $package->getSupport();
4325 $url = isset($support['source']) ? $support['source'] : $package->getSourceUrl();
4326 if (!$url || $showHomepage) {
4327 $url = $package->getHomepage();
4328 }
4329
4330 if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
4331 return false;
4332 }
4333
4334 if ($showOnly) {
4335 $this->getIO()->write(sprintf('<info>%s</info>', $url));
4336 } else {
4337 $this->openBrowser($url);
4338 }
4339
4340 return true;
4341 }
4342
4343
4344
4345
4346
4347
4348 private function openBrowser($url)
4349 {
4350 $url = ProcessExecutor::escape($url);
4351
4352 $process = new ProcessExecutor($this->getIO());
4353 if (Platform::isWindows()) {
4354 return $process->execute('start "web" explorer "' . $url . '"', $output);
4355 }
4356
4357 $linux = $process->execute('which xdg-open', $output);
4358 $osx = $process->execute('which open', $output);
4359
4360 if (0 === $linux) {
4361 $process->execute('xdg-open ' . $url, $output);
4362 } elseif (0 === $osx) {
4363 $process->execute('open ' . $url, $output);
4364 } else {
4365 $this->getIO()->writeError('No suitable browser opening command found, open yourself: ' . $url);
4366 }
4367 }
4368
4369
4370
4371
4372
4373
4374
4375
4376 private function initializeRepos()
4377 {
4378 $composer = $this->getComposer(false);
4379
4380 if ($composer) {
4381 return array_merge(
4382 array(new ArrayRepository(array($composer->getPackage()))), 
4383  array($composer->getRepositoryManager()->getLocalRepository()), 
4384  $composer->getRepositoryManager()->getRepositories() 
4385  );
4386 }
4387
4388 return RepositoryFactory::defaultRepos($this->getIO());
4389 }
4390 }
4391 <?php
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403 namespace Composer\Command;
4404
4405 use Composer\DependencyResolver\Pool;
4406 use Composer\Json\JsonFile;
4407 use Composer\Factory;
4408 use Composer\Repository\RepositoryFactory;
4409 use Composer\Package\BasePackage;
4410 use Composer\Package\Version\VersionParser;
4411 use Composer\Package\Version\VersionSelector;
4412 use Composer\Repository\CompositeRepository;
4413 use Composer\Repository\PlatformRepository;
4414 use Composer\Util\ProcessExecutor;
4415 use Symfony\Component\Console\Input\InputInterface;
4416 use Symfony\Component\Console\Input\InputOption;
4417 use Symfony\Component\Console\Output\OutputInterface;
4418 use Symfony\Component\Process\Process;
4419 use Symfony\Component\Process\ExecutableFinder;
4420
4421
4422
4423
4424
4425 class InitCommand extends BaseCommand
4426 {
4427
4428 protected $repos;
4429
4430
4431 private $gitConfig;
4432
4433
4434 private $pool;
4435
4436
4437
4438
4439 protected function configure()
4440 {
4441 $this
4442 ->setName('init')
4443 ->setDescription('Creates a basic composer.json file in current directory.')
4444 ->setDefinition(array(
4445 new InputOption('name', null, InputOption::VALUE_REQUIRED, 'Name of the package'),
4446 new InputOption('description', null, InputOption::VALUE_REQUIRED, 'Description of package'),
4447 new InputOption('author', null, InputOption::VALUE_REQUIRED, 'Author name of package'),
4448
4449  new InputOption('type', null, InputOption::VALUE_OPTIONAL, 'Type of package (e.g. library, project, metapackage, composer-plugin)'),
4450 new InputOption('homepage', null, InputOption::VALUE_REQUIRED, 'Homepage of package'),
4451 new InputOption('require', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
4452 new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
4453 new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::$stabilities)).')'),
4454 new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'),
4455 new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories, either by URL or using JSON arrays'),
4456 ))
4457 ->setHelp(<<<EOT
4458 The <info>init</info> command creates a basic composer.json file
4459 in the current directory.
4460
4461 <info>php composer.phar init</info>
4462
4463 EOT
4464 )
4465 ;
4466 }
4467
4468
4469
4470
4471 protected function execute(InputInterface $input, OutputInterface $output)
4472 {
4473 $io = $this->getIO();
4474
4475 $whitelist = array('name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license');
4476 $options = array_filter(array_intersect_key($input->getOptions(), array_flip($whitelist)));
4477
4478 if (isset($options['author'])) {
4479 $options['authors'] = $this->formatAuthors($options['author']);
4480 unset($options['author']);
4481 }
4482
4483 $repositories = $input->getOption('repository');
4484 if ($repositories) {
4485 $config = Factory::createConfig($io);
4486 foreach ($repositories as $repo) {
4487 $options['repositories'][] = RepositoryFactory::configFromString($io, $config, $repo);
4488 }
4489 }
4490
4491 if (isset($options['stability'])) {
4492 $options['minimum-stability'] = $options['stability'];
4493 unset($options['stability']);
4494 }
4495
4496 $options['require'] = isset($options['require']) ? $this->formatRequirements($options['require']) : new \stdClass;
4497 if (array() === $options['require']) {
4498 $options['require'] = new \stdClass;
4499 }
4500
4501 if (isset($options['require-dev'])) {
4502 $options['require-dev'] = $this->formatRequirements($options['require-dev']);
4503 if (array() === $options['require-dev']) {
4504 $options['require-dev'] = new \stdClass;
4505 }
4506 }
4507
4508 $file = new JsonFile(Factory::getComposerFile());
4509 $json = $file->encode($options);
4510
4511 if ($input->isInteractive()) {
4512 $io->writeError(array('', $json, ''));
4513 if (!$io->askConfirmation('Do you confirm generation [<comment>yes</comment>]? ', true)) {
4514 $io->writeError('<error>Command aborted</error>');
4515
4516 return 1;
4517 }
4518 }
4519
4520 $file->write($options);
4521
4522 if ($input->isInteractive() && is_dir('.git')) {
4523 $ignoreFile = realpath('.gitignore');
4524
4525 if (false === $ignoreFile) {
4526 $ignoreFile = realpath('.') . '/.gitignore';
4527 }
4528
4529 if (!$this->hasVendorIgnore($ignoreFile)) {
4530 $question = 'Would you like the <info>vendor</info> directory added to your <info>.gitignore</info> [<comment>yes</comment>]? ';
4531
4532 if ($io->askConfirmation($question, true)) {
4533 $this->addVendorIgnore($ignoreFile);
4534 }
4535 }
4536 }
4537 }
4538
4539
4540
4541
4542 protected function interact(InputInterface $input, OutputInterface $output)
4543 {
4544 $git = $this->getGitConfig();
4545 $io = $this->getIO();
4546 $formatter = $this->getHelperSet()->get('formatter');
4547
4548
4549  $repositories = $input->getOption('repository');
4550 if ($repositories) {
4551 $config = Factory::createConfig($io);
4552 $repos = array(new PlatformRepository);
4553 foreach ($repositories as $repo) {
4554 $repos[] = RepositoryFactory::fromString($io, $config, $repo);
4555 }
4556 $repos[] = RepositoryFactory::createRepo($io, $config, array(
4557 'type' => 'composer',
4558 'url' => 'https://packagist.org',
4559 ));
4560
4561 $this->repos = new CompositeRepository($repos);
4562 unset($repos, $config, $repositories);
4563 }
4564
4565 $io->writeError(array(
4566 '',
4567 $formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true),
4568 '',
4569 ));
4570
4571
4572  $io->writeError(array(
4573 '',
4574 'This command will guide you through creating your composer.json config.',
4575 '',
4576 ));
4577
4578 $cwd = realpath(".");
4579
4580 if (!$name = $input->getOption('name')) {
4581 $name = basename($cwd);
4582 $name = preg_replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $name);
4583 $name = strtolower($name);
4584 if (isset($git['github.user'])) {
4585 $name = $git['github.user'] . '/' . $name;
4586 } elseif (!empty($_SERVER['USERNAME'])) {
4587 $name = $_SERVER['USERNAME'] . '/' . $name;
4588 } elseif (get_current_user()) {
4589 $name = get_current_user() . '/' . $name;
4590 } else {
4591
4592  $name = $name . '/' . $name;
4593 }
4594 $name = strtolower($name);
4595 } else {
4596 if (!preg_match('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}', $name)) {
4597 throw new \InvalidArgumentException(
4598 'The package name '.$name.' is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+'
4599 );
4600 }
4601 }
4602
4603 $name = $io->askAndValidate(
4604 'Package name (<vendor>/<name>) [<comment>'.$name.'</comment>]: ',
4605 function ($value) use ($name) {
4606 if (null === $value) {
4607 return $name;
4608 }
4609
4610 if (!preg_match('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}', $value)) {
4611 throw new \InvalidArgumentException(
4612 'The package name '.$value.' is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+'
4613 );
4614 }
4615
4616 return $value;
4617 },
4618 null,
4619 $name
4620 );
4621 $input->setOption('name', $name);
4622
4623 $description = $input->getOption('description') ?: false;
4624 $description = $io->ask(
4625 'Description [<comment>'.$description.'</comment>]: ',
4626 $description
4627 );
4628 $input->setOption('description', $description);
4629
4630 if (null === $author = $input->getOption('author')) {
4631 if (isset($git['user.name']) && isset($git['user.email'])) {
4632 $author = sprintf('%s <%s>', $git['user.name'], $git['user.email']);
4633 }
4634 }
4635
4636 $self = $this;
4637 $author = $io->askAndValidate(
4638 'Author [<comment>'.$author.'</comment>, n to skip]: ',
4639 function ($value) use ($self, $author) {
4640 if ($value === 'n' || $value === 'no') {
4641 return;
4642 }
4643 $value = $value ?: $author;
4644 $author = $self->parseAuthorString($value);
4645
4646 return sprintf('%s <%s>', $author['name'], $author['email']);
4647 },
4648 null,
4649 $author
4650 );
4651 $input->setOption('author', $author);
4652
4653 $minimumStability = $input->getOption('stability') ?: null;
4654 $minimumStability = $io->askAndValidate(
4655 'Minimum Stability [<comment>'.$minimumStability.'</comment>]: ',
4656 function ($value) use ($self, $minimumStability) {
4657 if (null === $value) {
4658 return $minimumStability;
4659 }
4660
4661 if (!isset(BasePackage::$stabilities[$value])) {
4662 throw new \InvalidArgumentException(
4663 'Invalid minimum stability "'.$value.'". Must be empty or one of: '.
4664 implode(', ', array_keys(BasePackage::$stabilities))
4665 );
4666 }
4667
4668 return $value;
4669 },
4670 null,
4671 $minimumStability
4672 );
4673 $input->setOption('stability', $minimumStability);
4674
4675 $type = $input->getOption('type') ?: false;
4676 $type = $io->ask(
4677 'Package Type (e.g. library, project, metapackage, composer-plugin) [<comment>'.$type.'</comment>]: ',
4678 $type
4679 );
4680 $input->setOption('type', $type);
4681
4682 $license = $input->getOption('license') ?: false;
4683 $license = $io->ask(
4684 'License [<comment>'.$license.'</comment>]: ',
4685 $license
4686 );
4687 $input->setOption('license', $license);
4688
4689 $io->writeError(array('', 'Define your dependencies.', ''));
4690
4691 $question = 'Would you like to define your dependencies (require) interactively [<comment>yes</comment>]? ';
4692 $requirements = array();
4693 if ($io->askConfirmation($question, true)) {
4694 $requirements = $this->determineRequirements($input, $output, $input->getOption('require'));
4695 }
4696 $input->setOption('require', $requirements);
4697
4698 $question = 'Would you like to define your dev dependencies (require-dev) interactively [<comment>yes</comment>]? ';
4699 $devRequirements = array();
4700 if ($io->askConfirmation($question, true)) {
4701 $devRequirements = $this->determineRequirements($input, $output, $input->getOption('require-dev'));
4702 }
4703 $input->setOption('require-dev', $devRequirements);
4704 }
4705
4706
4707
4708
4709
4710
4711 public function parseAuthorString($author)
4712 {
4713 if (preg_match('/^(?P<name>[- .,\p{L}\p{N}\'’"()]+) <(?P<email>.+?)>$/u', $author, $match)) {
4714 if ($this->isValidEmail($match['email'])) {
4715 return array(
4716 'name' => trim($match['name']),
4717 'email' => $match['email'],
4718 );
4719 }
4720 }
4721
4722 throw new \InvalidArgumentException(
4723 'Invalid author string.  Must be in the format: '.
4724 'John Smith <john@example.com>'
4725 );
4726 }
4727
4728 protected function findPackages($name)
4729 {
4730 return $this->getRepos()->search($name);
4731 }
4732
4733 protected function getRepos()
4734 {
4735 if (!$this->repos) {
4736 $this->repos = new CompositeRepository(array_merge(
4737 array(new PlatformRepository),
4738 RepositoryFactory::defaultRepos($this->getIO())
4739 ));
4740 }
4741
4742 return $this->repos;
4743 }
4744
4745 protected function determineRequirements(InputInterface $input, OutputInterface $output, $requires = array(), $phpVersion = null, $preferredStability = 'stable')
4746 {
4747 if ($requires) {
4748 $requires = $this->normalizeRequirements($requires);
4749 $result = array();
4750 $io = $this->getIO();
4751
4752 foreach ($requires as $requirement) {
4753 if (!isset($requirement['version'])) {
4754
4755  $version = $this->findBestVersionForPackage($input, $requirement['name'], $phpVersion, $preferredStability);
4756 $requirement['version'] = $version;
4757
4758 $io->writeError(sprintf(
4759 'Using version <info>%s</info> for <info>%s</info>',
4760 $requirement['version'],
4761 $requirement['name']
4762 ));
4763 }
4764
4765 $result[] = $requirement['name'] . ' ' . $requirement['version'];
4766 }
4767
4768 return $result;
4769 }
4770
4771 $versionParser = new VersionParser();
4772 $io = $this->getIO();
4773 while (null !== $package = $io->ask('Search for a package: ')) {
4774 $matches = $this->findPackages($package);
4775
4776 if (count($matches)) {
4777 $exactMatch = null;
4778 $choices = array();
4779 foreach ($matches as $position => $foundPackage) {
4780 $choices[] = sprintf(' <info>%5s</info> %s', "[$position]", $foundPackage['name']);
4781 if ($foundPackage['name'] === $package) {
4782 $exactMatch = true;
4783 break;
4784 }
4785 }
4786
4787
4788  if (!$exactMatch) {
4789 $io->writeError(array(
4790 '',
4791 sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
4792 '',
4793 ));
4794
4795 $io->writeError($choices);
4796 $io->writeError('');
4797
4798 $validator = function ($selection) use ($matches, $versionParser) {
4799 if ('' === $selection) {
4800 return false;
4801 }
4802
4803 if (is_numeric($selection) && isset($matches[(int) $selection])) {
4804 $package = $matches[(int) $selection];
4805
4806 return $package['name'];
4807 }
4808
4809 if (preg_match('{^\s*(?P<name>[\S/]+)(?:\s+(?P<version>\S+))?\s*$}', $selection, $packageMatches)) {
4810 if (isset($packageMatches['version'])) {
4811
4812
4813
4814  $versionParser->parseConstraints($packageMatches['version']);
4815
4816 return $packageMatches['name'].' '.$packageMatches['version'];
4817 }
4818
4819
4820  return $packageMatches['name'];
4821 }
4822
4823 throw new \Exception('Not a valid selection');
4824 };
4825
4826 $package = $io->askAndValidate(
4827 'Enter package # to add, or the complete package name if it is not listed: ',
4828 $validator,
4829 3,
4830 false
4831 );
4832 }
4833
4834
4835  if (false !== $package && false === strpos($package, ' ')) {
4836 $validator = function ($input) {
4837 $input = trim($input);
4838
4839 return $input ?: false;
4840 };
4841
4842 $constraint = $io->askAndValidate(
4843 'Enter the version constraint to require (or leave blank to use the latest version): ',
4844 $validator,
4845 3,
4846 false
4847 );
4848
4849 if (false === $constraint) {
4850 $constraint = $this->findBestVersionForPackage($input, $package, $phpVersion, $preferredStability);
4851
4852 $io->writeError(sprintf(
4853 'Using version <info>%s</info> for <info>%s</info>',
4854 $constraint,
4855 $package
4856 ));
4857 }
4858
4859 $package .= ' '.$constraint;
4860 }
4861
4862 if (false !== $package) {
4863 $requires[] = $package;
4864 }
4865 }
4866 }
4867
4868 return $requires;
4869 }
4870
4871 protected function formatAuthors($author)
4872 {
4873 return array($this->parseAuthorString($author));
4874 }
4875
4876 protected function formatRequirements(array $requirements)
4877 {
4878 $requires = array();
4879 $requirements = $this->normalizeRequirements($requirements);
4880 foreach ($requirements as $requirement) {
4881 $requires[$requirement['name']] = $requirement['version'];
4882 }
4883
4884 return $requires;
4885 }
4886
4887 protected function getGitConfig()
4888 {
4889 if (null !== $this->gitConfig) {
4890 return $this->gitConfig;
4891 }
4892
4893 $finder = new ExecutableFinder();
4894 $gitBin = $finder->find('git');
4895
4896 $cmd = new Process(sprintf('%s config -l', ProcessExecutor::escape($gitBin)));
4897 $cmd->run();
4898
4899 if ($cmd->isSuccessful()) {
4900 $this->gitConfig = array();
4901 preg_match_all('{^([^=]+)=(.*)$}m', $cmd->getOutput(), $matches, PREG_SET_ORDER);
4902 foreach ($matches as $match) {
4903 $this->gitConfig[$match[1]] = $match[2];
4904 }
4905
4906 return $this->gitConfig;
4907 }
4908
4909 return $this->gitConfig = array();
4910 }
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928 protected function hasVendorIgnore($ignoreFile, $vendor = 'vendor')
4929 {
4930 if (!file_exists($ignoreFile)) {
4931 return false;
4932 }
4933
4934 $pattern = sprintf('{^/?%s(/\*?)?$}', preg_quote($vendor));
4935
4936 $lines = file($ignoreFile, FILE_IGNORE_NEW_LINES);
4937 foreach ($lines as $line) {
4938 if (preg_match($pattern, $line)) {
4939 return true;
4940 }
4941 }
4942
4943 return false;
4944 }
4945
4946 protected function normalizeRequirements(array $requirements)
4947 {
4948 $parser = new VersionParser();
4949
4950 return $parser->parseNameVersionPairs($requirements);
4951 }
4952
4953 protected function addVendorIgnore($ignoreFile, $vendor = '/vendor/')
4954 {
4955 $contents = "";
4956 if (file_exists($ignoreFile)) {
4957 $contents = file_get_contents($ignoreFile);
4958
4959 if ("\n" !== substr($contents, 0, -1)) {
4960 $contents .= "\n";
4961 }
4962 }
4963
4964 file_put_contents($ignoreFile, $contents . $vendor. "\n");
4965 }
4966
4967 protected function isValidEmail($email)
4968 {
4969
4970  if (!function_exists('filter_var')) {
4971 return true;
4972 }
4973
4974
4975  if (PHP_VERSION_ID < 50303) {
4976 return true;
4977 }
4978
4979 return false !== filter_var($email, FILTER_VALIDATE_EMAIL);
4980 }
4981
4982 private function getPool(InputInterface $input)
4983 {
4984 if (!$this->pool) {
4985 $this->pool = new Pool($this->getMinimumStability($input));
4986 $this->pool->addRepository($this->getRepos());
4987 }
4988
4989 return $this->pool;
4990 }
4991
4992 private function getMinimumStability(InputInterface $input)
4993 {
4994 if ($input->hasOption('stability')) {
4995 return $input->getOption('stability') ?: 'stable';
4996 }
4997
4998 $file = Factory::getComposerFile();
4999 if (is_file($file) && is_readable($file) && is_array($composer = json_decode(file_get_contents($file), true))) {
5000 if (!empty($composer['minimum-stability'])) {
5001 return $composer['minimum-stability'];
5002 }
5003 }
5004
5005 return 'stable';
5006 }
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020 private function findBestVersionForPackage(InputInterface $input, $name, $phpVersion, $preferredStability = 'stable')
5021 {
5022
5023  $versionSelector = new VersionSelector($this->getPool($input));
5024 $package = $versionSelector->findBestCandidate($name, null, $phpVersion, $preferredStability);
5025
5026 if (!$package) {
5027
5028  if ($phpVersion && $versionSelector->findBestCandidate($name)) {
5029 throw new \InvalidArgumentException(sprintf(
5030 'Could not find package %s at any version matching your PHP version %s', $name, $phpVersion
5031 ));
5032 }
5033 throw new \InvalidArgumentException(sprintf(
5034 'Could not find package %s at any version for your minimum-stability (%s). Check the package spelling or your minimum-stability',
5035 $name,
5036 $this->getMinimumStability($input)
5037 ));
5038 }
5039
5040 return $versionSelector->findRecommendedRequireVersion($package);
5041 }
5042 }
5043 <?php
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055 namespace Composer\Command;
5056
5057 use Composer\Installer;
5058 use Composer\Plugin\CommandEvent;
5059 use Composer\Plugin\PluginEvents;
5060 use Symfony\Component\Console\Input\InputInterface;
5061 use Symfony\Component\Console\Input\InputOption;
5062 use Symfony\Component\Console\Input\InputArgument;
5063 use Symfony\Component\Console\Output\OutputInterface;
5064
5065
5066
5067
5068
5069
5070
5071 class InstallCommand extends BaseCommand
5072 {
5073 protected function configure()
5074 {
5075 $this
5076 ->setName('install')
5077 ->setDescription('Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.')
5078 ->setDefinition(array(
5079 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
5080 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
5081 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
5082 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
5083 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
5084 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
5085 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
5086 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
5087 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
5088 new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'Do not show package suggestions.'),
5089 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
5090 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
5091 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
5092 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
5093 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
5094 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'),
5095 ))
5096 ->setHelp(<<<EOT
5097 The <info>install</info> command reads the composer.lock file from
5098 the current directory, processes it, and downloads and installs all the
5099 libraries and dependencies outlined in that file. If the file does not
5100 exist it will look for composer.json and do the same.
5101
5102 <info>php composer.phar install</info>
5103
5104 EOT
5105 )
5106 ;
5107 }
5108
5109 protected function execute(InputInterface $input, OutputInterface $output)
5110 {
5111 $io = $this->getIO();
5112 if ($args = $input->getArgument('packages')) {
5113 $io->writeError('<error>Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.</error>');
5114
5115 return 1;
5116 }
5117
5118 if ($input->getOption('no-custom-installers')) {
5119 $io->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
5120 $input->setOption('no-plugins', true);
5121 }
5122
5123 if ($input->getOption('dev')) {
5124 $io->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
5125 }
5126
5127 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
5128 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
5129
5130 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'install', $input, $output);
5131 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
5132
5133 $install = Installer::create($io, $composer);
5134
5135 $config = $composer->getConfig();
5136 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
5137
5138 $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
5139 $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
5140 $apcu = $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader');
5141
5142 $install
5143 ->setDryRun($input->getOption('dry-run'))
5144 ->setVerbose($input->getOption('verbose'))
5145 ->setPreferSource($preferSource)
5146 ->setPreferDist($preferDist)
5147 ->setDevMode(!$input->getOption('no-dev'))
5148 ->setDumpAutoloader(!$input->getOption('no-autoloader'))
5149 ->setRunScripts(!$input->getOption('no-scripts'))
5150 ->setSkipSuggest($input->getOption('no-suggest'))
5151 ->setOptimizeAutoloader($optimize)
5152 ->setClassMapAuthoritative($authoritative)
5153 ->setApcuAutoloader($apcu)
5154 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
5155 ;
5156
5157 if ($input->getOption('no-plugins')) {
5158 $install->disablePlugins();
5159 }
5160
5161 return $install->run();
5162 }
5163 }
5164 <?php
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176 namespace Composer\Command;
5177
5178 use Composer\Json\JsonFile;
5179 use Composer\Plugin\CommandEvent;
5180 use Composer\Plugin\PluginEvents;
5181 use Composer\Package\PackageInterface;
5182 use Composer\Repository\RepositoryInterface;
5183 use Symfony\Component\Console\Helper\Table;
5184 use Symfony\Component\Console\Input\InputInterface;
5185 use Symfony\Component\Console\Input\InputOption;
5186 use Symfony\Component\Console\Output\OutputInterface;
5187
5188
5189
5190
5191 class LicensesCommand extends BaseCommand
5192 {
5193 protected function configure()
5194 {
5195 $this
5196 ->setName('licenses')
5197 ->setDescription('Show information about licenses of dependencies.')
5198 ->setDefinition(array(
5199 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
5200 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
5201 ))
5202 ->setHelp(<<<EOT
5203 The license command displays detailed information about the licenses of
5204 the installed dependencies.
5205
5206 EOT
5207 )
5208 ;
5209 }
5210
5211 protected function execute(InputInterface $input, OutputInterface $output)
5212 {
5213 $composer = $this->getComposer();
5214
5215 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'licenses', $input, $output);
5216 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
5217
5218 $root = $composer->getPackage();
5219 $repo = $composer->getRepositoryManager()->getLocalRepository();
5220
5221 if ($input->getOption('no-dev')) {
5222 $packages = $this->filterRequiredPackages($repo, $root);
5223 } else {
5224 $packages = $this->appendPackages($repo->getPackages(), array());
5225 }
5226
5227 ksort($packages);
5228 $io = $this->getIO();
5229
5230 switch ($format = $input->getOption('format')) {
5231 case 'text':
5232 $io->write('Name: <comment>'.$root->getPrettyName().'</comment>');
5233 $io->write('Version: <comment>'.$root->getFullPrettyVersion().'</comment>');
5234 $io->write('Licenses: <comment>'.(implode(', ', $root->getLicense()) ?: 'none').'</comment>');
5235 $io->write('Dependencies:');
5236 $io->write('');
5237
5238 $table = new Table($output);
5239 $table->setStyle('compact');
5240 $table->getStyle()->setVerticalBorderChar('');
5241 $table->getStyle()->setCellRowContentFormat('%s  ');
5242 $table->setHeaders(array('Name', 'Version', 'License'));
5243 foreach ($packages as $package) {
5244 $table->addRow(array(
5245 $package->getPrettyName(),
5246 $package->getFullPrettyVersion(),
5247 implode(', ', $package->getLicense()) ?: 'none',
5248 ));
5249 }
5250 $table->render();
5251 break;
5252
5253 case 'json':
5254 $dependencies = array();
5255 foreach ($packages as $package) {
5256 $dependencies[$package->getPrettyName()] = array(
5257 'version' => $package->getFullPrettyVersion(),
5258 'license' => $package->getLicense(),
5259 );
5260 }
5261
5262 $io->write(JsonFile::encode(array(
5263 'name' => $root->getPrettyName(),
5264 'version' => $root->getFullPrettyVersion(),
5265 'license' => $root->getLicense(),
5266 'dependencies' => $dependencies,
5267 )));
5268 break;
5269
5270 default:
5271 throw new \RuntimeException(sprintf('Unsupported format "%s".  See help for supported formats.', $format));
5272 }
5273 }
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283 private function filterRequiredPackages(RepositoryInterface $repo, PackageInterface $package, $bucket = array())
5284 {
5285 $requires = array_keys($package->getRequires());
5286
5287 $packageListNames = array_keys($bucket);
5288 $packages = array_filter(
5289 $repo->getPackages(),
5290 function ($package) use ($requires, $packageListNames) {
5291 return in_array($package->getName(), $requires) && !in_array($package->getName(), $packageListNames);
5292 }
5293 );
5294
5295 $bucket = $this->appendPackages($packages, $bucket);
5296
5297 foreach ($packages as $package) {
5298 $bucket = $this->filterRequiredPackages($repo, $package, $bucket);
5299 }
5300
5301 return $bucket;
5302 }
5303
5304
5305
5306
5307
5308
5309
5310
5311 public function appendPackages(array $packages, array $bucket)
5312 {
5313 foreach ($packages as $package) {
5314 $bucket[$package->getName()] = $package;
5315 }
5316
5317 return $bucket;
5318 }
5319 }
5320 <?php
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332 namespace Composer\Command;
5333
5334 use Symfony\Component\Console\Input\InputInterface;
5335 use Symfony\Component\Console\Input\InputArgument;
5336 use Symfony\Component\Console\Input\ArrayInput;
5337 use Symfony\Component\Console\Input\InputOption;
5338 use Symfony\Component\Console\Output\OutputInterface;
5339
5340
5341
5342
5343 class OutdatedCommand extends ShowCommand
5344 {
5345 protected function configure()
5346 {
5347 $this
5348 ->setName('outdated')
5349 ->setDescription('Shows a list of installed packages that have updates available, including their latest version.')
5350 ->setDefinition(array(
5351 new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.'),
5352 new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show only packages that are outdated (this is the default, but present here for compat with `show`'),
5353 new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show all installed packages with their latest versions'),
5354 new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
5355 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
5356 new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
5357 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
5358 ))
5359 ->setHelp(<<<EOT
5360 The outdated command is just a proxy for `composer show -l`
5361
5362 The color coding (or signage if you have ANSI colors disabled) for dependency versions is as such:
5363
5364 - <info>green</info> (=): Dependency is in the latest version and is up to date.
5365 - <comment>yellow</comment> (~): Dependency has a new version available that includes backwards
5366   compatibility breaks according to semver, so upgrade when you can but it
5367   may involve work.
5368 - <highlight>red</highlight> (!): Dependency has a new version that is semver-compatible and you should upgrade it.
5369
5370
5371 EOT
5372 )
5373 ;
5374 }
5375
5376 protected function execute(InputInterface $input, OutputInterface $output)
5377 {
5378 $args = array(
5379 'show',
5380 '--latest' => true,
5381 );
5382 if (!$input->getOption('all')) {
5383 $args['--outdated'] = true;
5384 }
5385 if ($input->getOption('direct')) {
5386 $args['--direct'] = true;
5387 }
5388 if ($input->getArgument('package')) {
5389 $args['package'] = $input->getArgument('package');
5390 }
5391 if ($input->getOption('strict')) {
5392 $args['--strict'] = true;
5393 }
5394 if ($input->getOption('minor-only')) {
5395 $args['--minor-only'] = true;
5396 }
5397 $args['--format'] = $input->getOption('format');
5398
5399 $input = new ArrayInput($args);
5400
5401 return $this->getApplication()->run($input, $output);
5402 }
5403
5404
5405
5406
5407 public function isProxyCommand()
5408 {
5409 return true;
5410 }
5411 }
5412 <?php
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424 namespace Composer\Command;
5425
5426 use Symfony\Component\Console\Input\InputInterface;
5427 use Symfony\Component\Console\Output\OutputInterface;
5428
5429
5430
5431
5432 class ProhibitsCommand extends BaseDependencyCommand
5433 {
5434
5435
5436
5437 protected function configure()
5438 {
5439 parent::configure();
5440
5441 $this
5442 ->setName('prohibits')
5443 ->setAliases(array('why-not'))
5444 ->setDescription('Shows which packages prevent the given package from being installed.')
5445 ->setHelp(<<<EOT
5446 Displays detailed information about why a package cannot be installed.
5447
5448 <info>php composer.phar prohibits composer/composer</info>
5449
5450 EOT
5451 )
5452 ;
5453 }
5454
5455
5456
5457
5458
5459
5460
5461
5462 protected function execute(InputInterface $input, OutputInterface $output)
5463 {
5464 return parent::doExecute($input, $output, true);
5465 }
5466 }
5467 <?php
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479 namespace Composer\Command;
5480
5481 use Composer\Config\JsonConfigSource;
5482 use Composer\Installer;
5483 use Composer\Plugin\CommandEvent;
5484 use Composer\Plugin\PluginEvents;
5485 use Composer\Json\JsonFile;
5486 use Composer\Factory;
5487 use Symfony\Component\Console\Input\InputInterface;
5488 use Symfony\Component\Console\Input\InputOption;
5489 use Symfony\Component\Console\Input\InputArgument;
5490 use Symfony\Component\Console\Output\OutputInterface;
5491
5492
5493
5494
5495
5496 class RemoveCommand extends BaseCommand
5497 {
5498 protected function configure()
5499 {
5500 $this
5501 ->setName('remove')
5502 ->setDescription('Removes a package from the require or require-dev.')
5503 ->setDefinition(array(
5504 new InputArgument('packages', InputArgument::IS_ARRAY, 'Packages that should be removed.'),
5505 new InputOption('dev', null, InputOption::VALUE_NONE, 'Removes a package from the require-dev section.'),
5506 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
5507 new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.'),
5508 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
5509 new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
5510 new InputOption('update-with-dependencies', null, InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies. (Deprecrated, is now default behavior)'),
5511 new InputOption('no-update-with-dependencies', null, InputOption::VALUE_NONE, 'Does not allow inherited dependencies to be updated with explicit dependencies.'),
5512 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
5513 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
5514 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
5515 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
5516 ))
5517 ->setHelp(<<<EOT
5518 The <info>remove</info> command removes a package from the current
5519 list of installed packages
5520
5521 <info>php composer.phar remove</info>
5522
5523 EOT
5524 )
5525 ;
5526 }
5527
5528 protected function execute(InputInterface $input, OutputInterface $output)
5529 {
5530 $packages = $input->getArgument('packages');
5531 $packages = array_map('strtolower', $packages);
5532
5533 $file = Factory::getComposerFile();
5534
5535 $jsonFile = new JsonFile($file);
5536 $composer = $jsonFile->read();
5537 $composerBackup = file_get_contents($jsonFile->getPath());
5538
5539 $json = new JsonConfigSource($jsonFile);
5540
5541 $type = $input->getOption('dev') ? 'require-dev' : 'require';
5542 $altType = !$input->getOption('dev') ? 'require-dev' : 'require';
5543 $io = $this->getIO();
5544
5545 if ($input->getOption('update-with-dependencies')) {
5546 $io->writeError('<warning>You are using the deprecated option "update-with-dependencies". This is now default behaviour. The --no-update-with-dependencies option can be used to remove a package without its dependencies.</warning>');
5547 }
5548
5549
5550  foreach (array('require', 'require-dev') as $linkType) {
5551 if (isset($composer[$linkType])) {
5552 foreach ($composer[$linkType] as $name => $version) {
5553 $composer[$linkType][strtolower($name)] = $name;
5554 }
5555 }
5556 }
5557
5558 foreach ($packages as $package) {
5559 if (isset($composer[$type][$package])) {
5560 $json->removeLink($type, $composer[$type][$package]);
5561 } elseif (isset($composer[$altType][$package])) {
5562 $io->writeError('<warning>'.$composer[$altType][$package].' could not be found in '.$type.' but it is present in '.$altType.'</warning>');
5563 if ($io->isInteractive()) {
5564 if ($io->askConfirmation('Do you want to remove it from '.$altType.' [<comment>yes</comment>]? ', true)) {
5565 $json->removeLink($altType, $composer[$altType][$package]);
5566 }
5567 }
5568 } else {
5569 $io->writeError('<warning>'.$package.' is not required in your composer.json and has not been removed</warning>');
5570 }
5571 }
5572
5573 if ($input->getOption('no-update')) {
5574 return 0;
5575 }
5576
5577
5578  $this->resetComposer();
5579 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
5580 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
5581
5582 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'remove', $input, $output);
5583 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
5584
5585 $install = Installer::create($io, $composer);
5586
5587 $updateDevMode = !$input->getOption('update-no-dev');
5588 $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader');
5589 $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative');
5590 $apcu = $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader');
5591
5592 $install
5593 ->setVerbose($input->getOption('verbose'))
5594 ->setDevMode($updateDevMode)
5595 ->setOptimizeAutoloader($optimize)
5596 ->setClassMapAuthoritative($authoritative)
5597 ->setApcuAutoloader($apcu)
5598 ->setUpdate(true)
5599 ->setUpdateWhitelist($packages)
5600 ->setWhitelistDependencies(!$input->getOption('no-update-with-dependencies'))
5601 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
5602 ->setRunScripts(!$input->getOption('no-scripts'))
5603 ;
5604
5605 $exception = null;
5606 try {
5607 $status = $install->run();
5608 } catch (\Exception $exception) {
5609 $status = 1;
5610 }
5611 if ($status !== 0) {
5612 $io->writeError("\n".'<error>Removal failed, reverting '.$file.' to its original content.</error>');
5613 file_put_contents($jsonFile->getPath(), $composerBackup);
5614 }
5615 if ($exception) {
5616 throw $exception;
5617 }
5618
5619 return $status;
5620 }
5621 }
5622 <?php
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634 namespace Composer\Command;
5635
5636 use Symfony\Component\Console\Input\InputInterface;
5637 use Symfony\Component\Console\Input\InputArgument;
5638 use Symfony\Component\Console\Input\InputOption;
5639 use Symfony\Component\Console\Output\OutputInterface;
5640 use Composer\Factory;
5641 use Composer\Installer;
5642 use Composer\Json\JsonFile;
5643 use Composer\Json\JsonManipulator;
5644 use Composer\Package\Version\VersionParser;
5645 use Composer\Plugin\CommandEvent;
5646 use Composer\Plugin\PluginEvents;
5647 use Composer\Repository\CompositeRepository;
5648 use Composer\Repository\PlatformRepository;
5649
5650
5651
5652
5653
5654 class RequireCommand extends InitCommand
5655 {
5656 protected function configure()
5657 {
5658 $this
5659 ->setName('require')
5660 ->setDescription('Adds required packages to your composer.json and installs them.')
5661 ->setDefinition(array(
5662 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Required package name optionally including a version constraint, e.g. foo/bar or foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
5663 new InputOption('dev', null, InputOption::VALUE_NONE, 'Add requirement to require-dev.'),
5664 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
5665 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
5666 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
5667 new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'Do not show package suggestions.'),
5668 new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.'),
5669 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
5670 new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
5671 new InputOption('update-with-dependencies', null, InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies.'),
5672 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
5673 new InputOption('prefer-stable', null, InputOption::VALUE_NONE, 'Prefer stable versions of dependencies.'),
5674 new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies.'),
5675 new InputOption('sort-packages', null, InputOption::VALUE_NONE, 'Sorts packages when adding/updating a new dependency'),
5676 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
5677 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
5678 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
5679 ))
5680 ->setHelp(<<<EOT
5681 The require command adds required packages to your composer.json and installs them.
5682
5683 If you do not specify a version constraint, composer will choose a suitable one based on the available package versions.
5684
5685 If you do not want to install the new dependencies immediately you can call it with --no-update
5686
5687 EOT
5688 )
5689 ;
5690 }
5691
5692 protected function execute(InputInterface $input, OutputInterface $output)
5693 {
5694 $file = Factory::getComposerFile();
5695 $io = $this->getIO();
5696
5697 $newlyCreated = !file_exists($file);
5698 if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
5699 $io->writeError('<error>'.$file.' could not be created.</error>');
5700
5701 return 1;
5702 }
5703 if (!is_readable($file)) {
5704 $io->writeError('<error>'.$file.' is not readable.</error>');
5705
5706 return 1;
5707 }
5708 if (!is_writable($file)) {
5709 $io->writeError('<error>'.$file.' is not writable.</error>');
5710
5711 return 1;
5712 }
5713
5714 if (filesize($file) === 0) {
5715 file_put_contents($file, "{\n}\n");
5716 }
5717
5718 $json = new JsonFile($file);
5719 $composerBackup = file_get_contents($json->getPath());
5720
5721 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
5722 $repos = $composer->getRepositoryManager()->getRepositories();
5723
5724 $platformOverrides = $composer->getConfig()->get('platform') ?: array();
5725
5726  $this->repos = new CompositeRepository(array_merge(
5727 array(new PlatformRepository(array(), $platformOverrides)),
5728 $repos
5729 ));
5730
5731 if ($composer->getPackage()->getPreferStable()) {
5732 $preferredStability = 'stable';
5733 } else {
5734 $preferredStability = $composer->getPackage()->getMinimumStability();
5735 }
5736
5737 $phpVersion = $this->repos->findPackage('php', '*')->getVersion();
5738 $requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'), $phpVersion, $preferredStability);
5739
5740 $requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
5741 $removeKey = $input->getOption('dev') ? 'require' : 'require-dev';
5742 $requirements = $this->formatRequirements($requirements);
5743
5744
5745  $versionParser = new VersionParser();
5746 foreach ($requirements as $constraint) {
5747 $versionParser->parseConstraints($constraint);
5748 }
5749
5750 $sortPackages = $input->getOption('sort-packages') || $composer->getConfig()->get('sort-packages');
5751
5752 if (!$this->updateFileCleanly($json, $requirements, $requireKey, $removeKey, $sortPackages)) {
5753 $composerDefinition = $json->read();
5754 foreach ($requirements as $package => $version) {
5755 $composerDefinition[$requireKey][$package] = $version;
5756 unset($composerDefinition[$removeKey][$package]);
5757 }
5758 $json->write($composerDefinition);
5759 }
5760
5761 $io->writeError('<info>'.$file.' has been '.($newlyCreated ? 'created' : 'updated').'</info>');
5762
5763 if ($input->getOption('no-update')) {
5764 return 0;
5765 }
5766 $updateDevMode = !$input->getOption('update-no-dev');
5767 $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader');
5768 $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative');
5769 $apcu = $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader');
5770
5771
5772  $this->resetComposer();
5773 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
5774 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
5775
5776 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'require', $input, $output);
5777 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
5778
5779 $install = Installer::create($io, $composer);
5780
5781 $install
5782 ->setVerbose($input->getOption('verbose'))
5783 ->setPreferSource($input->getOption('prefer-source'))
5784 ->setPreferDist($input->getOption('prefer-dist'))
5785 ->setDevMode($updateDevMode)
5786 ->setRunScripts(!$input->getOption('no-scripts'))
5787 ->setSkipSuggest($input->getOption('no-suggest'))
5788 ->setOptimizeAutoloader($optimize)
5789 ->setClassMapAuthoritative($authoritative)
5790 ->setApcuAutoloader($apcu)
5791 ->setUpdate(true)
5792 ->setUpdateWhitelist(array_keys($requirements))
5793 ->setWhitelistDependencies($input->getOption('update-with-dependencies'))
5794 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
5795 ->setPreferStable($input->getOption('prefer-stable'))
5796 ->setPreferLowest($input->getOption('prefer-lowest'))
5797 ;
5798
5799 $exception = null;
5800 try {
5801 $status = $install->run();
5802 } catch (\Exception $exception) {
5803 $status = 1;
5804 }
5805 if ($status !== 0) {
5806 if ($newlyCreated) {
5807 $io->writeError("\n".'<error>Installation failed, deleting '.$file.'.</error>');
5808 unlink($json->getPath());
5809 } else {
5810 $io->writeError("\n".'<error>Installation failed, reverting '.$file.' to its original content.</error>');
5811 file_put_contents($json->getPath(), $composerBackup);
5812 }
5813 }
5814 if ($exception) {
5815 throw $exception;
5816 }
5817
5818 return $status;
5819 }
5820
5821 private function updateFileCleanly($json, array $new, $requireKey, $removeKey, $sortPackages)
5822 {
5823 $contents = file_get_contents($json->getPath());
5824
5825 $manipulator = new JsonManipulator($contents);
5826
5827 foreach ($new as $package => $constraint) {
5828 if (!$manipulator->addLink($requireKey, $package, $constraint, $sortPackages)) {
5829 return false;
5830 }
5831 if (!$manipulator->removeSubNode($removeKey, $package)) {
5832 return false;
5833 }
5834 }
5835
5836 file_put_contents($json->getPath(), $manipulator->getContents());
5837
5838 return true;
5839 }
5840
5841 protected function interact(InputInterface $input, OutputInterface $output)
5842 {
5843 return;
5844 }
5845 }
5846 <?php
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858 namespace Composer\Command;
5859
5860 use Composer\Script\Event as ScriptEvent;
5861 use Composer\Script\ScriptEvents;
5862 use Composer\Util\ProcessExecutor;
5863 use Symfony\Component\Console\Input\InputInterface;
5864 use Symfony\Component\Console\Input\InputOption;
5865 use Symfony\Component\Console\Input\InputArgument;
5866 use Symfony\Component\Console\Output\OutputInterface;
5867
5868
5869
5870
5871 class RunScriptCommand extends BaseCommand
5872 {
5873
5874
5875
5876 protected $scriptEvents = array(
5877 ScriptEvents::PRE_INSTALL_CMD,
5878 ScriptEvents::POST_INSTALL_CMD,
5879 ScriptEvents::PRE_UPDATE_CMD,
5880 ScriptEvents::POST_UPDATE_CMD,
5881 ScriptEvents::PRE_STATUS_CMD,
5882 ScriptEvents::POST_STATUS_CMD,
5883 ScriptEvents::POST_ROOT_PACKAGE_INSTALL,
5884 ScriptEvents::POST_CREATE_PROJECT_CMD,
5885 ScriptEvents::PRE_ARCHIVE_CMD,
5886 ScriptEvents::POST_ARCHIVE_CMD,
5887 ScriptEvents::PRE_AUTOLOAD_DUMP,
5888 ScriptEvents::POST_AUTOLOAD_DUMP,
5889 );
5890
5891 protected function configure()
5892 {
5893 $this
5894 ->setName('run-script')
5895 ->setDescription('Run the scripts defined in composer.json.')
5896 ->setDefinition(array(
5897 new InputArgument('script', InputArgument::OPTIONAL, 'Script name to run.'),
5898 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
5899 new InputOption('timeout', null, InputOption::VALUE_REQUIRED, 'Sets script timeout in seconds, or 0 for never.'),
5900 new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
5901 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
5902 new InputOption('list', 'l', InputOption::VALUE_NONE, 'List scripts.'),
5903 ))
5904 ->setHelp(<<<EOT
5905 The <info>run-script</info> command runs scripts defined in composer.json:
5906
5907 <info>php composer.phar run-script post-update-cmd</info>
5908 EOT
5909 )
5910 ;
5911 }
5912
5913 protected function execute(InputInterface $input, OutputInterface $output)
5914 {
5915 if ($input->getOption('list')) {
5916 return $this->listScripts();
5917 } elseif (!$input->getArgument('script')) {
5918 throw new \RuntimeException('Missing required argument "script"');
5919 }
5920
5921 $script = $input->getArgument('script');
5922 if (!in_array($script, $this->scriptEvents)) {
5923 if (defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
5924 throw new \InvalidArgumentException(sprintf('Script "%s" cannot be run with this command', $script));
5925 }
5926 }
5927
5928 $composer = $this->getComposer();
5929 $devMode = $input->getOption('dev') || !$input->getOption('no-dev');
5930 $event = new ScriptEvent($script, $composer, $this->getIO(), $devMode);
5931 $hasListeners = $composer->getEventDispatcher()->hasEventListeners($event);
5932 if (!$hasListeners) {
5933 throw new \InvalidArgumentException(sprintf('Script "%s" is not defined in this package', $script));
5934 }
5935
5936 $args = $input->getArgument('args');
5937
5938 if (!is_null($timeout = $input->getOption('timeout'))) {
5939 if (!ctype_digit($timeout)) {
5940 throw new \RuntimeException('Timeout value must be numeric and positive if defined, or 0 for forever');
5941 }
5942
5943  ProcessExecutor::setTimeout((int) $timeout);
5944 }
5945
5946 return $composer->getEventDispatcher()->dispatchScript($script, $devMode, $args);
5947 }
5948
5949 protected function listScripts()
5950 {
5951 $scripts = $this->getComposer()->getPackage()->getScripts();
5952
5953 if (!count($scripts)) {
5954 return 0;
5955 }
5956
5957 $io = $this->getIO();
5958 $io->writeError('<info>scripts:</info>');
5959 foreach ($scripts as $name => $script) {
5960 $io->write('  ' . $name);
5961 }
5962
5963 return 0;
5964 }
5965 }
5966 <?php
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978 namespace Composer\Command;
5979
5980 use Symfony\Component\Console\Input\InputInterface;
5981 use Symfony\Component\Console\Input\InputOption;
5982 use Symfony\Component\Console\Input\InputArgument;
5983 use Symfony\Component\Console\Output\OutputInterface;
5984
5985
5986
5987
5988 class ScriptAliasCommand extends BaseCommand
5989 {
5990 private $script;
5991
5992 public function __construct($script)
5993 {
5994 $this->script = $script;
5995
5996 parent::__construct();
5997 }
5998
5999 protected function configure()
6000 {
6001 $this
6002 ->setName($this->script)
6003 ->setDescription('Run the '.$this->script.' script as defined in composer.json.')
6004 ->setDefinition(array(
6005 new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
6006 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
6007 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
6008 ))
6009 ->setHelp(<<<EOT
6010 The <info>run-script</info> command runs scripts defined in composer.json:
6011
6012 <info>php composer.phar run-script post-update-cmd</info>
6013 EOT
6014 )
6015 ;
6016 }
6017
6018 protected function execute(InputInterface $input, OutputInterface $output)
6019 {
6020 $composer = $this->getComposer();
6021
6022 $args = $input->getArguments();
6023
6024 return $composer->getEventDispatcher()->dispatchScript($this->script, $input->getOption('dev') || !$input->getOption('no-dev'), $args['args']);
6025 }
6026 }
6027 <?php
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039 namespace Composer\Command;
6040
6041 use Composer\Factory;
6042 use Symfony\Component\Console\Input\InputInterface;
6043 use Symfony\Component\Console\Input\InputArgument;
6044 use Symfony\Component\Console\Input\InputOption;
6045 use Symfony\Component\Console\Output\OutputInterface;
6046 use Composer\Repository\CompositeRepository;
6047 use Composer\Repository\PlatformRepository;
6048 use Composer\Repository\RepositoryInterface;
6049 use Composer\Plugin\CommandEvent;
6050 use Composer\Plugin\PluginEvents;
6051
6052
6053
6054
6055 class SearchCommand extends BaseCommand
6056 {
6057 protected $matches;
6058 protected $lowMatches = array();
6059 protected $tokens;
6060 protected $output;
6061 protected $onlyName;
6062
6063 protected function configure()
6064 {
6065 $this
6066 ->setName('search')
6067 ->setDescription('Search for packages.')
6068 ->setDefinition(array(
6069 new InputOption('only-name', 'N', InputOption::VALUE_NONE, 'Search only in name'),
6070 new InputOption('type', 't', InputOption::VALUE_REQUIRED, 'Search for a specific package type'),
6071 new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'),
6072 ))
6073 ->setHelp(<<<EOT
6074 The search command searches for packages by its name
6075 <info>php composer.phar search symfony composer</info>
6076
6077 EOT
6078 )
6079 ;
6080 }
6081
6082 protected function execute(InputInterface $input, OutputInterface $output)
6083 {
6084
6085  $platformRepo = new PlatformRepository;
6086 $io = $this->getIO();
6087 if (!($composer = $this->getComposer(false))) {
6088 $composer = Factory::create($this->getIO(), array());
6089 }
6090 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
6091 $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
6092 $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
6093
6094 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output);
6095 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
6096
6097 $onlyName = $input->getOption('only-name');
6098 $type = $input->getOption('type') ?: null;
6099
6100 $flags = $onlyName ? RepositoryInterface::SEARCH_NAME : RepositoryInterface::SEARCH_FULLTEXT;
6101 $results = $repos->search(implode(' ', $input->getArgument('tokens')), $flags, $type);
6102
6103 foreach ($results as $result) {
6104 $io->write($result['name'] . (isset($result['description']) ? ' '. $result['description'] : ''));
6105 }
6106 }
6107 }
6108 <?php
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120 namespace Composer\Command;
6121
6122 use Composer\Composer;
6123 use Composer\Factory;
6124 use Composer\Config;
6125 use Composer\Util\Filesystem;
6126 use Composer\SelfUpdate\Keys;
6127 use Composer\SelfUpdate\Versions;
6128 use Composer\IO\IOInterface;
6129 use Composer\Downloader\FilesystemException;
6130 use Symfony\Component\Console\Input\InputInterface;
6131 use Symfony\Component\Console\Input\InputOption;
6132 use Symfony\Component\Console\Input\InputArgument;
6133 use Symfony\Component\Console\Output\OutputInterface;
6134 use Symfony\Component\Finder\Finder;
6135
6136
6137
6138
6139
6140
6141 class SelfUpdateCommand extends BaseCommand
6142 {
6143 const HOMEPAGE = 'getcomposer.org';
6144 const OLD_INSTALL_EXT = '-old.phar';
6145
6146 protected function configure()
6147 {
6148 $this
6149 ->setName('self-update')
6150 ->setAliases(array('selfupdate'))
6151 ->setDescription('Updates composer.phar to the latest version.')
6152 ->setDefinition(array(
6153 new InputOption('rollback', 'r', InputOption::VALUE_NONE, 'Revert to an older installation of composer'),
6154 new InputOption('clean-backups', null, InputOption::VALUE_NONE, 'Delete old backups during an update. This makes the current version of composer the only backup available after the update'),
6155 new InputArgument('version', InputArgument::OPTIONAL, 'The version to update to'),
6156 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
6157 new InputOption('update-keys', null, InputOption::VALUE_NONE, 'Prompt user for a key update'),
6158 new InputOption('stable', null, InputOption::VALUE_NONE, 'Force an update to the stable channel'),
6159 new InputOption('preview', null, InputOption::VALUE_NONE, 'Force an update to the preview channel'),
6160 new InputOption('snapshot', null, InputOption::VALUE_NONE, 'Force an update to the snapshot channel'),
6161 new InputOption('set-channel-only', null, InputOption::VALUE_NONE, 'Only store the channel as the default one and then exit'),
6162 ))
6163 ->setHelp(<<<EOT
6164 The <info>self-update</info> command checks getcomposer.org for newer
6165 versions of composer and if found, installs the latest.
6166
6167 <info>php composer.phar self-update</info>
6168
6169 EOT
6170 )
6171 ;
6172 }
6173
6174 protected function execute(InputInterface $input, OutputInterface $output)
6175 {
6176 $config = Factory::createConfig();
6177
6178 if ($config->get('disable-tls') === true) {
6179 $baseUrl = 'http://' . self::HOMEPAGE;
6180 } else {
6181 $baseUrl = 'https://' . self::HOMEPAGE;
6182 }
6183
6184 $io = $this->getIO();
6185 $remoteFilesystem = Factory::createRemoteFilesystem($io, $config);
6186
6187 $versionsUtil = new Versions($config, $remoteFilesystem);
6188
6189
6190  foreach (array('stable', 'preview', 'snapshot') as $channel) {
6191 if ($input->getOption($channel)) {
6192 $versionsUtil->setChannel($channel);
6193 }
6194 }
6195
6196 if ($input->getOption('set-channel-only')) {
6197 return 0;
6198 }
6199
6200 $cacheDir = $config->get('cache-dir');
6201 $rollbackDir = $config->get('data-dir');
6202 $home = $config->get('home');
6203 $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
6204
6205 if ($input->getOption('update-keys')) {
6206 return $this->fetchKeys($io, $config);
6207 }
6208
6209
6210  $tmpDir = is_writable(dirname($localFilename)) ? dirname($localFilename) : $cacheDir;
6211
6212
6213  if (!is_writable($tmpDir)) {
6214 throw new FilesystemException('Composer update failed: the "'.$tmpDir.'" directory used to download the temp file could not be written');
6215 }
6216
6217 if ($input->getOption('rollback')) {
6218 return $this->rollback($output, $rollbackDir, $localFilename);
6219 }
6220
6221 $latest = $versionsUtil->getLatest();
6222 $latestVersion = $latest['version'];
6223 $updateVersion = $input->getArgument('version') ?: $latestVersion;
6224
6225 if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
6226 $io->writeError('<error>You can not update to a specific SHA-1 as those phars are not available for download</error>');
6227
6228 return 1;
6229 }
6230
6231 if (Composer::VERSION === $updateVersion) {
6232 $io->writeError(sprintf('<info>You are already using composer version %s (%s channel).</info>', $updateVersion, $versionsUtil->getChannel()));
6233
6234
6235  if ($input->getOption('clean-backups')) {
6236 $this->cleanBackups($rollbackDir, $this->getLastBackupVersion($rollbackDir));
6237 }
6238
6239 return 0;
6240 }
6241
6242 $tempFilename = $tmpDir . '/' . basename($localFilename, '.phar').'-temp.phar';
6243 $backupFile = sprintf(
6244 '%s/%s-%s%s',
6245 $rollbackDir,
6246 strtr(Composer::RELEASE_DATE, ' :', '_-'),
6247 preg_replace('{^([0-9a-f]{7})[0-9a-f]{33}$}', '$1', Composer::VERSION),
6248 self::OLD_INSTALL_EXT
6249 );
6250
6251 $updatingToTag = !preg_match('{^[0-9a-f]{40}$}', $updateVersion);
6252
6253 $io->write(sprintf("Updating to version <info>%s</info> (%s channel).", $updateVersion, $versionsUtil->getChannel()));
6254 $remoteFilename = $baseUrl . ($updatingToTag ? "/download/{$updateVersion}/composer.phar" : '/composer.phar');
6255 $signature = $remoteFilesystem->getContents(self::HOMEPAGE, $remoteFilename.'.sig', false);
6256 $io->writeError('   ', false);
6257 $remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename, !$input->getOption('no-progress'));
6258 $io->writeError('');
6259
6260 if (!file_exists($tempFilename) || !$signature) {
6261 $io->writeError('<error>The download of the new composer version failed for an unexpected reason</error>');
6262
6263 return 1;
6264 }
6265
6266
6267  if (!extension_loaded('openssl') && $config->get('disable-tls')) {
6268 $io->writeError('<warning>Skipping phar signature verification as you have disabled OpenSSL via config.disable-tls</warning>');
6269 } else {
6270 if (!extension_loaded('openssl')) {
6271 throw new \RuntimeException('The openssl extension is required for phar signatures to be verified but it is not available. '
6272 . 'If you can not enable the openssl extension, you can disable this error, at your own risk, by setting the \'disable-tls\' option to true.');
6273 }
6274
6275 $sigFile = 'file://'.$home.'/' . ($updatingToTag ? 'keys.tags.pub' : 'keys.dev.pub');
6276 if (!file_exists($sigFile)) {
6277 file_put_contents($home.'/keys.dev.pub', <<<DEVPUBKEY
6278 -----BEGIN PUBLIC KEY-----
6279 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnBDHjZS6e0ZMoK3xTD7f
6280 FNCzlXjX/Aie2dit8QXA03pSrOTbaMnxON3hUL47Lz3g1SC6YJEMVHr0zYq4elWi
6281 i3ecFEgzLcj+pZM5X6qWu2Ozz4vWx3JYo1/a/HYdOuW9e3lwS8VtS0AVJA+U8X0A
6282 hZnBmGpltHhO8hPKHgkJtkTUxCheTcbqn4wGHl8Z2SediDcPTLwqezWKUfrYzu1f
6283 o/j3WFwFs6GtK4wdYtiXr+yspBZHO3y1udf8eFFGcb2V3EaLOrtfur6XQVizjOuk
6284 8lw5zzse1Qp/klHqbDRsjSzJ6iL6F4aynBc6Euqt/8ccNAIz0rLjLhOraeyj4eNn
6285 8iokwMKiXpcrQLTKH+RH1JCuOVxQ436bJwbSsp1VwiqftPQieN+tzqy+EiHJJmGf
6286 TBAbWcncicCk9q2md+AmhNbvHO4PWbbz9TzC7HJb460jyWeuMEvw3gNIpEo2jYa9
6287 pMV6cVqnSa+wOc0D7pC9a6bne0bvLcm3S+w6I5iDB3lZsb3A9UtRiSP7aGSo7D72
6288 8tC8+cIgZcI7k9vjvOqH+d7sdOU2yPCnRY6wFh62/g8bDnUpr56nZN1G89GwM4d4
6289 r/TU7BQQIzsZgAiqOGXvVklIgAMiV0iucgf3rNBLjjeNEwNSTTG9F0CtQ+7JLwaE
6290 wSEuAuRm+pRqi8BRnQ/GKUcCAwEAAQ==
6291 -----END PUBLIC KEY-----
6292 DEVPUBKEY
6293 );
6294 file_put_contents($home.'/keys.tags.pub', <<<TAGSPUBKEY
6295 -----BEGIN PUBLIC KEY-----
6296 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0Vi/2K6apCVj76nCnCl2
6297 MQUPdK+A9eqkYBacXo2wQBYmyVlXm2/n/ZsX6pCLYPQTHyr5jXbkQzBw8SKqPdlh
6298 vA7NpbMeNCz7wP/AobvUXM8xQuXKbMDTY2uZ4O7sM+PfGbptKPBGLe8Z8d2sUnTO
6299 bXtX6Lrj13wkRto7st/w/Yp33RHe9SlqkiiS4MsH1jBkcIkEHsRaveZzedUaxY0M
6300 mba0uPhGUInpPzEHwrYqBBEtWvP97t2vtfx8I5qv28kh0Y6t+jnjL1Urid2iuQZf
6301 noCMFIOu4vksK5HxJxxrN0GOmGmwVQjOOtxkwikNiotZGPR4KsVj8NnBrLX7oGuM
6302 nQvGciiu+KoC2r3HDBrpDeBVdOWxDzT5R4iI0KoLzFh2pKqwbY+obNPS2bj+2dgJ
6303 rV3V5Jjry42QOCBN3c88wU1PKftOLj2ECpewY6vnE478IipiEu7EAdK8Zwj2LmTr
6304 RKQUSa9k7ggBkYZWAeO/2Ag0ey3g2bg7eqk+sHEq5ynIXd5lhv6tC5PBdHlWipDK
6305 tl2IxiEnejnOmAzGVivE1YGduYBjN+mjxDVy8KGBrjnz1JPgAvgdwJ2dYw4Rsc/e
6306 TzCFWGk/HM6a4f0IzBWbJ5ot0PIi4amk07IotBXDWwqDiQTwyuGCym5EqWQ2BD95
6307 RGv89BPD+2DLnJysngsvVaUCAwEAAQ==
6308 -----END PUBLIC KEY-----
6309 TAGSPUBKEY
6310 );
6311 }
6312
6313 $pubkeyid = openssl_pkey_get_public($sigFile);
6314 $algo = defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'SHA384';
6315 if (!in_array('SHA384', openssl_get_md_methods())) {
6316 throw new \RuntimeException('SHA384 is not supported by your openssl extension, could not verify the phar file integrity');
6317 }
6318 $signature = json_decode($signature, true);
6319 $signature = base64_decode($signature['sha384']);
6320 $verified = 1 === openssl_verify(file_get_contents($tempFilename), $signature, $pubkeyid, $algo);
6321 openssl_free_key($pubkeyid);
6322 if (!$verified) {
6323 throw new \RuntimeException('The phar signature did not match the file you downloaded, this means your public keys are outdated or that the phar file is corrupt/has been modified');
6324 }
6325 }
6326
6327
6328  if ($input->getOption('clean-backups')) {
6329 $this->cleanBackups($rollbackDir);
6330 }
6331
6332 if ($err = $this->setLocalPhar($localFilename, $tempFilename, $backupFile)) {
6333 @unlink($tempFilename);
6334 $io->writeError('<error>The file is corrupted ('.$err->getMessage().').</error>');
6335 $io->writeError('<error>Please re-run the self-update command to try again.</error>');
6336
6337 return 1;
6338 }
6339
6340 if (file_exists($backupFile)) {
6341 $io->writeError('Use <info>composer self-update --rollback</info> to return to version '.Composer::VERSION);
6342 } else {
6343 $io->writeError('<warning>A backup of the current version could not be written to '.$backupFile.', no rollback possible</warning>');
6344 }
6345 }
6346
6347 protected function fetchKeys(IOInterface $io, Config $config)
6348 {
6349 if (!$io->isInteractive()) {
6350 throw new \RuntimeException('Public keys can not be fetched in non-interactive mode, please run Composer interactively');
6351 }
6352
6353 $io->write('Open <info>https://composer.github.io/pubkeys.html</info> to find the latest keys');
6354
6355 $validator = function ($value) {
6356 if (!preg_match('{^-----BEGIN PUBLIC KEY-----$}', trim($value))) {
6357 throw new \UnexpectedValueException('Invalid input');
6358 }
6359
6360 return trim($value)."\n";
6361 };
6362
6363 $devKey = '';
6364 while (!preg_match('{(-----BEGIN PUBLIC KEY-----.+?-----END PUBLIC KEY-----)}s', $devKey, $match)) {
6365 $devKey = $io->askAndValidate('Enter Dev / Snapshot Public Key (including lines with -----): ', $validator);
6366 while ($line = $io->ask('')) {
6367 $devKey .= trim($line)."\n";
6368 if (trim($line) === '-----END PUBLIC KEY-----') {
6369 break;
6370 }
6371 }
6372 }
6373 file_put_contents($keyPath = $config->get('home').'/keys.dev.pub', $match[0]);
6374 $io->write('Stored key with fingerprint: ' . Keys::fingerprint($keyPath));
6375
6376 $tagsKey = '';
6377 while (!preg_match('{(-----BEGIN PUBLIC KEY-----.+?-----END PUBLIC KEY-----)}s', $tagsKey, $match)) {
6378 $tagsKey = $io->askAndValidate('Enter Tags Public Key (including lines with -----): ', $validator);
6379 while ($line = $io->ask('')) {
6380 $tagsKey .= trim($line)."\n";
6381 if (trim($line) === '-----END PUBLIC KEY-----') {
6382 break;
6383 }
6384 }
6385 }
6386 file_put_contents($keyPath = $config->get('home').'/keys.tags.pub', $match[0]);
6387 $io->write('Stored key with fingerprint: ' . Keys::fingerprint($keyPath));
6388
6389 $io->write('Public keys stored in '.$config->get('home'));
6390 }
6391
6392 protected function rollback(OutputInterface $output, $rollbackDir, $localFilename)
6393 {
6394 $rollbackVersion = $this->getLastBackupVersion($rollbackDir);
6395 if (!$rollbackVersion) {
6396 throw new \UnexpectedValueException('Composer rollback failed: no installation to roll back to in "'.$rollbackDir.'"');
6397 }
6398
6399 $oldFile = $rollbackDir . '/' . $rollbackVersion . self::OLD_INSTALL_EXT;
6400
6401 if (!is_file($oldFile)) {
6402 throw new FilesystemException('Composer rollback failed: "'.$oldFile.'" could not be found');
6403 }
6404 if (!is_readable($oldFile)) {
6405 throw new FilesystemException('Composer rollback failed: "'.$oldFile.'" could not be read');
6406 }
6407
6408 $io = $this->getIO();
6409 $io->writeError(sprintf("Rolling back to version <info>%s</info>.", $rollbackVersion));
6410 if ($err = $this->setLocalPhar($localFilename, $oldFile)) {
6411 $io->writeError('<error>The backup file was corrupted ('.$err->getMessage().').</error>');
6412
6413 return 1;
6414 }
6415
6416 return 0;
6417 }
6418
6419
6420
6421
6422
6423
6424
6425
6426 protected function setLocalPhar($localFilename, $newFilename, $backupTarget = null)
6427 {
6428 try {
6429 @chmod($newFilename, fileperms($localFilename));
6430 if (!ini_get('phar.readonly')) {
6431
6432  $phar = new \Phar($newFilename);
6433
6434  unset($phar);
6435 }
6436
6437
6438  if ($backupTarget && file_exists($localFilename)) {
6439 @copy($localFilename, $backupTarget);
6440 }
6441
6442 rename($newFilename, $localFilename);
6443
6444 return null;
6445 } catch (\Exception $e) {
6446 if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
6447 throw $e;
6448 }
6449
6450 return $e;
6451 }
6452 }
6453
6454 protected function cleanBackups($rollbackDir, $except = null)
6455 {
6456 $finder = $this->getOldInstallationFinder($rollbackDir);
6457 $io = $this->getIO();
6458 $fs = new Filesystem;
6459
6460 foreach ($finder as $file) {
6461 if ($except && $file->getBasename(self::OLD_INSTALL_EXT) === $except) {
6462 continue;
6463 }
6464 $file = (string) $file;
6465 $io->writeError('<info>Removing: '.$file.'</info>');
6466 $fs->remove($file);
6467 }
6468 }
6469
6470 protected function getLastBackupVersion($rollbackDir)
6471 {
6472 $finder = $this->getOldInstallationFinder($rollbackDir);
6473 $finder->sortByName();
6474 $files = iterator_to_array($finder);
6475
6476 if (count($files)) {
6477 return basename(end($files), self::OLD_INSTALL_EXT);
6478 }
6479
6480 return false;
6481 }
6482
6483 protected function getOldInstallationFinder($rollbackDir)
6484 {
6485 $finder = Finder::create()
6486 ->depth(0)
6487 ->files()
6488 ->name('*' . self::OLD_INSTALL_EXT)
6489 ->in($rollbackDir);
6490
6491 return $finder;
6492 }
6493 }
6494 <?php
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506 namespace Composer\Command;
6507
6508 use Composer\DependencyResolver\Pool;
6509 use Composer\DependencyResolver\DefaultPolicy;
6510 use Composer\Json\JsonFile;
6511 use Composer\Package\CompletePackageInterface;
6512 use Composer\Package\Version\VersionParser;
6513 use Composer\Package\BasePackage;
6514 use Composer\Package\Version\VersionSelector;
6515 use Composer\Plugin\CommandEvent;
6516 use Composer\Plugin\PluginEvents;
6517 use Composer\Package\PackageInterface;
6518 use Composer\Semver\Constraint\ConstraintInterface;
6519 use Composer\Util\Platform;
6520 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
6521 use Symfony\Component\Console\Input\InputInterface;
6522 use Symfony\Component\Console\Input\InputArgument;
6523 use Symfony\Component\Console\Input\InputOption;
6524 use Symfony\Component\Console\Output\OutputInterface;
6525 use Composer\Repository\ArrayRepository;
6526 use Composer\Repository\CompositeRepository;
6527 use Composer\Repository\ComposerRepository;
6528 use Composer\Repository\PlatformRepository;
6529 use Composer\Repository\RepositoryInterface;
6530 use Composer\Repository\RepositoryFactory;
6531 use Composer\Spdx\SpdxLicenses;
6532 use Composer\Composer;
6533 use Composer\Semver\Semver;
6534
6535
6536
6537
6538
6539
6540 class ShowCommand extends BaseCommand
6541 {
6542
6543 protected $versionParser;
6544 protected $colors;
6545
6546
6547 private $pool;
6548
6549 protected function configure()
6550 {
6551 $this
6552 ->setName('show')
6553 ->setAliases(array('info'))
6554 ->setDescription('Show information about packages.')
6555 ->setDefinition(array(
6556 new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.'),
6557 new InputArgument('version', InputArgument::OPTIONAL, 'Version or version constraint to inspect'),
6558 new InputOption('all', null, InputOption::VALUE_NONE, 'List all packages'),
6559 new InputOption('installed', 'i', InputOption::VALUE_NONE, 'List installed packages only (enabled by default, only present for BC).'),
6560 new InputOption('platform', 'p', InputOption::VALUE_NONE, 'List platform packages only'),
6561 new InputOption('available', 'a', InputOption::VALUE_NONE, 'List available packages only'),
6562 new InputOption('self', 's', InputOption::VALUE_NONE, 'Show the root package information'),
6563 new InputOption('name-only', 'N', InputOption::VALUE_NONE, 'List package names only'),
6564 new InputOption('path', 'P', InputOption::VALUE_NONE, 'Show package paths'),
6565 new InputOption('tree', 't', InputOption::VALUE_NONE, 'List the dependencies as a tree'),
6566 new InputOption('latest', 'l', InputOption::VALUE_NONE, 'Show the latest version'),
6567 new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show the latest version but only for packages that are outdated'),
6568 new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
6569 new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
6570 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
6571 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
6572 ))
6573 ->setHelp(<<<EOT
6574 The show command displays detailed information about a package, or
6575 lists all packages available.
6576
6577 EOT
6578 )
6579 ;
6580 }
6581
6582 protected function execute(InputInterface $input, OutputInterface $output)
6583 {
6584 $this->versionParser = new VersionParser;
6585 if ($input->getOption('tree')) {
6586 $this->initStyles($output);
6587 }
6588
6589 $composer = $this->getComposer(false);
6590 $io = $this->getIO();
6591
6592 if ($input->getOption('installed')) {
6593 $io->writeError('<warning>You are using the deprecated option "installed". Only installed packages are shown by default now. The --all option can be used to show all packages.</warning>');
6594 }
6595
6596 if ($input->getOption('outdated')) {
6597 $input->setOption('latest', true);
6598 }
6599
6600 if ($input->getOption('direct') && ($input->getOption('all') || $input->getOption('available') || $input->getOption('platform'))) {
6601 $io->writeError('The --direct (-D) option is not usable in combination with --all, --platform (-p) or --available (-a)');
6602
6603 return 1;
6604 }
6605
6606 if ($input->getOption('tree') && ($input->getOption('all') || $input->getOption('available'))) {
6607 $io->writeError('The --tree (-t) option is not usable in combination with --all or --available (-a)');
6608
6609 return 1;
6610 }
6611
6612 $format = $input->getOption('format');
6613 if (!in_array($format, array('text', 'json'))) {
6614 $io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
6615
6616 return 1;
6617 }
6618
6619
6620  $platformOverrides = array();
6621 if ($composer) {
6622 $platformOverrides = $composer->getConfig()->get('platform') ?: array();
6623 }
6624 $platformRepo = new PlatformRepository(array(), $platformOverrides);
6625 $phpVersion = $platformRepo->findPackage('php', '*')->getVersion();
6626
6627 if ($input->getOption('self')) {
6628 $package = $this->getComposer()->getPackage();
6629 $repos = $installedRepo = new ArrayRepository(array($package));
6630 } elseif ($input->getOption('platform')) {
6631 $repos = $installedRepo = $platformRepo;
6632 } elseif ($input->getOption('available')) {
6633 $installedRepo = $platformRepo;
6634 if ($composer) {
6635 $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
6636 } else {
6637 $defaultRepos = RepositoryFactory::defaultRepos($io);
6638 $repos = new CompositeRepository($defaultRepos);
6639 $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
6640 }
6641 } elseif ($input->getOption('all') && $composer) {
6642 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
6643 $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
6644 $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
6645 } elseif ($input->getOption('all')) {
6646 $defaultRepos = RepositoryFactory::defaultRepos($io);
6647 $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
6648 $installedRepo = $platformRepo;
6649 $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
6650 } else {
6651 $repos = $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository();
6652 }
6653
6654 if ($composer) {
6655 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'show', $input, $output);
6656 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
6657 }
6658
6659 if ($input->getOption('latest') && null === $composer) {
6660 $io->writeError('No composer.json found in the current directory, disabling "latest" option');
6661 $input->setOption('latest', false);
6662 }
6663
6664 $packageFilter = $input->getArgument('package');
6665
6666
6667  if (($packageFilter && false === strpos($packageFilter, '*')) || !empty($package)) {
6668 if ('json' === $format) {
6669 $io->writeError('Format "json" is only supported for package listings, falling back to format "text"');
6670 }
6671 if (empty($package)) {
6672 list($package, $versions) = $this->getPackage($installedRepo, $repos, $input->getArgument('package'), $input->getArgument('version'));
6673
6674 if (empty($package)) {
6675 $options = $input->getOptions();
6676 if (!isset($options['working-dir']) || !file_exists('composer.json')) {
6677 throw new \InvalidArgumentException('Package ' . $packageFilter . ' not found');
6678 }
6679
6680 $io->writeError('Package ' . $packageFilter . ' not found in ' . $options['working-dir'] . '/composer.json');
6681
6682 return 1;
6683 }
6684 } else {
6685 $versions = array($package->getPrettyVersion() => $package->getVersion());
6686 }
6687
6688 if ($input->getOption('tree')) {
6689 $this->displayPackageTree($package, $installedRepo, $repos);
6690 } else {
6691 $latestPackage = null;
6692 if ($input->getOption('latest')) {
6693 $latestPackage = $this->findLatestPackage($package, $composer, $phpVersion);
6694 }
6695 $this->printMeta($package, $versions, $installedRepo, $latestPackage ?: null);
6696 $this->printLinks($package, 'requires');
6697 $this->printLinks($package, 'devRequires', 'requires (dev)');
6698 if ($package->getSuggests()) {
6699 $io->write("\n<info>suggests</info>");
6700 foreach ($package->getSuggests() as $suggested => $reason) {
6701 $io->write($suggested . ' <comment>' . $reason . '</comment>');
6702 }
6703 }
6704 $this->printLinks($package, 'provides');
6705 $this->printLinks($package, 'conflicts');
6706 $this->printLinks($package, 'replaces');
6707 }
6708
6709 return;
6710 }
6711
6712
6713  if ($input->getOption('tree')) {
6714 if ('json' === $format) {
6715 $io->writeError('Format "json" is only supported for package listings, falling back to format "text"');
6716 }
6717 $rootRequires = $this->getRootRequires();
6718 foreach ($installedRepo->getPackages() as $package) {
6719 if (in_array($package->getName(), $rootRequires, true)) {
6720 $this->displayPackageTree($package, $installedRepo, $repos);
6721 }
6722 }
6723
6724 return 0;
6725 }
6726
6727 if ($repos instanceof CompositeRepository) {
6728 $repos = $repos->getRepositories();
6729 } elseif (!is_array($repos)) {
6730 $repos = array($repos);
6731 }
6732
6733
6734  $packages = array();
6735 if (null !== $packageFilter) {
6736 $packageFilter = '{^'.str_replace('\\*', '.*?', preg_quote($packageFilter)).'$}i';
6737 }
6738
6739 $packageListFilter = array();
6740 if ($input->getOption('direct')) {
6741 $packageListFilter = $this->getRootRequires();
6742 }
6743
6744 list($width) = $this->getApplication()->getTerminalDimensions();
6745 if (null === $width) {
6746
6747  
6748  $width = PHP_INT_MAX;
6749 }
6750 if (Platform::isWindows()) {
6751 $width--;
6752 }
6753
6754 if ($input->getOption('path') && null === $composer) {
6755 $io->writeError('No composer.json found in the current directory, disabling "path" option');
6756 $input->setOption('path', false);
6757 }
6758
6759 foreach ($repos as $repo) {
6760 if ($repo === $platformRepo) {
6761 $type = 'platform';
6762 } elseif (
6763 $repo === $installedRepo
6764 || ($installedRepo instanceof CompositeRepository && in_array($repo, $installedRepo->getRepositories(), true))
6765 ) {
6766 $type = 'installed';
6767 } else {
6768 $type = 'available';
6769 }
6770 if ($repo instanceof ComposerRepository && $repo->hasProviders()) {
6771 foreach ($repo->getProviderNames() as $name) {
6772 if (!$packageFilter || preg_match($packageFilter, $name)) {
6773 $packages[$type][$name] = $name;
6774 }
6775 }
6776 } else {
6777 foreach ($repo->getPackages() as $package) {
6778 if (!isset($packages[$type][$package->getName()])
6779 || !is_object($packages[$type][$package->getName()])
6780 || version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')
6781 ) {
6782 if (!$packageFilter || preg_match($packageFilter, $package->getName())) {
6783 if (!$packageListFilter || in_array($package->getName(), $packageListFilter, true)) {
6784 $packages[$type][$package->getName()] = $package;
6785 }
6786 }
6787 }
6788 }
6789 }
6790 }
6791
6792 $showAllTypes = $input->getOption('all');
6793 $showLatest = $input->getOption('latest');
6794 $showMinorOnly = $input->getOption('minor-only');
6795 $indent = $showAllTypes ? '  ' : '';
6796 $latestPackages = array();
6797 $exitCode = 0;
6798 $viewData = array();
6799 $viewMetaData = array();
6800 foreach (array('platform' => true, 'available' => false, 'installed' => true) as $type => $showVersion) {
6801 if (isset($packages[$type])) {
6802 ksort($packages[$type]);
6803
6804 $nameLength = $versionLength = $latestLength = 0;
6805 foreach ($packages[$type] as $package) {
6806 if (is_object($package)) {
6807 $nameLength = max($nameLength, strlen($package->getPrettyName()));
6808 if ($showVersion) {
6809 $versionLength = max($versionLength, strlen($package->getFullPrettyVersion()));
6810 if ($showLatest) {
6811 $latestPackage = $this->findLatestPackage($package, $composer, $phpVersion, $showMinorOnly);
6812 if ($latestPackage === false) {
6813 continue;
6814 }
6815
6816 $latestPackages[$package->getPrettyName()] = $latestPackage;
6817 $latestLength = max($latestLength, strlen($latestPackage->getFullPrettyVersion()));
6818 }
6819 }
6820 } else {
6821 $nameLength = max($nameLength, strlen($package));
6822 }
6823 }
6824
6825 $writePath = !$input->getOption('name-only') && $input->getOption('path');
6826 $writeVersion = !$input->getOption('name-only') && !$input->getOption('path') && $showVersion;
6827 $writeLatest = $writeVersion && $showLatest;
6828 $writeDescription = !$input->getOption('name-only') && !$input->getOption('path');
6829
6830 $hasOutdatedPackages = false;
6831
6832 $viewData[$type] = array();
6833 $viewMetaData[$type] = array(
6834 'nameLength' => $nameLength,
6835 'versionLength' => $versionLength,
6836 'latestLength' => $latestLength,
6837 );
6838 foreach ($packages[$type] as $package) {
6839 $packageViewData = array();
6840 if (is_object($package)) {
6841 $latestPackage = null;
6842 if ($showLatest && isset($latestPackages[$package->getPrettyName()])) {
6843 $latestPackage = $latestPackages[$package->getPrettyName()];
6844 }
6845 if ($input->getOption('outdated') && $latestPackage && $latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion() && !$latestPackage->isAbandoned()) {
6846 continue;
6847 } elseif ($input->getOption('outdated')) {
6848 $hasOutdatedPackages = true;
6849 }
6850
6851 $packageViewData['name'] = $package->getPrettyName();
6852 if ($writeVersion) {
6853 $packageViewData['version'] = $package->getFullPrettyVersion();
6854 }
6855 if ($writeLatest && $latestPackage) {
6856 $packageViewData['latest'] = $latestPackage->getFullPrettyVersion();
6857 $packageViewData['latest-status'] = $this->getUpdateStatus($latestPackage, $package);
6858 }
6859 if ($writeDescription) {
6860 $packageViewData['description'] = $package->getDescription();
6861 }
6862 if ($writePath) {
6863 $packageViewData['path'] = strtok(realpath($composer->getInstallationManager()->getInstallPath($package)), "\r\n");
6864 }
6865
6866 if ($latestPackage && $latestPackage->isAbandoned()) {
6867 $replacement = (is_string($latestPackage->getReplacementPackage()))
6868 ? 'Use ' . $latestPackage->getReplacementPackage() . ' instead'
6869 : 'No replacement was suggested';
6870 $packageWarning = sprintf(
6871 'Package %s is abandoned, you should avoid using it. %s.',
6872 $package->getPrettyName(),
6873 $replacement
6874 );
6875 $packageViewData['warning'] = $packageWarning;
6876 }
6877 } else {
6878 $packageViewData['name'] = $package;
6879 }
6880 $viewData[$type][] = $packageViewData;
6881 }
6882 if ($input->getOption('strict') && $hasOutdatedPackages) {
6883 $exitCode = 1;
6884 break;
6885 }
6886 }
6887 }
6888
6889 if ('json' === $format) {
6890 $io->write(JsonFile::encode($viewData));
6891 } else {
6892 foreach ($viewData as $type => $packages) {
6893 $nameLength = $viewMetaData[$type]['nameLength'];
6894 $versionLength = $viewMetaData[$type]['versionLength'];
6895 $latestLength = $viewMetaData[$type]['latestLength'];
6896
6897 $writeVersion = $nameLength + $versionLength + 3 <= $width;
6898 $writeLatest = $nameLength + $versionLength + $latestLength + 3 <= $width;
6899 $writeDescription = $nameLength + $versionLength + $latestLength + 24 <= $width;
6900
6901 if ($writeLatest && !$io->isDecorated()) {
6902 $latestLength += 2;
6903 }
6904
6905 if ($showAllTypes) {
6906 if ('available' === $type) {
6907 $io->write('<comment>' . $type . '</comment>:');
6908 } else {
6909 $io->write('<info>' . $type . '</info>:');
6910 }
6911 }
6912
6913 foreach ($packages as $package) {
6914 $io->write($indent . str_pad($package['name'], $nameLength, ' '), false);
6915 if (isset($package['version']) && $writeVersion) {
6916 $io->write(' ' . str_pad($package['version'], $versionLength, ' '), false);
6917 }
6918 if (isset($package['latest']) && $writeLatest) {
6919 $latestVersion = $package['latest'];
6920 $updateStatus = $package['latest-status'];
6921 $style = $this->updateStatusToVersionStyle($updateStatus);
6922 if (!$io->isDecorated()) {
6923 $latestVersion = str_replace(array('up-to-date', 'semver-safe-update', 'update-possible'), array('=', '!', '~'), $updateStatus) . ' ' . $latestVersion;
6924 }
6925 $io->write(' <' . $style . '>' . str_pad($latestVersion, $latestLength, ' ') . '</' . $style . '>', false);
6926 }
6927 if (isset($package['description']) && $writeDescription) {
6928 $description = strtok($package['description'], "\r\n");
6929 $remaining = $width - $nameLength - $versionLength - 4;
6930 if ($writeLatest) {
6931 $remaining -= $latestLength;
6932 }
6933 if (strlen($description) > $remaining) {
6934 $description = substr($description, 0, $remaining - 3) . '...';
6935 }
6936 $io->write(' ' . $description, false);
6937 }
6938 if (isset($package['path'])) {
6939 $io->write(' ' . $package['path'], false);
6940 }
6941 if (isset($package['warning'])) {
6942 $io->writeError('');
6943 $io->writeError('<warning>' . $package['warning'] . '</warning>', false);
6944 }
6945 $io->write('');
6946 }
6947
6948 if ($showAllTypes) {
6949 $io->write('');
6950 }
6951 }
6952 }
6953
6954 return $exitCode;
6955 }
6956
6957 protected function getRootRequires()
6958 {
6959 $rootPackage = $this->getComposer()->getPackage();
6960
6961 return array_map(
6962 'strtolower',
6963 array_keys(array_merge($rootPackage->getRequires(), $rootPackage->getDevRequires()))
6964 );
6965 }
6966
6967 protected function getVersionStyle(PackageInterface $latestPackage, PackageInterface $package)
6968 {
6969 return $this->updateStatusToVersionStyle($this->getUpdateStatus($latestPackage, $package));
6970 }
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982 protected function getPackage(RepositoryInterface $installedRepo, RepositoryInterface $repos, $name, $version = null)
6983 {
6984 $name = strtolower($name);
6985 $constraint = is_string($version) ? $this->versionParser->parseConstraints($version) : $version;
6986
6987 $policy = new DefaultPolicy();
6988 $pool = new Pool('dev');
6989 $pool->addRepository($repos);
6990
6991 $matchedPackage = null;
6992 $versions = array();
6993 $matches = $pool->whatProvides($name, $constraint);
6994 foreach ($matches as $index => $package) {
6995
6996  if ($package->getName() !== $name) {
6997 unset($matches[$index]);
6998 continue;
6999 }
7000
7001
7002  if (null === $version && $installedRepo->hasPackage($package)) {
7003 $matchedPackage = $package;
7004 }
7005
7006 $versions[$package->getPrettyVersion()] = $package->getVersion();
7007 $matches[$index] = $package->getId();
7008 }
7009
7010
7011  if (!$matchedPackage && $matches && $preferred = $policy->selectPreferredPackages($pool, array(), $matches)) {
7012 $matchedPackage = $pool->literalToPackage($preferred[0]);
7013 }
7014
7015 return array($matchedPackage, $versions);
7016 }
7017
7018
7019
7020
7021
7022
7023
7024
7025 protected function printMeta(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, PackageInterface $latestPackage = null)
7026 {
7027 $io = $this->getIO();
7028 $io->write('<info>name</info>     : ' . $package->getPrettyName());
7029 $io->write('<info>descrip.</info> : ' . $package->getDescription());
7030 $io->write('<info>keywords</info> : ' . implode(', ', $package->getKeywords() ?: array()));
7031 $this->printVersions($package, $versions, $installedRepo);
7032 if ($latestPackage) {
7033 $style = $this->getVersionStyle($latestPackage, $package);
7034 $io->write('<info>latest</info>   : <'.$style.'>' . $latestPackage->getPrettyVersion() . '</'.$style.'>');
7035 } else {
7036 $latestPackage = $package;
7037 }
7038 $io->write('<info>type</info>     : ' . $package->getType());
7039 $this->printLicenses($package);
7040 $io->write('<info>source</info>   : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
7041 $io->write('<info>dist</info>     : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference()));
7042 $io->write('<info>names</info>    : ' . implode(', ', $package->getNames()));
7043
7044 if ($latestPackage->isAbandoned()) {
7045 $replacement = ($latestPackage->getReplacementPackage() !== null)
7046 ? ' The author suggests using the ' . $latestPackage->getReplacementPackage(). ' package instead.'
7047 : null;
7048
7049 $io->writeError(
7050 sprintf('<warning>Attention: This package is abandoned and no longer maintained.%s</warning>', $replacement)
7051 );
7052 }
7053
7054 if ($package->getSupport()) {
7055 $io->write("\n<info>support</info>");
7056 foreach ($package->getSupport() as $type => $value) {
7057 $io->write('<comment>' . $type . '</comment> : '.$value);
7058 }
7059 }
7060
7061 if ($package->getAutoload()) {
7062 $io->write("\n<info>autoload</info>");
7063 foreach ($package->getAutoload() as $type => $autoloads) {
7064 $io->write('<comment>' . $type . '</comment>');
7065
7066 if ($type === 'psr-0') {
7067 foreach ($autoloads as $name => $path) {
7068 $io->write(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
7069 }
7070 } elseif ($type === 'psr-4') {
7071 foreach ($autoloads as $name => $path) {
7072 $io->write(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
7073 }
7074 } elseif ($type === 'classmap') {
7075 $io->write(implode(', ', $autoloads));
7076 }
7077 }
7078 if ($package->getIncludePaths()) {
7079 $io->write('<comment>include-path</comment>');
7080 $io->write(implode(', ', $package->getIncludePaths()));
7081 }
7082 }
7083 }
7084
7085
7086
7087
7088
7089
7090
7091
7092 protected function printVersions(CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo)
7093 {
7094 uasort($versions, 'version_compare');
7095 $versions = array_keys(array_reverse($versions));
7096
7097
7098  if ($installedRepo->hasPackage($package)) {
7099 $installedVersion = $package->getPrettyVersion();
7100 $key = array_search($installedVersion, $versions);
7101 if (false !== $key) {
7102 $versions[$key] = '<info>* ' . $installedVersion . '</info>';
7103 }
7104 }
7105
7106 $versions = implode(', ', $versions);
7107
7108 $this->getIO()->write('<info>versions</info> : ' . $versions);
7109 }
7110
7111
7112
7113
7114
7115
7116
7117
7118 protected function printLinks(CompletePackageInterface $package, $linkType, $title = null)
7119 {
7120 $title = $title ?: $linkType;
7121 $io = $this->getIO();
7122 if ($links = $package->{'get'.ucfirst($linkType)}()) {
7123 $io->write("\n<info>" . $title . "</info>");
7124
7125 foreach ($links as $link) {
7126 $io->write($link->getTarget() . ' <comment>' . $link->getPrettyConstraint() . '</comment>');
7127 }
7128 }
7129 }
7130
7131
7132
7133
7134
7135
7136 protected function printLicenses(CompletePackageInterface $package)
7137 {
7138 $spdxLicenses = new SpdxLicenses();
7139
7140 $licenses = $package->getLicense();
7141 $io = $this->getIO();
7142
7143 foreach ($licenses as $licenseId) {
7144 $license = $spdxLicenses->getLicenseByIdentifier($licenseId); 
7145
7146 if (!$license) {
7147 $out = $licenseId;
7148 } else {
7149
7150  if ($license[1] === true) {
7151 $out = sprintf('%s (%s) (OSI approved) %s', $license[0], $licenseId, $license[2]);
7152 } else {
7153 $out = sprintf('%s (%s) %s', $license[0], $licenseId, $license[2]);
7154 }
7155 }
7156
7157 $io->write('<info>license</info>  : ' . $out);
7158 }
7159 }
7160
7161
7162
7163
7164
7165
7166 protected function initStyles(OutputInterface $output)
7167 {
7168 $this->colors = array(
7169 'green',
7170 'yellow',
7171 'cyan',
7172 'magenta',
7173 'blue',
7174 );
7175
7176 foreach ($this->colors as $color) {
7177 $style = new OutputFormatterStyle($color);
7178 $output->getFormatter()->setStyle($color, $style);
7179 }
7180 }
7181
7182
7183
7184
7185
7186
7187
7188
7189 protected function displayPackageTree(PackageInterface $package, RepositoryInterface $installedRepo, RepositoryInterface $distantRepos)
7190 {
7191 $io = $this->getIO();
7192 $io->write(sprintf('<info>%s</info>', $package->getPrettyName()), false);
7193 $io->write(' ' . $package->getPrettyVersion(), false);
7194 $io->write(' ' . strtok($package->getDescription(), "\r\n"));
7195
7196 if (is_object($package)) {
7197 $requires = $package->getRequires();
7198 $treeBar = '├';
7199 $j = 0;
7200 $total = count($requires);
7201 foreach ($requires as $requireName => $require) {
7202 $j++;
7203 if ($j == 0) {
7204 $this->writeTreeLine($treeBar);
7205 }
7206 if ($j == $total) {
7207 $treeBar = '└';
7208 }
7209 $level = 1;
7210 $color = $this->colors[$level];
7211 $info = sprintf('%s──<%s>%s</%s> %s', $treeBar, $color, $requireName, $color, $require->getPrettyConstraint());
7212 $this->writeTreeLine($info);
7213
7214 $treeBar = str_replace('└', ' ', $treeBar);
7215 $packagesInTree = array($package->getName(), $requireName);
7216
7217 $this->displayTree($requireName, $require, $installedRepo, $distantRepos, $packagesInTree, $treeBar, $level + 1);
7218 }
7219 }
7220 }
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233 protected function displayTree($name, $package, RepositoryInterface $installedRepo, RepositoryInterface $distantRepos, array $packagesInTree, $previousTreeBar = '├', $level = 1)
7234 {
7235 $previousTreeBar = str_replace('├', '│', $previousTreeBar);
7236 list($package, $versions) = $this->getPackage($installedRepo, $distantRepos, $name, $package->getPrettyConstraint() === 'self.version' ? $package->getConstraint() : $package->getPrettyConstraint());
7237 if (is_object($package)) {
7238 $requires = $package->getRequires();
7239 $treeBar = $previousTreeBar . '  ├';
7240 $i = 0;
7241 $total = count($requires);
7242 foreach ($requires as $requireName => $require) {
7243 $currentTree = $packagesInTree;
7244 $i++;
7245 if ($i == $total) {
7246 $treeBar = $previousTreeBar . '  └';
7247 }
7248 $colorIdent = $level % count($this->colors);
7249 $color = $this->colors[$colorIdent];
7250
7251 $circularWarn = in_array($requireName, $currentTree) ? '(circular dependency aborted here)' : '';
7252 $info = rtrim(sprintf('%s──<%s>%s</%s> %s %s', $treeBar, $color, $requireName, $color, $require->getPrettyConstraint(), $circularWarn));
7253 $this->writeTreeLine($info);
7254
7255 $treeBar = str_replace('└', ' ', $treeBar);
7256 if (!in_array($requireName, $currentTree)) {
7257 $currentTree[] = $requireName;
7258 $this->displayTree($requireName, $require, $installedRepo, $distantRepos, $currentTree, $treeBar, $level + 1);
7259 }
7260 }
7261 }
7262 }
7263
7264 private function updateStatusToVersionStyle($updateStatus)
7265 {
7266
7267  
7268  
7269  return str_replace(array('up-to-date', 'semver-safe-update', 'update-possible'), array('info', 'highlight', 'comment'), $updateStatus);
7270 }
7271
7272 private function getUpdateStatus(PackageInterface $latestPackage, PackageInterface $package)
7273 {
7274 if ($latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion()) {
7275 return 'up-to-date';
7276 }
7277
7278 $constraint = $package->getVersion();
7279 if (0 !== strpos($constraint, 'dev-')) {
7280 $constraint = '^'.$constraint;
7281 }
7282 if ($latestPackage->getVersion() && Semver::satisfies($latestPackage->getVersion(), $constraint)) {
7283
7284  return 'semver-safe-update';
7285 }
7286
7287
7288  return 'update-possible';
7289 }
7290
7291 private function writeTreeLine($line)
7292 {
7293 $io = $this->getIO();
7294 if (!$io->isDecorated()) {
7295 $line = str_replace(array('└', '├', '──', '│'), array('`-', '|-', '-', '|'), $line);
7296 }
7297
7298 $io->write($line);
7299 }
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311 private function findLatestPackage(PackageInterface $package, Composer $composer, $phpVersion, $minorOnly = false)
7312 {
7313
7314  $name = $package->getName();
7315 $versionSelector = new VersionSelector($this->getPool($composer));
7316 $stability = $composer->getPackage()->getMinimumStability();
7317 $flags = $composer->getPackage()->getStabilityFlags();
7318 if (isset($flags[$name])) {
7319 $stability = array_search($flags[$name], BasePackage::$stabilities, true);
7320 }
7321
7322 $bestStability = $stability;
7323 if ($composer->getPackage()->getPreferStable()) {
7324 $bestStability = $package->getStability();
7325 }
7326
7327 $targetVersion = null;
7328 if (0 === strpos($package->getVersion(), 'dev-')) {
7329 $targetVersion = $package->getVersion();
7330 }
7331
7332 if ($targetVersion === null && $minorOnly) {
7333 $targetVersion = '^' . $package->getVersion();
7334 }
7335
7336 return $versionSelector->findBestCandidate($name, $targetVersion, $phpVersion, $bestStability);
7337 }
7338
7339 private function getPool(Composer $composer)
7340 {
7341 if (!$this->pool) {
7342 $this->pool = new Pool($composer->getPackage()->getMinimumStability(), $composer->getPackage()->getStabilityFlags());
7343 $this->pool->addRepository(new CompositeRepository($composer->getRepositoryManager()->getRepositories()));
7344 }
7345
7346 return $this->pool;
7347 }
7348 }
7349 <?php
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361 namespace Composer\Command;
7362
7363 use Symfony\Component\Console\Input\InputInterface;
7364 use Symfony\Component\Console\Input\InputOption;
7365 use Symfony\Component\Console\Output\OutputInterface;
7366 use Composer\Downloader\ChangeReportInterface;
7367 use Composer\Downloader\DvcsDownloaderInterface;
7368 use Composer\Downloader\VcsCapableDownloaderInterface;
7369 use Composer\Package\Dumper\ArrayDumper;
7370 use Composer\Package\Version\VersionGuesser;
7371 use Composer\Package\Version\VersionParser;
7372 use Composer\Plugin\CommandEvent;
7373 use Composer\Plugin\PluginEvents;
7374 use Composer\Script\ScriptEvents;
7375 use Composer\Util\ProcessExecutor;
7376
7377
7378
7379
7380
7381 class StatusCommand extends BaseCommand
7382 {
7383 const EXIT_CODE_ERRORS = 1;
7384 const EXIT_CODE_UNPUSHED_CHANGES = 2;
7385 const EXIT_CODE_VERSION_CHANGES = 4;
7386
7387 protected function configure()
7388 {
7389 $this
7390 ->setName('status')
7391 ->setDescription('Show a list of locally modified packages.')
7392 ->setDefinition(array(
7393 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Show modified files for each directory that contains changes.'),
7394 ))
7395 ->setHelp(<<<EOT
7396 The status command displays a list of dependencies that have
7397 been modified locally.
7398
7399 EOT
7400 )
7401 ;
7402 }
7403
7404 protected function execute(InputInterface $input, OutputInterface $output)
7405 {
7406
7407  $composer = $this->getComposer();
7408
7409 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'status', $input, $output);
7410 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
7411
7412 $installedRepo = $composer->getRepositoryManager()->getLocalRepository();
7413
7414 $dm = $composer->getDownloadManager();
7415 $im = $composer->getInstallationManager();
7416
7417
7418  $composer->getEventDispatcher()->dispatchScript(ScriptEvents::PRE_STATUS_CMD, true);
7419
7420 $errors = array();
7421 $io = $this->getIO();
7422 $unpushedChanges = array();
7423 $vcsVersionChanges = array();
7424
7425 $parser = new VersionParser;
7426 $guesser = new VersionGuesser($composer->getConfig(), new ProcessExecutor($io), $parser);
7427 $dumper = new ArrayDumper;
7428
7429
7430  foreach ($installedRepo->getCanonicalPackages() as $package) {
7431 $downloader = $dm->getDownloaderForInstalledPackage($package);
7432 $targetDir = $im->getInstallPath($package);
7433
7434 if ($downloader instanceof ChangeReportInterface) {
7435 if (is_link($targetDir)) {
7436 $errors[$targetDir] = $targetDir . ' is a symbolic link.';
7437 }
7438
7439 if ($changes = $downloader->getLocalChanges($package, $targetDir)) {
7440 $errors[$targetDir] = $changes;
7441 }
7442 }
7443
7444 if ($downloader instanceof VcsCapableDownloaderInterface) {
7445 if ($currentRef = $downloader->getVcsReference($package, $targetDir)) {
7446 switch ($package->getInstallationSource()) {
7447 case 'source':
7448 $previousRef = $package->getSourceReference();
7449 break;
7450 case 'dist':
7451 $previousRef = $package->getDistReference();
7452 break;
7453 default:
7454 $previousRef = null;
7455 }
7456
7457 $currentVersion = $guesser->guessVersion($dumper->dump($package), $targetDir);
7458
7459 if ($previousRef && $currentVersion && $currentVersion['commit'] !== $previousRef) {
7460 $vcsVersionChanges[$targetDir] = array(
7461 'previous' => array(
7462 'version' => $package->getPrettyVersion(),
7463 'ref' => $previousRef,
7464 ),
7465 'current' => array(
7466 'version' => $currentVersion['pretty_version'],
7467 'ref' => $currentVersion['commit'],
7468 ),
7469 );
7470 }
7471 }
7472 }
7473
7474 if ($downloader instanceof DvcsDownloaderInterface) {
7475 if ($unpushed = $downloader->getUnpushedChanges($package, $targetDir)) {
7476 $unpushedChanges[$targetDir] = $unpushed;
7477 }
7478 }
7479 }
7480
7481
7482  if (!$errors && !$unpushedChanges && !$vcsVersionChanges) {
7483 $io->writeError('<info>No local changes</info>');
7484
7485 return 0;
7486 }
7487
7488 if ($errors) {
7489 $io->writeError('<error>You have changes in the following dependencies:</error>');
7490
7491 foreach ($errors as $path => $changes) {
7492 if ($input->getOption('verbose')) {
7493 $indentedChanges = implode("\n", array_map(function ($line) {
7494 return '    ' . ltrim($line);
7495 }, explode("\n", $changes)));
7496 $io->write('<info>'.$path.'</info>:');
7497 $io->write($indentedChanges);
7498 } else {
7499 $io->write($path);
7500 }
7501 }
7502 }
7503
7504 if ($unpushedChanges) {
7505 $io->writeError('<warning>You have unpushed changes on the current branch in the following dependencies:</warning>');
7506
7507 foreach ($unpushedChanges as $path => $changes) {
7508 if ($input->getOption('verbose')) {
7509 $indentedChanges = implode("\n", array_map(function ($line) {
7510 return '    ' . ltrim($line);
7511 }, explode("\n", $changes)));
7512 $io->write('<info>'.$path.'</info>:');
7513 $io->write($indentedChanges);
7514 } else {
7515 $io->write($path);
7516 }
7517 }
7518 }
7519
7520 if ($vcsVersionChanges) {
7521 $io->writeError('<warning>You have version variations in the following dependencies:</warning>');
7522
7523 foreach ($vcsVersionChanges as $path => $changes) {
7524 if ($input->getOption('verbose')) {
7525
7526  $currentVersion = $changes['current']['version'] ?: $changes['current']['ref'];
7527 $previousVersion = $changes['previous']['version'] ?: $changes['previous']['ref'];
7528
7529 if ($io->isVeryVerbose()) {
7530
7531  $currentVersion .= sprintf(' (%s)', $changes['current']['ref']);
7532 $previousVersion .= sprintf(' (%s)', $changes['previous']['ref']);
7533 }
7534
7535 $io->write('<info>'.$path.'</info>:');
7536 $io->write(sprintf('    From <comment>%s</comment> to <comment>%s</comment>', $previousVersion, $currentVersion));
7537 } else {
7538 $io->write($path);
7539 }
7540 }
7541 }
7542
7543 if (($errors || $unpushedChanges || $vcsVersionChanges) && !$input->getOption('verbose')) {
7544 $io->writeError('Use --verbose (-v) to see a list of files');
7545 }
7546
7547
7548  $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_STATUS_CMD, true);
7549
7550 return ($errors ? self::EXIT_CODE_ERRORS : 0) + ($unpushedChanges ? self::EXIT_CODE_UNPUSHED_CHANGES : 0) + ($vcsVersionChanges ? self::EXIT_CODE_VERSION_CHANGES : 0);
7551 }
7552 }
7553 <?php
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565 namespace Composer\Command;
7566
7567 use Composer\Repository\PlatformRepository;
7568 use Symfony\Component\Console\Input\InputArgument;
7569 use Symfony\Component\Console\Input\InputInterface;
7570 use Symfony\Component\Console\Input\InputOption;
7571 use Symfony\Component\Console\Output\OutputInterface;
7572
7573 class SuggestsCommand extends BaseCommand
7574 {
7575 protected function configure()
7576 {
7577 $this
7578 ->setName('suggests')
7579 ->setDescription('Show package suggestions.')
7580 ->setDefinition(array(
7581 new InputOption('by-package', null, InputOption::VALUE_NONE, 'Groups output by suggesting package'),
7582 new InputOption('by-suggestion', null, InputOption::VALUE_NONE, 'Groups output by suggested package'),
7583 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Exclude suggestions from require-dev packages'),
7584 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that you want to list suggestions from.'),
7585 ))
7586 ->setHelp(<<<EOT
7587
7588 The <info>%command.name%</info> command shows a sorted list of suggested packages.
7589
7590 Enabling <info>-v</info> implies <info>--by-package --by-suggestion</info>, showing both lists.
7591
7592 EOT
7593 )
7594 ;
7595 }
7596
7597 protected function execute(InputInterface $input, OutputInterface $output)
7598 {
7599 $lock = $this->getComposer()->getLocker()->getLockData();
7600
7601 if (empty($lock)) {
7602 throw new \RuntimeException('Lockfile seems to be empty?');
7603 }
7604
7605 $packages = $lock['packages'];
7606
7607 if (!$input->getOption('no-dev')) {
7608 $packages += $lock['packages-dev'];
7609 }
7610
7611 $filter = $input->getArgument('packages');
7612
7613
7614  $installed = array();
7615 foreach ($packages as $package) {
7616 $installed[] = $package['name'];
7617
7618 if (!empty($package['provide'])) {
7619 $installed = array_merge($installed, array_keys($package['provide']));
7620 }
7621
7622 if (!empty($package['replace'])) {
7623 $installed = array_merge($installed, array_keys($package['replace']));
7624 }
7625 }
7626
7627
7628  $installed = array_flip($installed);
7629 ksort($installed);
7630
7631
7632  $platform = new PlatformRepository(array(), $this->getComposer()->getConfig()->get('platform') ?: array());
7633
7634
7635  $suggesters = array();
7636 $suggested = array();
7637 foreach ($packages as $package) {
7638 $packageName = $package['name'];
7639 if ((!empty($filter) && !in_array($packageName, $filter)) || empty($package['suggest'])) {
7640 continue;
7641 }
7642 foreach ($package['suggest'] as $suggestion => $reason) {
7643 if (false === strpos('/', $suggestion) && !is_null($platform->findPackage($suggestion, '*'))) {
7644 continue;
7645 }
7646 if (!isset($installed[$suggestion])) {
7647 $suggesters[$packageName][$suggestion] = $reason;
7648 $suggested[$suggestion][$packageName] = $reason;
7649 }
7650 }
7651 }
7652 ksort($suggesters);
7653 ksort($suggested);
7654
7655
7656  $mode = 0;
7657 $io = $this->getIO();
7658 if ($input->getOption('by-package') || $io->isVerbose()) {
7659 $mode |= 1;
7660 }
7661 if ($input->getOption('by-suggestion')) {
7662 $mode |= 2;
7663 }
7664
7665
7666  if ($mode === 0) {
7667 foreach (array_keys($suggested) as $suggestion) {
7668 $io->write(sprintf('<info>%s</info>', $suggestion));
7669 }
7670
7671 return;
7672 }
7673
7674
7675  if ($mode & 1) {
7676 foreach ($suggesters as $suggester => $suggestions) {
7677 $io->write(sprintf('<comment>%s</comment> suggests:', $suggester));
7678
7679 foreach ($suggestions as $suggestion => $reason) {
7680 $io->write(sprintf(' - <info>%s</info>: %s', $suggestion, $reason ?: '*'));
7681 }
7682 $io->write('');
7683 }
7684 }
7685
7686
7687  if ($mode & 2) {
7688
7689  if ($mode & 1) {
7690 $io->write(str_repeat('-', 78));
7691 }
7692 foreach ($suggested as $suggestion => $suggesters) {
7693 $io->write(sprintf('<comment>%s</comment> is suggested by:', $suggestion));
7694
7695 foreach ($suggesters as $suggester => $reason) {
7696 $io->write(sprintf(' - <info>%s</info>: %s', $suggester, $reason ?: '*'));
7697 }
7698 $io->write('');
7699 }
7700 }
7701 }
7702 }
7703 <?php
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715 namespace Composer\Command;
7716
7717 use Composer\Composer;
7718 use Composer\Installer;
7719 use Composer\IO\IOInterface;
7720 use Composer\Plugin\CommandEvent;
7721 use Composer\Plugin\PluginEvents;
7722 use Symfony\Component\Console\Helper\Table;
7723 use Symfony\Component\Console\Input\InputInterface;
7724 use Symfony\Component\Console\Input\InputOption;
7725 use Symfony\Component\Console\Input\InputArgument;
7726 use Symfony\Component\Console\Output\OutputInterface;
7727 use Symfony\Component\Console\Question\Question;
7728
7729
7730
7731
7732
7733 class UpdateCommand extends BaseCommand
7734 {
7735 protected function configure()
7736 {
7737 $this
7738 ->setName('update')
7739 ->setDescription('Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file.')
7740 ->setDefinition(array(
7741 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be updated, if not provided all packages are.'),
7742 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
7743 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist even for dev versions.'),
7744 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
7745 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
7746 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
7747 new InputOption('lock', null, InputOption::VALUE_NONE, 'Only updates the lock file hash to suppress warning about the lock file being out of date.'),
7748 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
7749 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
7750 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
7751 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
7752 new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'Do not show package suggestions.'),
7753 new InputOption('with-dependencies', null, InputOption::VALUE_NONE, 'Add also all dependencies of whitelisted packages to the whitelist.'),
7754 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
7755 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'),
7756 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
7757 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
7758 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'),
7759 new InputOption('prefer-stable', null, InputOption::VALUE_NONE, 'Prefer stable versions of dependencies.'),
7760 new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies.'),
7761 new InputOption('interactive', 'i', InputOption::VALUE_NONE, 'Interactive interface with autocompletion to select the packages to update.'),
7762 new InputOption('root-reqs', null, InputOption::VALUE_NONE, 'Restricts the update to your first degree dependencies.'),
7763 ))
7764 ->setHelp(<<<EOT
7765 The <info>update</info> command reads the composer.json file from the
7766 current directory, processes it, and updates, removes or installs all the
7767 dependencies.
7768
7769 <info>php composer.phar update</info>
7770
7771 To limit the update operation to a few packages, you can list the package(s)
7772 you want to update as such:
7773
7774 <info>php composer.phar update vendor/package1 foo/mypackage [...]</info>
7775
7776 You may also use an asterisk (*) pattern to limit the update operation to package(s)
7777 from a specific vendor:
7778
7779 <info>php composer.phar update vendor/package1 foo/* [...]</info>
7780
7781 To select packages names interactively with auto-completion use <info>-i</info>.
7782
7783 EOT
7784 )
7785 ;
7786 }
7787
7788 protected function execute(InputInterface $input, OutputInterface $output)
7789 {
7790 $io = $this->getIO();
7791 if ($input->getOption('no-custom-installers')) {
7792 $io->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
7793 $input->setOption('no-plugins', true);
7794 }
7795
7796 if ($input->getOption('dev')) {
7797 $io->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
7798 }
7799
7800 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
7801
7802 $packages = $input->getArgument('packages');
7803
7804 if ($input->getOption('interactive')) {
7805 $packages = $this->getPackagesInteractively($io, $input, $output, $composer, $packages);
7806 }
7807
7808 if ($input->getOption('root-reqs')) {
7809 $require = array_keys($composer->getPackage()->getRequires());
7810 if (!$input->getOption('no-dev')) {
7811 $requireDev = array_keys($composer->getPackage()->getDevRequires());
7812 $require = array_merge($require, $requireDev);
7813 }
7814
7815 if (!empty($packages)) {
7816 $packages = array_intersect($packages, $require);
7817 } else {
7818 $packages = $require;
7819 }
7820 }
7821
7822 $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
7823
7824 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'update', $input, $output);
7825 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
7826
7827 $install = Installer::create($io, $composer);
7828
7829 $config = $composer->getConfig();
7830 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
7831
7832 $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
7833 $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
7834 $apcu = $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader');
7835
7836 $install
7837 ->setDryRun($input->getOption('dry-run'))
7838 ->setVerbose($input->getOption('verbose'))
7839 ->setPreferSource($preferSource)
7840 ->setPreferDist($preferDist)
7841 ->setDevMode(!$input->getOption('no-dev'))
7842 ->setDumpAutoloader(!$input->getOption('no-autoloader'))
7843 ->setRunScripts(!$input->getOption('no-scripts'))
7844 ->setSkipSuggest($input->getOption('no-suggest'))
7845 ->setOptimizeAutoloader($optimize)
7846 ->setClassMapAuthoritative($authoritative)
7847 ->setApcuAutoloader($apcu)
7848 ->setUpdate(true)
7849 ->setUpdateWhitelist($input->getOption('lock') ? array('lock') : $packages)
7850 ->setWhitelistDependencies($input->getOption('with-dependencies'))
7851 ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
7852 ->setPreferStable($input->getOption('prefer-stable'))
7853 ->setPreferLowest($input->getOption('prefer-lowest'))
7854 ;
7855
7856 if ($input->getOption('no-plugins')) {
7857 $install->disablePlugins();
7858 }
7859
7860 return $install->run();
7861 }
7862
7863 private function getPackagesInteractively(IOInterface $io, InputInterface $input, OutputInterface $output, Composer $composer, array $packages)
7864 {
7865 if (!$input->isInteractive()) {
7866 throw new \InvalidArgumentException('--interactive cannot be used in non-interactive terminals.');
7867 }
7868
7869 $requires = array_merge(
7870 $composer->getPackage()->getRequires(),
7871 $composer->getPackage()->getDevRequires()
7872 );
7873 $autocompleterValues = array();
7874 foreach ($requires as $require) {
7875 $autocompleterValues[strtolower($require->getTarget())] = $require->getTarget();
7876 }
7877
7878 $installedPackages = $composer->getRepositoryManager()->getLocalRepository()->getPackages();
7879 foreach ($installedPackages as $package) {
7880 $autocompleterValues[$package->getName()] = $package->getPrettyName();
7881 }
7882
7883 $helper = $this->getHelper('question');
7884 $question = new Question('<comment>Enter package name: </comment>', null);
7885
7886 $io->writeError('<info>Press enter without value to end submission</info>');
7887
7888 do {
7889 $autocompleterValues = array_diff($autocompleterValues, $packages);
7890 $question->setAutocompleterValues($autocompleterValues);
7891 $addedPackage = $helper->ask($input, $output, $question);
7892
7893 if (!is_string($addedPackage) || empty($addedPackage)) {
7894 break;
7895 }
7896
7897 $addedPackage = strtolower($addedPackage);
7898 if (!in_array($addedPackage, $packages)) {
7899 $packages[] = $addedPackage;
7900 }
7901 } while (true);
7902
7903 $packages = array_filter($packages);
7904 if (!$packages) {
7905 throw new \InvalidArgumentException('You must enter minimum one package.');
7906 }
7907
7908 $table = new Table($output);
7909 $table->setHeaders(array('Selected packages'));
7910 foreach ($packages as $package) {
7911 $table->addRow(array($package));
7912 }
7913 $table->render();
7914
7915 if ($io->askConfirmation(sprintf(
7916 'Would you like to continue and update the above package%s [<comment>yes</comment>]? ',
7917 1 === count($packages) ? '' : 's'
7918 ), true)) {
7919 return $packages;
7920 }
7921
7922 throw new \RuntimeException('Installation aborted.');
7923 }
7924 }
7925 <?php
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937 namespace Composer\Command;
7938
7939 use Composer\Factory;
7940 use Composer\Package\Loader\ValidatingArrayLoader;
7941 use Composer\Plugin\CommandEvent;
7942 use Composer\Plugin\PluginEvents;
7943 use Composer\Util\ConfigValidator;
7944 use Symfony\Component\Console\Input\InputArgument;
7945 use Symfony\Component\Console\Input\InputInterface;
7946 use Symfony\Component\Console\Input\InputOption;
7947 use Symfony\Component\Console\Output\OutputInterface;
7948
7949
7950
7951
7952
7953
7954
7955 class ValidateCommand extends BaseCommand
7956 {
7957
7958
7959
7960 protected function configure()
7961 {
7962 $this
7963 ->setName('validate')
7964 ->setDescription('Validates a composer.json and composer.lock.')
7965 ->setDefinition(array(
7966 new InputOption('no-check-all', null, InputOption::VALUE_NONE, 'Do not make a complete validation'),
7967 new InputOption('no-check-lock', null, InputOption::VALUE_NONE, 'Do not check if lock file is up to date'),
7968 new InputOption('no-check-publish', null, InputOption::VALUE_NONE, 'Do not check for publish errors'),
7969 new InputOption('with-dependencies', 'A', InputOption::VALUE_NONE, 'Also validate the composer.json of all installed dependencies'),
7970 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code for warnings as well as errors'),
7971 new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file', './composer.json'),
7972 ))
7973 ->setHelp(<<<EOT
7974 The validate command validates a given composer.json and composer.lock
7975
7976 Exit codes in case of errors are:
7977 1 validation warning(s), only when --strict is given
7978 2 validation error(s)
7979 3 file unreadable or missing
7980
7981 EOT
7982 );
7983 }
7984
7985
7986
7987
7988
7989
7990
7991 protected function execute(InputInterface $input, OutputInterface $output)
7992 {
7993 $file = $input->getArgument('file');
7994 $io = $this->getIO();
7995
7996 if (!file_exists($file)) {
7997 $io->writeError('<error>' . $file . ' not found.</error>');
7998
7999 return 3;
8000 }
8001 if (!is_readable($file)) {
8002 $io->writeError('<error>' . $file . ' is not readable.</error>');
8003
8004 return 3;
8005 }
8006
8007 $validator = new ConfigValidator($io);
8008 $checkAll = $input->getOption('no-check-all') ? 0 : ValidatingArrayLoader::CHECK_ALL;
8009 $checkPublish = !$input->getOption('no-check-publish');
8010 $checkLock = !$input->getOption('no-check-lock');
8011 $isStrict = $input->getOption('strict');
8012 list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll);
8013
8014 $lockErrors = array();
8015 $composer = Factory::create($io, $file);
8016 $locker = $composer->getLocker();
8017 if ($locker->isLocked() && !$locker->isFresh()) {
8018 $lockErrors[] = 'The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update`.';
8019 }
8020
8021 $this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true);
8022
8023 $exitCode = $errors || ($publishErrors && $checkPublish) || ($lockErrors && $checkLock) ? 2 : ($isStrict && $warnings ? 1 : 0);
8024
8025 if ($input->getOption('with-dependencies')) {
8026 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
8027 foreach ($localRepo->getPackages() as $package) {
8028 $path = $composer->getInstallationManager()->getInstallPath($package);
8029 $file = $path . '/composer.json';
8030 if (is_dir($path) && file_exists($file)) {
8031 list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll);
8032 $this->outputResult($io, $package->getPrettyName(), $errors, $warnings, $checkPublish, $publishErrors);
8033
8034 $depCode = $errors || ($publishErrors && $checkPublish) ? 2 : ($isStrict && $warnings ? 1 : 0);
8035 $exitCode = max($depCode, $exitCode);
8036 }
8037 }
8038 }
8039
8040 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'validate', $input, $output);
8041 $eventCode = $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
8042 $exitCode = max($eventCode, $exitCode);
8043
8044 return $exitCode;
8045 }
8046
8047 private function outputResult($io, $name, &$errors, &$warnings, $checkPublish = false, $publishErrors = array(), $checkLock = false, $lockErrors = array(), $printSchemaUrl = false)
8048 {
8049 if (!$errors && !$publishErrors && !$warnings) {
8050 $io->write('<info>' . $name . ' is valid</info>');
8051 } elseif (!$errors && !$publishErrors) {
8052 $io->writeError('<info>' . $name . ' is valid, but with a few warnings</info>');
8053 if ($printSchemaUrl) {
8054 $io->writeError('<warning>See https://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
8055 }
8056 } elseif (!$errors) {
8057 $io->writeError('<info>' . $name . ' is valid for simple usage with composer but has</info>');
8058 $io->writeError('<info>strict errors that make it unable to be published as a package:</info>');
8059 if ($printSchemaUrl) {
8060 $io->writeError('<warning>See https://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
8061 }
8062 } else {
8063 $io->writeError('<error>' . $name . ' is invalid, the following errors/warnings were found:</error>');
8064 }
8065
8066
8067  if ($checkPublish) {
8068 $errors = array_merge($errors, $publishErrors);
8069 } else {
8070 $warnings = array_merge($warnings, $publishErrors);
8071 }
8072
8073
8074  if ($checkLock) {
8075 $errors = array_merge($errors, $lockErrors);
8076 } else {
8077 $warnings = array_merge($warnings, $lockErrors);
8078 }
8079
8080 $messages = array(
8081 'error' => $errors,
8082 'warning' => $warnings,
8083 );
8084
8085 foreach ($messages as $style => $msgs) {
8086 foreach ($msgs as $msg) {
8087 $io->writeError('<' . $style . '>' . $msg . '</' . $style . '>');
8088 }
8089 }
8090 }
8091 }
8092 <?php
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104 namespace Composer;
8105
8106 use Composer\Package\RootPackageInterface;
8107 use Composer\Package\Locker;
8108 use Composer\Repository\RepositoryManager;
8109 use Composer\Installer\InstallationManager;
8110 use Composer\Plugin\PluginManager;
8111 use Composer\Downloader\DownloadManager;
8112 use Composer\EventDispatcher\EventDispatcher;
8113 use Composer\Autoload\AutoloadGenerator;
8114
8115
8116
8117
8118
8119
8120 class Composer
8121 {
8122 const VERSION = '1.4.1';
8123 const BRANCH_ALIAS_VERSION = '';
8124 const RELEASE_DATE = '2017-03-10 09:29:45';
8125
8126
8127
8128
8129 private $package;
8130
8131
8132
8133
8134 private $locker;
8135
8136
8137
8138
8139 private $repositoryManager;
8140
8141
8142
8143
8144 private $downloadManager;
8145
8146
8147
8148
8149 private $installationManager;
8150
8151
8152
8153
8154 private $pluginManager;
8155
8156
8157
8158
8159 private $config;
8160
8161
8162
8163
8164 private $eventDispatcher;
8165
8166
8167
8168
8169 private $autoloadGenerator;
8170
8171
8172
8173
8174
8175 public function setPackage(RootPackageInterface $package)
8176 {
8177 $this->package = $package;
8178 }
8179
8180
8181
8182
8183 public function getPackage()
8184 {
8185 return $this->package;
8186 }
8187
8188
8189
8190
8191 public function setConfig(Config $config)
8192 {
8193 $this->config = $config;
8194 }
8195
8196
8197
8198
8199 public function getConfig()
8200 {
8201 return $this->config;
8202 }
8203
8204
8205
8206
8207 public function setLocker(Locker $locker)
8208 {
8209 $this->locker = $locker;
8210 }
8211
8212
8213
8214
8215 public function getLocker()
8216 {
8217 return $this->locker;
8218 }
8219
8220
8221
8222
8223 public function setRepositoryManager(RepositoryManager $manager)
8224 {
8225 $this->repositoryManager = $manager;
8226 }
8227
8228
8229
8230
8231 public function getRepositoryManager()
8232 {
8233 return $this->repositoryManager;
8234 }
8235
8236
8237
8238
8239 public function setDownloadManager(DownloadManager $manager)
8240 {
8241 $this->downloadManager = $manager;
8242 }
8243
8244
8245
8246
8247 public function getDownloadManager()
8248 {
8249 return $this->downloadManager;
8250 }
8251
8252
8253
8254
8255 public function setInstallationManager(InstallationManager $manager)
8256 {
8257 $this->installationManager = $manager;
8258 }
8259
8260
8261
8262
8263 public function getInstallationManager()
8264 {
8265 return $this->installationManager;
8266 }
8267
8268
8269
8270
8271 public function setPluginManager(PluginManager $manager)
8272 {
8273 $this->pluginManager = $manager;
8274 }
8275
8276
8277
8278
8279 public function getPluginManager()
8280 {
8281 return $this->pluginManager;
8282 }
8283
8284
8285
8286
8287 public function setEventDispatcher(EventDispatcher $eventDispatcher)
8288 {
8289 $this->eventDispatcher = $eventDispatcher;
8290 }
8291
8292
8293
8294
8295 public function getEventDispatcher()
8296 {
8297 return $this->eventDispatcher;
8298 }
8299
8300
8301
8302
8303 public function setAutoloadGenerator(AutoloadGenerator $autoloadGenerator)
8304 {
8305 $this->autoloadGenerator = $autoloadGenerator;
8306 }
8307
8308
8309
8310
8311 public function getAutoloadGenerator()
8312 {
8313 return $this->autoloadGenerator;
8314 }
8315 }
8316 <?php
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328 namespace Composer;
8329
8330 use Composer\Config\ConfigSourceInterface;
8331 use Composer\Downloader\TransportException;
8332 use Composer\IO\IOInterface;
8333 use Composer\Util\Platform;
8334
8335
8336
8337
8338 class Config
8339 {
8340 const RELATIVE_PATHS = 1;
8341
8342 public static $defaultConfig = array(
8343 'process-timeout' => 300,
8344 'use-include-path' => false,
8345 'preferred-install' => 'auto',
8346 'notify-on-install' => true,
8347 'github-protocols' => array('https', 'ssh', 'git'),
8348 'vendor-dir' => 'vendor',
8349 'bin-dir' => '{$vendor-dir}/bin',
8350 'cache-dir' => '{$home}/cache',
8351 'data-dir' => '{$home}',
8352 'cache-files-dir' => '{$cache-dir}/files',
8353 'cache-repo-dir' => '{$cache-dir}/repo',
8354 'cache-vcs-dir' => '{$cache-dir}/vcs',
8355 'cache-ttl' => 15552000, 
8356  'cache-files-ttl' => null, 
8357  'cache-files-maxsize' => '300MiB',
8358 'bin-compat' => 'auto',
8359 'discard-changes' => false,
8360 'autoloader-suffix' => null,
8361 'sort-packages' => false,
8362 'optimize-autoloader' => false,
8363 'classmap-authoritative' => false,
8364 'apcu-autoloader' => false,
8365 'prepend-autoloader' => true,
8366 'github-domains' => array('github.com'),
8367 'bitbucket-expose-hostname' => true,
8368 'disable-tls' => false,
8369 'secure-http' => true,
8370 'cafile' => null,
8371 'capath' => null,
8372 'github-expose-hostname' => true,
8373 'gitlab-domains' => array('gitlab.com'),
8374 'store-auths' => 'prompt',
8375 'platform' => array(),
8376 'archive-format' => 'tar',
8377 'archive-dir' => '.',
8378
8379  
8380  
8381  
8382  
8383  
8384  );
8385
8386 public static $defaultRepositories = array(
8387 'packagist.org' => array(
8388 'type' => 'composer',
8389 'url' => 'https?://packagist.org',
8390 'allow_ssl_downgrade' => true,
8391 ),
8392 );
8393
8394 private $config;
8395 private $baseDir;
8396 private $repositories;
8397
8398 private $configSource;
8399
8400 private $authConfigSource;
8401 private $useEnvironment;
8402 private $warnedHosts = array();
8403
8404
8405
8406
8407
8408 public function __construct($useEnvironment = true, $baseDir = null)
8409 {
8410
8411  $this->config = static::$defaultConfig;
8412 $this->repositories = static::$defaultRepositories;
8413 $this->useEnvironment = (bool) $useEnvironment;
8414 $this->baseDir = $baseDir;
8415 }
8416
8417 public function setConfigSource(ConfigSourceInterface $source)
8418 {
8419 $this->configSource = $source;
8420 }
8421
8422 public function getConfigSource()
8423 {
8424 return $this->configSource;
8425 }
8426
8427 public function setAuthConfigSource(ConfigSourceInterface $source)
8428 {
8429 $this->authConfigSource = $source;
8430 }
8431
8432 public function getAuthConfigSource()
8433 {
8434 return $this->authConfigSource;
8435 }
8436
8437
8438
8439
8440
8441
8442 public function merge($config)
8443 {
8444
8445  if (!empty($config['config']) && is_array($config['config'])) {
8446 foreach ($config['config'] as $key => $val) {
8447 if (in_array($key, array('bitbucket-oauth', 'github-oauth', 'gitlab-oauth', 'gitlab-token', 'http-basic')) && isset($this->config[$key])) {
8448 $this->config[$key] = array_merge($this->config[$key], $val);
8449 } elseif ('preferred-install' === $key && isset($this->config[$key])) {
8450 if (is_array($val) || is_array($this->config[$key])) {
8451 if (is_string($val)) {
8452 $val = array('*' => $val);
8453 }
8454 if (is_string($this->config[$key])) {
8455 $this->config[$key] = array('*' => $this->config[$key]);
8456 }
8457 $this->config[$key] = array_merge($this->config[$key], $val);
8458
8459  if (isset($this->config[$key]['*'])) {
8460 $wildcard = $this->config[$key]['*'];
8461 unset($this->config[$key]['*']);
8462 $this->config[$key]['*'] = $wildcard;
8463 }
8464 } else {
8465 $this->config[$key] = $val;
8466 }
8467 } else {
8468 $this->config[$key] = $val;
8469 }
8470 }
8471 }
8472
8473 if (!empty($config['repositories']) && is_array($config['repositories'])) {
8474 $this->repositories = array_reverse($this->repositories, true);
8475 $newRepos = array_reverse($config['repositories'], true);
8476 foreach ($newRepos as $name => $repository) {
8477
8478  if (false === $repository) {
8479 $this->disableRepoByName($name);
8480 continue;
8481 }
8482
8483
8484  if (is_array($repository) && 1 === count($repository) && false === current($repository)) {
8485 $this->disableRepoByName(key($repository));
8486 continue;
8487 }
8488
8489
8490  if (is_int($name)) {
8491 $this->repositories[] = $repository;
8492 } else {
8493 if ($name === 'packagist') { 
8494  $this->repositories[$name . '.org'] = $repository;
8495 } else {
8496 $this->repositories[$name] = $repository;
8497 }
8498 }
8499 }
8500 $this->repositories = array_reverse($this->repositories, true);
8501 }
8502 }
8503
8504
8505
8506
8507 public function getRepositories()
8508 {
8509 return $this->repositories;
8510 }
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520 public function get($key, $flags = 0)
8521 {
8522 switch ($key) {
8523 case 'vendor-dir':
8524 case 'bin-dir':
8525 case 'process-timeout':
8526 case 'data-dir':
8527 case 'cache-dir':
8528 case 'cache-files-dir':
8529 case 'cache-repo-dir':
8530 case 'cache-vcs-dir':
8531 case 'cafile':
8532 case 'capath':
8533
8534  $env = 'COMPOSER_' . strtoupper(strtr($key, '-', '_'));
8535
8536 $val = $this->getComposerEnv($env);
8537 $val = rtrim((string) $this->process(false !== $val ? $val : $this->config[$key], $flags), '/\\');
8538 $val = Platform::expandPath($val);
8539
8540 if (substr($key, -4) !== '-dir') {
8541 return $val;
8542 }
8543
8544 return (($flags & self::RELATIVE_PATHS) == self::RELATIVE_PATHS) ? $val : $this->realpath($val);
8545
8546 case 'cache-ttl':
8547 return (int) $this->config[$key];
8548
8549 case 'cache-files-maxsize':
8550 if (!preg_match('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $this->config[$key], $matches)) {
8551 throw new \RuntimeException(
8552 "Could not parse the value of 'cache-files-maxsize': {$this->config[$key]}"
8553 );
8554 }
8555 $size = $matches[1];
8556 if (isset($matches[2])) {
8557 switch (strtolower($matches[2])) {
8558 case 'g':
8559 $size *= 1024;
8560
8561  case 'm':
8562 $size *= 1024;
8563
8564  case 'k':
8565 $size *= 1024;
8566 break;
8567 }
8568 }
8569
8570 return $size;
8571
8572 case 'cache-files-ttl':
8573 if (isset($this->config[$key])) {
8574 return (int) $this->config[$key];
8575 }
8576
8577 return (int) $this->config['cache-ttl'];
8578
8579 case 'home':
8580 $val = preg_replace('#^(\$HOME|~)(/|$)#', rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\') . '/', $this->config[$key]);
8581
8582 return rtrim($this->process($val, $flags), '/\\');
8583
8584 case 'bin-compat':
8585 $value = $this->getComposerEnv('COMPOSER_BIN_COMPAT') ?: $this->config[$key];
8586
8587 if (!in_array($value, array('auto', 'full'))) {
8588 throw new \RuntimeException(
8589 "Invalid value for 'bin-compat': {$value}. Expected auto, full"
8590 );
8591 }
8592
8593 return $value;
8594
8595 case 'discard-changes':
8596 if ($env = $this->getComposerEnv('COMPOSER_DISCARD_CHANGES')) {
8597 if (!in_array($env, array('stash', 'true', 'false', '1', '0'), true)) {
8598 throw new \RuntimeException(
8599 "Invalid value for COMPOSER_DISCARD_CHANGES: {$env}. Expected 1, 0, true, false or stash"
8600 );
8601 }
8602 if ('stash' === $env) {
8603 return 'stash';
8604 }
8605
8606
8607  return $env !== 'false' && (bool) $env;
8608 }
8609
8610 if (!in_array($this->config[$key], array(true, false, 'stash'), true)) {
8611 throw new \RuntimeException(
8612 "Invalid value for 'discard-changes': {$this->config[$key]}. Expected true, false or stash"
8613 );
8614 }
8615
8616 return $this->config[$key];
8617
8618 case 'github-protocols':
8619 $protos = $this->config['github-protocols'];
8620 if ($this->config['secure-http'] && false !== ($index = array_search('git', $protos))) {
8621 unset($protos[$index]);
8622 }
8623 if (reset($protos) === 'http') {
8624 throw new \RuntimeException('The http protocol for github is not available anymore, update your config\'s github-protocols to use "https", "git" or "ssh"');
8625 }
8626
8627 return $protos;
8628
8629 case 'disable-tls':
8630 return $this->config[$key] !== 'false' && (bool) $this->config[$key];
8631
8632 case 'secure-http':
8633 return $this->config[$key] !== 'false' && (bool) $this->config[$key];
8634
8635 default:
8636 if (!isset($this->config[$key])) {
8637 return null;
8638 }
8639
8640 return $this->process($this->config[$key], $flags);
8641 }
8642 }
8643
8644 public function all($flags = 0)
8645 {
8646 $all = array(
8647 'repositories' => $this->getRepositories(),
8648 );
8649 foreach (array_keys($this->config) as $key) {
8650 $all['config'][$key] = $this->get($key, $flags);
8651 }
8652
8653 return $all;
8654 }
8655
8656 public function raw()
8657 {
8658 return array(
8659 'repositories' => $this->getRepositories(),
8660 'config' => $this->config,
8661 );
8662 }
8663
8664
8665
8666
8667
8668
8669
8670 public function has($key)
8671 {
8672 return array_key_exists($key, $this->config);
8673 }
8674
8675
8676
8677
8678
8679
8680
8681
8682 private function process($value, $flags)
8683 {
8684 $config = $this;
8685
8686 if (!is_string($value)) {
8687 return $value;
8688 }
8689
8690 return preg_replace_callback('#\{\$(.+)\}#', function ($match) use ($config, $flags) {
8691 return $config->get($match[1], $flags);
8692 }, $value);
8693 }
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703 private function realpath($path)
8704 {
8705 if (preg_match('{^(?:/|[a-z]:|[a-z0-9.]+://)}i', $path)) {
8706 return $path;
8707 }
8708
8709 return $this->baseDir . '/' . $path;
8710 }
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721 private function getComposerEnv($var)
8722 {
8723 if ($this->useEnvironment) {
8724 return getenv($var);
8725 }
8726
8727 return false;
8728 }
8729
8730 private function disableRepoByName($name)
8731 {
8732 if (isset($this->repositories[$name])) {
8733 unset($this->repositories[$name]);
8734 } elseif ($name === 'packagist') { 
8735  unset($this->repositories['packagist.org']);
8736 }
8737 }
8738
8739
8740
8741
8742
8743
8744
8745 public function prohibitUrlByConfig($url, IOInterface $io = null)
8746 {
8747
8748  if (false === filter_var($url, FILTER_VALIDATE_URL)) {
8749 return;
8750 }
8751
8752
8753  $scheme = parse_url($url, PHP_URL_SCHEME);
8754 if (in_array($scheme, array('http', 'git', 'ftp', 'svn'))) {
8755 if ($this->get('secure-http')) {
8756 throw new TransportException("Your configuration does not allow connections to $url. See https://getcomposer.org/doc/06-config.md#secure-http for details.");
8757 } elseif ($io) {
8758 $host = parse_url($url, PHP_URL_HOST);
8759 if (!isset($this->warnedHosts[$host])) {
8760 $io->writeError("<warning>Warning: Accessing $host over $scheme which is an insecure protocol.</warning>");
8761 }
8762 $this->warnedHosts[$host] = true;
8763 }
8764 }
8765 }
8766 }
8767 <?php
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779 namespace Composer\Config;
8780
8781
8782
8783
8784
8785
8786
8787 interface ConfigSourceInterface
8788 {
8789
8790
8791
8792
8793
8794
8795 public function addRepository($name, $config);
8796
8797
8798
8799
8800
8801
8802 public function removeRepository($name);
8803
8804
8805
8806
8807
8808
8809
8810 public function addConfigSetting($name, $value);
8811
8812
8813
8814
8815
8816
8817 public function removeConfigSetting($name);
8818
8819
8820
8821
8822
8823
8824
8825 public function addProperty($name, $value);
8826
8827
8828
8829
8830
8831
8832 public function removeProperty($name);
8833
8834
8835
8836
8837
8838
8839
8840
8841 public function addLink($type, $name, $value);
8842
8843
8844
8845
8846
8847
8848
8849 public function removeLink($type, $name);
8850
8851
8852
8853
8854
8855
8856 public function getName();
8857 }
8858 <?php
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870 namespace Composer\Config;
8871
8872 use Composer\Json\JsonFile;
8873 use Composer\Json\JsonManipulator;
8874 use Composer\Util\Silencer;
8875
8876
8877
8878
8879
8880
8881
8882 class JsonConfigSource implements ConfigSourceInterface
8883 {
8884
8885
8886
8887 private $file;
8888
8889
8890
8891
8892 private $authConfig;
8893
8894
8895
8896
8897
8898
8899
8900 public function __construct(JsonFile $file, $authConfig = false)
8901 {
8902 $this->file = $file;
8903 $this->authConfig = $authConfig;
8904 }
8905
8906
8907
8908
8909 public function getName()
8910 {
8911 return $this->file->getPath();
8912 }
8913
8914
8915
8916
8917 public function addRepository($name, $config)
8918 {
8919 $this->manipulateJson('addRepository', $name, $config, function (&$config, $repo, $repoConfig) {
8920 $config['repositories'][$repo] = $repoConfig;
8921 });
8922 }
8923
8924
8925
8926
8927 public function removeRepository($name)
8928 {
8929 $this->manipulateJson('removeRepository', $name, function (&$config, $repo) {
8930 unset($config['repositories'][$repo]);
8931 });
8932 }
8933
8934
8935
8936
8937 public function addConfigSetting($name, $value)
8938 {
8939 $authConfig = $this->authConfig;
8940 $this->manipulateJson('addConfigSetting', $name, $value, function (&$config, $key, $val) use ($authConfig) {
8941 if (preg_match('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|http-basic|platform)\.}', $key)) {
8942 list($key, $host) = explode('.', $key, 2);
8943 if ($authConfig) {
8944 $config[$key][$host] = $val;
8945 } else {
8946 $config['config'][$key][$host] = $val;
8947 }
8948 } else {
8949 $config['config'][$key] = $val;
8950 }
8951 });
8952 }
8953
8954
8955
8956
8957 public function removeConfigSetting($name)
8958 {
8959 $authConfig = $this->authConfig;
8960 $this->manipulateJson('removeConfigSetting', $name, function (&$config, $key) use ($authConfig) {
8961 if (preg_match('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|http-basic|platform)\.}', $key)) {
8962 list($key, $host) = explode('.', $key, 2);
8963 if ($authConfig) {
8964 unset($config[$key][$host]);
8965 } else {
8966 unset($config['config'][$key][$host]);
8967 }
8968 } else {
8969 unset($config['config'][$key]);
8970 }
8971 });
8972 }
8973
8974
8975
8976
8977 public function addProperty($name, $value)
8978 {
8979 $this->manipulateJson('addProperty', $name, $value, function (&$config, $key, $val) {
8980 if (substr($key, 0, 6) === 'extra.') {
8981 $bits = explode('.', $key);
8982 $last = array_pop($bits);
8983 $arr = &$config['extra'];
8984 foreach ($bits as $bit) {
8985 if (!isset($arr[$bit])) {
8986 $arr[$bit] = array();
8987 }
8988 $arr = &$arr[$bit];
8989 }
8990 $arr[$last] = $val;
8991 } else {
8992 $config[$key] = $val;
8993 }
8994 });
8995 }
8996
8997
8998
8999
9000 public function removeProperty($name)
9001 {
9002 $authConfig = $this->authConfig;
9003 $this->manipulateJson('removeProperty', $name, function (&$config, $key) {
9004 if (substr($key, 0, 6) === 'extra.') {
9005 $bits = explode('.', $key);
9006 $last = array_pop($bits);
9007 $arr = &$config['extra'];
9008 foreach ($bits as $bit) {
9009 if (!isset($arr[$bit])) {
9010 return;
9011 }
9012 $arr = &$arr[$bit];
9013 }
9014 unset($arr[$last]);
9015 } else {
9016 unset($config[$key]);
9017 }
9018 });
9019 }
9020
9021
9022
9023
9024 public function addLink($type, $name, $value)
9025 {
9026 $this->manipulateJson('addLink', $type, $name, $value, function (&$config, $type, $name, $value) {
9027 $config[$type][$name] = $value;
9028 });
9029 }
9030
9031
9032
9033
9034 public function removeLink($type, $name)
9035 {
9036 $this->manipulateJson('removeSubNode', $type, $name, function (&$config, $type, $name) {
9037 unset($config[$type][$name]);
9038 });
9039 }
9040
9041 protected function manipulateJson($method, $args, $fallback)
9042 {
9043 $args = func_get_args();
9044
9045  array_shift($args);
9046 $fallback = array_pop($args);
9047
9048 if ($this->file->exists()) {
9049 if (!is_writable($this->file->getPath())) {
9050 throw new \RuntimeException(sprintf('The file "%s" is not writable.', $this->file->getPath()));
9051 }
9052
9053 if (!is_readable($this->file->getPath())) {
9054 throw new \RuntimeException(sprintf('The file "%s" is not readable.', $this->file->getPath()));
9055 }
9056
9057 $contents = file_get_contents($this->file->getPath());
9058 } elseif ($this->authConfig) {
9059 $contents = "{\n}\n";
9060 } else {
9061 $contents = "{\n    \"config\": {\n    }\n}\n";
9062 }
9063
9064 $manipulator = new JsonManipulator($contents);
9065
9066 $newFile = !$this->file->exists();
9067
9068
9069  if ($this->authConfig && $method === 'addConfigSetting') {
9070 $method = 'addSubNode';
9071 list($mainNode, $name) = explode('.', $args[0], 2);
9072 $args = array($mainNode, $name, $args[1]);
9073 } elseif ($this->authConfig && $method === 'removeConfigSetting') {
9074 $method = 'removeSubNode';
9075 list($mainNode, $name) = explode('.', $args[0], 2);
9076 $args = array($mainNode, $name);
9077 }
9078
9079
9080  if (call_user_func_array(array($manipulator, $method), $args)) {
9081 file_put_contents($this->file->getPath(), $manipulator->getContents());
9082 } else {
9083
9084  $config = $this->file->read();
9085 $this->arrayUnshiftRef($args, $config);
9086 call_user_func_array($fallback, $args);
9087 $this->file->write($config);
9088 }
9089
9090 if ($newFile) {
9091 Silencer::call('chmod', $this->file->getPath(), 0600);
9092 }
9093 }
9094
9095
9096
9097
9098
9099
9100
9101
9102 private function arrayUnshiftRef(&$array, &$value)
9103 {
9104 $return = array_unshift($array, '');
9105 $array[0] = &$value;
9106
9107 return $return;
9108 }
9109 }
9110 <?php
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122 namespace Composer\Console;
9123
9124 use Composer\Util\Platform;
9125 use Composer\Util\Silencer;
9126 use Symfony\Component\Console\Application as BaseApplication;
9127 use Symfony\Component\Console\Input\InputInterface;
9128 use Symfony\Component\Console\Input\InputOption;
9129 use Symfony\Component\Console\Output\OutputInterface;
9130 use Composer\Command;
9131 use Composer\Composer;
9132 use Composer\Factory;
9133 use Composer\IO\IOInterface;
9134 use Composer\IO\ConsoleIO;
9135 use Composer\Json\JsonValidationException;
9136 use Composer\Util\ErrorHandler;
9137 use Composer\EventDispatcher\ScriptExecutionException;
9138 use Composer\Exception\NoSslException;
9139
9140
9141
9142
9143
9144
9145
9146
9147 class Application extends BaseApplication
9148 {
9149
9150
9151
9152 protected $composer;
9153
9154
9155
9156
9157 protected $io;
9158
9159 private static $logo = '   ______
9160   / ____/___  ____ ___  ____  ____  ________  _____
9161  / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
9162 / /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
9163 \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
9164                     /_/
9165 ';
9166
9167 private $hasPluginCommands = false;
9168 private $disablePluginsByDefault = false;
9169
9170 public function __construct()
9171 {
9172 static $shutdownRegistered = false;
9173
9174 if (function_exists('ini_set') && extension_loaded('xdebug')) {
9175 ini_set('xdebug.show_exception_trace', false);
9176 ini_set('xdebug.scream', false);
9177 }
9178
9179 if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) {
9180 date_default_timezone_set(Silencer::call('date_default_timezone_get'));
9181 }
9182
9183 if (!$shutdownRegistered) {
9184 $shutdownRegistered = true;
9185
9186 register_shutdown_function(function () {
9187 $lastError = error_get_last();
9188
9189 if ($lastError && $lastError['message'] &&
9190 (strpos($lastError['message'], 'Allowed memory') !== false  ||
9191 strpos($lastError['message'], 'exceeded memory') !== false )) {
9192 echo "\n". 'Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.';
9193 }
9194 });
9195 }
9196
9197 parent::__construct('Composer', Composer::VERSION);
9198 }
9199
9200
9201
9202
9203 public function run(InputInterface $input = null, OutputInterface $output = null)
9204 {
9205 if (null === $output) {
9206 $output = Factory::createOutput();
9207 }
9208
9209 return parent::run($input, $output);
9210 }
9211
9212
9213
9214
9215 public function doRun(InputInterface $input, OutputInterface $output)
9216 {
9217 $this->disablePluginsByDefault = $input->hasParameterOption('--no-plugins');
9218
9219 $io = $this->io = new ConsoleIO($input, $output, $this->getHelperSet());
9220 ErrorHandler::register($io);
9221
9222
9223  if ($newWorkDir = $this->getNewWorkingDir($input)) {
9224 $oldWorkingDir = getcwd();
9225 chdir($newWorkDir);
9226 $io->writeError('Changed CWD to ' . getcwd(), true, IOInterface::DEBUG);
9227 }
9228
9229
9230  $commandName = '';
9231 if ($name = $this->getCommandName($input)) {
9232 try {
9233 $commandName = $this->find($name)->getName();
9234 } catch (\InvalidArgumentException $e) {
9235 }
9236 }
9237
9238 if (!$this->disablePluginsByDefault && !$this->hasPluginCommands && 'global' !== $commandName) {
9239 try {
9240 foreach ($this->getPluginCommands() as $command) {
9241 if ($this->has($command->getName())) {
9242 $io->writeError('<warning>Plugin command '.$command->getName().' ('.get_class($command).') would override a Composer command and has been skipped</warning>');
9243 } else {
9244 $this->add($command);
9245 }
9246 }
9247 } catch (NoSslException $e) {
9248
9249  }
9250
9251 $this->hasPluginCommands = true;
9252 }
9253
9254
9255  $isProxyCommand = false;
9256 if ($name = $this->getCommandName($input)) {
9257 try {
9258 $command = $this->find($name);
9259 $commandName = $command->getName();
9260 $isProxyCommand = ($command instanceof Command\BaseCommand && $command->isProxyCommand());
9261 } catch (\InvalidArgumentException $e) {
9262 }
9263 }
9264
9265 if (!$isProxyCommand) {
9266 $io->writeError(sprintf(
9267 'Running %s (%s) with %s on %s',
9268 Composer::VERSION,
9269 Composer::RELEASE_DATE,
9270 defined('HHVM_VERSION') ? 'HHVM '.HHVM_VERSION : 'PHP '.PHP_VERSION,
9271 php_uname('s') . ' / ' . php_uname('r')
9272 ), true, IOInterface::DEBUG);
9273
9274 if (PHP_VERSION_ID < 50302) {
9275 $io->writeError('<warning>Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.</warning>');
9276 }
9277
9278 if (extension_loaded('xdebug') && !getenv('COMPOSER_DISABLE_XDEBUG_WARN')) {
9279 $io->writeError('<warning>You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug</warning>');
9280 }
9281
9282 if (defined('COMPOSER_DEV_WARNING_TIME') && $commandName !== 'self-update' && $commandName !== 'selfupdate' && time() > COMPOSER_DEV_WARNING_TIME) {
9283 $io->writeError(sprintf('<warning>Warning: This development build of composer is over 60 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF']));
9284 }
9285
9286 if (getenv('COMPOSER_NO_INTERACTION')) {
9287 $input->setInteractive(false);
9288 }
9289
9290 if (!Platform::isWindows() && function_exists('exec') && !getenv('COMPOSER_ALLOW_SUPERUSER')) {
9291 if (function_exists('posix_getuid') && posix_getuid() === 0) {
9292 if ($commandName !== 'self-update' && $commandName !== 'selfupdate') {
9293 $io->writeError('<warning>Do not run Composer as root/super user! See https://getcomposer.org/root for details</warning>');
9294 }
9295 if ($uid = (int) getenv('SUDO_UID')) {
9296
9297  
9298  Silencer::call('exec', "sudo -u \\#{$uid} sudo -K > /dev/null 2>&1");
9299 }
9300 }
9301
9302  Silencer::call('exec', 'sudo -K > /dev/null 2>&1');
9303 }
9304
9305
9306  Silencer::call(function () use ($io) {
9307 $tempfile = sys_get_temp_dir() . '/temp-' . md5(microtime());
9308 if (!(file_put_contents($tempfile, __FILE__) && (file_get_contents($tempfile) == __FILE__) && unlink($tempfile) && !file_exists($tempfile))) {
9309 $io->writeError(sprintf('<error>PHP temp directory (%s) does not exist or is not writable to Composer. Set sys_temp_dir in your php.ini</error>', sys_get_temp_dir()));
9310 }
9311 });
9312
9313
9314  $file = Factory::getComposerFile();
9315 if (is_file($file) && is_readable($file) && is_array($composer = json_decode(file_get_contents($file), true))) {
9316 if (isset($composer['scripts']) && is_array($composer['scripts'])) {
9317 foreach ($composer['scripts'] as $script => $dummy) {
9318 if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
9319 if ($this->has($script)) {
9320 $io->writeError('<warning>A script named '.$script.' would override a Composer command and has been skipped</warning>');
9321 } else {
9322 $this->add(new Command\ScriptAliasCommand($script));
9323 }
9324 }
9325 }
9326 }
9327 }
9328 }
9329
9330 try {
9331 if ($input->hasParameterOption('--profile')) {
9332 $startTime = microtime(true);
9333 $this->io->enableDebugging($startTime);
9334 }
9335
9336 $result = parent::doRun($input, $output);
9337
9338 if (isset($oldWorkingDir)) {
9339 chdir($oldWorkingDir);
9340 }
9341
9342 if (isset($startTime)) {
9343 $io->writeError('<info>Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MB), time: '.round(microtime(true) - $startTime, 2).'s');
9344 }
9345
9346 restore_error_handler();
9347
9348 return $result;
9349 } catch (ScriptExecutionException $e) {
9350 return $e->getCode();
9351 } catch (\Exception $e) {
9352 $this->hintCommonErrors($e);
9353 restore_error_handler();
9354 throw $e;
9355 }
9356 }
9357
9358
9359
9360
9361
9362
9363 private function getNewWorkingDir(InputInterface $input)
9364 {
9365 $workingDir = $input->getParameterOption(array('--working-dir', '-d'));
9366 if (false !== $workingDir && !is_dir($workingDir)) {
9367 throw new \RuntimeException('Invalid working directory specified, '.$workingDir.' does not exist.');
9368 }
9369
9370 return $workingDir;
9371 }
9372
9373
9374
9375
9376 private function hintCommonErrors($exception)
9377 {
9378 $io = $this->getIO();
9379
9380 Silencer::suppress();
9381 try {
9382 $composer = $this->getComposer(false, true);
9383 if ($composer) {
9384 $config = $composer->getConfig();
9385
9386 $minSpaceFree = 1024 * 1024;
9387 if ((($df = disk_free_space($dir = $config->get('home'))) !== false && $df < $minSpaceFree)
9388 || (($df = disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree)
9389 || (($df = disk_free_space($dir = sys_get_temp_dir())) !== false && $df < $minSpaceFree)
9390 ) {
9391 $io->writeError('<error>The disk hosting '.$dir.' is full, this may be the cause of the following exception</error>', true, IOInterface::QUIET);
9392 }
9393 }
9394 } catch (\Exception $e) {
9395 }
9396 Silencer::restore();
9397
9398 if (Platform::isWindows() && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) {
9399 $io->writeError('<error>The following exception may be caused by a stale entry in your cmd.exe AutoRun</error>', true, IOInterface::QUIET);
9400 $io->writeError('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details</error>', true, IOInterface::QUIET);
9401 }
9402
9403 if (false !== strpos($exception->getMessage(), 'fork failed - Cannot allocate memory')) {
9404 $io->writeError('<error>The following exception is caused by a lack of memory or swap, or not having swap configured</error>', true, IOInterface::QUIET);
9405 $io->writeError('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details</error>', true, IOInterface::QUIET);
9406 }
9407 }
9408
9409
9410
9411
9412
9413
9414
9415 public function getComposer($required = true, $disablePlugins = null)
9416 {
9417 if (null === $disablePlugins) {
9418 $disablePlugins = $this->disablePluginsByDefault;
9419 }
9420
9421 if (null === $this->composer) {
9422 try {
9423 $this->composer = Factory::create($this->io, null, $disablePlugins);
9424 } catch (\InvalidArgumentException $e) {
9425 if ($required) {
9426 $this->io->writeError($e->getMessage());
9427 exit(1);
9428 }
9429 } catch (JsonValidationException $e) {
9430 $errors = ' - ' . implode(PHP_EOL . ' - ', $e->getErrors());
9431 $message = $e->getMessage() . ':' . PHP_EOL . $errors;
9432 throw new JsonValidationException($message);
9433 }
9434 }
9435
9436 return $this->composer;
9437 }
9438
9439
9440
9441
9442 public function resetComposer()
9443 {
9444 $this->composer = null;
9445 }
9446
9447
9448
9449
9450 public function getIO()
9451 {
9452 return $this->io;
9453 }
9454
9455 public function getHelp()
9456 {
9457 return self::$logo . parent::getHelp();
9458 }
9459
9460
9461
9462
9463 protected function getDefaultCommands()
9464 {
9465 $commands = array_merge(parent::getDefaultCommands(), array(
9466 new Command\AboutCommand(),
9467 new Command\ConfigCommand(),
9468 new Command\DependsCommand(),
9469 new Command\ProhibitsCommand(),
9470 new Command\InitCommand(),
9471 new Command\InstallCommand(),
9472 new Command\CreateProjectCommand(),
9473 new Command\UpdateCommand(),
9474 new Command\SearchCommand(),
9475 new Command\ValidateCommand(),
9476 new Command\ShowCommand(),
9477 new Command\SuggestsCommand(),
9478 new Command\RequireCommand(),
9479 new Command\DumpAutoloadCommand(),
9480 new Command\StatusCommand(),
9481 new Command\ArchiveCommand(),
9482 new Command\DiagnoseCommand(),
9483 new Command\RunScriptCommand(),
9484 new Command\LicensesCommand(),
9485 new Command\GlobalCommand(),
9486 new Command\ClearCacheCommand(),
9487 new Command\RemoveCommand(),
9488 new Command\HomeCommand(),
9489 new Command\ExecCommand(),
9490 new Command\OutdatedCommand(),
9491 ));
9492
9493 if ('phar:' === substr(__FILE__, 0, 5)) {
9494 $commands[] = new Command\SelfUpdateCommand();
9495 }
9496
9497 return $commands;
9498 }
9499
9500
9501
9502
9503 public function getLongVersion()
9504 {
9505 if (Composer::BRANCH_ALIAS_VERSION) {
9506 return sprintf(
9507 '<info>%s</info> version <comment>%s (%s)</comment> %s',
9508 $this->getName(),
9509 Composer::BRANCH_ALIAS_VERSION,
9510 $this->getVersion(),
9511 Composer::RELEASE_DATE
9512 );
9513 }
9514
9515 return parent::getLongVersion() . ' ' . Composer::RELEASE_DATE;
9516 }
9517
9518
9519
9520
9521 protected function getDefaultInputDefinition()
9522 {
9523 $definition = parent::getDefaultInputDefinition();
9524 $definition->addOption(new InputOption('--profile', null, InputOption::VALUE_NONE, 'Display timing and memory usage information'));
9525 $definition->addOption(new InputOption('--no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.'));
9526 $definition->addOption(new InputOption('--working-dir', '-d', InputOption::VALUE_REQUIRED, 'If specified, use the given directory as working directory.'));
9527
9528 return $definition;
9529 }
9530
9531 private function getPluginCommands()
9532 {
9533 $commands = array();
9534
9535 $composer = $this->getComposer(false, false);
9536 if (null === $composer) {
9537 $composer = Factory::createGlobal($this->io, false);
9538 }
9539
9540 if (null !== $composer) {
9541 $pm = $composer->getPluginManager();
9542 foreach ($pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider', array('composer' => $composer, 'io' => $this->io)) as $capability) {
9543 $newCommands = $capability->getCommands();
9544 if (!is_array($newCommands)) {
9545 throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' failed to return an array from getCommands');
9546 }
9547 foreach ($newCommands as $command) {
9548 if (!$command instanceof Command\BaseCommand) {
9549 throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' returned an invalid value, we expected an array of Composer\Command\BaseCommand objects');
9550 }
9551 }
9552 $commands = array_merge($commands, $newCommands);
9553 }
9554 }
9555
9556 return $commands;
9557 }
9558 }
9559 <?php
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571 namespace Composer\Console;
9572
9573 use Symfony\Component\Console\Formatter\OutputFormatter;
9574
9575
9576
9577
9578 class HtmlOutputFormatter extends OutputFormatter
9579 {
9580 private static $availableForegroundColors = array(
9581 30 => 'black',
9582 31 => 'red',
9583 32 => 'green',
9584 33 => 'yellow',
9585 34 => 'blue',
9586 35 => 'magenta',
9587 36 => 'cyan',
9588 37 => 'white',
9589 );
9590 private static $availableBackgroundColors = array(
9591 40 => 'black',
9592 41 => 'red',
9593 42 => 'green',
9594 43 => 'yellow',
9595 44 => 'blue',
9596 45 => 'magenta',
9597 46 => 'cyan',
9598 47 => 'white',
9599 );
9600 private static $availableOptions = array(
9601 1 => 'bold',
9602 4 => 'underscore',
9603
9604  
9605  
9606  );
9607
9608
9609
9610
9611 public function __construct(array $styles = array())
9612 {
9613 parent::__construct(true, $styles);
9614 }
9615
9616 public function format($message)
9617 {
9618 $formatted = parent::format($message);
9619
9620 $clearEscapeCodes = '(?:39|49|0|22|24|25|27|28)';
9621
9622 return preg_replace_callback("{\033\[([0-9;]+)m(.*?)\033\[(?:".$clearEscapeCodes.";)*?".$clearEscapeCodes."m}s", array($this, 'formatHtml'), $formatted);
9623 }
9624
9625 private function formatHtml($matches)
9626 {
9627 $out = '<span style="';
9628 foreach (explode(';', $matches[1]) as $code) {
9629 if (isset(self::$availableForegroundColors[$code])) {
9630 $out .= 'color:'.self::$availableForegroundColors[$code].';';
9631 } elseif (isset(self::$availableBackgroundColors[$code])) {
9632 $out .= 'background-color:'.self::$availableBackgroundColors[$code].';';
9633 } elseif (isset(self::$availableOptions[$code])) {
9634 switch (self::$availableOptions[$code]) {
9635 case 'bold':
9636 $out .= 'font-weight:bold;';
9637 break;
9638
9639 case 'underscore':
9640 $out .= 'text-decoration:underline;';
9641 break;
9642 }
9643 }
9644 }
9645
9646 return $out.'">'.$matches[2].'</span>';
9647 }
9648 }
9649 <?php
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661 namespace Composer\DependencyResolver;
9662
9663
9664
9665
9666
9667
9668 class Decisions implements \Iterator, \Countable
9669 {
9670 const DECISION_LITERAL = 0;
9671 const DECISION_REASON = 1;
9672
9673 protected $pool;
9674 protected $decisionMap;
9675 protected $decisionQueue = array();
9676
9677 public function __construct($pool)
9678 {
9679 $this->pool = $pool;
9680 $this->decisionMap = array();
9681 }
9682
9683 public function decide($literal, $level, $why)
9684 {
9685 $this->addDecision($literal, $level);
9686 $this->decisionQueue[] = array(
9687 self::DECISION_LITERAL => $literal,
9688 self::DECISION_REASON => $why,
9689 );
9690 }
9691
9692 public function satisfy($literal)
9693 {
9694 $packageId = abs($literal);
9695
9696 return (
9697 $literal > 0 && isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0 ||
9698 $literal < 0 && isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] < 0
9699 );
9700 }
9701
9702 public function conflict($literal)
9703 {
9704 $packageId = abs($literal);
9705
9706 return (
9707 (isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0 && $literal < 0) ||
9708 (isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] < 0 && $literal > 0)
9709 );
9710 }
9711
9712 public function decided($literalOrPackageId)
9713 {
9714 return !empty($this->decisionMap[abs($literalOrPackageId)]);
9715 }
9716
9717 public function undecided($literalOrPackageId)
9718 {
9719 return empty($this->decisionMap[abs($literalOrPackageId)]);
9720 }
9721
9722 public function decidedInstall($literalOrPackageId)
9723 {
9724 $packageId = abs($literalOrPackageId);
9725
9726 return isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0;
9727 }
9728
9729 public function decisionLevel($literalOrPackageId)
9730 {
9731 $packageId = abs($literalOrPackageId);
9732 if (isset($this->decisionMap[$packageId])) {
9733 return abs($this->decisionMap[$packageId]);
9734 }
9735
9736 return 0;
9737 }
9738
9739 public function decisionRule($literalOrPackageId)
9740 {
9741 $packageId = abs($literalOrPackageId);
9742
9743 foreach ($this->decisionQueue as $i => $decision) {
9744 if ($packageId === abs($decision[self::DECISION_LITERAL])) {
9745 return $decision[self::DECISION_REASON];
9746 }
9747 }
9748
9749 return null;
9750 }
9751
9752 public function atOffset($queueOffset)
9753 {
9754 return $this->decisionQueue[$queueOffset];
9755 }
9756
9757 public function validOffset($queueOffset)
9758 {
9759 return $queueOffset >= 0 && $queueOffset < count($this->decisionQueue);
9760 }
9761
9762 public function lastReason()
9763 {
9764 return $this->decisionQueue[count($this->decisionQueue) - 1][self::DECISION_REASON];
9765 }
9766
9767 public function lastLiteral()
9768 {
9769 return $this->decisionQueue[count($this->decisionQueue) - 1][self::DECISION_LITERAL];
9770 }
9771
9772 public function reset()
9773 {
9774 while ($decision = array_pop($this->decisionQueue)) {
9775 $this->decisionMap[abs($decision[self::DECISION_LITERAL])] = 0;
9776 }
9777 }
9778
9779 public function resetToOffset($offset)
9780 {
9781 while (count($this->decisionQueue) > $offset + 1) {
9782 $decision = array_pop($this->decisionQueue);
9783 $this->decisionMap[abs($decision[self::DECISION_LITERAL])] = 0;
9784 }
9785 }
9786
9787 public function revertLast()
9788 {
9789 $this->decisionMap[abs($this->lastLiteral())] = 0;
9790 array_pop($this->decisionQueue);
9791 }
9792
9793 public function count()
9794 {
9795 return count($this->decisionQueue);
9796 }
9797
9798 public function rewind()
9799 {
9800 end($this->decisionQueue);
9801 }
9802
9803 public function current()
9804 {
9805 return current($this->decisionQueue);
9806 }
9807
9808 public function key()
9809 {
9810 return key($this->decisionQueue);
9811 }
9812
9813 public function next()
9814 {
9815 return prev($this->decisionQueue);
9816 }
9817
9818 public function valid()
9819 {
9820 return false !== current($this->decisionQueue);
9821 }
9822
9823 public function isEmpty()
9824 {
9825 return count($this->decisionQueue) === 0;
9826 }
9827
9828 protected function addDecision($literal, $level)
9829 {
9830 $packageId = abs($literal);
9831
9832 $previousDecision = isset($this->decisionMap[$packageId]) ? $this->decisionMap[$packageId] : null;
9833 if ($previousDecision != 0) {
9834 $literalString = $this->pool->literalToString($literal);
9835 $package = $this->pool->literalToPackage($literal);
9836 throw new SolverBugException(
9837 "Trying to decide $literalString on level $level, even though $package was previously decided as ".(int) $previousDecision."."
9838 );
9839 }
9840
9841 if ($literal > 0) {
9842 $this->decisionMap[$packageId] = $level;
9843 } else {
9844 $this->decisionMap[$packageId] = -$level;
9845 }
9846 }
9847 }
9848 <?php
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860 namespace Composer\DependencyResolver;
9861
9862 use Composer\Package\PackageInterface;
9863 use Composer\Package\AliasPackage;
9864 use Composer\Package\BasePackage;
9865 use Composer\Semver\Constraint\Constraint;
9866
9867
9868
9869
9870
9871 class DefaultPolicy implements PolicyInterface
9872 {
9873 private $preferStable;
9874 private $preferLowest;
9875
9876 public function __construct($preferStable = false, $preferLowest = false)
9877 {
9878 $this->preferStable = $preferStable;
9879 $this->preferLowest = $preferLowest;
9880 }
9881
9882 public function versionCompare(PackageInterface $a, PackageInterface $b, $operator)
9883 {
9884 if ($this->preferStable && ($stabA = $a->getStability()) !== ($stabB = $b->getStability())) {
9885 return BasePackage::$stabilities[$stabA] < BasePackage::$stabilities[$stabB];
9886 }
9887
9888 $constraint = new Constraint($operator, $b->getVersion());
9889 $version = new Constraint('==', $a->getVersion());
9890
9891 return $constraint->matchSpecific($version, true);
9892 }
9893
9894 public function findUpdatePackages(Pool $pool, array $installedMap, PackageInterface $package, $mustMatchName = false)
9895 {
9896 $packages = array();
9897
9898 foreach ($pool->whatProvides($package->getName(), null, $mustMatchName) as $candidate) {
9899 if ($candidate !== $package) {
9900 $packages[] = $candidate;
9901 }
9902 }
9903
9904 return $packages;
9905 }
9906
9907 public function getPriority(Pool $pool, PackageInterface $package)
9908 {
9909 return $pool->getPriority($package->getRepository());
9910 }
9911
9912 public function selectPreferredPackages(Pool $pool, array $installedMap, array $literals, $requiredPackage = null)
9913 {
9914 $packages = $this->groupLiteralsByNamePreferInstalled($pool, $installedMap, $literals);
9915
9916 foreach ($packages as &$literals) {
9917 $policy = $this;
9918 usort($literals, function ($a, $b) use ($policy, $pool, $installedMap, $requiredPackage) {
9919 return $policy->compareByPriorityPreferInstalled($pool, $installedMap, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage, true);
9920 });
9921 }
9922
9923 foreach ($packages as &$literals) {
9924 $literals = $this->pruneToHighestPriorityOrInstalled($pool, $installedMap, $literals);
9925
9926 $literals = $this->pruneToBestVersion($pool, $literals);
9927
9928 $literals = $this->pruneRemoteAliases($pool, $literals);
9929 }
9930
9931 $selected = call_user_func_array('array_merge', $packages);
9932
9933
9934  usort($selected, function ($a, $b) use ($policy, $pool, $installedMap, $requiredPackage) {
9935 return $policy->compareByPriorityPreferInstalled($pool, $installedMap, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage);
9936 });
9937
9938 return $selected;
9939 }
9940
9941 protected function groupLiteralsByNamePreferInstalled(Pool $pool, array $installedMap, $literals)
9942 {
9943 $packages = array();
9944 foreach ($literals as $literal) {
9945 $packageName = $pool->literalToPackage($literal)->getName();
9946
9947 if (!isset($packages[$packageName])) {
9948 $packages[$packageName] = array();
9949 }
9950
9951 if (isset($installedMap[abs($literal)])) {
9952 array_unshift($packages[$packageName], $literal);
9953 } else {
9954 $packages[$packageName][] = $literal;
9955 }
9956 }
9957
9958 return $packages;
9959 }
9960
9961
9962
9963
9964 public function compareByPriorityPreferInstalled(Pool $pool, array $installedMap, PackageInterface $a, PackageInterface $b, $requiredPackage = null, $ignoreReplace = false)
9965 {
9966 if ($a->getRepository() === $b->getRepository()) {
9967
9968  if ($a->getName() === $b->getName()) {
9969 $aAliased = $a instanceof AliasPackage;
9970 $bAliased = $b instanceof AliasPackage;
9971 if ($aAliased && !$bAliased) {
9972 return -1; 
9973  }
9974 if (!$aAliased && $bAliased) {
9975 return 1; 
9976  }
9977 }
9978
9979 if (!$ignoreReplace) {
9980
9981  if ($this->replaces($a, $b)) {
9982 return 1; 
9983  }
9984 if ($this->replaces($b, $a)) {
9985 return -1; 
9986  }
9987
9988
9989  
9990  if ($requiredPackage && false !== ($pos = strpos($requiredPackage, '/'))) {
9991 $requiredVendor = substr($requiredPackage, 0, $pos);
9992
9993 $aIsSameVendor = substr($a->getName(), 0, $pos) === $requiredVendor;
9994 $bIsSameVendor = substr($b->getName(), 0, $pos) === $requiredVendor;
9995
9996 if ($bIsSameVendor !== $aIsSameVendor) {
9997 return $aIsSameVendor ? -1 : 1;
9998 }
9999 }
10000 }
10001
10002
10003  if ($a->id === $b->id) {
10004 return 0;
10005 }
10006
10007 return ($a->id < $b->id) ? -1 : 1;
10008 }
10009
10010 if (isset($installedMap[$a->id])) {
10011 return -1;
10012 }
10013
10014 if (isset($installedMap[$b->id])) {
10015 return 1;
10016 }
10017
10018 return ($this->getPriority($pool, $a) > $this->getPriority($pool, $b)) ? -1 : 1;
10019 }
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031 protected function replaces(PackageInterface $source, PackageInterface $target)
10032 {
10033 foreach ($source->getReplaces() as $link) {
10034 if ($link->getTarget() === $target->getName()
10035
10036
10037  ) {
10038 return true;
10039 }
10040 }
10041
10042 return false;
10043 }
10044
10045 protected function pruneToBestVersion(Pool $pool, $literals)
10046 {
10047 $operator = $this->preferLowest ? '<' : '>';
10048 $bestLiterals = array($literals[0]);
10049 $bestPackage = $pool->literalToPackage($literals[0]);
10050 foreach ($literals as $i => $literal) {
10051 if (0 === $i) {
10052 continue;
10053 }
10054
10055 $package = $pool->literalToPackage($literal);
10056
10057 if ($this->versionCompare($package, $bestPackage, $operator)) {
10058 $bestPackage = $package;
10059 $bestLiterals = array($literal);
10060 } elseif ($this->versionCompare($package, $bestPackage, '==')) {
10061 $bestLiterals[] = $literal;
10062 }
10063 }
10064
10065 return $bestLiterals;
10066 }
10067
10068
10069
10070
10071 protected function pruneToHighestPriorityOrInstalled(Pool $pool, array $installedMap, array $literals)
10072 {
10073 $selected = array();
10074
10075 $priority = null;
10076
10077 foreach ($literals as $literal) {
10078 $package = $pool->literalToPackage($literal);
10079
10080 if (isset($installedMap[$package->id])) {
10081 $selected[] = $literal;
10082 continue;
10083 }
10084
10085 if (null === $priority) {
10086 $priority = $this->getPriority($pool, $package);
10087 }
10088
10089 if ($this->getPriority($pool, $package) != $priority) {
10090 break;
10091 }
10092
10093 $selected[] = $literal;
10094 }
10095
10096 return $selected;
10097 }
10098
10099
10100
10101
10102
10103
10104 protected function pruneRemoteAliases(Pool $pool, array $literals)
10105 {
10106 $hasLocalAlias = false;
10107
10108 foreach ($literals as $literal) {
10109 $package = $pool->literalToPackage($literal);
10110
10111 if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
10112 $hasLocalAlias = true;
10113 break;
10114 }
10115 }
10116
10117 if (!$hasLocalAlias) {
10118 return $literals;
10119 }
10120
10121 $selected = array();
10122 foreach ($literals as $literal) {
10123 $package = $pool->literalToPackage($literal);
10124
10125 if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
10126 $selected[] = $literal;
10127 }
10128 }
10129
10130 return $selected;
10131 }
10132 }
10133 <?php
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145 namespace Composer\DependencyResolver;
10146
10147 use Composer\Package\PackageInterface;
10148 use Composer\Package\Link;
10149
10150
10151
10152
10153 class GenericRule extends Rule
10154 {
10155 protected $literals;
10156
10157
10158
10159
10160
10161
10162
10163 public function __construct(array $literals, $reason, $reasonData, $job = null)
10164 {
10165 parent::__construct($reason, $reasonData, $job);
10166
10167
10168  sort($literals);
10169
10170 $this->literals = $literals;
10171 }
10172
10173 public function getLiterals()
10174 {
10175 return $this->literals;
10176 }
10177
10178 public function getHash()
10179 {
10180 $data = unpack('ihash', md5(implode(',', $this->literals), true));
10181
10182 return $data['hash'];
10183 }
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193 public function equals(Rule $rule)
10194 {
10195 return $this->literals === $rule->getLiterals();
10196 }
10197
10198 public function isAssertion()
10199 {
10200 return 1 === count($this->literals);
10201 }
10202
10203
10204
10205
10206
10207
10208 public function __toString()
10209 {
10210 $result = ($this->isDisabled()) ? 'disabled(' : '(';
10211
10212 foreach ($this->literals as $i => $literal) {
10213 if ($i != 0) {
10214 $result .= '|';
10215 }
10216 $result .= $literal;
10217 }
10218
10219 $result .= ')';
10220
10221 return $result;
10222 }
10223 }
10224 <?php
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236 namespace Composer\DependencyResolver\Operation;
10237
10238 use Composer\Package\PackageInterface;
10239
10240
10241
10242
10243
10244
10245 class InstallOperation extends SolverOperation
10246 {
10247 protected $package;
10248
10249
10250
10251
10252
10253
10254
10255 public function __construct(PackageInterface $package, $reason = null)
10256 {
10257 parent::__construct($reason);
10258
10259 $this->package = $package;
10260 }
10261
10262
10263
10264
10265
10266
10267 public function getPackage()
10268 {
10269 return $this->package;
10270 }
10271
10272
10273
10274
10275
10276
10277 public function getJobType()
10278 {
10279 return 'install';
10280 }
10281
10282
10283
10284
10285 public function __toString()
10286 {
10287 return 'Installing '.$this->package->getPrettyName().' ('.$this->formatVersion($this->package).')';
10288 }
10289 }
10290 <?php
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302 namespace Composer\DependencyResolver\Operation;
10303
10304 use Composer\Package\AliasPackage;
10305 use Composer\Package\PackageInterface;
10306
10307
10308
10309
10310
10311
10312 class MarkAliasInstalledOperation extends SolverOperation
10313 {
10314 protected $package;
10315
10316
10317
10318
10319
10320
10321
10322 public function __construct(AliasPackage $package, $reason = null)
10323 {
10324 parent::__construct($reason);
10325
10326 $this->package = $package;
10327 }
10328
10329
10330
10331
10332
10333
10334 public function getPackage()
10335 {
10336 return $this->package;
10337 }
10338
10339
10340
10341
10342
10343
10344 public function getJobType()
10345 {
10346 return 'markAliasInstalled';
10347 }
10348
10349
10350
10351
10352 public function __toString()
10353 {
10354 return 'Marking '.$this->package->getPrettyName().' ('.$this->formatVersion($this->package).') as installed, alias of '.$this->package->getAliasOf()->getPrettyName().' ('.$this->formatVersion($this->package->getAliasOf()).')';
10355 }
10356 }
10357 <?php
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369 namespace Composer\DependencyResolver\Operation;
10370
10371 use Composer\Package\AliasPackage;
10372 use Composer\Package\PackageInterface;
10373
10374
10375
10376
10377
10378
10379 class MarkAliasUninstalledOperation extends SolverOperation
10380 {
10381 protected $package;
10382
10383
10384
10385
10386
10387
10388
10389 public function __construct(AliasPackage $package, $reason = null)
10390 {
10391 parent::__construct($reason);
10392
10393 $this->package = $package;
10394 }
10395
10396
10397
10398
10399
10400
10401 public function getPackage()
10402 {
10403 return $this->package;
10404 }
10405
10406
10407
10408
10409
10410
10411 public function getJobType()
10412 {
10413 return 'markAliasUninstalled';
10414 }
10415
10416
10417
10418
10419 public function __toString()
10420 {
10421 return 'Marking '.$this->package->getPrettyName().' ('.$this->formatVersion($this->package).') as uninstalled, alias of '.$this->package->getAliasOf()->getPrettyName().' ('.$this->formatVersion($this->package->getAliasOf()).')';
10422 }
10423 }
10424 <?php
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436 namespace Composer\DependencyResolver\Operation;
10437
10438
10439
10440
10441
10442
10443 interface OperationInterface
10444 {
10445
10446
10447
10448
10449
10450 public function getJobType();
10451
10452
10453
10454
10455
10456
10457 public function getReason();
10458
10459
10460
10461
10462
10463
10464 public function __toString();
10465 }
10466 <?php
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478 namespace Composer\DependencyResolver\Operation;
10479
10480 use Composer\Package\PackageInterface;
10481
10482
10483
10484
10485
10486
10487 abstract class SolverOperation implements OperationInterface
10488 {
10489 protected $reason;
10490
10491
10492
10493
10494
10495
10496 public function __construct($reason = null)
10497 {
10498 $this->reason = $reason;
10499 }
10500
10501
10502
10503
10504
10505
10506 public function getReason()
10507 {
10508 return $this->reason;
10509 }
10510
10511 protected function formatVersion(PackageInterface $package)
10512 {
10513 return $package->getFullPrettyVersion();
10514 }
10515 }
10516 <?php
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528 namespace Composer\DependencyResolver\Operation;
10529
10530 use Composer\Package\PackageInterface;
10531
10532
10533
10534
10535
10536
10537 class UninstallOperation extends SolverOperation
10538 {
10539 protected $package;
10540
10541
10542
10543
10544
10545
10546
10547 public function __construct(PackageInterface $package, $reason = null)
10548 {
10549 parent::__construct($reason);
10550
10551 $this->package = $package;
10552 }
10553
10554
10555
10556
10557
10558
10559 public function getPackage()
10560 {
10561 return $this->package;
10562 }
10563
10564
10565
10566
10567
10568
10569 public function getJobType()
10570 {
10571 return 'uninstall';
10572 }
10573
10574
10575
10576
10577 public function __toString()
10578 {
10579 return 'Uninstalling '.$this->package->getPrettyName().' ('.$this->formatVersion($this->package).')';
10580 }
10581 }
10582 <?php
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594 namespace Composer\DependencyResolver\Operation;
10595
10596 use Composer\Package\PackageInterface;
10597
10598
10599
10600
10601
10602
10603 class UpdateOperation extends SolverOperation
10604 {
10605 protected $initialPackage;
10606 protected $targetPackage;
10607
10608
10609
10610
10611
10612
10613
10614
10615 public function __construct(PackageInterface $initial, PackageInterface $target, $reason = null)
10616 {
10617 parent::__construct($reason);
10618
10619 $this->initialPackage = $initial;
10620 $this->targetPackage = $target;
10621 }
10622
10623
10624
10625
10626
10627
10628 public function getInitialPackage()
10629 {
10630 return $this->initialPackage;
10631 }
10632
10633
10634
10635
10636
10637
10638 public function getTargetPackage()
10639 {
10640 return $this->targetPackage;
10641 }
10642
10643
10644
10645
10646
10647
10648 public function getJobType()
10649 {
10650 return 'update';
10651 }
10652
10653
10654
10655
10656 public function __toString()
10657 {
10658 return 'Updating '.$this->initialPackage->getPrettyName().' ('.$this->formatVersion($this->initialPackage).') to '.
10659 $this->targetPackage->getPrettyName(). ' ('.$this->formatVersion($this->targetPackage).')';
10660 }
10661 }
10662 <?php
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674 namespace Composer\DependencyResolver;
10675
10676 use Composer\Package\PackageInterface;
10677
10678
10679
10680
10681 interface PolicyInterface
10682 {
10683 public function versionCompare(PackageInterface $a, PackageInterface $b, $operator);
10684
10685 public function findUpdatePackages(Pool $pool, array $installedMap, PackageInterface $package);
10686
10687 public function selectPreferredPackages(Pool $pool, array $installedMap, array $literals, $requiredPackage = null);
10688 }
10689 <?php
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701 namespace Composer\DependencyResolver;
10702
10703 use Composer\Package\BasePackage;
10704 use Composer\Package\AliasPackage;
10705 use Composer\Package\Version\VersionParser;
10706 use Composer\Semver\Constraint\ConstraintInterface;
10707 use Composer\Semver\Constraint\Constraint;
10708 use Composer\Semver\Constraint\EmptyConstraint;
10709 use Composer\Repository\RepositoryInterface;
10710 use Composer\Repository\CompositeRepository;
10711 use Composer\Repository\ComposerRepository;
10712 use Composer\Repository\InstalledRepositoryInterface;
10713 use Composer\Repository\PlatformRepository;
10714 use Composer\Package\PackageInterface;
10715
10716
10717
10718
10719
10720
10721
10722 class Pool implements \Countable
10723 {
10724 const MATCH_NAME = -1;
10725 const MATCH_NONE = 0;
10726 const MATCH = 1;
10727 const MATCH_PROVIDE = 2;
10728 const MATCH_REPLACE = 3;
10729 const MATCH_FILTERED = 4;
10730
10731 protected $repositories = array();
10732 protected $providerRepos = array();
10733 protected $packages = array();
10734 protected $packageByName = array();
10735 protected $packageByExactName = array();
10736 protected $acceptableStabilities;
10737 protected $stabilityFlags;
10738 protected $versionParser;
10739 protected $providerCache = array();
10740 protected $filterRequires;
10741 protected $whitelist = null;
10742 protected $id = 1;
10743
10744 public function __construct($minimumStability = 'stable', array $stabilityFlags = array(), array $filterRequires = array())
10745 {
10746 $this->versionParser = new VersionParser;
10747 $this->acceptableStabilities = array();
10748 foreach (BasePackage::$stabilities as $stability => $value) {
10749 if ($value <= BasePackage::$stabilities[$minimumStability]) {
10750 $this->acceptableStabilities[$stability] = $value;
10751 }
10752 }
10753 $this->stabilityFlags = $stabilityFlags;
10754 $this->filterRequires = $filterRequires;
10755 foreach ($filterRequires as $name => $constraint) {
10756 if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name)) {
10757 unset($this->filterRequires[$name]);
10758 }
10759 }
10760 }
10761
10762 public function setWhitelist($whitelist)
10763 {
10764 $this->whitelist = $whitelist;
10765 $this->providerCache = array();
10766 }
10767
10768
10769
10770
10771
10772
10773
10774 public function addRepository(RepositoryInterface $repo, $rootAliases = array())
10775 {
10776 if ($repo instanceof CompositeRepository) {
10777 $repos = $repo->getRepositories();
10778 } else {
10779 $repos = array($repo);
10780 }
10781
10782 foreach ($repos as $repo) {
10783 $this->repositories[] = $repo;
10784
10785 $exempt = $repo instanceof PlatformRepository || $repo instanceof InstalledRepositoryInterface;
10786
10787 if ($repo instanceof ComposerRepository && $repo->hasProviders()) {
10788 $this->providerRepos[] = $repo;
10789 $repo->setRootAliases($rootAliases);
10790 $repo->resetPackageIds();
10791 } else {
10792 foreach ($repo->getPackages() as $package) {
10793 $names = $package->getNames();
10794 $stability = $package->getStability();
10795 if ($exempt || $this->isPackageAcceptable($names, $stability)) {
10796 $package->setId($this->id++);
10797 $this->packages[] = $package;
10798 $this->packageByExactName[$package->getName()][$package->id] = $package;
10799
10800 foreach ($names as $provided) {
10801 $this->packageByName[$provided][] = $package;
10802 }
10803
10804
10805  $name = $package->getName();
10806 if (isset($rootAliases[$name][$package->getVersion()])) {
10807 $alias = $rootAliases[$name][$package->getVersion()];
10808 if ($package instanceof AliasPackage) {
10809 $package = $package->getAliasOf();
10810 }
10811 $aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']);
10812 $aliasPackage->setRootPackageAlias(true);
10813 $aliasPackage->setId($this->id++);
10814
10815 $package->getRepository()->addPackage($aliasPackage);
10816 $this->packages[] = $aliasPackage;
10817 $this->packageByExactName[$aliasPackage->getName()][$aliasPackage->id] = $aliasPackage;
10818
10819 foreach ($aliasPackage->getNames() as $name) {
10820 $this->packageByName[$name][] = $aliasPackage;
10821 }
10822 }
10823 }
10824 }
10825 }
10826 }
10827 }
10828
10829 public function getPriority(RepositoryInterface $repo)
10830 {
10831 $priority = array_search($repo, $this->repositories, true);
10832
10833 if (false === $priority) {
10834 throw new \RuntimeException("Could not determine repository priority. The repository was not registered in the pool.");
10835 }
10836
10837 return -$priority;
10838 }
10839
10840
10841
10842
10843
10844
10845
10846 public function packageById($id)
10847 {
10848 return $this->packages[$id - 1];
10849 }
10850
10851
10852
10853
10854 public function count()
10855 {
10856 return count($this->packages);
10857 }
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870 public function whatProvides($name, ConstraintInterface $constraint = null, $mustMatchName = false, $bypassFilters = false)
10871 {
10872 if ($bypassFilters) {
10873 return $this->computeWhatProvides($name, $constraint, $mustMatchName, true);
10874 }
10875
10876 $key = ((int) $mustMatchName).$constraint;
10877 if (isset($this->providerCache[$name][$key])) {
10878 return $this->providerCache[$name][$key];
10879 }
10880
10881 return $this->providerCache[$name][$key] = $this->computeWhatProvides($name, $constraint, $mustMatchName, $bypassFilters);
10882 }
10883
10884
10885
10886
10887 private function computeWhatProvides($name, $constraint, $mustMatchName = false, $bypassFilters = false)
10888 {
10889 $candidates = array();
10890
10891 foreach ($this->providerRepos as $repo) {
10892 foreach ($repo->whatProvides($this, $name, $bypassFilters) as $candidate) {
10893 $candidates[] = $candidate;
10894 if ($candidate->id < 1) {
10895 $candidate->setId($this->id++);
10896 $this->packages[$this->id - 2] = $candidate;
10897 }
10898 }
10899 }
10900
10901 if ($mustMatchName) {
10902 $candidates = array_filter($candidates, function ($candidate) use ($name) {
10903 return $candidate->getName() == $name;
10904 });
10905 if (isset($this->packageByExactName[$name])) {
10906 $candidates = array_merge($candidates, $this->packageByExactName[$name]);
10907 }
10908 } elseif (isset($this->packageByName[$name])) {
10909 $candidates = array_merge($candidates, $this->packageByName[$name]);
10910 }
10911
10912 $matches = $provideMatches = array();
10913 $nameMatch = false;
10914
10915 foreach ($candidates as $candidate) {
10916 $aliasOfCandidate = null;
10917
10918
10919  
10920  if ($candidate instanceof AliasPackage) {
10921 $aliasOfCandidate = $candidate->getAliasOf();
10922 }
10923
10924 if ($this->whitelist !== null && !$bypassFilters && (
10925 (!($candidate instanceof AliasPackage) && !isset($this->whitelist[$candidate->id])) ||
10926 ($candidate instanceof AliasPackage && !isset($this->whitelist[$aliasOfCandidate->id]))
10927 )) {
10928 continue;
10929 }
10930 switch ($this->match($candidate, $name, $constraint, $bypassFilters)) {
10931 case self::MATCH_NONE:
10932 break;
10933
10934 case self::MATCH_NAME:
10935 $nameMatch = true;
10936 break;
10937
10938 case self::MATCH:
10939 $nameMatch = true;
10940 $matches[] = $candidate;
10941 break;
10942
10943 case self::MATCH_PROVIDE:
10944 $provideMatches[] = $candidate;
10945 break;
10946
10947 case self::MATCH_REPLACE:
10948 $matches[] = $candidate;
10949 break;
10950
10951 case self::MATCH_FILTERED:
10952 break;
10953
10954 default:
10955 throw new \UnexpectedValueException('Unexpected match type');
10956 }
10957 }
10958
10959
10960  if ($nameMatch) {
10961 return $matches;
10962 }
10963
10964 return array_merge($matches, $provideMatches);
10965 }
10966
10967 public function literalToPackage($literal)
10968 {
10969 $packageId = abs($literal);
10970
10971 return $this->packageById($packageId);
10972 }
10973
10974 public function literalToPrettyString($literal, $installedMap)
10975 {
10976 $package = $this->literalToPackage($literal);
10977
10978 if (isset($installedMap[$package->id])) {
10979 $prefix = ($literal > 0 ? 'keep' : 'remove');
10980 } else {
10981 $prefix = ($literal > 0 ? 'install' : 'don\'t install');
10982 }
10983
10984 return $prefix.' '.$package->getPrettyString();
10985 }
10986
10987 public function isPackageAcceptable($name, $stability)
10988 {
10989 foreach ((array) $name as $n) {
10990
10991  if (!isset($this->stabilityFlags[$n]) && isset($this->acceptableStabilities[$stability])) {
10992 return true;
10993 }
10994
10995
10996  if (isset($this->stabilityFlags[$n]) && BasePackage::$stabilities[$stability] <= $this->stabilityFlags[$n]) {
10997 return true;
10998 }
10999 }
11000
11001 return false;
11002 }
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013 private function match($candidate, $name, ConstraintInterface $constraint = null, $bypassFilters)
11014 {
11015 $candidateName = $candidate->getName();
11016 $candidateVersion = $candidate->getVersion();
11017 $isDev = $candidate->getStability() === 'dev';
11018 $isAlias = $candidate instanceof AliasPackage;
11019
11020 if (!$bypassFilters && !$isDev && !$isAlias && isset($this->filterRequires[$name])) {
11021 $requireFilter = $this->filterRequires[$name];
11022 } else {
11023 $requireFilter = new EmptyConstraint;
11024 }
11025
11026 if ($candidateName === $name) {
11027 $pkgConstraint = new Constraint('==', $candidateVersion);
11028
11029 if ($constraint === null || $constraint->matches($pkgConstraint)) {
11030 return $requireFilter->matches($pkgConstraint) ? self::MATCH : self::MATCH_FILTERED;
11031 }
11032
11033 return self::MATCH_NAME;
11034 }
11035
11036 $provides = $candidate->getProvides();
11037 $replaces = $candidate->getReplaces();
11038
11039
11040  if (isset($replaces[0]) || isset($provides[0])) {
11041 foreach ($provides as $link) {
11042 if ($link->getTarget() === $name && ($constraint === null || $constraint->matches($link->getConstraint()))) {
11043 return $requireFilter->matches($link->getConstraint()) ? self::MATCH_PROVIDE : self::MATCH_FILTERED;
11044 }
11045 }
11046
11047 foreach ($replaces as $link) {
11048 if ($link->getTarget() === $name && ($constraint === null || $constraint->matches($link->getConstraint()))) {
11049 return $requireFilter->matches($link->getConstraint()) ? self::MATCH_REPLACE : self::MATCH_FILTERED;
11050 }
11051 }
11052
11053 return self::MATCH_NONE;
11054 }
11055
11056 if (isset($provides[$name]) && ($constraint === null || $constraint->matches($provides[$name]->getConstraint()))) {
11057 return $requireFilter->matches($provides[$name]->getConstraint()) ? self::MATCH_PROVIDE : self::MATCH_FILTERED;
11058 }
11059
11060 if (isset($replaces[$name]) && ($constraint === null || $constraint->matches($replaces[$name]->getConstraint()))) {
11061 return $requireFilter->matches($replaces[$name]->getConstraint()) ? self::MATCH_REPLACE : self::MATCH_FILTERED;
11062 }
11063
11064 return self::MATCH_NONE;
11065 }
11066 }
11067 <?php
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079 namespace Composer\DependencyResolver;
11080
11081
11082
11083
11084
11085
11086 class Problem
11087 {
11088
11089
11090
11091
11092 protected $reasonSeen;
11093
11094
11095
11096
11097
11098 protected $reasons = array();
11099
11100 protected $section = 0;
11101
11102 protected $pool;
11103
11104 public function __construct(Pool $pool)
11105 {
11106 $this->pool = $pool;
11107 }
11108
11109
11110
11111
11112
11113
11114 public function addRule(Rule $rule)
11115 {
11116 $this->addReason(spl_object_hash($rule), array(
11117 'rule' => $rule,
11118 'job' => $rule->getJob(),
11119 ));
11120 }
11121
11122
11123
11124
11125
11126
11127 public function getReasons()
11128 {
11129 return $this->reasons;
11130 }
11131
11132
11133
11134
11135
11136
11137
11138 public function getPrettyString(array $installedMap = array())
11139 {
11140 $reasons = call_user_func_array('array_merge', array_reverse($this->reasons));
11141
11142 if (count($reasons) === 1) {
11143 reset($reasons);
11144 $reason = current($reasons);
11145
11146 $rule = $reason['rule'];
11147 $job = $reason['job'];
11148
11149 if (isset($job['constraint'])) {
11150 $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']);
11151 } else {
11152 $packages = array();
11153 }
11154
11155 if ($job && $job['cmd'] === 'install' && empty($packages)) {
11156
11157
11158  if ($job['packageName'] === 'php' || $job['packageName'] === 'php-64bit' || $job['packageName'] === 'hhvm') {
11159 $available = $this->pool->whatProvides($job['packageName']);
11160 $version = count($available) ? $available[0]->getPrettyVersion() : phpversion();
11161
11162 $msg = "\n    - This package requires ".$job['packageName'].$this->constraintToText($job['constraint']).' but ';
11163
11164 if (defined('HHVM_VERSION')) {
11165 return $msg . 'your HHVM version does not satisfy that requirement.';
11166 }
11167
11168 if ($job['packageName'] === 'hhvm') {
11169 return $msg . 'you are running this with PHP and not HHVM.';
11170 }
11171
11172 return $msg . 'your PHP version ('. $version .') does not satisfy that requirement.';
11173 }
11174
11175
11176  if (0 === stripos($job['packageName'], 'ext-')) {
11177 $ext = substr($job['packageName'], 4);
11178 $error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system';
11179
11180 return "\n    - The requested PHP extension ".$job['packageName'].$this->constraintToText($job['constraint']).' '.$error.'. Install or enable PHP\'s '.$ext.' extension.';
11181 }
11182
11183
11184  if (0 === stripos($job['packageName'], 'lib-')) {
11185 if (strtolower($job['packageName']) === 'lib-icu') {
11186 $error = extension_loaded('intl') ? 'has the wrong version installed, try upgrading the intl extension.' : 'is missing from your system, make sure the intl extension is loaded.';
11187
11188 return "\n    - The requested linked library ".$job['packageName'].$this->constraintToText($job['constraint']).' '.$error;
11189 }
11190
11191 return "\n    - The requested linked library ".$job['packageName'].$this->constraintToText($job['constraint']).' has the wrong version installed or is missing from your system, make sure to load the extension providing it.';
11192 }
11193
11194 if (!preg_match('{^[A-Za-z0-9_./-]+$}', $job['packageName'])) {
11195 $illegalChars = preg_replace('{[A-Za-z0-9_./-]+}', '', $job['packageName']);
11196
11197 return "\n    - The requested package ".$job['packageName'].' could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.';
11198 }
11199
11200 if ($providers = $this->pool->whatProvides($job['packageName'], $job['constraint'], true, true)) {
11201 return "\n    - The requested package ".$job['packageName'].$this->constraintToText($job['constraint']).' is satisfiable by '.$this->getPackageList($providers).' but these conflict with your requirements or minimum-stability.';
11202 }
11203
11204 if ($providers = $this->pool->whatProvides($job['packageName'], null, true, true)) {
11205 return "\n    - The requested package ".$job['packageName'].$this->constraintToText($job['constraint']).' exists as '.$this->getPackageList($providers).' but these are rejected by your constraint.';
11206 }
11207
11208 return "\n    - The requested package ".$job['packageName'].' could not be found in any version, there may be a typo in the package name.';
11209 }
11210 }
11211
11212 $messages = array();
11213
11214 foreach ($reasons as $reason) {
11215 $rule = $reason['rule'];
11216 $job = $reason['job'];
11217
11218 if ($job) {
11219 $messages[] = $this->jobToText($job);
11220 } elseif ($rule) {
11221 if ($rule instanceof Rule) {
11222 $messages[] = $rule->getPrettyString($this->pool, $installedMap);
11223 }
11224 }
11225 }
11226
11227 return "\n    - ".implode("\n    - ", $messages);
11228 }
11229
11230
11231
11232
11233
11234
11235
11236 protected function addReason($id, $reason)
11237 {
11238 if (!isset($this->reasonSeen[$id])) {
11239 $this->reasonSeen[$id] = true;
11240 $this->reasons[$this->section][] = $reason;
11241 }
11242 }
11243
11244 public function nextSection()
11245 {
11246 $this->section++;
11247 }
11248
11249
11250
11251
11252
11253
11254
11255 protected function jobToText($job)
11256 {
11257 switch ($job['cmd']) {
11258 case 'install':
11259 $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']);
11260 if (!$packages) {
11261 return 'No package found to satisfy install request for '.$job['packageName'].$this->constraintToText($job['constraint']);
11262 }
11263
11264 return 'Installation request for '.$job['packageName'].$this->constraintToText($job['constraint']).' -> satisfiable by '.$this->getPackageList($packages).'.';
11265 case 'update':
11266 return 'Update request for '.$job['packageName'].$this->constraintToText($job['constraint']).'.';
11267 case 'remove':
11268 return 'Removal request for '.$job['packageName'].$this->constraintToText($job['constraint']).'';
11269 }
11270
11271 if (isset($job['constraint'])) {
11272 $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']);
11273 } else {
11274 $packages = array();
11275 }
11276
11277 return 'Job(cmd='.$job['cmd'].', target='.$job['packageName'].', packages=['.$this->getPackageList($packages).'])';
11278 }
11279
11280 protected function getPackageList($packages)
11281 {
11282 $prepared = array();
11283 foreach ($packages as $package) {
11284 $prepared[$package->getName()]['name'] = $package->getPrettyName();
11285 $prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion();
11286 }
11287 foreach ($prepared as $name => $package) {
11288 $prepared[$name] = $package['name'].'['.implode(', ', $package['versions']).']';
11289 }
11290
11291 return implode(', ', $prepared);
11292 }
11293
11294
11295
11296
11297
11298
11299
11300 protected function constraintToText($constraint)
11301 {
11302 return ($constraint) ? ' '.$constraint->getPrettyString() : '';
11303 }
11304 }
11305 <?php
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317 namespace Composer\DependencyResolver;
11318
11319 use Composer\Semver\Constraint\ConstraintInterface;
11320
11321
11322
11323
11324 class Request
11325 {
11326 protected $jobs;
11327
11328 public function __construct()
11329 {
11330 $this->jobs = array();
11331 }
11332
11333 public function install($packageName, ConstraintInterface $constraint = null)
11334 {
11335 $this->addJob($packageName, 'install', $constraint);
11336 }
11337
11338 public function update($packageName, ConstraintInterface $constraint = null)
11339 {
11340 $this->addJob($packageName, 'update', $constraint);
11341 }
11342
11343 public function remove($packageName, ConstraintInterface $constraint = null)
11344 {
11345 $this->addJob($packageName, 'remove', $constraint);
11346 }
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356 public function fix($packageName, ConstraintInterface $constraint = null)
11357 {
11358 $this->addJob($packageName, 'install', $constraint, true);
11359 }
11360
11361 protected function addJob($packageName, $cmd, ConstraintInterface $constraint = null, $fixed = false)
11362 {
11363 $packageName = strtolower($packageName);
11364
11365 $this->jobs[] = array(
11366 'cmd' => $cmd,
11367 'packageName' => $packageName,
11368 'constraint' => $constraint,
11369 'fixed' => $fixed,
11370 );
11371 }
11372
11373 public function updateAll()
11374 {
11375 $this->jobs[] = array('cmd' => 'update-all');
11376 }
11377
11378 public function getJobs()
11379 {
11380 return $this->jobs;
11381 }
11382 }
11383 <?php
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395 namespace Composer\DependencyResolver;
11396
11397 use Composer\Package\CompletePackage;
11398
11399
11400
11401
11402
11403 abstract class Rule
11404 {
11405
11406  const RULE_INTERNAL_ALLOW_UPDATE = 1;
11407 const RULE_JOB_INSTALL = 2;
11408 const RULE_JOB_REMOVE = 3;
11409 const RULE_PACKAGE_CONFLICT = 6;
11410 const RULE_PACKAGE_REQUIRES = 7;
11411 const RULE_PACKAGE_OBSOLETES = 8;
11412 const RULE_INSTALLED_PACKAGE_OBSOLETES = 9;
11413 const RULE_PACKAGE_SAME_NAME = 10;
11414 const RULE_PACKAGE_IMPLICIT_OBSOLETES = 11;
11415 const RULE_LEARNED = 12;
11416 const RULE_PACKAGE_ALIAS = 13;
11417
11418
11419  const BITFIELD_TYPE = 0;
11420 const BITFIELD_REASON = 8;
11421 const BITFIELD_DISABLED = 16;
11422
11423 protected $bitfield;
11424 protected $reasonData;
11425
11426
11427
11428
11429
11430
11431 public function __construct($reason, $reasonData, $job = null)
11432 {
11433 $this->reasonData = $reasonData;
11434
11435 if ($job) {
11436 $this->job = $job;
11437 }
11438
11439 $this->bitfield = (0 << self::BITFIELD_DISABLED) |
11440 ($reason << self::BITFIELD_REASON) |
11441 (255 << self::BITFIELD_TYPE);
11442 }
11443
11444 abstract public function getLiterals();
11445
11446 abstract public function getHash();
11447
11448 public function getJob()
11449 {
11450 return isset($this->job) ? $this->job : null;
11451 }
11452
11453 abstract public function equals(Rule $rule);
11454
11455 public function getReason()
11456 {
11457 return ($this->bitfield & (255 << self::BITFIELD_REASON)) >> self::BITFIELD_REASON;
11458 }
11459
11460 public function getReasonData()
11461 {
11462 return $this->reasonData;
11463 }
11464
11465 public function getRequiredPackage()
11466 {
11467 if ($this->getReason() === self::RULE_JOB_INSTALL) {
11468 return $this->reasonData;
11469 }
11470
11471 if ($this->getReason() === self::RULE_PACKAGE_REQUIRES) {
11472 return $this->reasonData->getTarget();
11473 }
11474 }
11475
11476 public function setType($type)
11477 {
11478 $this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_TYPE)) | ((255 & $type) << self::BITFIELD_TYPE);
11479 }
11480
11481 public function getType()
11482 {
11483 return ($this->bitfield & (255 << self::BITFIELD_TYPE)) >> self::BITFIELD_TYPE;
11484 }
11485
11486 public function disable()
11487 {
11488 $this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_DISABLED)) | (1 << self::BITFIELD_DISABLED);
11489 }
11490
11491 public function enable()
11492 {
11493 $this->bitfield = $this->bitfield & ~(255 << self::BITFIELD_DISABLED);
11494 }
11495
11496 public function isDisabled()
11497 {
11498 return (bool) (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
11499 }
11500
11501 public function isEnabled()
11502 {
11503 return !(($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
11504 }
11505
11506 abstract public function isAssertion();
11507
11508 public function getPrettyString(Pool $pool, array $installedMap = array())
11509 {
11510 $literals = $this->getLiterals();
11511
11512 $ruleText = '';
11513 foreach ($literals as $i => $literal) {
11514 if ($i != 0) {
11515 $ruleText .= '|';
11516 }
11517 $ruleText .= $pool->literalToPrettyString($literal, $installedMap);
11518 }
11519
11520 switch ($this->getReason()) {
11521 case self::RULE_INTERNAL_ALLOW_UPDATE:
11522 return $ruleText;
11523
11524 case self::RULE_JOB_INSTALL:
11525 return "Install command rule ($ruleText)";
11526
11527 case self::RULE_JOB_REMOVE:
11528 return "Remove command rule ($ruleText)";
11529
11530 case self::RULE_PACKAGE_CONFLICT:
11531 $package1 = $pool->literalToPackage($literals[0]);
11532 $package2 = $pool->literalToPackage($literals[1]);
11533
11534 return $package1->getPrettyString().' conflicts with '.$this->formatPackagesUnique($pool, array($package2)).'.';
11535
11536 case self::RULE_PACKAGE_REQUIRES:
11537 $sourceLiteral = array_shift($literals);
11538 $sourcePackage = $pool->literalToPackage($sourceLiteral);
11539
11540 $requires = array();
11541 foreach ($literals as $literal) {
11542 $requires[] = $pool->literalToPackage($literal);
11543 }
11544
11545 $text = $this->reasonData->getPrettyString($sourcePackage);
11546 if ($requires) {
11547 $text .= ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $requires) . '.';
11548 } else {
11549 $targetName = $this->reasonData->getTarget();
11550
11551 if ($targetName === 'php' || $targetName === 'php-64bit' || $targetName === 'hhvm') {
11552
11553  if (defined('HHVM_VERSION')) {
11554 return $text . ' -> your HHVM version does not satisfy that requirement.';
11555 }
11556
11557 if ($targetName === 'hhvm') {
11558 return $text . ' -> you are running this with PHP and not HHVM.';
11559 }
11560
11561 $packages = $pool->whatProvides($targetName);
11562 $package = count($packages) ? current($packages) : phpversion();
11563
11564 if (!($package instanceof CompletePackage)) {
11565 return $text . ' -> your PHP version ('.phpversion().') does not satisfy that requirement.';
11566 }
11567
11568 $extra = $package->getExtra();
11569
11570 if (!empty($extra['config.platform'])) {
11571 $text .= ' -> your PHP version ('.phpversion().') overridden by "config.platform.php" version ('.$package->getPrettyVersion().') does not satisfy that requirement.';
11572 } else {
11573 $text .= ' -> your PHP version ('.$package->getPrettyVersion().') does not satisfy that requirement.';
11574 }
11575
11576 return $text;
11577 }
11578
11579 if (0 === strpos($targetName, 'ext-')) {
11580
11581  $ext = substr($targetName, 4);
11582 $error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system';
11583
11584 return $text . ' -> the requested PHP extension '.$ext.' '.$error.'.';
11585 }
11586
11587 if (0 === strpos($targetName, 'lib-')) {
11588
11589  $lib = substr($targetName, 4);
11590
11591 return $text . ' -> the requested linked library '.$lib.' has the wrong version installed or is missing from your system, make sure to have the extension providing it.';
11592 }
11593
11594 if ($providers = $pool->whatProvides($targetName, $this->reasonData->getConstraint(), true, true)) {
11595 return $text . ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $providers) .' but these conflict with your requirements or minimum-stability.';
11596 }
11597
11598 return $text . ' -> no matching package found.';
11599 }
11600
11601 return $text;
11602
11603 case self::RULE_PACKAGE_OBSOLETES:
11604 return $ruleText;
11605 case self::RULE_INSTALLED_PACKAGE_OBSOLETES:
11606 return $ruleText;
11607 case self::RULE_PACKAGE_SAME_NAME:
11608 return 'Can only install one of: ' . $this->formatPackagesUnique($pool, $literals) . '.';
11609 case self::RULE_PACKAGE_IMPLICIT_OBSOLETES:
11610 return $ruleText;
11611 case self::RULE_LEARNED:
11612 return 'Conclusion: '.$ruleText;
11613 case self::RULE_PACKAGE_ALIAS:
11614 return $ruleText;
11615 default:
11616 return '('.$ruleText.')';
11617 }
11618 }
11619
11620 protected function formatPackagesUnique($pool, array $packages)
11621 {
11622 $prepared = array();
11623 foreach ($packages as $package) {
11624 if (!is_object($package)) {
11625 $package = $pool->literalToPackage($package);
11626 }
11627 $prepared[$package->getName()]['name'] = $package->getPrettyName();
11628 $prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion();
11629 }
11630 foreach ($prepared as $name => $package) {
11631 $prepared[$name] = $package['name'].'['.implode(', ', $package['versions']).']';
11632 }
11633
11634 return implode(', ', $prepared);
11635 }
11636 }
11637 <?php
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649 namespace Composer\DependencyResolver;
11650
11651 use Composer\Package\PackageInterface;
11652 use Composer\Package\Link;
11653
11654
11655
11656
11657 class Rule2Literals extends Rule
11658 {
11659 protected $literal1;
11660 protected $literal2;
11661
11662
11663
11664
11665
11666
11667
11668
11669 public function __construct($literal1, $literal2, $reason, $reasonData, $job = null)
11670 {
11671 parent::__construct($reason, $reasonData, $job);
11672
11673 if ($literal1 < $literal2) {
11674 $this->literal1 = $literal1;
11675 $this->literal2 = $literal2;
11676 } else {
11677 $this->literal1 = $literal2;
11678 $this->literal2 = $literal1;
11679 }
11680 }
11681
11682 public function getLiterals()
11683 {
11684 return array($this->literal1, $this->literal2);
11685 }
11686
11687 public function getHash()
11688 {
11689 $data = unpack('ihash', md5($this->literal1.','.$this->literal2, true));
11690
11691 return $data['hash'];
11692 }
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702 public function equals(Rule $rule)
11703 {
11704 $literals = $rule->getLiterals();
11705 if (2 != count($literals)) {
11706 return false;
11707 }
11708
11709 if ($this->literal1 !== $literals[0]) {
11710 return false;
11711 }
11712
11713 if ($this->literal2 !== $literals[1]) {
11714 return false;
11715 }
11716
11717 return true;
11718 }
11719
11720 public function isAssertion()
11721 {
11722 return false;
11723 }
11724
11725
11726
11727
11728
11729
11730 public function __toString()
11731 {
11732 $result = ($this->isDisabled()) ? 'disabled(' : '(';
11733
11734 $result .= $this->literal1 . '|' . $this->literal2 . ')';
11735
11736 return $result;
11737 }
11738 }
11739 <?php
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751 namespace Composer\DependencyResolver;
11752
11753
11754
11755
11756 class RuleSet implements \IteratorAggregate, \Countable
11757 {
11758
11759  const TYPE_PACKAGE = 0;
11760 const TYPE_JOB = 1;
11761 const TYPE_LEARNED = 4;
11762
11763
11764
11765
11766
11767
11768 public $ruleById;
11769
11770 protected static $types = array(
11771 255 => 'UNKNOWN',
11772 self::TYPE_PACKAGE => 'PACKAGE',
11773 self::TYPE_JOB => 'JOB',
11774 self::TYPE_LEARNED => 'LEARNED',
11775 );
11776
11777 protected $rules;
11778 protected $nextRuleId;
11779
11780 protected $rulesByHash;
11781
11782 public function __construct()
11783 {
11784 $this->nextRuleId = 0;
11785
11786 foreach ($this->getTypes() as $type) {
11787 $this->rules[$type] = array();
11788 }
11789
11790 $this->rulesByHash = array();
11791 }
11792
11793 public function add(Rule $rule, $type)
11794 {
11795 if (!isset(self::$types[$type])) {
11796 throw new \OutOfBoundsException('Unknown rule type: ' . $type);
11797 }
11798
11799 $hash = $rule->getHash();
11800
11801
11802  if (isset($this->rulesByHash[$hash])) {
11803 $potentialDuplicates = $this->rulesByHash[$hash];
11804 if (is_array($potentialDuplicates)) {
11805 foreach ($potentialDuplicates as $potentialDuplicate) {
11806 if ($rule->equals($potentialDuplicate)) {
11807 return;
11808 }
11809 }
11810 } else {
11811 if ($rule->equals($potentialDuplicates)) {
11812 return;
11813 }
11814 }
11815 }
11816
11817 if (!isset($this->rules[$type])) {
11818 $this->rules[$type] = array();
11819 }
11820
11821 $this->rules[$type][] = $rule;
11822 $this->ruleById[$this->nextRuleId] = $rule;
11823 $rule->setType($type);
11824
11825 $this->nextRuleId++;
11826
11827 if (!isset($this->rulesByHash[$hash])) {
11828 $this->rulesByHash[$hash] = $rule;
11829 } elseif (is_array($this->rulesByHash[$hash])) {
11830 $this->rulesByHash[$hash][] = $rule;
11831 } else {
11832 $originalRule = $this->rulesByHash[$hash];
11833 $this->rulesByHash[$hash] = array($originalRule, $rule);
11834 }
11835 }
11836
11837 public function count()
11838 {
11839 return $this->nextRuleId;
11840 }
11841
11842 public function ruleById($id)
11843 {
11844 return $this->ruleById[$id];
11845 }
11846
11847 public function getRules()
11848 {
11849 return $this->rules;
11850 }
11851
11852 public function getIterator()
11853 {
11854 return new RuleSetIterator($this->getRules());
11855 }
11856
11857 public function getIteratorFor($types)
11858 {
11859 if (!is_array($types)) {
11860 $types = array($types);
11861 }
11862
11863 $allRules = $this->getRules();
11864 $rules = array();
11865
11866 foreach ($types as $type) {
11867 $rules[$type] = $allRules[$type];
11868 }
11869
11870 return new RuleSetIterator($rules);
11871 }
11872
11873 public function getIteratorWithout($types)
11874 {
11875 if (!is_array($types)) {
11876 $types = array($types);
11877 }
11878
11879 $rules = $this->getRules();
11880
11881 foreach ($types as $type) {
11882 unset($rules[$type]);
11883 }
11884
11885 return new RuleSetIterator($rules);
11886 }
11887
11888 public function getTypes()
11889 {
11890 $types = self::$types;
11891 unset($types[255]);
11892
11893 return array_keys($types);
11894 }
11895
11896 public function getPrettyString(Pool $pool = null)
11897 {
11898 $string = "\n";
11899 foreach ($this->rules as $type => $rules) {
11900 $string .= str_pad(self::$types[$type], 8, ' ') . ": ";
11901 foreach ($rules as $rule) {
11902 $string .= ($pool ? $rule->getPrettyString($pool) : $rule)."\n";
11903 }
11904 $string .= "\n\n";
11905 }
11906
11907 return $string;
11908 }
11909
11910 public function __toString()
11911 {
11912 return $this->getPrettyString(null);
11913 }
11914 }
11915 <?php
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927 namespace Composer\DependencyResolver;
11928
11929 use Composer\Package\PackageInterface;
11930 use Composer\Package\AliasPackage;
11931 use Composer\Repository\PlatformRepository;
11932
11933
11934
11935
11936 class RuleSetGenerator
11937 {
11938 protected $policy;
11939 protected $pool;
11940 protected $rules;
11941 protected $jobs;
11942 protected $installedMap;
11943 protected $whitelistedMap;
11944 protected $addedMap;
11945
11946 public function __construct(PolicyInterface $policy, Pool $pool)
11947 {
11948 $this->policy = $policy;
11949 $this->pool = $pool;
11950 }
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966 protected function createRequireRule(PackageInterface $package, array $providers, $reason, $reasonData = null)
11967 {
11968 $literals = array(-$package->id);
11969
11970 foreach ($providers as $provider) {
11971
11972  if ($provider === $package) {
11973 return null;
11974 }
11975 $literals[] = $provider->id;
11976 }
11977
11978 return new GenericRule($literals, $reason, $reasonData);
11979 }
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993 protected function createInstallOneOfRule(array $packages, $reason, $job)
11994 {
11995 $literals = array();
11996 foreach ($packages as $package) {
11997 $literals[] = $package->id;
11998 }
11999
12000 return new GenericRule($literals, $reason, $job['packageName'], $job);
12001 }
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014 protected function createRemoveRule(PackageInterface $package, $reason, $job)
12015 {
12016 return new GenericRule(array(-$package->id), $reason, $job['packageName'], $job);
12017 }
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033 protected function createRule2Literals(PackageInterface $issuer, PackageInterface $provider, $reason, $reasonData = null)
12034 {
12035
12036  if ($issuer === $provider) {
12037 return null;
12038 }
12039
12040 return new Rule2Literals(-$issuer->id, -$provider->id, $reason, $reasonData);
12041 }
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052 private function addRule($type, Rule $newRule = null)
12053 {
12054 if (!$newRule) {
12055 return;
12056 }
12057
12058 $this->rules->add($newRule, $type);
12059 }
12060
12061 protected function whitelistFromPackage(PackageInterface $package)
12062 {
12063 $workQueue = new \SplQueue;
12064 $workQueue->enqueue($package);
12065
12066 while (!$workQueue->isEmpty()) {
12067 $package = $workQueue->dequeue();
12068 if (isset($this->whitelistedMap[$package->id])) {
12069 continue;
12070 }
12071
12072 $this->whitelistedMap[$package->id] = true;
12073
12074 foreach ($package->getRequires() as $link) {
12075 $possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint(), true);
12076
12077 foreach ($possibleRequires as $require) {
12078 $workQueue->enqueue($require);
12079 }
12080 }
12081
12082 $obsoleteProviders = $this->pool->whatProvides($package->getName(), null, true);
12083
12084 foreach ($obsoleteProviders as $provider) {
12085 if ($provider === $package) {
12086 continue;
12087 }
12088
12089 if (($package instanceof AliasPackage) && $package->getAliasOf() === $provider) {
12090 $workQueue->enqueue($provider);
12091 }
12092 }
12093 }
12094 }
12095
12096 protected function addRulesForPackage(PackageInterface $package, $ignorePlatformReqs)
12097 {
12098 $workQueue = new \SplQueue;
12099 $workQueue->enqueue($package);
12100
12101 while (!$workQueue->isEmpty()) {
12102 $package = $workQueue->dequeue();
12103 if (isset($this->addedMap[$package->id])) {
12104 continue;
12105 }
12106
12107 $this->addedMap[$package->id] = true;
12108
12109 foreach ($package->getRequires() as $link) {
12110 if ($ignorePlatformReqs && preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $link->getTarget())) {
12111 continue;
12112 }
12113
12114 $possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
12115
12116 $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, $possibleRequires, Rule::RULE_PACKAGE_REQUIRES, $link));
12117
12118 foreach ($possibleRequires as $require) {
12119 $workQueue->enqueue($require);
12120 }
12121 }
12122
12123 foreach ($package->getConflicts() as $link) {
12124 $possibleConflicts = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
12125
12126 foreach ($possibleConflicts as $conflict) {
12127 $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRule2Literals($package, $conflict, Rule::RULE_PACKAGE_CONFLICT, $link));
12128 }
12129 }
12130
12131
12132  $isInstalled = (isset($this->installedMap[$package->id]));
12133
12134 foreach ($package->getReplaces() as $link) {
12135 $obsoleteProviders = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
12136
12137 foreach ($obsoleteProviders as $provider) {
12138 if ($provider === $package) {
12139 continue;
12140 }
12141
12142 if (!$this->obsoleteImpossibleForAlias($package, $provider)) {
12143 $reason = ($isInstalled) ? Rule::RULE_INSTALLED_PACKAGE_OBSOLETES : Rule::RULE_PACKAGE_OBSOLETES;
12144 $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRule2Literals($package, $provider, $reason, $link));
12145 }
12146 }
12147 }
12148
12149 $obsoleteProviders = $this->pool->whatProvides($package->getName(), null);
12150
12151 foreach ($obsoleteProviders as $provider) {
12152 if ($provider === $package) {
12153 continue;
12154 }
12155
12156 if (($package instanceof AliasPackage) && $package->getAliasOf() === $provider) {
12157 $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, array($provider), Rule::RULE_PACKAGE_ALIAS, $package));
12158 } elseif (!$this->obsoleteImpossibleForAlias($package, $provider)) {
12159 $reason = ($package->getName() == $provider->getName()) ? Rule::RULE_PACKAGE_SAME_NAME : Rule::RULE_PACKAGE_IMPLICIT_OBSOLETES;
12160 $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRule2Literals($package, $provider, $reason, $package));
12161 }
12162 }
12163 }
12164 }
12165
12166 protected function obsoleteImpossibleForAlias($package, $provider)
12167 {
12168 $packageIsAlias = $package instanceof AliasPackage;
12169 $providerIsAlias = $provider instanceof AliasPackage;
12170
12171 $impossible = (
12172 ($packageIsAlias && $package->getAliasOf() === $provider) ||
12173 ($providerIsAlias && $provider->getAliasOf() === $package) ||
12174 ($packageIsAlias && $providerIsAlias && $provider->getAliasOf() === $package->getAliasOf())
12175 );
12176
12177 return $impossible;
12178 }
12179
12180 protected function whitelistFromJobs()
12181 {
12182 foreach ($this->jobs as $job) {
12183 switch ($job['cmd']) {
12184 case 'install':
12185 $packages = $this->pool->whatProvides($job['packageName'], $job['constraint'], true);
12186 foreach ($packages as $package) {
12187 $this->whitelistFromPackage($package);
12188 }
12189 break;
12190 }
12191 }
12192 }
12193
12194 protected function addRulesForJobs($ignorePlatformReqs)
12195 {
12196 foreach ($this->jobs as $job) {
12197 switch ($job['cmd']) {
12198 case 'install':
12199 if (!$job['fixed'] && $ignorePlatformReqs && preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $job['packageName'])) {
12200 continue;
12201 }
12202
12203 $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']);
12204 if ($packages) {
12205 foreach ($packages as $package) {
12206 if (!isset($this->installedMap[$package->id])) {
12207 $this->addRulesForPackage($package, $ignorePlatformReqs);
12208 }
12209 }
12210
12211 $rule = $this->createInstallOneOfRule($packages, Rule::RULE_JOB_INSTALL, $job);
12212 $this->addRule(RuleSet::TYPE_JOB, $rule);
12213 }
12214 break;
12215 case 'remove':
12216
12217  
12218  $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']);
12219 foreach ($packages as $package) {
12220 $rule = $this->createRemoveRule($package, Rule::RULE_JOB_REMOVE, $job);
12221 $this->addRule(RuleSet::TYPE_JOB, $rule);
12222 }
12223 break;
12224 }
12225 }
12226 }
12227
12228 public function getRulesFor($jobs, $installedMap, $ignorePlatformReqs = false)
12229 {
12230 $this->jobs = $jobs;
12231 $this->rules = new RuleSet;
12232 $this->installedMap = $installedMap;
12233
12234 $this->whitelistedMap = array();
12235 foreach ($this->installedMap as $package) {
12236 $this->whitelistFromPackage($package);
12237 }
12238 $this->whitelistFromJobs();
12239
12240 $this->pool->setWhitelist($this->whitelistedMap);
12241
12242 $this->addedMap = array();
12243 foreach ($this->installedMap as $package) {
12244 $this->addRulesForPackage($package, $ignorePlatformReqs);
12245 }
12246
12247 $this->addRulesForJobs($ignorePlatformReqs);
12248
12249 return $this->rules;
12250 }
12251 }
12252 <?php
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264 namespace Composer\DependencyResolver;
12265
12266
12267
12268
12269 class RuleSetIterator implements \Iterator
12270 {
12271 protected $rules;
12272 protected $types;
12273
12274 protected $currentOffset;
12275 protected $currentType;
12276 protected $currentTypeOffset;
12277
12278 public function __construct(array $rules)
12279 {
12280 $this->rules = $rules;
12281 $this->types = array_keys($rules);
12282 sort($this->types);
12283
12284 $this->rewind();
12285 }
12286
12287 public function current()
12288 {
12289 return $this->rules[$this->currentType][$this->currentOffset];
12290 }
12291
12292 public function key()
12293 {
12294 return $this->currentType;
12295 }
12296
12297 public function next()
12298 {
12299 $this->currentOffset++;
12300
12301 if (!isset($this->rules[$this->currentType])) {
12302 return;
12303 }
12304
12305 if ($this->currentOffset >= sizeof($this->rules[$this->currentType])) {
12306 $this->currentOffset = 0;
12307
12308 do {
12309 $this->currentTypeOffset++;
12310
12311 if (!isset($this->types[$this->currentTypeOffset])) {
12312 $this->currentType = -1;
12313 break;
12314 }
12315
12316 $this->currentType = $this->types[$this->currentTypeOffset];
12317 } while (isset($this->types[$this->currentTypeOffset]) && !sizeof($this->rules[$this->currentType]));
12318 }
12319 }
12320
12321 public function rewind()
12322 {
12323 $this->currentOffset = 0;
12324
12325 $this->currentTypeOffset = -1;
12326 $this->currentType = -1;
12327
12328 do {
12329 $this->currentTypeOffset++;
12330
12331 if (!isset($this->types[$this->currentTypeOffset])) {
12332 $this->currentType = -1;
12333 break;
12334 }
12335
12336 $this->currentType = $this->types[$this->currentTypeOffset];
12337 } while (isset($this->types[$this->currentTypeOffset]) && !sizeof($this->rules[$this->currentType]));
12338 }
12339
12340 public function valid()
12341 {
12342 return isset($this->rules[$this->currentType])
12343 && isset($this->rules[$this->currentType][$this->currentOffset]);
12344 }
12345 }
12346 <?php
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358 namespace Composer\DependencyResolver;
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368 class RuleWatchChain extends \SplDoublyLinkedList
12369 {
12370 protected $offset = 0;
12371
12372
12373
12374
12375
12376
12377 public function seek($offset)
12378 {
12379 $this->rewind();
12380 for ($i = 0; $i < $offset; $i++, $this->next());
12381 }
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391 public function remove()
12392 {
12393 $offset = $this->key();
12394 $this->offsetUnset($offset);
12395 $this->seek($offset);
12396 }
12397 }
12398 <?php
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410 namespace Composer\DependencyResolver;
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422 class RuleWatchGraph
12423 {
12424 protected $watchChains = array();
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438 public function insert(RuleWatchNode $node)
12439 {
12440 if ($node->getRule()->isAssertion()) {
12441 return;
12442 }
12443
12444 foreach (array($node->watch1, $node->watch2) as $literal) {
12445 if (!isset($this->watchChains[$literal])) {
12446 $this->watchChains[$literal] = new RuleWatchChain;
12447 }
12448
12449 $this->watchChains[$literal]->unshift($node);
12450 }
12451 }
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476 public function propagateLiteral($decidedLiteral, $level, $decisions)
12477 {
12478
12479  
12480  
12481  $literal = -$decidedLiteral;
12482
12483 if (!isset($this->watchChains[$literal])) {
12484 return null;
12485 }
12486
12487 $chain = $this->watchChains[$literal];
12488
12489 $chain->rewind();
12490 while ($chain->valid()) {
12491 $node = $chain->current();
12492 $otherWatch = $node->getOtherWatch($literal);
12493
12494 if (!$node->getRule()->isDisabled() && !$decisions->satisfy($otherWatch)) {
12495 $ruleLiterals = $node->getRule()->getLiterals();
12496
12497 $alternativeLiterals = array_filter($ruleLiterals, function ($ruleLiteral) use ($literal, $otherWatch, $decisions) {
12498 return $literal !== $ruleLiteral &&
12499 $otherWatch !== $ruleLiteral &&
12500 !$decisions->conflict($ruleLiteral);
12501 });
12502
12503 if ($alternativeLiterals) {
12504 reset($alternativeLiterals);
12505 $this->moveWatch($literal, current($alternativeLiterals), $node);
12506 continue;
12507 }
12508
12509 if ($decisions->conflict($otherWatch)) {
12510 return $node->getRule();
12511 }
12512
12513 $decisions->decide($otherWatch, $level, $node->getRule());
12514 }
12515
12516 $chain->next();
12517 }
12518
12519 return null;
12520 }
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531 protected function moveWatch($fromLiteral, $toLiteral, $node)
12532 {
12533 if (!isset($this->watchChains[$toLiteral])) {
12534 $this->watchChains[$toLiteral] = new RuleWatchChain;
12535 }
12536
12537 $node->moveWatch($fromLiteral, $toLiteral);
12538 $this->watchChains[$fromLiteral]->remove();
12539 $this->watchChains[$toLiteral]->unshift($node);
12540 }
12541 }
12542 <?php
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554 namespace Composer\DependencyResolver;
12555
12556
12557
12558
12559
12560
12561
12562
12563 class RuleWatchNode
12564 {
12565 public $watch1;
12566 public $watch2;
12567
12568 protected $rule;
12569
12570
12571
12572
12573
12574
12575 public function __construct($rule)
12576 {
12577 $this->rule = $rule;
12578
12579 $literals = $rule->getLiterals();
12580
12581 $this->watch1 = count($literals) > 0 ? $literals[0] : 0;
12582 $this->watch2 = count($literals) > 1 ? $literals[1] : 0;
12583 }
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593 public function watch2OnHighest(Decisions $decisions)
12594 {
12595 $literals = $this->rule->getLiterals();
12596
12597
12598  if (count($literals) < 3) {
12599 return;
12600 }
12601
12602 $watchLevel = 0;
12603
12604 foreach ($literals as $literal) {
12605 $level = $decisions->decisionLevel($literal);
12606
12607 if ($level > $watchLevel) {
12608 $this->watch2 = $literal;
12609 $watchLevel = $level;
12610 }
12611 }
12612 }
12613
12614
12615
12616
12617
12618
12619 public function getRule()
12620 {
12621 return $this->rule;
12622 }
12623
12624
12625
12626
12627
12628
12629
12630 public function getOtherWatch($literal)
12631 {
12632 if ($this->watch1 == $literal) {
12633 return $this->watch2;
12634 } else {
12635 return $this->watch1;
12636 }
12637 }
12638
12639
12640
12641
12642
12643
12644
12645 public function moveWatch($from, $to)
12646 {
12647 if ($this->watch1 == $from) {
12648 $this->watch1 = $to;
12649 } else {
12650 $this->watch2 = $to;
12651 }
12652 }
12653 }
12654 <?php
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666 namespace Composer\DependencyResolver;
12667
12668 use Composer\IO\IOInterface;
12669 use Composer\Repository\RepositoryInterface;
12670 use Composer\Repository\PlatformRepository;
12671
12672
12673
12674
12675 class Solver
12676 {
12677 const BRANCH_LITERALS = 0;
12678 const BRANCH_LEVEL = 1;
12679
12680
12681 protected $policy;
12682
12683 protected $pool;
12684
12685 protected $installed;
12686
12687 protected $rules;
12688
12689 protected $ruleSetGenerator;
12690
12691 protected $jobs;
12692
12693
12694 protected $updateMap = array();
12695
12696 protected $watchGraph;
12697
12698 protected $decisions;
12699
12700 protected $installedMap;
12701
12702
12703 protected $propagateIndex;
12704
12705 protected $branches = array();
12706
12707 protected $problems = array();
12708
12709 protected $learnedPool = array();
12710
12711 protected $learnedWhy = array();
12712
12713
12714 protected $io;
12715
12716
12717
12718
12719
12720
12721
12722 public function __construct(PolicyInterface $policy, Pool $pool, RepositoryInterface $installed, IOInterface $io)
12723 {
12724 $this->io = $io;
12725 $this->policy = $policy;
12726 $this->pool = $pool;
12727 $this->installed = $installed;
12728 $this->ruleSetGenerator = new RuleSetGenerator($policy, $pool);
12729 }
12730
12731
12732
12733
12734 public function getRuleSetSize()
12735 {
12736 return count($this->rules);
12737 }
12738
12739
12740
12741 private function makeAssertionRuleDecisions()
12742 {
12743 $decisionStart = count($this->decisions) - 1;
12744
12745 $rulesCount = count($this->rules);
12746 for ($ruleIndex = 0; $ruleIndex < $rulesCount; $ruleIndex++) {
12747 $rule = $this->rules->ruleById[$ruleIndex];
12748
12749 if (!$rule->isAssertion() || $rule->isDisabled()) {
12750 continue;
12751 }
12752
12753 $literals = $rule->getLiterals();
12754 $literal = $literals[0];
12755
12756 if (!$this->decisions->decided(abs($literal))) {
12757 $this->decisions->decide($literal, 1, $rule);
12758 continue;
12759 }
12760
12761 if ($this->decisions->satisfy($literal)) {
12762 continue;
12763 }
12764
12765
12766  if (RuleSet::TYPE_LEARNED === $rule->getType()) {
12767 $rule->disable();
12768 continue;
12769 }
12770
12771 $conflict = $this->decisions->decisionRule($literal);
12772
12773 if ($conflict && RuleSet::TYPE_PACKAGE === $conflict->getType()) {
12774 $problem = new Problem($this->pool);
12775
12776 $problem->addRule($rule);
12777 $problem->addRule($conflict);
12778 $this->disableProblem($rule);
12779 $this->problems[] = $problem;
12780 continue;
12781 }
12782
12783
12784  $problem = new Problem($this->pool);
12785 $problem->addRule($rule);
12786 $problem->addRule($conflict);
12787
12788
12789  
12790  foreach ($this->rules->getIteratorFor(RuleSet::TYPE_JOB) as $assertRule) {
12791 if ($assertRule->isDisabled() || !$assertRule->isAssertion()) {
12792 continue;
12793 }
12794
12795 $assertRuleLiterals = $assertRule->getLiterals();
12796 $assertRuleLiteral = $assertRuleLiterals[0];
12797
12798 if (abs($literal) !== abs($assertRuleLiteral)) {
12799 continue;
12800 }
12801
12802 $problem->addRule($assertRule);
12803 $this->disableProblem($assertRule);
12804 }
12805 $this->problems[] = $problem;
12806
12807 $this->decisions->resetToOffset($decisionStart);
12808 $ruleIndex = -1;
12809 }
12810 }
12811
12812 protected function setupInstalledMap()
12813 {
12814 $this->installedMap = array();
12815 foreach ($this->installed->getPackages() as $package) {
12816 $this->installedMap[$package->id] = $package;
12817 }
12818 }
12819
12820
12821
12822
12823 protected function checkForRootRequireProblems($ignorePlatformReqs)
12824 {
12825 foreach ($this->jobs as $job) {
12826 switch ($job['cmd']) {
12827 case 'update':
12828 $packages = $this->pool->whatProvides($job['packageName'], $job['constraint']);
12829 foreach ($packages as $package) {
12830 if (isset($this->installedMap[$package->id])) {
12831 $this->updateMap[$package->id] = true;
12832 }
12833 }
12834 break;
12835
12836 case 'update-all':
12837 foreach ($this->installedMap as $package) {
12838 $this->updateMap[$package->id] = true;
12839 }
12840 break;
12841
12842 case 'install':
12843 if ($ignorePlatformReqs && preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $job['packageName'])) {
12844 break;
12845 }
12846
12847 if (!$this->pool->whatProvides($job['packageName'], $job['constraint'])) {
12848 $problem = new Problem($this->pool);
12849 $problem->addRule(new GenericRule(array(), null, null, $job));
12850 $this->problems[] = $problem;
12851 }
12852 break;
12853 }
12854 }
12855 }
12856
12857
12858
12859
12860
12861
12862 public function solve(Request $request, $ignorePlatformReqs = false)
12863 {
12864 $this->jobs = $request->getJobs();
12865
12866 $this->setupInstalledMap();
12867 $this->rules = $this->ruleSetGenerator->getRulesFor($this->jobs, $this->installedMap, $ignorePlatformReqs);
12868 $this->checkForRootRequireProblems($ignorePlatformReqs);
12869 $this->decisions = new Decisions($this->pool);
12870 $this->watchGraph = new RuleWatchGraph;
12871
12872 foreach ($this->rules as $rule) {
12873 $this->watchGraph->insert(new RuleWatchNode($rule));
12874 }
12875
12876
12877 $this->makeAssertionRuleDecisions();
12878
12879 $this->io->writeError('Resolving dependencies through SAT', true, IOInterface::DEBUG);
12880 $before = microtime(true);
12881 $this->runSat(true);
12882 $this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE);
12883
12884
12885  foreach ($this->installedMap as $packageId => $void) {
12886 if ($this->decisions->undecided($packageId)) {
12887 $this->decisions->decide(-$packageId, 1, null);
12888 }
12889 }
12890
12891 if ($this->problems) {
12892 throw new SolverProblemsException($this->problems, $this->installedMap);
12893 }
12894
12895 $transaction = new Transaction($this->policy, $this->pool, $this->installedMap, $this->decisions);
12896
12897 return $transaction->getOperations();
12898 }
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909 protected function propagate($level)
12910 {
12911 while ($this->decisions->validOffset($this->propagateIndex)) {
12912 $decision = $this->decisions->atOffset($this->propagateIndex);
12913
12914 $conflict = $this->watchGraph->propagateLiteral(
12915 $decision[Decisions::DECISION_LITERAL],
12916 $level,
12917 $this->decisions
12918 );
12919
12920 $this->propagateIndex++;
12921
12922 if ($conflict) {
12923 return $conflict;
12924 }
12925 }
12926
12927 return null;
12928 }
12929
12930
12931
12932
12933
12934
12935 private function revert($level)
12936 {
12937 while (!$this->decisions->isEmpty()) {
12938 $literal = $this->decisions->lastLiteral();
12939
12940 if ($this->decisions->undecided($literal)) {
12941 break;
12942 }
12943
12944 $decisionLevel = $this->decisions->decisionLevel($literal);
12945
12946 if ($decisionLevel <= $level) {
12947 break;
12948 }
12949
12950 $this->decisions->revertLast();
12951 $this->propagateIndex = count($this->decisions);
12952 }
12953
12954 while (!empty($this->branches) && $this->branches[count($this->branches) - 1][self::BRANCH_LEVEL] >= $level) {
12955 array_pop($this->branches);
12956 }
12957 }
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978 private function setPropagateLearn($level, $literal, $disableRules, Rule $rule)
12979 {
12980 $level++;
12981
12982 $this->decisions->decide($literal, $level, $rule);
12983
12984 while (true) {
12985 $rule = $this->propagate($level);
12986
12987 if (!$rule) {
12988 break;
12989 }
12990
12991 if ($level == 1) {
12992 return $this->analyzeUnsolvable($rule, $disableRules);
12993 }
12994
12995
12996  list($learnLiteral, $newLevel, $newRule, $why) = $this->analyze($level, $rule);
12997
12998 if ($newLevel <= 0 || $newLevel >= $level) {
12999 throw new SolverBugException(
13000 "Trying to revert to invalid level ".(int) $newLevel." from level ".(int) $level."."
13001 );
13002 } elseif (!$newRule) {
13003 throw new SolverBugException(
13004 "No rule was learned from analyzing $rule at level $level."
13005 );
13006 }
13007
13008 $level = $newLevel;
13009
13010 $this->revert($level);
13011
13012 $this->rules->add($newRule, RuleSet::TYPE_LEARNED);
13013
13014 $this->learnedWhy[spl_object_hash($newRule)] = $why;
13015
13016 $ruleNode = new RuleWatchNode($newRule);
13017 $ruleNode->watch2OnHighest($this->decisions);
13018 $this->watchGraph->insert($ruleNode);
13019
13020 $this->decisions->decide($learnLiteral, $level, $newRule);
13021 }
13022
13023 return $level;
13024 }
13025
13026
13027
13028
13029
13030
13031
13032
13033 private function selectAndInstall($level, array $decisionQueue, $disableRules, Rule $rule)
13034 {
13035
13036  $literals = $this->policy->selectPreferredPackages($this->pool, $this->installedMap, $decisionQueue, $rule->getRequiredPackage());
13037
13038 $selectedLiteral = array_shift($literals);
13039
13040
13041  if (count($literals)) {
13042 $this->branches[] = array($literals, $level);
13043 }
13044
13045 return $this->setPropagateLearn($level, $selectedLiteral, $disableRules, $rule);
13046 }
13047
13048
13049
13050
13051
13052
13053 protected function analyze($level, Rule $rule)
13054 {
13055 $analyzedRule = $rule;
13056 $ruleLevel = 1;
13057 $num = 0;
13058 $l1num = 0;
13059 $seen = array();
13060 $learnedLiterals = array(null);
13061
13062 $decisionId = count($this->decisions);
13063
13064 $this->learnedPool[] = array();
13065
13066 while (true) {
13067 $this->learnedPool[count($this->learnedPool) - 1][] = $rule;
13068
13069 foreach ($rule->getLiterals() as $literal) {
13070
13071  if ($this->decisions->satisfy($literal)) {
13072 continue;
13073 }
13074
13075 if (isset($seen[abs($literal)])) {
13076 continue;
13077 }
13078 $seen[abs($literal)] = true;
13079
13080 $l = $this->decisions->decisionLevel($literal);
13081
13082 if (1 === $l) {
13083 $l1num++;
13084 } elseif ($level === $l) {
13085 $num++;
13086 } else {
13087
13088  $learnedLiterals[] = $literal;
13089
13090 if ($l > $ruleLevel) {
13091 $ruleLevel = $l;
13092 }
13093 }
13094 }
13095
13096 $l1retry = true;
13097 while ($l1retry) {
13098 $l1retry = false;
13099
13100 if (!$num && !--$l1num) {
13101
13102  break 2;
13103 }
13104
13105 while (true) {
13106 if ($decisionId <= 0) {
13107 throw new SolverBugException(
13108 "Reached invalid decision id $decisionId while looking through $rule for a literal present in the analyzed rule $analyzedRule."
13109 );
13110 }
13111
13112 $decisionId--;
13113
13114 $decision = $this->decisions->atOffset($decisionId);
13115 $literal = $decision[Decisions::DECISION_LITERAL];
13116
13117 if (isset($seen[abs($literal)])) {
13118 break;
13119 }
13120 }
13121
13122 unset($seen[abs($literal)]);
13123
13124 if ($num && 0 === --$num) {
13125 $learnedLiterals[0] = -abs($literal);
13126
13127 if (!$l1num) {
13128 break 2;
13129 }
13130
13131 foreach ($learnedLiterals as $i => $learnedLiteral) {
13132 if ($i !== 0) {
13133 unset($seen[abs($learnedLiteral)]);
13134 }
13135 }
13136
13137  $l1num++;
13138 $l1retry = true;
13139 }
13140 }
13141
13142 $decision = $this->decisions->atOffset($decisionId);
13143 $rule = $decision[Decisions::DECISION_REASON];
13144 }
13145
13146 $why = count($this->learnedPool) - 1;
13147
13148 if (!$learnedLiterals[0]) {
13149 throw new SolverBugException(
13150 "Did not find a learnable literal in analyzed rule $analyzedRule."
13151 );
13152 }
13153
13154 $newRule = new GenericRule($learnedLiterals, Rule::RULE_LEARNED, $why);
13155
13156 return array($learnedLiterals[0], $ruleLevel, $newRule, $why);
13157 }
13158
13159
13160
13161
13162
13163 private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule)
13164 {
13165 $why = spl_object_hash($conflictRule);
13166
13167 if ($conflictRule->getType() == RuleSet::TYPE_LEARNED) {
13168 $learnedWhy = $this->learnedWhy[$why];
13169 $problemRules = $this->learnedPool[$learnedWhy];
13170
13171 foreach ($problemRules as $problemRule) {
13172 $this->analyzeUnsolvableRule($problem, $problemRule);
13173 }
13174
13175 return;
13176 }
13177
13178 if ($conflictRule->getType() == RuleSet::TYPE_PACKAGE) {
13179
13180  return;
13181 }
13182
13183 $problem->nextSection();
13184 $problem->addRule($conflictRule);
13185 }
13186
13187
13188
13189
13190
13191
13192 private function analyzeUnsolvable(Rule $conflictRule, $disableRules)
13193 {
13194 $problem = new Problem($this->pool);
13195 $problem->addRule($conflictRule);
13196
13197 $this->analyzeUnsolvableRule($problem, $conflictRule);
13198
13199 $this->problems[] = $problem;
13200
13201 $seen = array();
13202 $literals = $conflictRule->getLiterals();
13203
13204 foreach ($literals as $literal) {
13205
13206  if ($this->decisions->satisfy($literal)) {
13207 continue;
13208 }
13209 $seen[abs($literal)] = true;
13210 }
13211
13212 foreach ($this->decisions as $decision) {
13213 $literal = $decision[Decisions::DECISION_LITERAL];
13214
13215
13216  if (!isset($seen[abs($literal)])) {
13217 continue;
13218 }
13219
13220 $why = $decision[Decisions::DECISION_REASON];
13221
13222 $problem->addRule($why);
13223 $this->analyzeUnsolvableRule($problem, $why);
13224
13225 $literals = $why->getLiterals();
13226
13227 foreach ($literals as $literal) {
13228
13229  if ($this->decisions->satisfy($literal)) {
13230 continue;
13231 }
13232 $seen[abs($literal)] = true;
13233 }
13234 }
13235
13236 if ($disableRules) {
13237 foreach ($this->problems[count($this->problems) - 1] as $reason) {
13238 $this->disableProblem($reason['rule']);
13239 }
13240
13241 $this->resetSolver();
13242
13243 return 1;
13244 }
13245
13246 return 0;
13247 }
13248
13249
13250
13251
13252 private function disableProblem(Rule $why)
13253 {
13254 $job = $why->getJob();
13255
13256 if (!$job) {
13257 $why->disable();
13258
13259 return;
13260 }
13261
13262
13263  foreach ($this->rules as $rule) {
13264
13265 if ($job === $rule->getJob()) {
13266 $rule->disable();
13267 }
13268 }
13269 }
13270
13271 private function resetSolver()
13272 {
13273 $this->decisions->reset();
13274
13275 $this->propagateIndex = 0;
13276 $this->branches = array();
13277
13278 $this->enableDisableLearnedRules();
13279 $this->makeAssertionRuleDecisions();
13280 }
13281
13282
13283
13284
13285
13286
13287
13288
13289 private function enableDisableLearnedRules()
13290 {
13291 foreach ($this->rules->getIteratorFor(RuleSet::TYPE_LEARNED) as $rule) {
13292 $why = $this->learnedWhy[spl_object_hash($rule)];
13293 $problemRules = $this->learnedPool[$why];
13294
13295 $foundDisabled = false;
13296 foreach ($problemRules as $problemRule) {
13297 if ($problemRule->isDisabled()) {
13298 $foundDisabled = true;
13299 break;
13300 }
13301 }
13302
13303 if ($foundDisabled && $rule->isEnabled()) {
13304 $rule->disable();
13305 } elseif (!$foundDisabled && $rule->isDisabled()) {
13306 $rule->enable();
13307 }
13308 }
13309 }
13310
13311
13312
13313
13314 private function runSat($disableRules = true)
13315 {
13316 $this->propagateIndex = 0;
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328 $decisionQueue = array();
13329 $decisionSupplementQueue = array();
13330
13331
13332
13333 $disableRules = array();
13334
13335 $level = 1;
13336 $systemLevel = $level + 1;
13337 $installedPos = 0;
13338
13339 while (true) {
13340 if (1 === $level) {
13341 $conflictRule = $this->propagate($level);
13342 if (null !== $conflictRule) {
13343 if ($this->analyzeUnsolvable($conflictRule, $disableRules)) {
13344 continue;
13345 }
13346
13347 return;
13348 }
13349 }
13350
13351
13352  if ($level < $systemLevel) {
13353 $iterator = $this->rules->getIteratorFor(RuleSet::TYPE_JOB);
13354 foreach ($iterator as $rule) {
13355 if ($rule->isEnabled()) {
13356 $decisionQueue = array();
13357 $noneSatisfied = true;
13358
13359 foreach ($rule->getLiterals() as $literal) {
13360 if ($this->decisions->satisfy($literal)) {
13361 $noneSatisfied = false;
13362 break;
13363 }
13364 if ($literal > 0 && $this->decisions->undecided($literal)) {
13365 $decisionQueue[] = $literal;
13366 }
13367 }
13368
13369 if ($noneSatisfied && count($decisionQueue)) {
13370
13371  
13372  if (count($this->installed) != count($this->updateMap)) {
13373 $prunedQueue = array();
13374 foreach ($decisionQueue as $literal) {
13375 if (isset($this->installedMap[abs($literal)])) {
13376 $prunedQueue[] = $literal;
13377 if (isset($this->updateMap[abs($literal)])) {
13378 $prunedQueue = $decisionQueue;
13379 break;
13380 }
13381 }
13382 }
13383 $decisionQueue = $prunedQueue;
13384 }
13385 }
13386
13387 if ($noneSatisfied && count($decisionQueue)) {
13388 $oLevel = $level;
13389 $level = $this->selectAndInstall($level, $decisionQueue, $disableRules, $rule);
13390
13391 if (0 === $level) {
13392 return;
13393 }
13394 if ($level <= $oLevel) {
13395 break;
13396 }
13397 }
13398 }
13399 }
13400
13401 $systemLevel = $level + 1;
13402
13403
13404  $iterator->next();
13405 if ($iterator->valid()) {
13406 continue;
13407 }
13408 }
13409
13410 if ($level < $systemLevel) {
13411 $systemLevel = $level;
13412 }
13413
13414 $rulesCount = count($this->rules);
13415
13416 for ($i = 0, $n = 0; $n < $rulesCount; $i++, $n++) {
13417 if ($i == $rulesCount) {
13418 $i = 0;
13419 }
13420
13421 $rule = $this->rules->ruleById[$i];
13422 $literals = $rule->getLiterals();
13423
13424 if ($rule->isDisabled()) {
13425 continue;
13426 }
13427
13428 $decisionQueue = array();
13429
13430
13431  
13432  
13433  
13434  
13435  
13436  foreach ($literals as $literal) {
13437 if ($literal <= 0) {
13438 if (!$this->decisions->decidedInstall(abs($literal))) {
13439 continue 2; 
13440  }
13441 } else {
13442 if ($this->decisions->decidedInstall(abs($literal))) {
13443 continue 2; 
13444  }
13445 if ($this->decisions->undecided(abs($literal))) {
13446 $decisionQueue[] = $literal;
13447 }
13448 }
13449 }
13450
13451
13452  if (count($decisionQueue) < 2) {
13453 continue;
13454 }
13455
13456 $level = $this->selectAndInstall($level, $decisionQueue, $disableRules, $rule);
13457
13458 if (0 === $level) {
13459 return;
13460 }
13461
13462
13463  $rulesCount = count($this->rules);
13464 $n = -1;
13465 }
13466
13467 if ($level < $systemLevel) {
13468 continue;
13469 }
13470
13471
13472  if (count($this->branches)) {
13473 $lastLiteral = null;
13474 $lastLevel = null;
13475 $lastBranchIndex = 0;
13476 $lastBranchOffset = 0;
13477
13478 for ($i = count($this->branches) - 1; $i >= 0; $i--) {
13479 list($literals, $l) = $this->branches[$i];
13480
13481 foreach ($literals as $offset => $literal) {
13482 if ($literal && $literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) {
13483 $lastLiteral = $literal;
13484 $lastBranchIndex = $i;
13485 $lastBranchOffset = $offset;
13486 $lastLevel = $l;
13487 }
13488 }
13489 }
13490
13491 if ($lastLiteral) {
13492 unset($this->branches[$lastBranchIndex][self::BRANCH_LITERALS][$lastBranchOffset]);
13493
13494 $level = $lastLevel;
13495 $this->revert($level);
13496
13497 $why = $this->decisions->lastReason();
13498
13499 $level = $this->setPropagateLearn($level, $lastLiteral, $disableRules, $why);
13500
13501 if ($level == 0) {
13502 return;
13503 }
13504
13505 continue;
13506 }
13507 }
13508
13509 break;
13510 }
13511 }
13512 }
13513 <?php
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525 namespace Composer\DependencyResolver;
13526
13527
13528
13529
13530 class SolverBugException extends \RuntimeException
13531 {
13532 public function __construct($message)
13533 {
13534 parent::__construct(
13535 $message."\nThis exception was most likely caused by a bug in Composer.\n".
13536 "Please report the command you ran, the exact error you received, and your composer.json on https://github.com/composer/composer/issues - thank you!\n");
13537 }
13538 }
13539 <?php
13540
13541
13542
13543
13544
13545
13546
13547
13548
13549
13550
13551 namespace Composer\DependencyResolver;
13552
13553 use Composer\Util\IniHelper;
13554
13555
13556
13557
13558 class SolverProblemsException extends \RuntimeException
13559 {
13560 protected $problems;
13561 protected $installedMap;
13562
13563 public function __construct(array $problems, array $installedMap)
13564 {
13565 $this->problems = $problems;
13566 $this->installedMap = $installedMap;
13567
13568 parent::__construct($this->createMessage(), 2);
13569 }
13570
13571 protected function createMessage()
13572 {
13573 $text = "\n";
13574 $hasExtensionProblems = false;
13575 foreach ($this->problems as $i => $problem) {
13576 $text .= "  Problem ".($i + 1).$problem->getPrettyString($this->installedMap)."\n";
13577
13578 if (!$hasExtensionProblems && $this->hasExtensionProblems($problem->getReasons())) {
13579 $hasExtensionProblems = true;
13580 }
13581 }
13582
13583 if (strpos($text, 'could not be found') || strpos($text, 'no matching package found')) {
13584 $text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n   see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
13585 }
13586
13587 if ($hasExtensionProblems) {
13588 $text .= $this->createExtensionHint();
13589 }
13590
13591 return $text;
13592 }
13593
13594 public function getProblems()
13595 {
13596 return $this->problems;
13597 }
13598
13599 private function createExtensionHint()
13600 {
13601 $paths = IniHelper::getAll();
13602
13603 if (count($paths) === 1 && empty($paths[0])) {
13604 return '';
13605 }
13606
13607 $text = "\n  To enable extensions, verify that they are enabled in your .ini files:\n    - ";
13608 $text .= implode("\n    - ", $paths);
13609 $text .= "\n  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.";
13610
13611 return $text;
13612 }
13613
13614 private function hasExtensionProblems(array $reasonSets)
13615 {
13616 foreach ($reasonSets as $reasonSet) {
13617 foreach ($reasonSet as $reason) {
13618 if (isset($reason["rule"]) && 0 === strpos($reason["rule"]->getRequiredPackage(), 'ext-')) {
13619 return true;
13620 }
13621 }
13622 }
13623
13624 return false;
13625 }
13626 }
13627 <?php
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639 namespace Composer\DependencyResolver;
13640
13641 use Composer\Package\AliasPackage;
13642
13643
13644
13645
13646 class Transaction
13647 {
13648 protected $policy;
13649 protected $pool;
13650 protected $installedMap;
13651 protected $decisions;
13652 protected $transaction;
13653
13654 public function __construct($policy, $pool, $installedMap, $decisions)
13655 {
13656 $this->policy = $policy;
13657 $this->pool = $pool;
13658 $this->installedMap = $installedMap;
13659 $this->decisions = $decisions;
13660 $this->transaction = array();
13661 }
13662
13663 public function getOperations()
13664 {
13665 $installMeansUpdateMap = $this->findUpdates();
13666
13667 $updateMap = array();
13668 $installMap = array();
13669 $uninstallMap = array();
13670
13671 foreach ($this->decisions as $i => $decision) {
13672 $literal = $decision[Decisions::DECISION_LITERAL];
13673 $reason = $decision[Decisions::DECISION_REASON];
13674
13675 $package = $this->pool->literalToPackage($literal);
13676
13677
13678  if (($literal > 0) == (isset($this->installedMap[$package->id]))) {
13679 continue;
13680 }
13681
13682 if ($literal > 0) {
13683 if (isset($installMeansUpdateMap[abs($literal)]) && !$package instanceof AliasPackage) {
13684 $source = $installMeansUpdateMap[abs($literal)];
13685
13686 $updateMap[$package->id] = array(
13687 'package' => $package,
13688 'source' => $source,
13689 'reason' => $reason,
13690 );
13691
13692
13693  unset($installMeansUpdateMap[abs($literal)]);
13694 $ignoreRemove[$source->id] = true;
13695 } else {
13696 $installMap[$package->id] = array(
13697 'package' => $package,
13698 'reason' => $reason,
13699 );
13700 }
13701 }
13702 }
13703
13704 foreach ($this->decisions as $i => $decision) {
13705 $literal = $decision[Decisions::DECISION_LITERAL];
13706 $reason = $decision[Decisions::DECISION_REASON];
13707 $package = $this->pool->literalToPackage($literal);
13708
13709 if ($literal <= 0 &&
13710 isset($this->installedMap[$package->id]) &&
13711 !isset($ignoreRemove[$package->id])) {
13712 $uninstallMap[$package->id] = array(
13713 'package' => $package,
13714 'reason' => $reason,
13715 );
13716 }
13717 }
13718
13719 $this->transactionFromMaps($installMap, $updateMap, $uninstallMap);
13720
13721 return $this->transaction;
13722 }
13723
13724 protected function transactionFromMaps($installMap, $updateMap, $uninstallMap)
13725 {
13726 $queue = array_map(
13727 function ($operation) {
13728 return $operation['package'];
13729 },
13730 $this->findRootPackages($installMap, $updateMap)
13731 );
13732
13733 $visited = array();
13734
13735 while (!empty($queue)) {
13736 $package = array_pop($queue);
13737 $packageId = $package->id;
13738
13739 if (!isset($visited[$packageId])) {
13740 array_push($queue, $package);
13741
13742 if ($package instanceof AliasPackage) {
13743 array_push($queue, $package->getAliasOf());
13744 } else {
13745 foreach ($package->getRequires() as $link) {
13746 $possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
13747
13748 foreach ($possibleRequires as $require) {
13749 array_push($queue, $require);
13750 }
13751 }
13752 }
13753
13754 $visited[$package->id] = true;
13755 } else {
13756 if (isset($installMap[$packageId])) {
13757 $this->install(
13758 $installMap[$packageId]['package'],
13759 $installMap[$packageId]['reason']
13760 );
13761 unset($installMap[$packageId]);
13762 }
13763 if (isset($updateMap[$packageId])) {
13764 $this->update(
13765 $updateMap[$packageId]['source'],
13766 $updateMap[$packageId]['package'],
13767 $updateMap[$packageId]['reason']
13768 );
13769 unset($updateMap[$packageId]);
13770 }
13771 }
13772 }
13773
13774 foreach ($uninstallMap as $uninstall) {
13775 $this->uninstall($uninstall['package'], $uninstall['reason']);
13776 }
13777 }
13778
13779 protected function findRootPackages($installMap, $updateMap)
13780 {
13781 $packages = $installMap + $updateMap;
13782 $roots = $packages;
13783
13784 foreach ($packages as $packageId => $operation) {
13785 $package = $operation['package'];
13786
13787 if (!isset($roots[$packageId])) {
13788 continue;
13789 }
13790
13791 foreach ($package->getRequires() as $link) {
13792 $possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint());
13793
13794 foreach ($possibleRequires as $require) {
13795 if ($require !== $package) {
13796 unset($roots[$require->id]);
13797 }
13798 }
13799 }
13800 }
13801
13802 return $roots;
13803 }
13804
13805 protected function findUpdates()
13806 {
13807 $installMeansUpdateMap = array();
13808
13809 foreach ($this->decisions as $i => $decision) {
13810 $literal = $decision[Decisions::DECISION_LITERAL];
13811 $package = $this->pool->literalToPackage($literal);
13812
13813 if ($package instanceof AliasPackage) {
13814 continue;
13815 }
13816
13817
13818  if ($literal <= 0 && isset($this->installedMap[$package->id])) {
13819 $updates = $this->policy->findUpdatePackages($this->pool, $this->installedMap, $package);
13820
13821 $literals = array($package->id);
13822
13823 foreach ($updates as $update) {
13824 $literals[] = $update->id;
13825 }
13826
13827 foreach ($literals as $updateLiteral) {
13828 if ($updateLiteral !== $literal) {
13829 $installMeansUpdateMap[abs($updateLiteral)] = $package;
13830 }
13831 }
13832 }
13833 }
13834
13835 return $installMeansUpdateMap;
13836 }
13837
13838 protected function install($package, $reason)
13839 {
13840 if ($package instanceof AliasPackage) {
13841 return $this->markAliasInstalled($package, $reason);
13842 }
13843
13844 $this->transaction[] = new Operation\InstallOperation($package, $reason);
13845 }
13846
13847 protected function update($from, $to, $reason)
13848 {
13849 $this->transaction[] = new Operation\UpdateOperation($from, $to, $reason);
13850 }
13851
13852 protected function uninstall($package, $reason)
13853 {
13854 if ($package instanceof AliasPackage) {
13855 return $this->markAliasUninstalled($package, $reason);
13856 }
13857
13858 $this->transaction[] = new Operation\UninstallOperation($package, $reason);
13859 }
13860
13861 protected function markAliasInstalled($package, $reason)
13862 {
13863 $this->transaction[] = new Operation\MarkAliasInstalledOperation($package, $reason);
13864 }
13865
13866 protected function markAliasUninstalled($package, $reason)
13867 {
13868 $this->transaction[] = new Operation\MarkAliasUninstalledOperation($package, $reason);
13869 }
13870 }
13871 <?php
13872
13873
13874
13875
13876
13877
13878
13879
13880
13881
13882
13883 namespace Composer\Downloader;
13884
13885 use Composer\Package\PackageInterface;
13886 use Symfony\Component\Finder\Finder;
13887 use Composer\IO\IOInterface;
13888
13889
13890
13891
13892
13893
13894
13895
13896 abstract class ArchiveDownloader extends FileDownloader
13897 {
13898
13899
13900
13901 public function download(PackageInterface $package, $path, $output = true)
13902 {
13903 $temporaryDir = $this->config->get('vendor-dir').'/composer/'.substr(md5(uniqid('', true)), 0, 8);
13904 $retries = 3;
13905 while ($retries--) {
13906 $fileName = parent::download($package, $path, $output);
13907
13908 $this->io->writeError(' Extracting archive', false, IOInterface::VERBOSE);
13909
13910 try {
13911 $this->filesystem->ensureDirectoryExists($temporaryDir);
13912 try {
13913 $this->extract($fileName, $temporaryDir);
13914 } catch (\Exception $e) {
13915
13916  parent::clearLastCacheWrite($package);
13917 throw $e;
13918 }
13919
13920 $this->filesystem->unlink($fileName);
13921
13922 $contentDir = $this->getFolderContent($temporaryDir);
13923
13924
13925  if (1 === count($contentDir) && is_dir(reset($contentDir))) {
13926 $contentDir = $this->getFolderContent((string) reset($contentDir));
13927 }
13928
13929
13930  foreach ($contentDir as $file) {
13931 $file = (string) $file;
13932 $this->filesystem->rename($file, $path . '/' . basename($file));
13933 }
13934
13935 $this->filesystem->removeDirectory($temporaryDir);
13936 if ($this->filesystem->isDirEmpty($this->config->get('vendor-dir').'/composer/')) {
13937 $this->filesystem->removeDirectory($this->config->get('vendor-dir').'/composer/');
13938 }
13939 if ($this->filesystem->isDirEmpty($this->config->get('vendor-dir'))) {
13940 $this->filesystem->removeDirectory($this->config->get('vendor-dir'));
13941 }
13942 } catch (\Exception $e) {
13943
13944  $this->filesystem->removeDirectory($path);
13945 $this->filesystem->removeDirectory($temporaryDir);
13946
13947
13948  if ($retries && $e instanceof \UnexpectedValueException && class_exists('ZipArchive') && $e->getCode() === \ZipArchive::ER_NOZIP) {
13949 $this->io->writeError('');
13950 if ($this->io->isDebug()) {
13951 $this->io->writeError('    Invalid zip file ('.$e->getMessage().'), retrying...');
13952 } else {
13953 $this->io->writeError('    Invalid zip file, retrying...');
13954 }
13955 usleep(500000);
13956 continue;
13957 }
13958
13959 throw $e;
13960 }
13961
13962 break;
13963 }
13964
13965 if ($output) {
13966 $this->io->writeError('');
13967 }
13968 }
13969
13970
13971
13972
13973 protected function getFileName(PackageInterface $package, $path)
13974 {
13975 return rtrim($path.'/'.md5($path.spl_object_hash($package)).'.'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_EXTENSION), '.');
13976 }
13977
13978
13979
13980
13981 protected function processUrl(PackageInterface $package, $url)
13982 {
13983 if ($package->getDistReference() && strpos($url, 'github.com')) {
13984 if (preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i', $url, $match)) {
13985
13986  $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $package->getDistReference();
13987 } elseif ($package->getDistReference() && preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$}i', $url, $match)) {
13988
13989  $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $package->getDistReference();
13990 } elseif ($package->getDistReference() && preg_match('{^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$}i', $url, $match)) {
13991
13992  $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $package->getDistReference();
13993 }
13994 } elseif ($package->getDistReference() && strpos($url, 'bitbucket.org')) {
13995 if (preg_match('{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i', $url, $match)) {
13996
13997  $url = 'https://bitbucket.org/' . $match[1] . '/'. $match[2] . '/get/' . $package->getDistReference() . '.' . $match[4];
13998 }
13999 }
14000
14001 return parent::processUrl($package, $url);
14002 }
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012 abstract protected function extract($file, $path);
14013
14014
14015
14016
14017
14018
14019
14020 private function getFolderContent($dir)
14021 {
14022 $finder = Finder::create()
14023 ->ignoreVCS(false)
14024 ->ignoreDotFiles(false)
14025 ->depth(0)
14026 ->in($dir);
14027
14028 return iterator_to_array($finder);
14029 }
14030 }
14031 <?php
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043 namespace Composer\Downloader;
14044
14045 use Composer\Package\PackageInterface;
14046
14047
14048
14049
14050
14051
14052 interface ChangeReportInterface
14053 {
14054
14055
14056
14057
14058
14059
14060
14061 public function getLocalChanges(PackageInterface $package, $path);
14062 }
14063 <?php
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075 namespace Composer\Downloader;
14076
14077 use Composer\Package\PackageInterface;
14078 use Composer\IO\IOInterface;
14079 use Composer\Util\Filesystem;
14080
14081
14082
14083
14084
14085
14086 class DownloadManager
14087 {
14088 private $io;
14089 private $preferDist = false;
14090 private $preferSource = false;
14091 private $packagePreferences = array();
14092 private $filesystem;
14093 private $downloaders = array();
14094
14095
14096
14097
14098
14099
14100
14101
14102 public function __construct(IOInterface $io, $preferSource = false, Filesystem $filesystem = null)
14103 {
14104 $this->io = $io;
14105 $this->preferSource = $preferSource;
14106 $this->filesystem = $filesystem ?: new Filesystem();
14107 }
14108
14109
14110
14111
14112
14113
14114
14115 public function setPreferSource($preferSource)
14116 {
14117 $this->preferSource = $preferSource;
14118
14119 return $this;
14120 }
14121
14122
14123
14124
14125
14126
14127
14128 public function setPreferDist($preferDist)
14129 {
14130 $this->preferDist = $preferDist;
14131
14132 return $this;
14133 }
14134
14135
14136
14137
14138
14139
14140
14141 public function setPreferences(array $preferences)
14142 {
14143 $this->packagePreferences = $preferences;
14144
14145 return $this;
14146 }
14147
14148
14149
14150
14151
14152
14153
14154
14155 public function setOutputProgress($outputProgress)
14156 {
14157 foreach ($this->downloaders as $downloader) {
14158 $downloader->setOutputProgress($outputProgress);
14159 }
14160
14161 return $this;
14162 }
14163
14164
14165
14166
14167
14168
14169
14170
14171 public function setDownloader($type, DownloaderInterface $downloader)
14172 {
14173 $type = strtolower($type);
14174 $this->downloaders[$type] = $downloader;
14175
14176 return $this;
14177 }
14178
14179
14180
14181
14182
14183
14184
14185
14186 public function getDownloader($type)
14187 {
14188 $type = strtolower($type);
14189 if (!isset($this->downloaders[$type])) {
14190 throw new \InvalidArgumentException(sprintf('Unknown downloader type: %s. Available types: %s.', $type, implode(', ', array_keys($this->downloaders))));
14191 }
14192
14193 return $this->downloaders[$type];
14194 }
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205 public function getDownloaderForInstalledPackage(PackageInterface $package)
14206 {
14207 $installationSource = $package->getInstallationSource();
14208
14209 if ('metapackage' === $package->getType()) {
14210 return;
14211 }
14212
14213 if ('dist' === $installationSource) {
14214 $downloader = $this->getDownloader($package->getDistType());
14215 } elseif ('source' === $installationSource) {
14216 $downloader = $this->getDownloader($package->getSourceType());
14217 } else {
14218 throw new \InvalidArgumentException(
14219 'Package '.$package.' seems not been installed properly'
14220 );
14221 }
14222
14223 if ($installationSource !== $downloader->getInstallationSource()) {
14224 throw new \LogicException(sprintf(
14225 'Downloader "%s" is a %s type downloader and can not be used to download %s',
14226 get_class($downloader), $downloader->getInstallationSource(), $installationSource
14227 ));
14228 }
14229
14230 return $downloader;
14231 }
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243 public function download(PackageInterface $package, $targetDir, $preferSource = null)
14244 {
14245 $preferSource = null !== $preferSource ? $preferSource : $this->preferSource;
14246 $sourceType = $package->getSourceType();
14247 $distType = $package->getDistType();
14248
14249 $sources = array();
14250 if ($sourceType) {
14251 $sources[] = 'source';
14252 }
14253 if ($distType) {
14254 $sources[] = 'dist';
14255 }
14256
14257 if (empty($sources)) {
14258 throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified');
14259 }
14260
14261 if (!$preferSource && ($this->preferDist || 'dist' === $this->resolvePackageInstallPreference($package))) {
14262 $sources = array_reverse($sources);
14263 }
14264
14265 $this->filesystem->ensureDirectoryExists($targetDir);
14266
14267 foreach ($sources as $i => $source) {
14268 if (isset($e)) {
14269 $this->io->writeError('    <warning>Now trying to download from ' . $source . '</warning>');
14270 }
14271 $package->setInstallationSource($source);
14272 try {
14273 $downloader = $this->getDownloaderForInstalledPackage($package);
14274 if ($downloader) {
14275 $downloader->download($package, $targetDir);
14276 }
14277 break;
14278 } catch (\RuntimeException $e) {
14279 if ($i === count($sources) - 1) {
14280 throw $e;
14281 }
14282
14283 $this->io->writeError(
14284 '    <warning>Failed to download '.
14285 $package->getPrettyName().
14286 ' from ' . $source . ': '.
14287 $e->getMessage().'</warning>'
14288 );
14289 }
14290 }
14291 }
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302 public function update(PackageInterface $initial, PackageInterface $target, $targetDir)
14303 {
14304 $downloader = $this->getDownloaderForInstalledPackage($initial);
14305 if (!$downloader) {
14306 return;
14307 }
14308
14309 $installationSource = $initial->getInstallationSource();
14310
14311 if ('dist' === $installationSource) {
14312 $initialType = $initial->getDistType();
14313 $targetType = $target->getDistType();
14314 } else {
14315 $initialType = $initial->getSourceType();
14316 $targetType = $target->getSourceType();
14317 }
14318
14319
14320  if ($target->isDev() && 'dist' === $installationSource) {
14321 $downloader->remove($initial, $targetDir);
14322 $this->download($target, $targetDir);
14323
14324 return;
14325 }
14326
14327 if ($initialType === $targetType) {
14328 $target->setInstallationSource($installationSource);
14329 try {
14330 $downloader->update($initial, $target, $targetDir);
14331
14332 return;
14333 } catch (\RuntimeException $e) {
14334 if (!$this->io->isInteractive()) {
14335 throw $e;
14336 }
14337 $this->io->writeError('<error>    Update failed ('.$e->getMessage().')</error>');
14338 if (!$this->io->askConfirmation('    Would you like to try reinstalling the package instead [<comment>yes</comment>]? ', true)) {
14339 throw $e;
14340 }
14341 }
14342 }
14343
14344 $downloader->remove($initial, $targetDir);
14345 $this->download($target, $targetDir, 'source' === $installationSource);
14346 }
14347
14348
14349
14350
14351
14352
14353
14354 public function remove(PackageInterface $package, $targetDir)
14355 {
14356 $downloader = $this->getDownloaderForInstalledPackage($package);
14357 if ($downloader) {
14358 $downloader->remove($package, $targetDir);
14359 }
14360 }
14361
14362
14363
14364
14365
14366
14367
14368
14369 protected function resolvePackageInstallPreference(PackageInterface $package)
14370 {
14371 foreach ($this->packagePreferences as $pattern => $preference) {
14372 $pattern = '{^'.str_replace('\\*', '.*', preg_quote($pattern)).'$}i';
14373 if (preg_match($pattern, $package->getName())) {
14374 if ('dist' === $preference || (!$package->isDev() && 'auto' === $preference)) {
14375 return 'dist';
14376 }
14377
14378 return 'source';
14379 }
14380 }
14381
14382 return $package->isDev() ? 'source' : 'dist';
14383 }
14384 }
14385 <?php
14386
14387
14388
14389
14390
14391
14392
14393
14394
14395
14396
14397 namespace Composer\Downloader;
14398
14399 use Composer\Package\PackageInterface;
14400
14401
14402
14403
14404
14405
14406
14407 interface DownloaderInterface
14408 {
14409
14410
14411
14412
14413
14414 public function getInstallationSource();
14415
14416
14417
14418
14419
14420
14421
14422 public function download(PackageInterface $package, $path);
14423
14424
14425
14426
14427
14428
14429
14430
14431 public function update(PackageInterface $initial, PackageInterface $target, $path);
14432
14433
14434
14435
14436
14437
14438
14439 public function remove(PackageInterface $package, $path);
14440
14441
14442
14443
14444
14445
14446
14447 public function setOutputProgress($outputProgress);
14448 }
14449 <?php
14450
14451
14452
14453
14454
14455
14456
14457
14458
14459
14460
14461 namespace Composer\Downloader;
14462
14463 use Composer\Package\PackageInterface;
14464
14465
14466
14467
14468
14469
14470 interface DvcsDownloaderInterface
14471 {
14472
14473
14474
14475
14476
14477
14478
14479 public function getUnpushedChanges(PackageInterface $package, $path);
14480 }
14481 <?php
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493 namespace Composer\Downloader;
14494
14495 use Composer\Config;
14496 use Composer\Cache;
14497 use Composer\Factory;
14498 use Composer\IO\IOInterface;
14499 use Composer\Package\PackageInterface;
14500 use Composer\Plugin\PluginEvents;
14501 use Composer\Plugin\PreFileDownloadEvent;
14502 use Composer\EventDispatcher\EventDispatcher;
14503 use Composer\Util\Filesystem;
14504 use Composer\Util\RemoteFilesystem;
14505
14506
14507
14508
14509
14510
14511
14512
14513
14514 class FileDownloader implements DownloaderInterface
14515 {
14516 protected $io;
14517 protected $config;
14518 protected $rfs;
14519 protected $filesystem;
14520 protected $cache;
14521 protected $outputProgress = true;
14522 private $lastCacheWrites = array();
14523 private $eventDispatcher;
14524
14525
14526
14527
14528
14529
14530
14531
14532
14533
14534
14535 public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, RemoteFilesystem $rfs = null, Filesystem $filesystem = null)
14536 {
14537 $this->io = $io;
14538 $this->config = $config;
14539 $this->eventDispatcher = $eventDispatcher;
14540 $this->rfs = $rfs ?: Factory::createRemoteFilesystem($this->io, $config);
14541 $this->filesystem = $filesystem ?: new Filesystem();
14542 $this->cache = $cache;
14543
14544 if ($this->cache && $this->cache->gcIsNecessary()) {
14545 $this->cache->gc($config->get('cache-files-ttl'), $config->get('cache-files-maxsize'));
14546 }
14547 }
14548
14549
14550
14551
14552 public function getInstallationSource()
14553 {
14554 return 'dist';
14555 }
14556
14557
14558
14559
14560 public function download(PackageInterface $package, $path, $output = true)
14561 {
14562 if (!$package->getDistUrl()) {
14563 throw new \InvalidArgumentException('The given package is missing url information');
14564 }
14565
14566 if ($output) {
14567 $this->io->writeError("  - Installing <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>): ", false);
14568 }
14569
14570 $urls = $package->getDistUrls();
14571 while ($url = array_shift($urls)) {
14572 try {
14573 return $this->doDownload($package, $path, $url);
14574 } catch (\Exception $e) {
14575 if ($this->io->isDebug()) {
14576 $this->io->writeError('');
14577 $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage());
14578 } elseif (count($urls)) {
14579 $this->io->writeError('');
14580 $this->io->writeError(' Failed, trying the next URL ('.$e->getCode().': '.$e->getMessage().')', false);
14581 }
14582
14583 if (!count($urls)) {
14584 throw $e;
14585 }
14586 }
14587 }
14588
14589 if ($output) {
14590 $this->io->writeError('');
14591 }
14592 }
14593
14594 protected function doDownload(PackageInterface $package, $path, $url)
14595 {
14596 $this->filesystem->emptyDirectory($path);
14597
14598 $fileName = $this->getFileName($package, $path);
14599
14600 $processedUrl = $this->processUrl($package, $url);
14601 $hostname = parse_url($processedUrl, PHP_URL_HOST);
14602
14603 $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->rfs, $processedUrl);
14604 if ($this->eventDispatcher) {
14605 $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
14606 }
14607 $rfs = $preFileDownloadEvent->getRemoteFilesystem();
14608
14609 try {
14610 $checksum = $package->getDistSha1Checksum();
14611 $cacheKey = $this->getCacheKey($package, $processedUrl);
14612
14613
14614  if (!$this->cache || ($checksum && $checksum !== $this->cache->sha1($cacheKey)) || !$this->cache->copyTo($cacheKey, $fileName)) {
14615 if (!$this->outputProgress) {
14616 $this->io->writeError('Downloading', false);
14617 }
14618
14619
14620  $retries = 3;
14621 while ($retries--) {
14622 try {
14623 $rfs->copy($hostname, $processedUrl, $fileName, $this->outputProgress, $package->getTransportOptions());
14624 break;
14625 } catch (TransportException $e) {
14626
14627  if ((0 !== $e->getCode() && !in_array($e->getCode(), array(500, 502, 503, 504))) || !$retries) {
14628 throw $e;
14629 }
14630 $this->io->writeError('');
14631 $this->io->writeError('    Download failed, retrying...', true, IOInterface::VERBOSE);
14632 usleep(500000);
14633 }
14634 }
14635
14636 if (!$this->outputProgress) {
14637 $this->io->writeError(' (<comment>100%</comment>)', false);
14638 }
14639
14640 if ($this->cache) {
14641 $this->lastCacheWrites[$package->getName()] = $cacheKey;
14642 $this->cache->copyFrom($cacheKey, $fileName);
14643 }
14644 } else {
14645 $this->io->writeError('Loading from cache', false);
14646 }
14647
14648 if (!file_exists($fileName)) {
14649 throw new \UnexpectedValueException($url.' could not be saved to '.$fileName.', make sure the'
14650 .' directory is writable and you have internet connectivity');
14651 }
14652
14653 if ($checksum && hash_file('sha1', $fileName) !== $checksum) {
14654 throw new \UnexpectedValueException('The checksum verification of the file failed (downloaded from '.$url.')');
14655 }
14656 } catch (\Exception $e) {
14657
14658  $this->filesystem->removeDirectory($path);
14659 $this->clearLastCacheWrite($package);
14660 throw $e;
14661 }
14662
14663 return $fileName;
14664 }
14665
14666
14667
14668
14669 public function setOutputProgress($outputProgress)
14670 {
14671 $this->outputProgress = $outputProgress;
14672
14673 return $this;
14674 }
14675
14676 protected function clearLastCacheWrite(PackageInterface $package)
14677 {
14678 if ($this->cache && isset($this->lastCacheWrites[$package->getName()])) {
14679 $this->cache->remove($this->lastCacheWrites[$package->getName()]);
14680 unset($this->lastCacheWrites[$package->getName()]);
14681 }
14682 }
14683
14684
14685
14686
14687 public function update(PackageInterface $initial, PackageInterface $target, $path)
14688 {
14689 $name = $target->getName();
14690 $from = $initial->getPrettyVersion();
14691 $to = $target->getPrettyVersion();
14692
14693 $this->io->writeError("  - Updating <info>" . $name . "</info> (<comment>" . $from . "</comment> => <comment>" . $to . "</comment>): ", false);
14694
14695 $this->remove($initial, $path, false);
14696 $this->download($target, $path, false);
14697
14698 $this->io->writeError('');
14699 }
14700
14701
14702
14703
14704 public function remove(PackageInterface $package, $path, $output = true)
14705 {
14706 if ($output) {
14707 $this->io->writeError("  - Removing <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>)");
14708 }
14709 if (!$this->filesystem->removeDirectory($path)) {
14710 throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
14711 }
14712 }
14713
14714
14715
14716
14717
14718
14719
14720
14721 protected function getFileName(PackageInterface $package, $path)
14722 {
14723 return $path.'/'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_BASENAME);
14724 }
14725
14726
14727
14728
14729
14730
14731
14732
14733
14734 protected function processUrl(PackageInterface $package, $url)
14735 {
14736 if (!extension_loaded('openssl') && 0 === strpos($url, 'https:')) {
14737 throw new \RuntimeException('You must enable the openssl extension to download files via https');
14738 }
14739
14740 return $url;
14741 }
14742
14743 private function getCacheKey(PackageInterface $package, $processedUrl)
14744 {
14745
14746  
14747  
14748  
14749  $cacheKey = sha1($processedUrl);
14750
14751 return $package->getName().'/'.$cacheKey.'.'.$package->getDistType();
14752 }
14753 }
14754 <?php
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766 namespace Composer\Downloader;
14767
14768
14769
14770
14771
14772
14773 class FilesystemException extends \Exception
14774 {
14775 public function __construct($message = '', $code = 0, \Exception $previous = null)
14776 {
14777 parent::__construct("Filesystem exception: \n".$message, $code, $previous);
14778 }
14779 }
14780 <?php
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
14791
14792 namespace Composer\Downloader;
14793
14794 use Composer\Package\PackageInterface;
14795 use Composer\Util\ProcessExecutor;
14796
14797
14798
14799
14800 class FossilDownloader extends VcsDownloader
14801 {
14802
14803
14804
14805 public function doDownload(PackageInterface $package, $path, $url)
14806 {
14807
14808  $this->config->prohibitUrlByConfig($url, $this->io);
14809
14810 $url = ProcessExecutor::escape($url);
14811 $ref = ProcessExecutor::escape($package->getSourceReference());
14812 $repoFile = $path . '.fossil';
14813 $this->io->writeError("Cloning ".$package->getSourceReference());
14814 $command = sprintf('fossil clone %s %s', $url, ProcessExecutor::escape($repoFile));
14815 if (0 !== $this->process->execute($command, $ignoredOutput)) {
14816 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
14817 }
14818 $command = sprintf('fossil open %s', ProcessExecutor::escape($repoFile));
14819 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
14820 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
14821 }
14822 $command = sprintf('fossil update %s', $ref);
14823 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
14824 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
14825 }
14826 }
14827
14828
14829
14830
14831 public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
14832 {
14833
14834  $this->config->prohibitUrlByConfig($url, $this->io);
14835
14836 $url = ProcessExecutor::escape($url);
14837 $ref = ProcessExecutor::escape($target->getSourceReference());
14838 $this->io->writeError(" Updating to ".$target->getSourceReference());
14839
14840 if (!$this->hasMetadataRepository($path)) {
14841 throw new \RuntimeException('The .fslckout file is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
14842 }
14843
14844 $command = sprintf('fossil pull && fossil up %s', $ref);
14845 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
14846 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
14847 }
14848 }
14849
14850
14851
14852
14853 public function getLocalChanges(PackageInterface $package, $path)
14854 {
14855 if (!$this->hasMetadataRepository($path)) {
14856 return null;
14857 }
14858
14859 $this->process->execute('fossil changes', $output, realpath($path));
14860
14861 return trim($output) ?: null;
14862 }
14863
14864
14865
14866
14867 protected function getCommitLogs($fromReference, $toReference, $path)
14868 {
14869 $command = sprintf('fossil timeline -t ci -W 0 -n 0 before %s', $toReference);
14870
14871 if (0 !== $this->process->execute($command, $output, realpath($path))) {
14872 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
14873 }
14874
14875 $log = '';
14876 $match = '/\d\d:\d\d:\d\d\s+\[' . $toReference . '\]/';
14877
14878 foreach ($this->process->splitLines($output) as $line) {
14879 if (preg_match($match, $line)) {
14880 break;
14881 }
14882 $log .= $line;
14883 }
14884
14885 return $log;
14886 }
14887
14888
14889
14890
14891 protected function hasMetadataRepository($path)
14892 {
14893 return is_file($path . '/.fslckout') || is_file($path . '/_FOSSIL_');
14894 }
14895 }
14896 <?php
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908 namespace Composer\Downloader;
14909
14910 use Composer\Package\PackageInterface;
14911 use Composer\Util\Git as GitUtil;
14912 use Composer\Util\Platform;
14913 use Composer\Util\ProcessExecutor;
14914 use Composer\IO\IOInterface;
14915 use Composer\Util\Filesystem;
14916 use Composer\Config;
14917
14918
14919
14920
14921 class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
14922 {
14923 private $hasStashedChanges = false;
14924 private $hasDiscardedChanges = false;
14925 private $gitUtil;
14926
14927 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
14928 {
14929 parent::__construct($io, $config, $process, $fs);
14930 $this->gitUtil = new GitUtil($this->io, $this->config, $this->process, $this->filesystem);
14931 }
14932
14933
14934
14935
14936 public function doDownload(PackageInterface $package, $path, $url)
14937 {
14938 GitUtil::cleanEnv();
14939 $path = $this->normalizePath($path);
14940 $cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/';
14941 $cacheOptions = '';
14942 $ref = $package->getSourceReference();
14943 $flag = Platform::isWindows() ? '/D ' : '';
14944
14945
14946  $gitVersion = $this->gitUtil->getVersion();
14947 $msg = "Cloning ".$this->getShortHash($ref);
14948 if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=')) {
14949 $this->io->writeError('', true, IOInterface::DEBUG);
14950 $this->io->writeError(sprintf('    Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
14951 try {
14952 $this->gitUtil->syncMirror($url, $cachePath);
14953 if (is_dir($cachePath)) {
14954 $cacheOptions = sprintf('--dissociate --reference %s ', ProcessExecutor::escape($cachePath));
14955 $msg = "Cloning ".$this->getShortHash($ref).' from cache';
14956 }
14957 } catch (\RuntimeException $e) {
14958 }
14959 }
14960 $command = 'git clone --no-checkout %s %s '.$cacheOptions.'&& cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';
14961 $this->io->writeError($msg);
14962
14963 $commandCallable = function ($url) use ($ref, $path, $command) {
14964 return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref));
14965 };
14966
14967 $this->gitUtil->runCommand($commandCallable, $url, $path, true);
14968 if ($url !== $package->getSourceUrl()) {
14969 $this->updateOriginUrl($path, $package->getSourceUrl());
14970 } else {
14971 $this->setPushUrl($path, $url);
14972 }
14973
14974 if ($newRef = $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate())) {
14975 if ($package->getDistReference() === $package->getSourceReference()) {
14976 $package->setDistReference($newRef);
14977 }
14978 $package->setSourceReference($newRef);
14979 }
14980 }
14981
14982
14983
14984
14985 public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
14986 {
14987 GitUtil::cleanEnv();
14988 if (!$this->hasMetadataRepository($path)) {
14989 throw new \RuntimeException('The .git directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
14990 }
14991
14992 $updateOriginUrl = false;
14993 if (
14994 0 === $this->process->execute('git remote -v', $output, $path)
14995 && preg_match('{^origin\s+(?P<url>\S+)}m', $output, $originMatch)
14996 && preg_match('{^composer\s+(?P<url>\S+)}m', $output, $composerMatch)
14997 ) {
14998 if ($originMatch['url'] === $composerMatch['url'] && $composerMatch['url'] !== $target->getSourceUrl()) {
14999 $updateOriginUrl = true;
15000 }
15001 }
15002
15003 $ref = $target->getSourceReference();
15004 $this->io->writeError(" Checking out ".$this->getShortHash($ref));
15005 $command = 'git remote set-url composer %s && git rev-parse --quiet --verify %s^{commit} || (git fetch composer && git fetch --tags composer)';
15006
15007 $commandCallable = function ($url) use ($command, $ref) {
15008 return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($ref));
15009 };
15010
15011 $this->gitUtil->runCommand($commandCallable, $url, $path);
15012 if ($newRef = $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) {
15013 if ($target->getDistReference() === $target->getSourceReference()) {
15014 $target->setDistReference($newRef);
15015 }
15016 $target->setSourceReference($newRef);
15017 }
15018
15019 if ($updateOriginUrl) {
15020 $this->updateOriginUrl($path, $target->getSourceUrl());
15021 }
15022 }
15023
15024
15025
15026
15027 public function getLocalChanges(PackageInterface $package, $path)
15028 {
15029 GitUtil::cleanEnv();
15030 if (!$this->hasMetadataRepository($path)) {
15031 return;
15032 }
15033
15034 $command = 'git status --porcelain --untracked-files=no';
15035 if (0 !== $this->process->execute($command, $output, $path)) {
15036 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15037 }
15038
15039 return trim($output) ?: null;
15040 }
15041
15042 public function getUnpushedChanges(PackageInterface $package, $path)
15043 {
15044 GitUtil::cleanEnv();
15045 $path = $this->normalizePath($path);
15046 if (!$this->hasMetadataRepository($path)) {
15047 return;
15048 }
15049
15050 $command = 'git show-ref --head -d';
15051 if (0 !== $this->process->execute($command, $output, $path)) {
15052 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15053 }
15054
15055 $refs = trim($output);
15056 if (!preg_match('{^([a-f0-9]+) HEAD$}mi', $refs, $match)) {
15057
15058  return;
15059 }
15060
15061 $headRef = $match[1];
15062 if (!preg_match_all('{^'.$headRef.' refs/heads/(.+)$}mi', $refs, $matches)) {
15063
15064  return;
15065 }
15066
15067
15068  $branch = $matches[1][0];
15069 $unpushedChanges = null;
15070
15071
15072  for ($i = 0; $i <= 1; $i++) {
15073
15074  foreach ($matches[1] as $candidate) {
15075 if (preg_match('{^[a-f0-9]+ refs/remotes/((?:composer|origin)/'.preg_quote($candidate).')$}mi', $refs, $match)) {
15076 $branch = $candidate;
15077 $remoteBranch = $match[1];
15078 break;
15079 }
15080 }
15081
15082
15083  
15084  
15085  if (!isset($remoteBranch)) {
15086 $unpushedChanges = 'Branch ' . $branch . ' could not be found on the origin remote and appears to be unpushed';
15087 } else {
15088 $command = sprintf('git diff --name-status %s...%s --', $remoteBranch, $branch);
15089 if (0 !== $this->process->execute($command, $output, $path)) {
15090 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15091 }
15092
15093 $unpushedChanges = trim($output) ?: null;
15094 }
15095
15096
15097  
15098  if ($unpushedChanges && $i === 0) {
15099 $this->process->execute('git fetch composer && git fetch origin', $output, $path);
15100 }
15101
15102
15103  if (!$unpushedChanges) {
15104 break;
15105 }
15106 }
15107
15108 return $unpushedChanges;
15109 }
15110
15111
15112
15113
15114 protected function cleanChanges(PackageInterface $package, $path, $update)
15115 {
15116 GitUtil::cleanEnv();
15117 $path = $this->normalizePath($path);
15118
15119 $unpushed = $this->getUnpushedChanges($package, $path);
15120 if ($unpushed && ($this->io->isInteractive() || $this->config->get('discard-changes') !== true)) {
15121 throw new \RuntimeException('Source directory ' . $path . ' has unpushed changes on the current branch: '."\n".$unpushed);
15122 }
15123
15124 if (!$changes = $this->getLocalChanges($package, $path)) {
15125 return;
15126 }
15127
15128 if (!$this->io->isInteractive()) {
15129 $discardChanges = $this->config->get('discard-changes');
15130 if (true === $discardChanges) {
15131 return $this->discardChanges($path);
15132 }
15133 if ('stash' === $discardChanges) {
15134 if (!$update) {
15135 return parent::cleanChanges($package, $path, $update);
15136 }
15137
15138 return $this->stashChanges($path);
15139 }
15140
15141 return parent::cleanChanges($package, $path, $update);
15142 }
15143
15144 $changes = array_map(function ($elem) {
15145 return '    '.$elem;
15146 }, preg_split('{\s*\r?\n\s*}', $changes));
15147 $this->io->writeError('    <error>The package has modified files:</error>');
15148 $this->io->writeError(array_slice($changes, 0, 10));
15149 if (count($changes) > 10) {
15150 $this->io->writeError('    <info>' . (count($changes) - 10) . ' more files modified, choose "v" to view the full list</info>');
15151 }
15152
15153 while (true) {
15154 switch ($this->io->ask('    <info>Discard changes [y,n,v,d,'.($update ? 's,' : '').'?]?</info> ', '?')) {
15155 case 'y':
15156 $this->discardChanges($path);
15157 break 2;
15158
15159 case 's':
15160 if (!$update) {
15161 goto help;
15162 }
15163
15164 $this->stashChanges($path);
15165 break 2;
15166
15167 case 'n':
15168 throw new \RuntimeException('Update aborted');
15169
15170 case 'v':
15171 $this->io->writeError($changes);
15172 break;
15173
15174 case 'd':
15175 $this->viewDiff($path);
15176 break;
15177
15178 case '?':
15179 default:
15180 help:
15181 $this->io->writeError(array(
15182 '    y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
15183 '    n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
15184 '    v - view modified files',
15185 '    d - view local modifications (diff)',
15186 ));
15187 if ($update) {
15188 $this->io->writeError('    s - stash changes and try to reapply them after the update');
15189 }
15190 $this->io->writeError('    ? - print help');
15191 break;
15192 }
15193 }
15194 }
15195
15196
15197
15198
15199 protected function reapplyChanges($path)
15200 {
15201 $path = $this->normalizePath($path);
15202 if ($this->hasStashedChanges) {
15203 $this->hasStashedChanges = false;
15204 $this->io->writeError('    <info>Re-applying stashed changes</info>');
15205 if (0 !== $this->process->execute('git stash pop', $output, $path)) {
15206 throw new \RuntimeException("Failed to apply stashed changes:\n\n".$this->process->getErrorOutput());
15207 }
15208 }
15209
15210 $this->hasDiscardedChanges = false;
15211 }
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223 protected function updateToCommit($path, $reference, $branch, $date)
15224 {
15225 $force = $this->hasDiscardedChanges || $this->hasStashedChanges ? '-f ' : '';
15226
15227
15228  
15229  
15230  
15231  
15232  $template = 'git checkout '.$force.'%s -- && git reset --hard %1$s --';
15233 $branch = preg_replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $branch);
15234
15235 $branches = null;
15236 if (0 === $this->process->execute('git branch -r', $output, $path)) {
15237 $branches = $output;
15238 }
15239
15240
15241  $gitRef = $reference;
15242 if (!preg_match('{^[a-f0-9]{40}$}', $reference)
15243 && $branches
15244 && preg_match('{^\s+composer/'.preg_quote($reference).'$}m', $branches)
15245 ) {
15246 $command = sprintf('git checkout '.$force.'-B %s %s -- && git reset --hard %2$s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$reference));
15247 if (0 === $this->process->execute($command, $output, $path)) {
15248 return;
15249 }
15250 }
15251
15252
15253  if (preg_match('{^[a-f0-9]{40}$}', $reference)) {
15254
15255  if (!preg_match('{^\s+composer/'.preg_quote($branch).'$}m', $branches) && preg_match('{^\s+composer/v'.preg_quote($branch).'$}m', $branches)) {
15256 $branch = 'v' . $branch;
15257 }
15258
15259 $command = sprintf('git checkout %s --', ProcessExecutor::escape($branch));
15260 $fallbackCommand = sprintf('git checkout '.$force.'-B %s %s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$branch));
15261 if (0 === $this->process->execute($command, $output, $path)
15262 || 0 === $this->process->execute($fallbackCommand, $output, $path)
15263 ) {
15264 $command = sprintf('git reset --hard %s --', ProcessExecutor::escape($reference));
15265 if (0 === $this->process->execute($command, $output, $path)) {
15266 return;
15267 }
15268 }
15269 }
15270
15271 $command = sprintf($template, ProcessExecutor::escape($gitRef));
15272 if (0 === $this->process->execute($command, $output, $path)) {
15273 return;
15274 }
15275
15276
15277  if (false !== strpos($this->process->getErrorOutput(), $reference)) {
15278 $this->io->writeError('    <warning>'.$reference.' is gone (history was rewritten?)</warning>');
15279 }
15280
15281 throw new \RuntimeException(GitUtil::sanitizeUrl('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()));
15282 }
15283
15284 protected function updateOriginUrl($path, $url)
15285 {
15286 $this->process->execute(sprintf('git remote set-url origin %s', ProcessExecutor::escape($url)), $output, $path);
15287 $this->setPushUrl($path, $url);
15288 }
15289
15290 protected function setPushUrl($path, $url)
15291 {
15292
15293  if (preg_match('{^(?:https?|git)://'.GitUtil::getGitHubDomainsRegex($this->config).'/([^/]+)/([^/]+?)(?:\.git)?$}', $url, $match)) {
15294 $protocols = $this->config->get('github-protocols');
15295 $pushUrl = 'git@'.$match[1].':'.$match[2].'/'.$match[3].'.git';
15296 if (!in_array('ssh', $protocols, true)) {
15297 $pushUrl = 'https://' . $match[1] . '/'.$match[2].'/'.$match[3].'.git';
15298 }
15299 $cmd = sprintf('git remote set-url --push origin %s', ProcessExecutor::escape($pushUrl));
15300 $this->process->execute($cmd, $ignoredOutput, $path);
15301 }
15302 }
15303
15304
15305
15306
15307 protected function getCommitLogs($fromReference, $toReference, $path)
15308 {
15309 $path = $this->normalizePath($path);
15310 $command = sprintf('git log %s..%s --pretty=format:"%%h - %%an: %%s"', $fromReference, $toReference);
15311
15312 if (0 !== $this->process->execute($command, $output, $path)) {
15313 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15314 }
15315
15316 return $output;
15317 }
15318
15319
15320
15321
15322
15323 protected function discardChanges($path)
15324 {
15325 $path = $this->normalizePath($path);
15326 if (0 !== $this->process->execute('git reset --hard', $output, $path)) {
15327 throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
15328 }
15329
15330 $this->hasDiscardedChanges = true;
15331 }
15332
15333
15334
15335
15336
15337 protected function stashChanges($path)
15338 {
15339 $path = $this->normalizePath($path);
15340 if (0 !== $this->process->execute('git stash --include-untracked', $output, $path)) {
15341 throw new \RuntimeException("Could not stash changes\n\n:".$this->process->getErrorOutput());
15342 }
15343
15344 $this->hasStashedChanges = true;
15345 }
15346
15347
15348
15349
15350
15351 protected function viewDiff($path)
15352 {
15353 $path = $this->normalizePath($path);
15354 if (0 !== $this->process->execute('git diff HEAD', $output, $path)) {
15355 throw new \RuntimeException("Could not view diff\n\n:".$this->process->getErrorOutput());
15356 }
15357
15358 $this->io->writeError($output);
15359 }
15360
15361 protected function normalizePath($path)
15362 {
15363 if (Platform::isWindows() && strlen($path) > 0) {
15364 $basePath = $path;
15365 $removed = array();
15366
15367 while (!is_dir($basePath) && $basePath !== '\\') {
15368 array_unshift($removed, basename($basePath));
15369 $basePath = dirname($basePath);
15370 }
15371
15372 if ($basePath === '\\') {
15373 return $path;
15374 }
15375
15376 $path = rtrim(realpath($basePath) . '/' . implode('/', $removed), '/');
15377 }
15378
15379 return $path;
15380 }
15381
15382
15383
15384
15385 protected function hasMetadataRepository($path)
15386 {
15387 $path = $this->normalizePath($path);
15388
15389 return is_dir($path.'/.git');
15390 }
15391
15392 protected function getShortHash($reference)
15393 {
15394 if (!$this->io->isVerbose() && preg_match('{^[0-9a-f]{40}$}', $reference)) {
15395 return substr($reference, 0, 10);
15396 }
15397
15398 return $reference;
15399 }
15400 }
15401 <?php
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413 namespace Composer\Downloader;
15414
15415 use Composer\Config;
15416 use Composer\Cache;
15417 use Composer\EventDispatcher\EventDispatcher;
15418 use Composer\Package\PackageInterface;
15419 use Composer\Util\Platform;
15420 use Composer\Util\ProcessExecutor;
15421 use Composer\Util\RemoteFilesystem;
15422 use Composer\IO\IOInterface;
15423
15424
15425
15426
15427
15428
15429 class GzipDownloader extends ArchiveDownloader
15430 {
15431 protected $process;
15432
15433 public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, RemoteFilesystem $rfs = null)
15434 {
15435 $this->process = $process ?: new ProcessExecutor($io);
15436 parent::__construct($io, $config, $eventDispatcher, $cache, $rfs);
15437 }
15438
15439 protected function extract($file, $path)
15440 {
15441 $targetFilepath = $path . DIRECTORY_SEPARATOR . basename(substr($file, 0, -3));
15442
15443
15444  if (!Platform::isWindows()) {
15445 $command = 'gzip -cd ' . ProcessExecutor::escape($file) . ' > ' . ProcessExecutor::escape($targetFilepath);
15446
15447 if (0 === $this->process->execute($command, $ignoredOutput)) {
15448 return;
15449 }
15450
15451 if (extension_loaded('zlib')) {
15452
15453  $this->extractUsingExt($file, $targetFilepath);
15454
15455 return;
15456 }
15457
15458 $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput();
15459 throw new \RuntimeException($processError);
15460 }
15461
15462
15463  $this->extractUsingExt($file, $targetFilepath);
15464 }
15465
15466
15467
15468
15469 protected function getFileName(PackageInterface $package, $path)
15470 {
15471 return $path.'/'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_BASENAME);
15472 }
15473
15474 private function extractUsingExt($file, $targetFilepath)
15475 {
15476 $archiveFile = gzopen($file, 'rb');
15477 $targetFile = fopen($targetFilepath, 'wb');
15478 while ($string = gzread($archiveFile, 4096)) {
15479 fwrite($targetFile, $string, Platform::strlen($string));
15480 }
15481 gzclose($archiveFile);
15482 fclose($targetFile);
15483 }
15484 }
15485 <?php
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497 namespace Composer\Downloader;
15498
15499 use Composer\Package\PackageInterface;
15500 use Composer\Util\ProcessExecutor;
15501
15502
15503
15504
15505 class HgDownloader extends VcsDownloader
15506 {
15507
15508
15509
15510 public function doDownload(PackageInterface $package, $path, $url)
15511 {
15512
15513  $this->config->prohibitUrlByConfig($url, $this->io);
15514
15515 $url = ProcessExecutor::escape($url);
15516 $ref = ProcessExecutor::escape($package->getSourceReference());
15517 $this->io->writeError("Cloning ".$package->getSourceReference());
15518 $command = sprintf('hg clone %s %s', $url, ProcessExecutor::escape($path));
15519 if (0 !== $this->process->execute($command, $ignoredOutput)) {
15520 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15521 }
15522 $command = sprintf('hg up %s', $ref);
15523 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
15524 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15525 }
15526 }
15527
15528
15529
15530
15531 public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
15532 {
15533
15534  $this->config->prohibitUrlByConfig($url, $this->io);
15535
15536 $url = ProcessExecutor::escape($url);
15537 $ref = ProcessExecutor::escape($target->getSourceReference());
15538 $this->io->writeError(" Updating to ".$target->getSourceReference());
15539
15540 if (!$this->hasMetadataRepository($path)) {
15541 throw new \RuntimeException('The .hg directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
15542 }
15543
15544 $command = sprintf('hg pull %s && hg up %s', $url, $ref);
15545 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
15546 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15547 }
15548 }
15549
15550
15551
15552
15553 public function getLocalChanges(PackageInterface $package, $path)
15554 {
15555 if (!is_dir($path.'/.hg')) {
15556 return null;
15557 }
15558
15559 $this->process->execute('hg st', $output, realpath($path));
15560
15561 return trim($output) ?: null;
15562 }
15563
15564
15565
15566
15567 protected function getCommitLogs($fromReference, $toReference, $path)
15568 {
15569 $command = sprintf('hg log -r %s:%s --style compact', $fromReference, $toReference);
15570
15571 if (0 !== $this->process->execute($command, $output, realpath($path))) {
15572 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
15573 }
15574
15575 return $output;
15576 }
15577
15578
15579
15580
15581 protected function hasMetadataRepository($path)
15582 {
15583 return is_dir($path . '/.hg');
15584 }
15585 }
15586 <?php
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598 namespace Composer\Downloader;
15599
15600 use Composer\Package\Dumper\ArrayDumper;
15601 use Composer\Package\PackageInterface;
15602 use Composer\Package\Version\VersionGuesser;
15603 use Composer\Package\Version\VersionParser;
15604 use Composer\Util\Platform;
15605 use Composer\Util\ProcessExecutor;
15606 use Symfony\Component\Filesystem\Exception\IOException;
15607 use Symfony\Component\Filesystem\Filesystem;
15608
15609
15610
15611
15612
15613
15614
15615 class PathDownloader extends FileDownloader implements VcsCapableDownloaderInterface
15616 {
15617 const STRATEGY_SYMLINK = 10;
15618 const STRATEGY_MIRROR = 20;
15619
15620
15621
15622
15623 public function download(PackageInterface $package, $path, $output = true)
15624 {
15625 $url = $package->getDistUrl();
15626 $realUrl = realpath($url);
15627 if (false === $realUrl || !file_exists($realUrl) || !is_dir($realUrl)) {
15628 throw new \RuntimeException(sprintf(
15629 'Source path "%s" is not found for package %s', $url, $package->getName()
15630 ));
15631 }
15632
15633 if (strpos(realpath($path) . DIRECTORY_SEPARATOR, $realUrl . DIRECTORY_SEPARATOR) === 0) {
15634
15635  
15636  
15637  
15638  throw new \RuntimeException(sprintf(
15639 'Package %s cannot install to "%s" inside its source at "%s"',
15640 $package->getName(), realpath($path), $realUrl
15641 ));
15642 }
15643
15644
15645  $transportOptions = $package->getTransportOptions() + array('symlink' => null);
15646
15647
15648  $currentStrategy = self::STRATEGY_SYMLINK;
15649 $allowedStrategies = array(self::STRATEGY_SYMLINK, self::STRATEGY_MIRROR);
15650
15651 $mirrorPathRepos = getenv('COMPOSER_MIRROR_PATH_REPOS');
15652 if ($mirrorPathRepos) {
15653 $currentStrategy = self::STRATEGY_MIRROR;
15654 }
15655
15656 if (true === $transportOptions['symlink']) {
15657 $currentStrategy = self::STRATEGY_SYMLINK;
15658 $allowedStrategies = array(self::STRATEGY_SYMLINK);
15659 } elseif (false === $transportOptions['symlink']) {
15660 $currentStrategy = self::STRATEGY_MIRROR;
15661 $allowedStrategies = array(self::STRATEGY_MIRROR);
15662 }
15663
15664 $fileSystem = new Filesystem();
15665 $this->filesystem->removeDirectory($path);
15666
15667 if ($output) {
15668 $this->io->writeError(sprintf(
15669 '  - Installing <info>%s</info> (<comment>%s</comment>): ',
15670 $package->getName(),
15671 $package->getFullPrettyVersion()
15672 ), false);
15673 }
15674
15675 $isFallback = false;
15676 if (self::STRATEGY_SYMLINK == $currentStrategy) {
15677 try {
15678 if (Platform::isWindows()) {
15679
15680  $this->io->writeError(sprintf('Junctioning from %s', $url), false);
15681 $this->filesystem->junction($realUrl, $path);
15682 } else {
15683 $absolutePath = $path;
15684 if (!$this->filesystem->isAbsolutePath($absolutePath)) {
15685 $absolutePath = getcwd() . DIRECTORY_SEPARATOR . $path;
15686 }
15687 $shortestPath = $this->filesystem->findShortestPath($absolutePath, $realUrl);
15688 $path = rtrim($path, "/");
15689 $this->io->writeError(sprintf('Symlinking from %s', $url), false);
15690 $fileSystem->symlink($shortestPath, $path);
15691 }
15692 } catch (IOException $e) {
15693 if (in_array(self::STRATEGY_MIRROR, $allowedStrategies)) {
15694 $this->io->writeError('');
15695 $this->io->writeError('    <error>Symlink failed, fallback to use mirroring!</error>');
15696 $currentStrategy = self::STRATEGY_MIRROR;
15697 $isFallback = true;
15698 } else {
15699 throw new \RuntimeException(sprintf('Symlink from "%s" to "%s" failed!', $realUrl, $path));
15700 }
15701 }
15702 }
15703
15704
15705  if (self::STRATEGY_MIRROR == $currentStrategy) {
15706 $this->io->writeError(sprintf('%sMirroring from %s', $isFallback ? '    ' : '', $url), false);
15707 $fileSystem->mirror($realUrl, $path);
15708 }
15709
15710 $this->io->writeError('');
15711 }
15712
15713
15714
15715
15716 public function remove(PackageInterface $package, $path, $output = true)
15717 {
15718
15719
15720
15721
15722
15723 if (Platform::isWindows() && $this->filesystem->isJunction($path)) {
15724 if ($output) {
15725 $this->io->writeError("  - Removing junction for <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>)");
15726 }
15727 if (!$this->filesystem->removeJunction($path)) {
15728 $this->io->writeError("    <warn>Could not remove junction at " . $path . " - is another process locking it?</warn>");
15729 throw new \RuntimeException('Could not reliably remove junction for package ' . $package->getName());
15730 }
15731 } else {
15732 parent::remove($package, $path, $output);
15733 }
15734 }
15735
15736
15737
15738
15739 public function getVcsReference(PackageInterface $package, $path)
15740 {
15741 $parser = new VersionParser;
15742 $guesser = new VersionGuesser($this->config, new ProcessExecutor($this->io), $parser);
15743 $dumper = new ArrayDumper;
15744
15745 $packageConfig = $dumper->dump($package);
15746 if ($packageVersion = $guesser->guessVersion($packageConfig, $path)) {
15747 return $packageVersion['commit'];
15748 }
15749 }
15750 }
15751 <?php
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763 namespace Composer\Downloader;
15764
15765 use Composer\Util\Filesystem;
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776 class PearPackageExtractor
15777 {
15778 private static $rolesWithoutPackageNamePrefix = array('php', 'script', 'www');
15779
15780 private $filesystem;
15781 private $file;
15782
15783 public function __construct($file)
15784 {
15785 if (!is_file($file)) {
15786 throw new \UnexpectedValueException('PEAR package file is not found at '.$file);
15787 }
15788
15789 $this->filesystem = new Filesystem();
15790 $this->file = $file;
15791 }
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802 public function extractTo($target, array $roles = array('php' => '/', 'script' => '/bin'), $vars = array())
15803 {
15804 $extractionPath = $target.'/tarball';
15805
15806 try {
15807 $archive = new \PharData($this->file);
15808 $archive->extractTo($extractionPath, null, true);
15809
15810 if (!is_file($this->combine($extractionPath, '/package.xml'))) {
15811 throw new \RuntimeException('Invalid PEAR package. It must contain package.xml file.');
15812 }
15813
15814 $fileCopyActions = $this->buildCopyActions($extractionPath, $roles, $vars);
15815 $this->copyFiles($fileCopyActions, $extractionPath, $target, $roles, $vars);
15816 $this->filesystem->removeDirectory($extractionPath);
15817 } catch (\Exception $exception) {
15818 throw new \UnexpectedValueException(sprintf('Failed to extract PEAR package %s to %s. Reason: %s', $this->file, $target, $exception->getMessage()), 0, $exception);
15819 }
15820 }
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831 private function copyFiles($files, $source, $target, $roles, $vars)
15832 {
15833 foreach ($files as $file) {
15834 $from = $this->combine($source, $file['from']);
15835 $to = $this->combine($target, $roles[$file['role']]);
15836 $to = $this->combine($to, $file['to']);
15837 $tasks = $file['tasks'];
15838 $this->copyFile($from, $to, $tasks, $vars);
15839 }
15840 }
15841
15842 private function copyFile($from, $to, $tasks, $vars)
15843 {
15844 if (!is_file($from)) {
15845 throw new \RuntimeException('Invalid PEAR package. package.xml defines file that is not located inside tarball.');
15846 }
15847
15848 $this->filesystem->ensureDirectoryExists(dirname($to));
15849
15850 if (0 == count($tasks)) {
15851 $copied = copy($from, $to);
15852 } else {
15853 $content = file_get_contents($from);
15854 $replacements = array();
15855 foreach ($tasks as $task) {
15856 $pattern = $task['from'];
15857 $varName = $task['to'];
15858 if (isset($vars[$varName])) {
15859 if ($varName === 'php_bin' && false === strpos($to, '.bat')) {
15860 $replacements[$pattern] = preg_replace('{\.bat$}', '', $vars[$varName]);
15861 } else {
15862 $replacements[$pattern] = $vars[$varName];
15863 }
15864 }
15865 }
15866 $content = strtr($content, $replacements);
15867
15868 $copied = file_put_contents($to, $content);
15869 }
15870
15871 if (false === $copied) {
15872 throw new \RuntimeException(sprintf('Failed to copy %s to %s', $from, $to));
15873 }
15874 }
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886 private function buildCopyActions($source, array $roles, $vars)
15887 {
15888
15889 $package = simplexml_load_string(file_get_contents($this->combine($source, 'package.xml')));
15890 if (false === $package) {
15891 throw new \RuntimeException('Package definition file is not valid.');
15892 }
15893
15894 $packageSchemaVersion = $package['version'];
15895 if ('1.0' == $packageSchemaVersion) {
15896 $children = $package->release->filelist->children();
15897 $packageName = (string) $package->name;
15898 $packageVersion = (string) $package->release->version;
15899 $sourceDir = $packageName . '-' . $packageVersion;
15900 $result = $this->buildSourceList10($children, $roles, $sourceDir, '', null, $packageName);
15901 } elseif ('2.0' == $packageSchemaVersion || '2.1' == $packageSchemaVersion) {
15902 $children = $package->contents->children();
15903 $packageName = (string) $package->name;
15904 $packageVersion = (string) $package->version->release;
15905 $sourceDir = $packageName . '-' . $packageVersion;
15906 $result = $this->buildSourceList20($children, $roles, $sourceDir, '', null, $packageName);
15907
15908 $namespaces = $package->getNamespaces();
15909 $package->registerXPathNamespace('ns', $namespaces['']);
15910 $releaseNodes = $package->xpath('ns:phprelease');
15911 $this->applyRelease($result, $releaseNodes, $vars);
15912 } else {
15913 throw new \RuntimeException('Unsupported schema version of package definition file.');
15914 }
15915
15916 return $result;
15917 }
15918
15919 private function applyRelease(&$actions, $releaseNodes, $vars)
15920 {
15921 foreach ($releaseNodes as $releaseNode) {
15922 $requiredOs = $releaseNode->installconditions && $releaseNode->installconditions->os && $releaseNode->installconditions->os->name ? (string) $releaseNode->installconditions->os->name : '';
15923 if ($requiredOs && $vars['os'] != $requiredOs) {
15924 continue;
15925 }
15926
15927 if ($releaseNode->filelist) {
15928 foreach ($releaseNode->filelist->children() as $action) {
15929 if ('install' == $action->getName()) {
15930 $name = (string) $action['name'];
15931 $as = (string) $action['as'];
15932 if (isset($actions[$name])) {
15933 $actions[$name]['to'] = $as;
15934 }
15935 } elseif ('ignore' == $action->getName()) {
15936 $name = (string) $action['name'];
15937 unset($actions[$name]);
15938 } else {
15939
15940  }
15941 }
15942 }
15943 break;
15944 }
15945 }
15946
15947 private function buildSourceList10($children, $targetRoles, $source, $target, $role, $packageName)
15948 {
15949 $result = array();
15950
15951
15952  foreach ($children as $child) {
15953
15954 if ($child->getName() == 'dir') {
15955 $dirSource = $this->combine($source, (string) $child['name']);
15956 $dirTarget = $child['baseinstalldir'] ?: $target;
15957 $dirRole = $child['role'] ?: $role;
15958 $dirFiles = $this->buildSourceList10($child->children(), $targetRoles, $dirSource, $dirTarget, $dirRole, $packageName);
15959 $result = array_merge($result, $dirFiles);
15960 } elseif ($child->getName() == 'file') {
15961 $fileRole = (string) $child['role'] ?: $role;
15962 if (isset($targetRoles[$fileRole])) {
15963 $fileName = (string) ($child['name'] ?: $child[0]); 
15964  $fileSource = $this->combine($source, $fileName);
15965 $fileTarget = $this->combine((string) $child['baseinstalldir'] ?: $target, $fileName);
15966 if (!in_array($fileRole, self::$rolesWithoutPackageNamePrefix)) {
15967 $fileTarget = $packageName . '/' . $fileTarget;
15968 }
15969 $result[(string) $child['name']] = array('from' => $fileSource, 'to' => $fileTarget, 'role' => $fileRole, 'tasks' => array());
15970 }
15971 }
15972 }
15973
15974 return $result;
15975 }
15976
15977 private function buildSourceList20($children, $targetRoles, $source, $target, $role, $packageName)
15978 {
15979 $result = array();
15980
15981
15982  foreach ($children as $child) {
15983
15984 if ('dir' == $child->getName()) {
15985 $dirSource = $this->combine($source, $child['name']);
15986 $dirTarget = $child['baseinstalldir'] ?: $target;
15987 $dirRole = $child['role'] ?: $role;
15988 $dirFiles = $this->buildSourceList20($child->children(), $targetRoles, $dirSource, $dirTarget, $dirRole, $packageName);
15989 $result = array_merge($result, $dirFiles);
15990 } elseif ('file' == $child->getName()) {
15991 $fileRole = (string) $child['role'] ?: $role;
15992 if (isset($targetRoles[$fileRole])) {
15993 $fileSource = $this->combine($source, (string) $child['name']);
15994 $fileTarget = $this->combine((string) ($child['baseinstalldir'] ?: $target), (string) $child['name']);
15995 $fileTasks = array();
15996 foreach ($child->children('http://pear.php.net/dtd/tasks-1.0') as $taskNode) {
15997 if ('replace' == $taskNode->getName()) {
15998 $fileTasks[] = array('from' => (string) $taskNode->attributes()->from, 'to' => (string) $taskNode->attributes()->to);
15999 }
16000 }
16001 if (!in_array($fileRole, self::$rolesWithoutPackageNamePrefix)) {
16002 $fileTarget = $packageName . '/' . $fileTarget;
16003 }
16004 $result[(string) $child['name']] = array('from' => $fileSource, 'to' => $fileTarget, 'role' => $fileRole, 'tasks' => $fileTasks);
16005 }
16006 }
16007 }
16008
16009 return $result;
16010 }
16011
16012 private function combine($left, $right)
16013 {
16014 return rtrim($left, '/') . '/' . ltrim($right, '/');
16015 }
16016 }
16017 <?php
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029 namespace Composer\Downloader;
16030
16031 use Composer\Package\PackageInterface;
16032 use Composer\Repository\VcsRepository;
16033 use Composer\Util\Perforce;
16034
16035
16036
16037
16038 class PerforceDownloader extends VcsDownloader
16039 {
16040
16041 protected $perforce;
16042
16043
16044
16045
16046 public function doDownload(PackageInterface $package, $path, $url)
16047 {
16048 $ref = $package->getSourceReference();
16049 $label = $this->getLabelFromSourceReference($ref);
16050
16051 $this->io->writeError('Cloning ' . $ref);
16052 $this->initPerforce($package, $path, $url);
16053 $this->perforce->setStream($ref);
16054 $this->perforce->p4Login();
16055 $this->perforce->writeP4ClientSpec();
16056 $this->perforce->connectClient();
16057 $this->perforce->syncCodeBase($label);
16058 $this->perforce->cleanupClientSpec();
16059 }
16060
16061 private function getLabelFromSourceReference($ref)
16062 {
16063 $pos = strpos($ref, '@');
16064 if (false !== $pos) {
16065 return substr($ref, $pos + 1);
16066 }
16067
16068 return null;
16069 }
16070
16071 public function initPerforce(PackageInterface $package, $path, $url)
16072 {
16073 if (!empty($this->perforce)) {
16074 $this->perforce->initializePath($path);
16075
16076 return;
16077 }
16078
16079 $repository = $package->getRepository();
16080 $repoConfig = null;
16081 if ($repository instanceof VcsRepository) {
16082 $repoConfig = $this->getRepoConfig($repository);
16083 }
16084 $this->perforce = Perforce::create($repoConfig, $url, $path, $this->process, $this->io);
16085 }
16086
16087 private function getRepoConfig(VcsRepository $repository)
16088 {
16089 return $repository->getRepoConfig();
16090 }
16091
16092
16093
16094
16095 public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
16096 {
16097 $this->doDownload($target, $path, $url);
16098 }
16099
16100
16101
16102
16103 public function getLocalChanges(PackageInterface $package, $path)
16104 {
16105 $this->io->writeError('Perforce driver does not check for local changes before overriding', true);
16106
16107 return;
16108 }
16109
16110
16111
16112
16113 protected function getCommitLogs($fromReference, $toReference, $path)
16114 {
16115 $commitLogs = $this->perforce->getCommitLogs($fromReference, $toReference);
16116
16117 return $commitLogs;
16118 }
16119
16120 public function setPerforce($perforce)
16121 {
16122 $this->perforce = $perforce;
16123 }
16124
16125
16126
16127
16128 protected function hasMetadataRepository($path)
16129 {
16130 return true;
16131 }
16132 }
16133 <?php
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145 namespace Composer\Downloader;
16146
16147
16148
16149
16150
16151
16152 class PharDownloader extends ArchiveDownloader
16153 {
16154
16155
16156
16157 protected function extract($file, $path)
16158 {
16159
16160  $archive = new \Phar($file);
16161 $archive->extractTo($path, null, true);
16162
16163
16164
16165
16166
16167 }
16168 }
16169 <?php
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181 namespace Composer\Downloader;
16182
16183 use Composer\Config;
16184 use Composer\Cache;
16185 use Composer\EventDispatcher\EventDispatcher;
16186 use Composer\Util\IniHelper;
16187 use Composer\Util\Platform;
16188 use Composer\Util\ProcessExecutor;
16189 use Composer\Util\RemoteFilesystem;
16190 use Composer\IO\IOInterface;
16191 use RarArchive;
16192
16193
16194
16195
16196
16197
16198
16199
16200 class RarDownloader extends ArchiveDownloader
16201 {
16202 protected $process;
16203
16204 public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, RemoteFilesystem $rfs = null)
16205 {
16206 $this->process = $process ?: new ProcessExecutor($io);
16207 parent::__construct($io, $config, $eventDispatcher, $cache, $rfs);
16208 }
16209
16210 protected function extract($file, $path)
16211 {
16212 $processError = null;
16213
16214
16215  if (!Platform::isWindows()) {
16216 $command = 'unrar x ' . ProcessExecutor::escape($file) . ' ' . ProcessExecutor::escape($path) . ' >/dev/null && chmod -R u+w ' . ProcessExecutor::escape($path);
16217
16218 if (0 === $this->process->execute($command, $ignoredOutput)) {
16219 return;
16220 }
16221
16222 $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput();
16223 }
16224
16225 if (!class_exists('RarArchive')) {
16226
16227  $iniMessage = IniHelper::getMessage();
16228
16229 $error = "Could not decompress the archive, enable the PHP rar extension or install unrar.\n"
16230 . $iniMessage . "\n" . $processError;
16231
16232 if (!Platform::isWindows()) {
16233 $error = "Could not decompress the archive, enable the PHP rar extension.\n" . $iniMessage;
16234 }
16235
16236 throw new \RuntimeException($error);
16237 }
16238
16239 $rarArchive = RarArchive::open($file);
16240
16241 if (false === $rarArchive) {
16242 throw new \UnexpectedValueException('Could not open RAR archive: ' . $file);
16243 }
16244
16245 $entries = $rarArchive->getEntries();
16246
16247 if (false === $entries) {
16248 throw new \RuntimeException('Could not retrieve RAR archive entries');
16249 }
16250
16251 foreach ($entries as $entry) {
16252 if (false === $entry->extract($path)) {
16253 throw new \RuntimeException('Could not extract entry');
16254 }
16255 }
16256
16257 $rarArchive->close();
16258 }
16259 }
16260 <?php
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272 namespace Composer\Downloader;
16273
16274 use Composer\Package\PackageInterface;
16275 use Composer\Util\Svn as SvnUtil;
16276 use Composer\Repository\VcsRepository;
16277
16278
16279
16280
16281
16282 class SvnDownloader extends VcsDownloader
16283 {
16284 protected $cacheCredentials = true;
16285
16286
16287
16288
16289 public function doDownload(PackageInterface $package, $path, $url)
16290 {
16291 SvnUtil::cleanEnv();
16292 $ref = $package->getSourceReference();
16293
16294 $repo = $package->getRepository();
16295 if ($repo instanceof VcsRepository) {
16296 $repoConfig = $repo->getRepoConfig();
16297 if (array_key_exists('svn-cache-credentials', $repoConfig)) {
16298 $this->cacheCredentials = (bool) $repoConfig['svn-cache-credentials'];
16299 }
16300 }
16301
16302 $this->io->writeError(" Checking out ".$package->getSourceReference());
16303 $this->execute($url, "svn co", sprintf("%s/%s", $url, $ref), null, $path);
16304 }
16305
16306
16307
16308
16309 public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
16310 {
16311 SvnUtil::cleanEnv();
16312 $ref = $target->getSourceReference();
16313
16314 if (!$this->hasMetadataRepository($path)) {
16315 throw new \RuntimeException('The .svn directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
16316 }
16317
16318 $flags = "";
16319 if (0 === $this->process->execute('svn --version', $output)) {
16320 if (preg_match('{(\d+(?:\.\d+)+)}', $output, $match) && version_compare($match[1], '1.7.0', '>=')) {
16321 $flags .= ' --ignore-ancestry';
16322 }
16323 }
16324
16325 $this->io->writeError(" Checking out " . $ref);
16326 $this->execute($url, "svn switch" . $flags, sprintf("%s/%s", $url, $ref), $path);
16327 }
16328
16329
16330
16331
16332 public function getLocalChanges(PackageInterface $package, $path)
16333 {
16334 if (!$this->hasMetadataRepository($path)) {
16335 return null;
16336 }
16337
16338 $this->process->execute('svn status --ignore-externals', $output, $path);
16339
16340 return preg_match('{^ *[^X ] +}m', $output) ? $output : null;
16341 }
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355 protected function execute($baseUrl, $command, $url, $cwd = null, $path = null)
16356 {
16357 $util = new SvnUtil($baseUrl, $this->io, $this->config);
16358 $util->setCacheCredentials($this->cacheCredentials);
16359 try {
16360 return $util->execute($command, $url, $cwd, $path, $this->io->isVerbose());
16361 } catch (\RuntimeException $e) {
16362 throw new \RuntimeException(
16363 'Package could not be downloaded, '.$e->getMessage()
16364 );
16365 }
16366 }
16367
16368
16369
16370
16371 protected function cleanChanges(PackageInterface $package, $path, $update)
16372 {
16373 if (!$changes = $this->getLocalChanges($package, $path)) {
16374 return;
16375 }
16376
16377 if (!$this->io->isInteractive()) {
16378 if (true === $this->config->get('discard-changes')) {
16379 return $this->discardChanges($path);
16380 }
16381
16382 return parent::cleanChanges($package, $path, $update);
16383 }
16384
16385 $changes = array_map(function ($elem) {
16386 return '    '.$elem;
16387 }, preg_split('{\s*\r?\n\s*}', $changes));
16388 $this->io->writeError('    <error>The package has modified files:</error>');
16389 $this->io->writeError(array_slice($changes, 0, 10));
16390 if (count($changes) > 10) {
16391 $this->io->writeError('    <info>'.count($changes) - 10 . ' more files modified, choose "v" to view the full list</info>');
16392 }
16393
16394 while (true) {
16395 switch ($this->io->ask('    <info>Discard changes [y,n,v,?]?</info> ', '?')) {
16396 case 'y':
16397 $this->discardChanges($path);
16398 break 2;
16399
16400 case 'n':
16401 throw new \RuntimeException('Update aborted');
16402
16403 case 'v':
16404 $this->io->writeError($changes);
16405 break;
16406
16407 case '?':
16408 default:
16409 $this->io->writeError(array(
16410 '    y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
16411 '    n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
16412 '    v - view modified files',
16413 '    ? - print help',
16414 ));
16415 break;
16416 }
16417 }
16418 }
16419
16420
16421
16422
16423 protected function getCommitLogs($fromReference, $toReference, $path)
16424 {
16425 if (preg_match('{.*@(\d+)$}', $fromReference) && preg_match('{.*@(\d+)$}', $toReference)) {
16426
16427  $fromRevision = preg_replace('{.*@(\d+)$}', '$1', $fromReference);
16428 $toRevision = preg_replace('{.*@(\d+)$}', '$1', $toReference);
16429
16430 $command = sprintf('svn log -r%s:%s --incremental', $fromRevision, $toRevision);
16431
16432 if (0 !== $this->process->execute($command, $output, $path)) {
16433 throw new \RuntimeException(
16434 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()
16435 );
16436 }
16437 } else {
16438 $output = "Could not retrieve changes between $fromReference and $toReference due to missing revision information";
16439 }
16440
16441 return $output;
16442 }
16443
16444 protected function discardChanges($path)
16445 {
16446 if (0 !== $this->process->execute('svn revert -R .', $output, $path)) {
16447 throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
16448 }
16449 }
16450
16451
16452
16453
16454 protected function hasMetadataRepository($path)
16455 {
16456 return is_dir($path.'/.svn');
16457 }
16458 }
16459 <?php
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471 namespace Composer\Downloader;
16472
16473
16474
16475
16476
16477
16478 class TarDownloader extends ArchiveDownloader
16479 {
16480
16481
16482
16483 protected function extract($file, $path)
16484 {
16485
16486  $archive = new \PharData($file);
16487 $archive->extractTo($path, null, true);
16488 }
16489 }
16490 <?php
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502 namespace Composer\Downloader;
16503
16504
16505
16506
16507 class TransportException extends \RuntimeException
16508 {
16509 protected $headers;
16510 protected $response;
16511 protected $statusCode;
16512
16513 public function setHeaders($headers)
16514 {
16515 $this->headers = $headers;
16516 }
16517
16518 public function getHeaders()
16519 {
16520 return $this->headers;
16521 }
16522
16523 public function setResponse($response)
16524 {
16525 $this->response = $response;
16526 }
16527
16528 public function getResponse()
16529 {
16530 return $this->response;
16531 }
16532
16533 public function setStatusCode($statusCode)
16534 {
16535 $this->statusCode = $statusCode;
16536 }
16537
16538 public function getStatusCode()
16539 {
16540 return $this->statusCode;
16541 }
16542 }
16543 <?php
16544
16545
16546
16547
16548
16549
16550
16551
16552
16553
16554
16555 namespace Composer\Downloader;
16556
16557 use Composer\Package\PackageInterface;
16558
16559
16560
16561
16562
16563
16564 interface VcsCapableDownloaderInterface
16565 {
16566
16567
16568
16569
16570
16571
16572
16573 public function getVcsReference(PackageInterface $package, $path);
16574 }
16575 <?php
16576
16577
16578
16579
16580
16581
16582
16583
16584
16585
16586
16587 namespace Composer\Downloader;
16588
16589 use Composer\Config;
16590 use Composer\Package\Dumper\ArrayDumper;
16591 use Composer\Package\PackageInterface;
16592 use Composer\Package\Version\VersionGuesser;
16593 use Composer\Package\Version\VersionParser;
16594 use Composer\Util\ProcessExecutor;
16595 use Composer\IO\IOInterface;
16596 use Composer\Util\Filesystem;
16597
16598
16599
16600
16601 abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterface, VcsCapableDownloaderInterface
16602 {
16603
16604 protected $io;
16605
16606 protected $config;
16607
16608 protected $process;
16609
16610 protected $filesystem;
16611
16612 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
16613 {
16614 $this->io = $io;
16615 $this->config = $config;
16616 $this->process = $process ?: new ProcessExecutor($io);
16617 $this->filesystem = $fs ?: new Filesystem($this->process);
16618 }
16619
16620
16621
16622
16623 public function getInstallationSource()
16624 {
16625 return 'source';
16626 }
16627
16628
16629
16630
16631 public function download(PackageInterface $package, $path)
16632 {
16633 if (!$package->getSourceReference()) {
16634 throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
16635 }
16636
16637 $this->io->writeError("  - Installing <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>): ", false);
16638 $this->filesystem->emptyDirectory($path);
16639
16640 $urls = $package->getSourceUrls();
16641 while ($url = array_shift($urls)) {
16642 try {
16643 if (Filesystem::isLocalPath($url)) {
16644
16645  
16646  $needle = 'file://';
16647 $isFileProtocol = false;
16648 if (0 === strpos($url, $needle)) {
16649 $url = substr($url, strlen($needle));
16650 $isFileProtocol = true;
16651 }
16652
16653
16654  if (false !== strpos($url, '%')) {
16655 $url = rawurldecode($url);
16656 }
16657
16658 $url = realpath($url);
16659
16660 if ($isFileProtocol) {
16661 $url = $needle . $url;
16662 }
16663 }
16664 $this->doDownload($package, $path, $url);
16665 break;
16666 } catch (\Exception $e) {
16667
16668  if ($e instanceof \PHPUnit_Framework_Exception) {
16669 throw $e;
16670 }
16671 if ($this->io->isDebug()) {
16672 $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage());
16673 } elseif (count($urls)) {
16674 $this->io->writeError('    Failed, trying the next URL');
16675 }
16676 if (!count($urls)) {
16677 throw $e;
16678 }
16679 }
16680 }
16681 }
16682
16683
16684
16685
16686 public function update(PackageInterface $initial, PackageInterface $target, $path)
16687 {
16688 if (!$target->getSourceReference()) {
16689 throw new \InvalidArgumentException('Package '.$target->getPrettyName().' is missing reference information');
16690 }
16691
16692 $name = $target->getName();
16693 if ($initial->getPrettyVersion() == $target->getPrettyVersion()) {
16694 if ($target->getSourceType() === 'svn') {
16695 $from = $initial->getSourceReference();
16696 $to = $target->getSourceReference();
16697 } else {
16698 $from = substr($initial->getSourceReference(), 0, 7);
16699 $to = substr($target->getSourceReference(), 0, 7);
16700 }
16701 $name .= ' '.$initial->getPrettyVersion();
16702 } else {
16703 $from = $initial->getFullPrettyVersion();
16704 $to = $target->getFullPrettyVersion();
16705 }
16706
16707 $this->io->writeError("  - Updating <info>" . $name . "</info> (<comment>" . $from . "</comment> => <comment>" . $to . "</comment>): ", false);
16708
16709 $this->cleanChanges($initial, $path, true);
16710 $urls = $target->getSourceUrls();
16711
16712 $exception = null;
16713 while ($url = array_shift($urls)) {
16714 try {
16715 if (Filesystem::isLocalPath($url)) {
16716 $url = realpath($url);
16717 }
16718 $this->doUpdate($initial, $target, $path, $url);
16719
16720 $exception = null;
16721 break;
16722 } catch (\Exception $exception) {
16723
16724  if ($exception instanceof \PHPUnit_Framework_Exception) {
16725 throw $exception;
16726 }
16727 if ($this->io->isDebug()) {
16728 $this->io->writeError('Failed: ['.get_class($exception).'] '.$exception->getMessage());
16729 } elseif (count($urls)) {
16730 $this->io->writeError('    Failed, trying the next URL');
16731 }
16732 }
16733 }
16734
16735 $this->reapplyChanges($path);
16736
16737
16738  
16739  if (!$exception && $this->io->isVerbose() && $this->hasMetadataRepository($path)) {
16740 $message = 'Pulling in changes:';
16741 $logs = $this->getCommitLogs($initial->getSourceReference(), $target->getSourceReference(), $path);
16742
16743 if (!trim($logs)) {
16744 $message = 'Rolling back changes:';
16745 $logs = $this->getCommitLogs($target->getSourceReference(), $initial->getSourceReference(), $path);
16746 }
16747
16748 if (trim($logs)) {
16749 $logs = implode("\n", array_map(function ($line) {
16750 return '      ' . $line;
16751 }, explode("\n", $logs)));
16752
16753
16754  $logs = str_replace('<', '\<', $logs);
16755
16756 $this->io->writeError('    '.$message);
16757 $this->io->writeError($logs);
16758 }
16759 }
16760
16761 if (!$urls && $exception) {
16762 throw $exception;
16763 }
16764 }
16765
16766
16767
16768
16769 public function remove(PackageInterface $package, $path)
16770 {
16771 $this->io->writeError("  - Removing <info>" . $package->getName() . "</info> (<comment>" . $package->getPrettyVersion() . "</comment>)");
16772 $this->cleanChanges($package, $path, false);
16773 if (!$this->filesystem->removeDirectory($path)) {
16774 throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
16775 }
16776 }
16777
16778
16779
16780
16781
16782 public function setOutputProgress($outputProgress)
16783 {
16784 return $this;
16785 }
16786
16787
16788
16789
16790 public function getVcsReference(PackageInterface $package, $path)
16791 {
16792 $parser = new VersionParser;
16793 $guesser = new VersionGuesser($this->config, $this->process, $parser);
16794 $dumper = new ArrayDumper;
16795
16796 $packageConfig = $dumper->dump($package);
16797 if ($packageVersion = $guesser->guessVersion($packageConfig, $path)) {
16798 return $packageVersion['commit'];
16799 }
16800 }
16801
16802
16803
16804
16805
16806
16807
16808
16809
16810
16811 protected function cleanChanges(PackageInterface $package, $path, $update)
16812 {
16813
16814  if (null !== $this->getLocalChanges($package, $path)) {
16815 throw new \RuntimeException('Source directory ' . $path . ' has uncommitted changes.');
16816 }
16817 }
16818
16819
16820
16821
16822
16823
16824
16825 protected function reapplyChanges($path)
16826 {
16827 }
16828
16829
16830
16831
16832
16833
16834
16835
16836 abstract protected function doDownload(PackageInterface $package, $path, $url);
16837
16838
16839
16840
16841
16842
16843
16844
16845
16846 abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url);
16847
16848
16849
16850
16851
16852
16853
16854
16855
16856 abstract protected function getCommitLogs($fromReference, $toReference, $path);
16857
16858
16859
16860
16861
16862
16863
16864
16865 abstract protected function hasMetadataRepository($path);
16866 }
16867 <?php
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879 namespace Composer\Downloader;
16880
16881 use Composer\Config;
16882 use Composer\Cache;
16883 use Composer\EventDispatcher\EventDispatcher;
16884 use Composer\Package\PackageInterface;
16885 use Composer\Util\ProcessExecutor;
16886 use Composer\Util\RemoteFilesystem;
16887 use Composer\IO\IOInterface;
16888
16889
16890
16891
16892
16893
16894
16895 class XzDownloader extends ArchiveDownloader
16896 {
16897 protected $process;
16898
16899 public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, RemoteFilesystem $rfs = null)
16900 {
16901 $this->process = $process ?: new ProcessExecutor($io);
16902
16903 parent::__construct($io, $config, $eventDispatcher, $cache, $rfs);
16904 }
16905
16906 protected function extract($file, $path)
16907 {
16908 $command = 'tar -xJf ' . ProcessExecutor::escape($file) . ' -C ' . ProcessExecutor::escape($path);
16909
16910 if (0 === $this->process->execute($command, $ignoredOutput)) {
16911 return;
16912 }
16913
16914 $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput();
16915
16916 throw new \RuntimeException($processError);
16917 }
16918
16919
16920
16921
16922 protected function getFileName(PackageInterface $package, $path)
16923 {
16924 return $path.'/'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_BASENAME);
16925 }
16926 }
16927 <?php
16928
16929
16930
16931
16932
16933
16934
16935
16936
16937
16938
16939 namespace Composer\Downloader;
16940
16941 use Composer\Config;
16942 use Composer\Cache;
16943 use Composer\EventDispatcher\EventDispatcher;
16944 use Composer\Package\PackageInterface;
16945 use Composer\Util\IniHelper;
16946 use Composer\Util\Platform;
16947 use Composer\Util\ProcessExecutor;
16948 use Composer\Util\RemoteFilesystem;
16949 use Composer\IO\IOInterface;
16950 use Symfony\Component\Process\ExecutableFinder;
16951 use ZipArchive;
16952
16953
16954
16955
16956 class ZipDownloader extends ArchiveDownloader
16957 {
16958 protected $process;
16959 protected static $hasSystemUnzip;
16960
16961 public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, RemoteFilesystem $rfs = null)
16962 {
16963 $this->process = $process ?: new ProcessExecutor($io);
16964 parent::__construct($io, $config, $eventDispatcher, $cache, $rfs);
16965 }
16966
16967
16968
16969
16970 public function download(PackageInterface $package, $path, $output = true)
16971 {
16972 if (null === self::$hasSystemUnzip) {
16973 $finder = new ExecutableFinder;
16974 self::$hasSystemUnzip = (bool) $finder->find('unzip');
16975 }
16976
16977 if (!class_exists('ZipArchive') && !self::$hasSystemUnzip) {
16978
16979  $iniMessage = IniHelper::getMessage();
16980 $error = "The zip extension and unzip command are both missing, skipping.\n" . $iniMessage;
16981
16982 throw new \RuntimeException($error);
16983 }
16984
16985 return parent::download($package, $path, $output);
16986 }
16987
16988 protected function extract($file, $path)
16989 {
16990 $processError = null;
16991
16992 if (self::$hasSystemUnzip && !(class_exists('ZipArchive') && Platform::isWindows())) {
16993 $command = 'unzip -qq '.ProcessExecutor::escape($file).' -d '.ProcessExecutor::escape($path);
16994 if (!Platform::isWindows()) {
16995 $command .= ' && chmod -R u+w ' . ProcessExecutor::escape($path);
16996 }
16997
16998 try {
16999 if (0 === $this->process->execute($command, $ignoredOutput)) {
17000 return;
17001 }
17002
17003 $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput();
17004 } catch (\Exception $e) {
17005 $processError = 'Failed to execute ' . $command . "\n\n" . $e->getMessage();
17006 }
17007
17008 if (!class_exists('ZipArchive')) {
17009 throw new \RuntimeException($processError);
17010 }
17011 }
17012
17013 $zipArchive = new ZipArchive();
17014
17015 if (true !== ($retval = $zipArchive->open($file))) {
17016 throw new \UnexpectedValueException(rtrim($this->getErrorMessage($retval, $file)."\n".$processError), $retval);
17017 }
17018
17019 if (true !== $zipArchive->extractTo($path)) {
17020 throw new \RuntimeException(rtrim("There was an error extracting the ZIP file, it is either corrupted or using an invalid format.\n".$processError));
17021 }
17022
17023 $zipArchive->close();
17024 }
17025
17026
17027
17028
17029
17030
17031
17032
17033 protected function getErrorMessage($retval, $file)
17034 {
17035 switch ($retval) {
17036 case ZipArchive::ER_EXISTS:
17037 return sprintf("File '%s' already exists.", $file);
17038 case ZipArchive::ER_INCONS:
17039 return sprintf("Zip archive '%s' is inconsistent.", $file);
17040 case ZipArchive::ER_INVAL:
17041 return sprintf("Invalid argument (%s)", $file);
17042 case ZipArchive::ER_MEMORY:
17043 return sprintf("Malloc failure (%s)", $file);
17044 case ZipArchive::ER_NOENT:
17045 return sprintf("No such zip file: '%s'", $file);
17046 case ZipArchive::ER_NOZIP:
17047 return sprintf("'%s' is not a zip archive.", $file);
17048 case ZipArchive::ER_OPEN:
17049 return sprintf("Can't open zip file: %s", $file);
17050 case ZipArchive::ER_READ:
17051 return sprintf("Zip read error (%s)", $file);
17052 case ZipArchive::ER_SEEK:
17053 return sprintf("Zip seek error (%s)", $file);
17054 default:
17055 return sprintf("'%s' is not a valid zip archive, got error code: %s", $file, $retval);
17056 }
17057 }
17058 }
17059 <?php
17060
17061
17062
17063
17064
17065
17066
17067
17068
17069
17070
17071 namespace Composer\EventDispatcher;
17072
17073
17074
17075
17076
17077
17078 class Event
17079 {
17080
17081
17082
17083 protected $name;
17084
17085
17086
17087
17088 protected $args;
17089
17090
17091
17092
17093 protected $flags;
17094
17095
17096
17097
17098 private $propagationStopped = false;
17099
17100
17101
17102
17103
17104
17105
17106
17107 public function __construct($name, array $args = array(), array $flags = array())
17108 {
17109 $this->name = $name;
17110 $this->args = $args;
17111 $this->flags = $flags;
17112 }
17113
17114
17115
17116
17117
17118
17119 public function getName()
17120 {
17121 return $this->name;
17122 }
17123
17124
17125
17126
17127
17128
17129 public function getArguments()
17130 {
17131 return $this->args;
17132 }
17133
17134
17135
17136
17137
17138
17139 public function getFlags()
17140 {
17141 return $this->flags;
17142 }
17143
17144
17145
17146
17147
17148
17149 public function isPropagationStopped()
17150 {
17151 return $this->propagationStopped;
17152 }
17153
17154
17155
17156
17157 public function stopPropagation()
17158 {
17159 $this->propagationStopped = true;
17160 }
17161 }
17162 <?php
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174 namespace Composer\EventDispatcher;
17175
17176 use Composer\DependencyResolver\PolicyInterface;
17177 use Composer\DependencyResolver\Pool;
17178 use Composer\DependencyResolver\Request;
17179 use Composer\Installer\InstallerEvent;
17180 use Composer\IO\IOInterface;
17181 use Composer\Composer;
17182 use Composer\DependencyResolver\Operation\OperationInterface;
17183 use Composer\Repository\CompositeRepository;
17184 use Composer\Script;
17185 use Composer\Installer\PackageEvent;
17186 use Composer\Installer\BinaryInstaller;
17187 use Composer\Util\ProcessExecutor;
17188 use Composer\Script\Event as ScriptEvent;
17189 use Symfony\Component\Process\PhpExecutableFinder;
17190
17191
17192
17193
17194
17195
17196
17197
17198
17199
17200
17201
17202
17203
17204 class EventDispatcher
17205 {
17206 protected $composer;
17207 protected $io;
17208 protected $loader;
17209 protected $process;
17210 protected $listeners;
17211 private $eventStack;
17212
17213
17214
17215
17216
17217
17218
17219
17220 public function __construct(Composer $composer, IOInterface $io, ProcessExecutor $process = null)
17221 {
17222 $this->composer = $composer;
17223 $this->io = $io;
17224 $this->process = $process ?: new ProcessExecutor($io);
17225 $this->eventStack = array();
17226 }
17227
17228
17229
17230
17231
17232
17233
17234
17235
17236 public function dispatch($eventName, Event $event = null)
17237 {
17238 if (null === $event) {
17239 $event = new Event($eventName);
17240 }
17241
17242 return $this->doDispatch($event);
17243 }
17244
17245
17246
17247
17248
17249
17250
17251
17252
17253
17254
17255 public function dispatchScript($eventName, $devMode = false, $additionalArgs = array(), $flags = array())
17256 {
17257 return $this->doDispatch(new Script\Event($eventName, $this->composer, $this->io, $devMode, $additionalArgs, $flags));
17258 }
17259
17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275 public function dispatchPackageEvent($eventName, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation)
17276 {
17277 return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $policy, $pool, $installedRepo, $request, $operations, $operation));
17278 }
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294 public function dispatchInstallerEvent($eventName, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
17295 {
17296 return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $policy, $pool, $installedRepo, $request, $operations));
17297 }
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307 protected function doDispatch(Event $event)
17308 {
17309 $pathStr = 'PATH';
17310 if (!isset($_SERVER[$pathStr]) && isset($_SERVER['Path'])) {
17311 $pathStr = 'Path';
17312 }
17313
17314
17315  $binDir = $this->composer->getConfig()->get('bin-dir');
17316 if (is_dir($binDir)) {
17317 $binDir = realpath($binDir);
17318 if (isset($_SERVER[$pathStr]) && !preg_match('{(^|'.PATH_SEPARATOR.')'.preg_quote($binDir).'($|'.PATH_SEPARATOR.')}', $_SERVER[$pathStr])) {
17319 $_SERVER[$pathStr] = $binDir.PATH_SEPARATOR.getenv($pathStr);
17320 putenv($pathStr.'='.$_SERVER[$pathStr]);
17321 }
17322 }
17323
17324 $listeners = $this->getListeners($event);
17325
17326 $this->pushEvent($event);
17327
17328 $return = 0;
17329 foreach ($listeners as $callable) {
17330 if (!is_string($callable) && is_callable($callable)) {
17331 $event = $this->checkListenerExpectedEvent($callable, $event);
17332 $return = false === call_user_func($callable, $event) ? 1 : 0;
17333 } elseif ($this->isComposerScript($callable)) {
17334 $this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable), true, IOInterface::VERBOSE);
17335 $scriptName = substr($callable, 1);
17336 $args = $event->getArguments();
17337 $flags = $event->getFlags();
17338 if (substr($callable, 0, 10) === '@composer ') {
17339 $exec = $this->getPhpExecCommand() . ' ' . ProcessExecutor::escape(getenv('COMPOSER_BINARY')) . substr($callable, 9);
17340 if (0 !== ($exitCode = $this->process->execute($exec))) {
17341 $this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()), true, IOInterface::QUIET);
17342
17343 throw new ScriptExecutionException('Error Output: '.$this->process->getErrorOutput(), $exitCode);
17344 }
17345 } else {
17346 if (!$this->getListeners(new Event($scriptName))) {
17347 $this->io->writeError(sprintf('<warning>You made a reference to a non-existent script %s</warning>', $callable), true, IOInterface::QUIET);
17348 }
17349
17350 $return = $this->dispatch($scriptName, new Script\Event($scriptName, $event->getComposer(), $event->getIO(), $event->isDevMode(), $args, $flags));
17351 }
17352 } elseif ($this->isPhpScript($callable)) {
17353 $className = substr($callable, 0, strpos($callable, '::'));
17354 $methodName = substr($callable, strpos($callable, '::') + 2);
17355
17356 if (!class_exists($className)) {
17357 $this->io->writeError('<warning>Class '.$className.' is not autoloadable, can not call '.$event->getName().' script</warning>', true, IOInterface::QUIET);
17358 continue;
17359 }
17360 if (!is_callable($callable)) {
17361 $this->io->writeError('<warning>Method '.$callable.' is not callable, can not call '.$event->getName().' script</warning>', true, IOInterface::QUIET);
17362 continue;
17363 }
17364
17365 try {
17366 $return = false === $this->executeEventPhpScript($className, $methodName, $event) ? 1 : 0;
17367 } catch (\Exception $e) {
17368 $message = "Script %s handling the %s event terminated with an exception";
17369 $this->io->writeError('<error>'.sprintf($message, $callable, $event->getName()).'</error>', true, IOInterface::QUIET);
17370 throw $e;
17371 }
17372 } else {
17373 $args = implode(' ', array_map(array('Composer\Util\ProcessExecutor', 'escape'), $event->getArguments()));
17374 $exec = $callable . ($args === '' ? '' : ' '.$args);
17375 if ($this->io->isVerbose()) {
17376 $this->io->writeError(sprintf('> %s: %s', $event->getName(), $exec));
17377 } else {
17378 $this->io->writeError(sprintf('> %s', $exec));
17379 }
17380
17381 $possibleLocalBinaries = $this->composer->getPackage()->getBinaries();
17382 if ($possibleLocalBinaries) {
17383 foreach ($possibleLocalBinaries as $localExec) {
17384 if (preg_match('{\b'.preg_quote($callable).'$}', $localExec)) {
17385 $caller = BinaryInstaller::determineBinaryCaller($localExec);
17386 $exec = preg_replace('{^'.preg_quote($callable).'}', $caller . ' ' . $localExec, $exec);
17387 break;
17388 }
17389 }
17390 }
17391
17392 if (substr($exec, 0, 5) === '@php ') {
17393 $exec = $this->getPhpExecCommand() . ' ' . substr($exec, 5);
17394 }
17395
17396 if (0 !== ($exitCode = $this->process->execute($exec))) {
17397 $this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()), true, IOInterface::QUIET);
17398
17399 throw new ScriptExecutionException('Error Output: '.$this->process->getErrorOutput(), $exitCode);
17400 }
17401 }
17402
17403 if ($event->isPropagationStopped()) {
17404 break;
17405 }
17406 }
17407
17408 $this->popEvent();
17409
17410 return $return;
17411 }
17412
17413 protected function getPhpExecCommand()
17414 {
17415 $finder = new PhpExecutableFinder();
17416 $phpPath = $finder->find();
17417 if (!$phpPath) {
17418 throw new \RuntimeException('Failed to locate PHP binary to execute '.$scriptName);
17419 }
17420
17421 $memoryFlag = ' -d memory_limit='.ini_get('memory_limit');
17422
17423 return ProcessExecutor::escape($phpPath) . $memoryFlag;
17424 }
17425
17426
17427
17428
17429
17430
17431 protected function executeEventPhpScript($className, $methodName, Event $event)
17432 {
17433 $event = $this->checkListenerExpectedEvent(array($className, $methodName), $event);
17434
17435 if ($this->io->isVerbose()) {
17436 $this->io->writeError(sprintf('> %s: %s::%s', $event->getName(), $className, $methodName));
17437 } else {
17438 $this->io->writeError(sprintf('> %s::%s', $className, $methodName));
17439 }
17440
17441 return $className::$methodName($event);
17442 }
17443
17444
17445
17446
17447
17448
17449 protected function checkListenerExpectedEvent($target, Event $event)
17450 {
17451 if (in_array($event->getName(), array(
17452 'init',
17453 'command',
17454 'pre-file-download',
17455 ), true)) {
17456 return $event;
17457 }
17458
17459 try {
17460 $reflected = new \ReflectionParameter($target, 0);
17461 } catch (\Exception $e) {
17462 return $event;
17463 }
17464
17465 $typehint = $reflected->getClass();
17466
17467 if (!$typehint instanceof \ReflectionClass) {
17468 return $event;
17469 }
17470
17471 $expected = $typehint->getName();
17472
17473
17474  if (!$event instanceof $expected && $expected === 'Composer\Script\CommandEvent') {
17475 trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED);
17476 $event = new \Composer\Script\CommandEvent(
17477 $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), $event->getArguments()
17478 );
17479 }
17480 if (!$event instanceof $expected && $expected === 'Composer\Script\PackageEvent') {
17481 trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED);
17482 $event = new \Composer\Script\PackageEvent(
17483 $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(),
17484 $event->getPolicy(), $event->getPool(), $event->getInstalledRepo(), $event->getRequest(),
17485 $event->getOperations(), $event->getOperation()
17486 );
17487 }
17488 if (!$event instanceof $expected && $expected === 'Composer\Script\Event') {
17489 trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED);
17490 $event = new \Composer\Script\Event(
17491 $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(),
17492 $event->getArguments(), $event->getFlags()
17493 );
17494 }
17495
17496 return $event;
17497 }
17498
17499 private function serializeCallback($cb)
17500 {
17501 if (is_array($cb) && count($cb) === 2) {
17502 if (is_object($cb[0])) {
17503 $cb[0] = get_class($cb[0]);
17504 }
17505 if (is_string($cb[0]) && is_string($cb[1])) {
17506 $cb = implode('::', $cb);
17507 }
17508 }
17509 if (is_string($cb)) {
17510 return $cb;
17511 }
17512
17513 return var_export($cb, true);
17514 }
17515
17516
17517
17518
17519
17520
17521
17522
17523 public function addListener($eventName, $listener, $priority = 0)
17524 {
17525 $this->listeners[$eventName][$priority][] = $listener;
17526 }
17527
17528
17529
17530
17531
17532
17533
17534
17535 public function addSubscriber(EventSubscriberInterface $subscriber)
17536 {
17537 foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
17538 if (is_string($params)) {
17539 $this->addListener($eventName, array($subscriber, $params));
17540 } elseif (is_string($params[0])) {
17541 $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
17542 } else {
17543 foreach ($params as $listener) {
17544 $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
17545 }
17546 }
17547 }
17548 }
17549
17550
17551
17552
17553
17554
17555
17556 protected function getListeners(Event $event)
17557 {
17558 $scriptListeners = $this->getScriptListeners($event);
17559
17560 if (!isset($this->listeners[$event->getName()][0])) {
17561 $this->listeners[$event->getName()][0] = array();
17562 }
17563 krsort($this->listeners[$event->getName()]);
17564
17565 $listeners = $this->listeners;
17566 $listeners[$event->getName()][0] = array_merge($listeners[$event->getName()][0], $scriptListeners);
17567
17568 return call_user_func_array('array_merge', $listeners[$event->getName()]);
17569 }
17570
17571
17572
17573
17574
17575
17576
17577 public function hasEventListeners(Event $event)
17578 {
17579 $listeners = $this->getListeners($event);
17580
17581 return count($listeners) > 0;
17582 }
17583
17584
17585
17586
17587
17588
17589
17590 protected function getScriptListeners(Event $event)
17591 {
17592 $package = $this->composer->getPackage();
17593 $scripts = $package->getScripts();
17594
17595 if (empty($scripts[$event->getName()])) {
17596 return array();
17597 }
17598
17599 if ($this->loader) {
17600 $this->loader->unregister();
17601 }
17602
17603 $generator = $this->composer->getAutoloadGenerator();
17604 if ($event instanceof ScriptEvent) {
17605 $generator->setDevMode($event->isDevMode());
17606 }
17607
17608 $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages();
17609 $packageMap = $generator->buildPackageMap($this->composer->getInstallationManager(), $package, $packages);
17610 $map = $generator->parseAutoloads($packageMap, $package);
17611 $this->loader = $generator->createLoader($map);
17612 $this->loader->register();
17613
17614 return $scripts[$event->getName()];
17615 }
17616
17617
17618
17619
17620
17621
17622
17623 protected function isPhpScript($callable)
17624 {
17625 return false === strpos($callable, ' ') && false !== strpos($callable, '::');
17626 }
17627
17628
17629
17630
17631
17632
17633
17634 protected function isComposerScript($callable)
17635 {
17636 return '@' === substr($callable, 0, 1) && '@php ' !== substr($callable, 0, 5);
17637 }
17638
17639
17640
17641
17642
17643
17644
17645
17646 protected function pushEvent(Event $event)
17647 {
17648 $eventName = $event->getName();
17649 if (in_array($eventName, $this->eventStack)) {
17650 throw new \RuntimeException(sprintf("Circular call to script handler '%s' detected", $eventName));
17651 }
17652
17653 return array_push($this->eventStack, $eventName);
17654 }
17655
17656
17657
17658
17659
17660
17661 protected function popEvent()
17662 {
17663 return array_pop($this->eventStack);
17664 }
17665 }
17666 <?php
17667
17668
17669
17670
17671
17672
17673
17674
17675
17676
17677
17678 namespace Composer\EventDispatcher;
17679
17680
17681
17682
17683
17684
17685
17686
17687
17688
17689
17690
17691
17692 interface EventSubscriberInterface
17693 {
17694
17695
17696
17697
17698
17699
17700
17701
17702
17703
17704
17705
17706
17707
17708
17709
17710
17711
17712 public static function getSubscribedEvents();
17713 }
17714 <?php
17715
17716
17717
17718
17719
17720
17721
17722
17723
17724
17725
17726 namespace Composer\EventDispatcher;
17727
17728
17729
17730
17731 class ScriptExecutionException extends \RuntimeException
17732 {
17733 }
17734 <?php
17735
17736
17737
17738
17739
17740
17741
17742
17743
17744
17745
17746 namespace Composer\Exception;
17747
17748
17749
17750
17751 class NoSslException extends \RuntimeException
17752 {
17753 }
17754 <?php
17755
17756
17757
17758
17759
17760
17761
17762
17763
17764
17765
17766 namespace Composer;
17767
17768 use Composer\Config\JsonConfigSource;
17769 use Composer\Json\JsonFile;
17770 use Composer\IO\IOInterface;
17771 use Composer\Package\Archiver;
17772 use Composer\Package\Version\VersionGuesser;
17773 use Composer\Repository\RepositoryManager;
17774 use Composer\Repository\RepositoryFactory;
17775 use Composer\Repository\WritableRepositoryInterface;
17776 use Composer\Util\Filesystem;
17777 use Composer\Util\Platform;
17778 use Composer\Util\ProcessExecutor;
17779 use Composer\Util\RemoteFilesystem;
17780 use Composer\Util\Silencer;
17781 use Composer\Plugin\PluginEvents;
17782 use Composer\EventDispatcher\Event;
17783 use Seld\JsonLint\DuplicateKeyException;
17784 use Symfony\Component\Console\Formatter\OutputFormatter;
17785 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
17786 use Symfony\Component\Console\Output\ConsoleOutput;
17787 use Composer\EventDispatcher\EventDispatcher;
17788 use Composer\Autoload\AutoloadGenerator;
17789 use Composer\Package\Version\VersionParser;
17790 use Composer\Downloader\TransportException;
17791 use Seld\JsonLint\JsonParser;
17792
17793
17794
17795
17796
17797
17798
17799
17800
17801 class Factory
17802 {
17803
17804
17805
17806
17807 protected static function getHomeDir()
17808 {
17809 $home = getenv('COMPOSER_HOME');
17810 if ($home) {
17811 return $home;
17812 }
17813
17814 if (Platform::isWindows()) {
17815 if (!getenv('APPDATA')) {
17816 throw new \RuntimeException('The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly');
17817 }
17818
17819 return rtrim(strtr(getenv('APPDATA'), '\\', '/'), '/') . '/Composer';
17820 }
17821
17822 $userDir = self::getUserDir();
17823 if (is_dir($userDir . '/.composer')) {
17824 return $userDir . '/.composer';
17825 }
17826
17827 if (self::useXdg()) {
17828
17829  $xdgConfig = getenv('XDG_CONFIG_HOME') ?: $userDir . '/.config';
17830
17831 return $xdgConfig . '/composer';
17832 }
17833
17834 return $userDir . '/.composer';
17835 }
17836
17837
17838
17839
17840
17841 protected static function getCacheDir($home)
17842 {
17843 $cacheDir = getenv('COMPOSER_CACHE_DIR');
17844 if ($cacheDir) {
17845 return $cacheDir;
17846 }
17847
17848 $homeEnv = getenv('COMPOSER_HOME');
17849 if ($homeEnv) {
17850 return $homeEnv . '/cache';
17851 }
17852
17853 if (Platform::isWindows()) {
17854 if ($cacheDir = getenv('LOCALAPPDATA')) {
17855 $cacheDir .= '/Composer';
17856 } else {
17857 $cacheDir = $home . '/cache';
17858 }
17859
17860 return rtrim(strtr($cacheDir, '\\', '/'), '/');
17861 }
17862
17863 $userDir = self::getUserDir();
17864 if ($home === $userDir . '/.composer' && is_dir($home . '/cache')) {
17865 return $home . '/cache';
17866 }
17867
17868 if (self::useXdg()) {
17869 $xdgCache = getenv('XDG_CACHE_HOME') ?: $userDir . '/.cache';
17870
17871 return $xdgCache . '/composer';
17872 }
17873
17874 return $home . '/cache';
17875 }
17876
17877
17878
17879
17880
17881 protected static function getDataDir($home)
17882 {
17883 $homeEnv = getenv('COMPOSER_HOME');
17884 if ($homeEnv) {
17885 return $homeEnv;
17886 }
17887
17888 if (Platform::isWindows()) {
17889 return strtr($home, '\\', '/');
17890 }
17891
17892 $userDir = self::getUserDir();
17893 if ($home !== $userDir . '/.composer' && self::useXdg()) {
17894 $xdgData = getenv('XDG_DATA_HOME') ?: $userDir . '/.local/share';
17895
17896 return $xdgData . '/composer';
17897 }
17898
17899 return $home;
17900 }
17901
17902
17903
17904
17905
17906 public static function createConfig(IOInterface $io = null, $cwd = null)
17907 {
17908 $cwd = $cwd ?: getcwd();
17909
17910 $config = new Config(true, $cwd);
17911
17912
17913  $home = self::getHomeDir();
17914 $config->merge(array('config' => array(
17915 'home' => $home,
17916 'cache-dir' => self::getCacheDir($home),
17917 'data-dir' => self::getDataDir($home),
17918 )));
17919
17920
17921  
17922  
17923  $dirs = array($config->get('home'), $config->get('cache-dir'), $config->get('data-dir'));
17924 foreach ($dirs as $dir) {
17925 if (!file_exists($dir . '/.htaccess')) {
17926 if (!is_dir($dir)) {
17927 Silencer::call('mkdir', $dir, 0777, true);
17928 }
17929 Silencer::call('file_put_contents', $dir . '/.htaccess', 'Deny from all');
17930 }
17931 }
17932
17933
17934  $file = new JsonFile($config->get('home').'/config.json');
17935 if ($file->exists()) {
17936 if ($io && $io->isDebug()) {
17937 $io->writeError('Loading config file ' . $file->getPath());
17938 }
17939 $config->merge($file->read());
17940 }
17941 $config->setConfigSource(new JsonConfigSource($file));
17942
17943
17944  $file = new JsonFile($config->get('home').'/auth.json');
17945 if ($file->exists()) {
17946 if ($io && $io->isDebug()) {
17947 $io->writeError('Loading config file ' . $file->getPath());
17948 }
17949 $config->merge(array('config' => $file->read()));
17950 }
17951 $config->setAuthConfigSource(new JsonConfigSource($file, true));
17952
17953
17954  if ($composerAuthEnv = getenv('COMPOSER_AUTH')) {
17955 $authData = json_decode($composerAuthEnv, true);
17956
17957 if (is_null($authData)) {
17958 throw new \UnexpectedValueException('COMPOSER_AUTH environment variable is malformed, should be a valid JSON object');
17959 }
17960
17961 if ($io && $io->isDebug()) {
17962 $io->writeError('Loading auth config from COMPOSER_AUTH');
17963 }
17964 $config->merge(array('config' => $authData));
17965 }
17966
17967 return $config;
17968 }
17969
17970 public static function getComposerFile()
17971 {
17972 return trim(getenv('COMPOSER')) ?: './composer.json';
17973 }
17974
17975 public static function createAdditionalStyles()
17976 {
17977 return array(
17978 'highlight' => new OutputFormatterStyle('red'),
17979 'warning' => new OutputFormatterStyle('black', 'yellow'),
17980 );
17981 }
17982
17983
17984
17985
17986
17987
17988 public static function createOutput()
17989 {
17990 $styles = self::createAdditionalStyles();
17991 $formatter = new OutputFormatter(null, $styles);
17992
17993 return new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, null, $formatter);
17994 }
17995
17996
17997
17998
17999 public static function createDefaultRepositories(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null)
18000 {
18001 return RepositoryFactory::defaultRepos($io, $config, $rm);
18002 }
18003
18004
18005
18006
18007
18008
18009
18010
18011
18012
18013
18014
18015
18016 public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true)
18017 {
18018 $cwd = $cwd ?: getcwd();
18019
18020
18021  if (null === $localConfig) {
18022 $localConfig = static::getComposerFile();
18023 }
18024
18025 if (is_string($localConfig)) {
18026 $composerFile = $localConfig;
18027
18028 $file = new JsonFile($localConfig, null, $io);
18029
18030 if (!$file->exists()) {
18031 if ($localConfig === './composer.json' || $localConfig === 'composer.json') {
18032 $message = 'Composer could not find a composer.json file in '.$cwd;
18033 } else {
18034 $message = 'Composer could not find the config file: '.$localConfig;
18035 }
18036 $instructions = 'To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section';
18037 throw new \InvalidArgumentException($message.PHP_EOL.$instructions);
18038 }
18039
18040 $file->validateSchema(JsonFile::LAX_SCHEMA);
18041 $jsonParser = new JsonParser;
18042 try {
18043 $jsonParser->parse(file_get_contents($localConfig), JsonParser::DETECT_KEY_CONFLICTS);
18044 } catch (DuplicateKeyException $e) {
18045 $details = $e->getDetails();
18046 $io->writeError('<warning>Key '.$details['key'].' is a duplicate in '.$localConfig.' at line '.$details['line'].'</warning>');
18047 }
18048
18049 $localConfig = $file->read();
18050 }
18051
18052
18053  $config = static::createConfig($io, $cwd);
18054 $config->merge($localConfig);
18055 if (isset($composerFile)) {
18056 $io->writeError('Loading config file ' . $composerFile, true, IOInterface::DEBUG);
18057 $config->setConfigSource(new JsonConfigSource(new JsonFile(realpath($composerFile), null, $io)));
18058
18059 $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json', null, $io);
18060 if ($localAuthFile->exists()) {
18061 $io->writeError('Loading config file ' . $localAuthFile->getPath(), true, IOInterface::DEBUG);
18062 $config->merge(array('config' => $localAuthFile->read()));
18063 $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
18064 }
18065 }
18066
18067 $vendorDir = $config->get('vendor-dir');
18068
18069
18070  $composer = new Composer();
18071 $composer->setConfig($config);
18072
18073 if ($fullLoad) {
18074
18075  $io->loadConfiguration($config);
18076 }
18077
18078 $rfs = self::createRemoteFilesystem($io, $config);
18079
18080
18081  $dispatcher = new EventDispatcher($composer, $io);
18082 $composer->setEventDispatcher($dispatcher);
18083
18084
18085  $rm = RepositoryFactory::manager($io, $config, $dispatcher, $rfs);
18086 $composer->setRepositoryManager($rm);
18087
18088
18089  $this->addLocalRepository($io, $rm, $vendorDir);
18090
18091
18092  
18093  if (!$fullLoad && !isset($localConfig['version'])) {
18094 $localConfig['version'] = '1.0.0';
18095 }
18096
18097
18098  $parser = new VersionParser;
18099 $guesser = new VersionGuesser($config, new ProcessExecutor($io), $parser);
18100 $loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser);
18101 $package = $loader->load($localConfig, 'Composer\Package\RootPackage', $cwd);
18102 $composer->setPackage($package);
18103
18104
18105  $im = $this->createInstallationManager();
18106 $composer->setInstallationManager($im);
18107
18108 if ($fullLoad) {
18109
18110  $dm = $this->createDownloadManager($io, $config, $dispatcher, $rfs);
18111 $composer->setDownloadManager($dm);
18112
18113
18114  $generator = new AutoloadGenerator($dispatcher, $io);
18115 $composer->setAutoloadGenerator($generator);
18116 }
18117
18118
18119  $this->createDefaultInstallers($im, $composer, $io);
18120
18121 if ($fullLoad) {
18122 $globalComposer = null;
18123 if (realpath($config->get('home')) !== $cwd) {
18124 $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins);
18125 }
18126
18127 $pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins);
18128 $composer->setPluginManager($pm);
18129
18130 $pm->loadInstalledPlugins();
18131 }
18132
18133
18134  if ($fullLoad && isset($composerFile)) {
18135 $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION)
18136 ? substr($composerFile, 0, -4).'lock'
18137 : $composerFile . '.lock';
18138
18139 $locker = new Package\Locker($io, new JsonFile($lockFile, null, $io), $rm, $im, file_get_contents($composerFile));
18140 $composer->setLocker($locker);
18141 }
18142
18143 if ($fullLoad) {
18144 $initEvent = new Event(PluginEvents::INIT);
18145 $composer->getEventDispatcher()->dispatch($initEvent->getName(), $initEvent);
18146
18147
18148  
18149  if ($rm->getLocalRepository()) {
18150 $this->purgePackages($rm->getLocalRepository(), $im);
18151 }
18152 }
18153
18154 return $composer;
18155 }
18156
18157
18158
18159
18160
18161
18162 public static function createGlobal(IOInterface $io, $disablePlugins = false)
18163 {
18164 $factory = new static();
18165
18166 return $factory->createGlobalComposer($io, static::createConfig($io), $disablePlugins, true);
18167 }
18168
18169
18170
18171
18172
18173 protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir)
18174 {
18175 $rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed.json', null, $io)));
18176 }
18177
18178
18179
18180
18181
18182 protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins, $fullLoad = false)
18183 {
18184 $composer = null;
18185 try {
18186 $composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), $fullLoad);
18187 } catch (\Exception $e) {
18188 $io->writeError('Failed to initialize global composer: '.$e->getMessage(), true, IOInterface::DEBUG);
18189 }
18190
18191 return $composer;
18192 }
18193
18194
18195
18196
18197
18198
18199
18200 public function createDownloadManager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
18201 {
18202 $cache = null;
18203 if ($config->get('cache-files-ttl') > 0) {
18204 $cache = new Cache($io, $config->get('cache-files-dir'), 'a-z0-9_./');
18205 }
18206
18207 $dm = new Downloader\DownloadManager($io);
18208 switch ($preferred = $config->get('preferred-install')) {
18209 case 'dist':
18210 $dm->setPreferDist(true);
18211 break;
18212 case 'source':
18213 $dm->setPreferSource(true);
18214 break;
18215 case 'auto':
18216 default:
18217
18218  break;
18219 }
18220
18221 if (is_array($preferred)) {
18222 $dm->setPreferences($preferred);
18223 }
18224
18225 $executor = new ProcessExecutor($io);
18226 $fs = new Filesystem($executor);
18227
18228 $dm->setDownloader('git', new Downloader\GitDownloader($io, $config, $executor, $fs));
18229 $dm->setDownloader('svn', new Downloader\SvnDownloader($io, $config, $executor, $fs));
18230 $dm->setDownloader('fossil', new Downloader\FossilDownloader($io, $config, $executor, $fs));
18231 $dm->setDownloader('hg', new Downloader\HgDownloader($io, $config, $executor, $fs));
18232 $dm->setDownloader('perforce', new Downloader\PerforceDownloader($io, $config));
18233 $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
18234 $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
18235 $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $eventDispatcher, $cache, $rfs));
18236 $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
18237 $dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
18238 $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $eventDispatcher, $cache, $rfs));
18239 $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $eventDispatcher, $cache, $rfs));
18240 $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $eventDispatcher, $cache, $rfs));
18241
18242 return $dm;
18243 }
18244
18245
18246
18247
18248
18249
18250 public function createArchiveManager(Config $config, Downloader\DownloadManager $dm = null)
18251 {
18252 if (null === $dm) {
18253 $io = new IO\NullIO();
18254 $io->loadConfiguration($config);
18255 $dm = $this->createDownloadManager($io, $config);
18256 }
18257
18258 $am = new Archiver\ArchiveManager($dm);
18259 $am->addArchiver(new Archiver\ZipArchiver);
18260 $am->addArchiver(new Archiver\PharArchiver);
18261
18262 return $am;
18263 }
18264
18265
18266
18267
18268
18269
18270
18271
18272 protected function createPluginManager(IOInterface $io, Composer $composer, Composer $globalComposer = null, $disablePlugins = false)
18273 {
18274 return new Plugin\PluginManager($io, $composer, $globalComposer, $disablePlugins);
18275 }
18276
18277
18278
18279
18280 protected function createInstallationManager()
18281 {
18282 return new Installer\InstallationManager();
18283 }
18284
18285
18286
18287
18288
18289
18290 protected function createDefaultInstallers(Installer\InstallationManager $im, Composer $composer, IOInterface $io)
18291 {
18292 $im->addInstaller(new Installer\LibraryInstaller($io, $composer, null));
18293 $im->addInstaller(new Installer\PearInstaller($io, $composer, 'pear-library'));
18294 $im->addInstaller(new Installer\PluginInstaller($io, $composer));
18295 $im->addInstaller(new Installer\MetapackageInstaller($io));
18296 }
18297
18298
18299
18300
18301
18302 protected function purgePackages(WritableRepositoryInterface $repo, Installer\InstallationManager $im)
18303 {
18304 foreach ($repo->getPackages() as $package) {
18305 if (!$im->isPackageInstalled($repo, $package)) {
18306 $repo->removePackage($package);
18307 }
18308 }
18309 }
18310
18311
18312
18313
18314
18315
18316
18317
18318 public static function create(IOInterface $io, $config = null, $disablePlugins = false)
18319 {
18320 $factory = new static();
18321
18322 return $factory->createComposer($io, $config, $disablePlugins);
18323 }
18324
18325
18326
18327
18328
18329
18330
18331 public static function createRemoteFilesystem(IOInterface $io, Config $config = null, $options = array())
18332 {
18333 static $warned = false;
18334 $disableTls = false;
18335 if ($config && $config->get('disable-tls') === true) {
18336 if (!$warned) {
18337 $io->write('<warning>You are running Composer with SSL/TLS protection disabled.</warning>');
18338 }
18339 $warned = true;
18340 $disableTls = true;
18341 } elseif (!extension_loaded('openssl')) {
18342 throw new Exception\NoSslException('The openssl extension is required for SSL/TLS protection but is not available. '
18343 . 'If you can not enable the openssl extension, you can disable this error, at your own risk, by setting the \'disable-tls\' option to true.');
18344 }
18345 $remoteFilesystemOptions = array();
18346 if ($disableTls === false) {
18347 if ($config && $config->get('cafile')) {
18348 $remoteFilesystemOptions['ssl']['cafile'] = $config->get('cafile');
18349 }
18350 if ($config && $config->get('capath')) {
18351 $remoteFilesystemOptions['ssl']['capath'] = $config->get('capath');
18352 }
18353 $remoteFilesystemOptions = array_replace_recursive($remoteFilesystemOptions, $options);
18354 }
18355 try {
18356 $remoteFilesystem = new RemoteFilesystem($io, $config, $remoteFilesystemOptions, $disableTls);
18357 } catch (TransportException $e) {
18358 if (false !== strpos($e->getMessage(), 'cafile')) {
18359 $io->write('<error>Unable to locate a valid CA certificate file. You must set a valid \'cafile\' option.</error>');
18360 $io->write('<error>A valid CA certificate file is required for SSL/TLS protection.</error>');
18361 if (PHP_VERSION_ID < 50600) {
18362 $io->write('<error>It is recommended you upgrade to PHP 5.6+ which can detect your system CA file automatically.</error>');
18363 }
18364 $io->write('<error>You can disable this error, at your own risk, by setting the \'disable-tls\' option to true.</error>');
18365 }
18366 throw $e;
18367 }
18368
18369 return $remoteFilesystem;
18370 }
18371
18372
18373
18374
18375 private static function useXdg()
18376 {
18377 foreach (array_keys($_SERVER) as $key) {
18378 if (substr($key, 0, 4) === 'XDG_') {
18379 return true;
18380 }
18381 }
18382
18383 return false;
18384 }
18385
18386
18387
18388
18389
18390 private static function getUserDir()
18391 {
18392 $home = getenv('HOME');
18393 if (!$home) {
18394 throw new \RuntimeException('The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly');
18395 }
18396
18397 return rtrim(strtr($home, '\\', '/'), '/');
18398 }
18399 }
18400 <?php
18401
18402
18403
18404
18405
18406
18407
18408
18409
18410
18411
18412 namespace Composer\IO;
18413
18414 use Composer\Config;
18415 use Composer\Util\ProcessExecutor;
18416 use Psr\Log\LoggerInterface;
18417 use Psr\Log\LogLevel;
18418
18419 abstract class BaseIO implements IOInterface, LoggerInterface
18420 {
18421 protected $authentications = array();
18422
18423
18424
18425
18426 public function getAuthentications()
18427 {
18428 return $this->authentications;
18429 }
18430
18431
18432
18433
18434 public function hasAuthentication($repositoryName)
18435 {
18436 return isset($this->authentications[$repositoryName]);
18437 }
18438
18439
18440
18441
18442 public function getAuthentication($repositoryName)
18443 {
18444 if (isset($this->authentications[$repositoryName])) {
18445 return $this->authentications[$repositoryName];
18446 }
18447
18448 return array('username' => null, 'password' => null);
18449 }
18450
18451
18452
18453
18454 public function setAuthentication($repositoryName, $username, $password = null)
18455 {
18456 $this->authentications[$repositoryName] = array('username' => $username, 'password' => $password);
18457 }
18458
18459
18460
18461
18462
18463
18464
18465
18466 protected function checkAndSetAuthentication($repositoryName, $username, $password = null)
18467 {
18468 if ($this->hasAuthentication($repositoryName)) {
18469 $auth = $this->getAuthentication($repositoryName);
18470 if ($auth['username'] === $username && $auth['password'] === $password) {
18471 return;
18472 }
18473
18474 $this->writeError(
18475 sprintf(
18476 "<warning>Warning: You should avoid overwriting already defined auth settings for %s.</warning>",
18477 $repositoryName
18478 )
18479 );
18480 }
18481 $this->setAuthentication($repositoryName, $username, $password);
18482 }
18483
18484
18485
18486
18487 public function loadConfiguration(Config $config)
18488 {
18489 $bitbucketOauth = $config->get('bitbucket-oauth') ?: array();
18490 $githubOauth = $config->get('github-oauth') ?: array();
18491 $gitlabOauth = $config->get('gitlab-oauth') ?: array();
18492 $gitlabToken = $config->get('gitlab-token') ?: array();
18493 $httpBasic = $config->get('http-basic') ?: array();
18494
18495
18496
18497 foreach ($bitbucketOauth as $domain => $cred) {
18498 $this->checkAndSetAuthentication($domain, $cred['consumer-key'], $cred['consumer-secret']);
18499 }
18500
18501 foreach ($githubOauth as $domain => $token) {
18502 if (!preg_match('{^[.a-z0-9]+$}', $token)) {
18503 throw new \UnexpectedValueException('Your github oauth token for '.$domain.' contains invalid characters: "'.$token.'"');
18504 }
18505 $this->checkAndSetAuthentication($domain, $token, 'x-oauth-basic');
18506 }
18507
18508 foreach ($gitlabOauth as $domain => $token) {
18509 $this->checkAndSetAuthentication($domain, $token, 'oauth2');
18510 }
18511
18512 foreach ($gitlabToken as $domain => $token) {
18513 $this->checkAndSetAuthentication($domain, $token, 'private-token');
18514 }
18515
18516
18517  foreach ($httpBasic as $domain => $cred) {
18518 $this->checkAndSetAuthentication($domain, $cred['username'], $cred['password']);
18519 }
18520
18521
18522  ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
18523 }
18524
18525
18526
18527
18528
18529
18530
18531
18532 public function emergency($message, array $context = array())
18533 {
18534 return $this->log(LogLevel::EMERGENCY, $message, $context);
18535 }
18536
18537
18538
18539
18540
18541
18542
18543
18544
18545
18546
18547 public function alert($message, array $context = array())
18548 {
18549 return $this->log(LogLevel::ALERT, $message, $context);
18550 }
18551
18552
18553
18554
18555
18556
18557
18558
18559
18560
18561 public function critical($message, array $context = array())
18562 {
18563 return $this->log(LogLevel::CRITICAL, $message, $context);
18564 }
18565
18566
18567
18568
18569
18570
18571
18572
18573
18574 public function error($message, array $context = array())
18575 {
18576 return $this->log(LogLevel::ERROR, $message, $context);
18577 }
18578
18579
18580
18581
18582
18583
18584
18585
18586
18587
18588
18589 public function warning($message, array $context = array())
18590 {
18591 return $this->log(LogLevel::WARNING, $message, $context);
18592 }
18593
18594
18595
18596
18597
18598
18599
18600
18601 public function notice($message, array $context = array())
18602 {
18603 return $this->log(LogLevel::NOTICE, $message, $context);
18604 }
18605
18606
18607
18608
18609
18610
18611
18612
18613
18614
18615 public function info($message, array $context = array())
18616 {
18617 return $this->log(LogLevel::INFO, $message, $context);
18618 }
18619
18620
18621
18622
18623
18624
18625
18626
18627 public function debug($message, array $context = array())
18628 {
18629 return $this->log(LogLevel::DEBUG, $message, $context);
18630 }
18631
18632
18633
18634
18635
18636
18637
18638
18639
18640 public function log($level, $message, array $context = array())
18641 {
18642 if (in_array($level, array(LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL, LogLevel::ERROR))) {
18643 $this->writeError('<error>'.$message.'</error>', true, self::NORMAL);
18644 } elseif ($level === LogLevel::WARNING) {
18645 $this->writeError('<warning>'.$message.'</warning>', true, self::NORMAL);
18646 } elseif ($level === LogLevel::NOTICE) {
18647 $this->writeError('<info>'.$message.'</info>', true, self::VERBOSE);
18648 } elseif ($level === LogLevel::INFO) {
18649 $this->writeError('<info>'.$message.'</info>', true, self::VERY_VERBOSE);
18650 } else {
18651 $this->writeError($message, true, self::DEBUG);
18652 }
18653 }
18654 }
18655 <?php
18656
18657
18658
18659
18660
18661
18662
18663
18664
18665
18666
18667 namespace Composer\IO;
18668
18669 use Symfony\Component\Console\Output\StreamOutput;
18670 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
18671 use Symfony\Component\Console\Input\StringInput;
18672 use Symfony\Component\Console\Helper\HelperSet;
18673
18674
18675
18676
18677 class BufferIO extends ConsoleIO
18678 {
18679
18680
18681
18682
18683
18684 public function __construct($input = '', $verbosity = StreamOutput::VERBOSITY_NORMAL, OutputFormatterInterface $formatter = null)
18685 {
18686 $input = new StringInput($input);
18687 $input->setInteractive(false);
18688
18689 $output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, $formatter ? $formatter->isDecorated() : false, $formatter);
18690
18691 parent::__construct($input, $output, new HelperSet(array()));
18692 }
18693
18694 public function getOutput()
18695 {
18696 fseek($this->output->getStream(), 0);
18697
18698 $output = stream_get_contents($this->output->getStream());
18699
18700 $output = preg_replace_callback("{(?<=^|\n|\x08)(.+?)(\x08+)}", function ($matches) {
18701 $pre = strip_tags($matches[1]);
18702
18703 if (strlen($pre) === strlen($matches[2])) {
18704 return '';
18705 }
18706
18707
18708  return rtrim($matches[1])."\n";
18709 }, $output);
18710
18711 return $output;
18712 }
18713 }
18714 <?php
18715
18716
18717
18718
18719
18720
18721
18722
18723
18724
18725
18726 namespace Composer\IO;
18727
18728 use Symfony\Component\Console\Input\InputInterface;
18729 use Symfony\Component\Console\Output\ConsoleOutputInterface;
18730 use Symfony\Component\Console\Output\OutputInterface;
18731 use Symfony\Component\Console\Helper\HelperSet;
18732 use Symfony\Component\Console\Question\ConfirmationQuestion;
18733 use Symfony\Component\Console\Question\Question;
18734
18735
18736
18737
18738
18739
18740
18741 class ConsoleIO extends BaseIO
18742 {
18743
18744 protected $input;
18745
18746 protected $output;
18747
18748 protected $helperSet;
18749
18750 protected $lastMessage;
18751
18752 protected $lastMessageErr;
18753
18754
18755 private $startTime;
18756
18757 private $verbosityMap;
18758
18759
18760
18761
18762
18763
18764
18765
18766 public function __construct(InputInterface $input, OutputInterface $output, HelperSet $helperSet)
18767 {
18768 $this->input = $input;
18769 $this->output = $output;
18770 $this->helperSet = $helperSet;
18771 $this->verbosityMap = array(
18772 self::QUIET => OutputInterface::VERBOSITY_QUIET,
18773 self::NORMAL => OutputInterface::VERBOSITY_NORMAL,
18774 self::VERBOSE => OutputInterface::VERBOSITY_VERBOSE,
18775 self::VERY_VERBOSE => OutputInterface::VERBOSITY_VERY_VERBOSE,
18776 self::DEBUG => OutputInterface::VERBOSITY_DEBUG,
18777 );
18778 }
18779
18780
18781
18782
18783 public function enableDebugging($startTime)
18784 {
18785 $this->startTime = $startTime;
18786 }
18787
18788
18789
18790
18791 public function isInteractive()
18792 {
18793 return $this->input->isInteractive();
18794 }
18795
18796
18797
18798
18799 public function isDecorated()
18800 {
18801 return $this->output->isDecorated();
18802 }
18803
18804
18805
18806
18807 public function isVerbose()
18808 {
18809 return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE;
18810 }
18811
18812
18813
18814
18815 public function isVeryVerbose()
18816 {
18817 return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE;
18818 }
18819
18820
18821
18822
18823 public function isDebug()
18824 {
18825 return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG;
18826 }
18827
18828
18829
18830
18831 public function write($messages, $newline = true, $verbosity = self::NORMAL)
18832 {
18833 $this->doWrite($messages, $newline, false, $verbosity);
18834 }
18835
18836
18837
18838
18839 public function writeError($messages, $newline = true, $verbosity = self::NORMAL)
18840 {
18841 $this->doWrite($messages, $newline, true, $verbosity);
18842 }
18843
18844
18845
18846
18847
18848
18849
18850 private function doWrite($messages, $newline, $stderr, $verbosity)
18851 {
18852 $sfVerbosity = $this->verbosityMap[$verbosity];
18853 if ($sfVerbosity > $this->output->getVerbosity()) {
18854 return;
18855 }
18856
18857
18858  
18859  
18860  if (OutputInterface::VERBOSITY_QUIET === 0) {
18861 $sfVerbosity = OutputInterface::OUTPUT_NORMAL;
18862 }
18863
18864 if (null !== $this->startTime) {
18865 $memoryUsage = memory_get_usage() / 1024 / 1024;
18866 $timeSpent = microtime(true) - $this->startTime;
18867 $messages = array_map(function ($message) use ($memoryUsage, $timeSpent) {
18868 return sprintf('[%.1fMB/%.2fs] %s', $memoryUsage, $timeSpent, $message);
18869 }, (array) $messages);
18870 }
18871
18872 if (true === $stderr && $this->output instanceof ConsoleOutputInterface) {
18873 $this->output->getErrorOutput()->write($messages, $newline, $sfVerbosity);
18874 $this->lastMessageErr = implode($newline ? "\n" : '', (array) $messages);
18875
18876 return;
18877 }
18878
18879 $this->output->write($messages, $newline, $sfVerbosity);
18880 $this->lastMessage = implode($newline ? "\n" : '', (array) $messages);
18881 }
18882
18883
18884
18885
18886 public function overwrite($messages, $newline = true, $size = null, $verbosity = self::NORMAL)
18887 {
18888 $this->doOverwrite($messages, $newline, $size, false, $verbosity);
18889 }
18890
18891
18892
18893
18894 public function overwriteError($messages, $newline = true, $size = null, $verbosity = self::NORMAL)
18895 {
18896 $this->doOverwrite($messages, $newline, $size, true, $verbosity);
18897 }
18898
18899
18900
18901
18902
18903
18904
18905
18906 private function doOverwrite($messages, $newline, $size, $stderr, $verbosity)
18907 {
18908
18909  $messages = implode($newline ? "\n" : '', (array) $messages);
18910
18911
18912  if (!isset($size)) {
18913
18914  $size = strlen(strip_tags($stderr ? $this->lastMessageErr : $this->lastMessage));
18915 }
18916
18917  $this->doWrite(str_repeat("\x08", $size), false, $stderr, $verbosity);
18918
18919
18920  $this->doWrite($messages, false, $stderr, $verbosity);
18921
18922
18923  
18924  
18925  $fill = $size - strlen(strip_tags($messages));
18926 if ($fill > 0) {
18927
18928  $this->doWrite(str_repeat(' ', $fill), false, $stderr, $verbosity);
18929
18930  $this->doWrite(str_repeat("\x08", $fill), false, $stderr, $verbosity);
18931 }
18932
18933 if ($newline) {
18934 $this->doWrite('', true, $stderr, $verbosity);
18935 }
18936
18937 if ($stderr) {
18938 $this->lastMessageErr = $messages;
18939 } else {
18940 $this->lastMessage = $messages;
18941 }
18942 }
18943
18944
18945
18946
18947 public function ask($question, $default = null)
18948 {
18949
18950 $helper = $this->helperSet->get('question');
18951 $question = new Question($question, $default);
18952
18953 return $helper->ask($this->input, $this->getErrorOutput(), $question);
18954 }
18955
18956
18957
18958
18959 public function askConfirmation($question, $default = true)
18960 {
18961
18962 $helper = $this->helperSet->get('question');
18963 $question = new ConfirmationQuestion($question, $default);
18964
18965 return $helper->ask($this->input, $this->getErrorOutput(), $question);
18966 }
18967
18968
18969
18970
18971 public function askAndValidate($question, $validator, $attempts = null, $default = null)
18972 {
18973
18974 $helper = $this->helperSet->get('question');
18975 $question = new Question($question, $default);
18976 $question->setValidator($validator);
18977 $question->setMaxAttempts($attempts);
18978
18979 return $helper->ask($this->input, $this->getErrorOutput(), $question);
18980 }
18981
18982
18983
18984
18985 public function askAndHideAnswer($question)
18986 {
18987 $this->writeError($question, false);
18988
18989 return \Seld\CliPrompt\CliPrompt::hiddenPrompt(true);
18990 }
18991
18992
18993
18994
18995 public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
18996 {
18997 if ($this->isInteractive()) {
18998 return $this->helperSet->get('dialog')->select($this->getErrorOutput(), $question, $choices, $default, $attempts, $errorMessage, $multiselect);
18999 }
19000
19001 return $default;
19002 }
19003
19004
19005
19006
19007 private function getErrorOutput()
19008 {
19009 if ($this->output instanceof ConsoleOutputInterface) {
19010 return $this->output->getErrorOutput();
19011 }
19012
19013 return $this->output;
19014 }
19015 }
19016 <?php
19017
19018
19019
19020
19021
19022
19023
19024
19025
19026
19027
19028 namespace Composer\IO;
19029
19030 use Composer\Config;
19031
19032
19033
19034
19035
19036
19037 interface IOInterface
19038 {
19039 const QUIET = 1;
19040 const NORMAL = 2;
19041 const VERBOSE = 4;
19042 const VERY_VERBOSE = 8;
19043 const DEBUG = 16;
19044
19045
19046
19047
19048
19049
19050 public function isInteractive();
19051
19052
19053
19054
19055
19056
19057 public function isVerbose();
19058
19059
19060
19061
19062
19063
19064 public function isVeryVerbose();
19065
19066
19067
19068
19069
19070
19071 public function isDebug();
19072
19073
19074
19075
19076
19077
19078 public function isDecorated();
19079
19080
19081
19082
19083
19084
19085
19086
19087 public function write($messages, $newline = true, $verbosity = self::NORMAL);
19088
19089
19090
19091
19092
19093
19094
19095
19096 public function writeError($messages, $newline = true, $verbosity = self::NORMAL);
19097
19098
19099
19100
19101
19102
19103
19104
19105
19106 public function overwrite($messages, $newline = true, $size = null, $verbosity = self::NORMAL);
19107
19108
19109
19110
19111
19112
19113
19114
19115
19116 public function overwriteError($messages, $newline = true, $size = null, $verbosity = self::NORMAL);
19117
19118
19119
19120
19121
19122
19123
19124
19125
19126
19127 public function ask($question, $default = null);
19128
19129
19130
19131
19132
19133
19134
19135
19136
19137
19138
19139 public function askConfirmation($question, $default = true);
19140
19141
19142
19143
19144
19145
19146
19147
19148
19149
19150
19151
19152
19153
19154
19155
19156 public function askAndValidate($question, $validator, $attempts = null, $default = null);
19157
19158
19159
19160
19161
19162
19163
19164
19165 public function askAndHideAnswer($question);
19166
19167
19168
19169
19170
19171
19172
19173
19174
19175
19176
19177
19178
19179
19180 public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false);
19181
19182
19183
19184
19185
19186
19187 public function getAuthentications();
19188
19189
19190
19191
19192
19193
19194
19195
19196 public function hasAuthentication($repositoryName);
19197
19198
19199
19200
19201
19202
19203
19204
19205 public function getAuthentication($repositoryName);
19206
19207
19208
19209
19210
19211
19212
19213
19214 public function setAuthentication($repositoryName, $username, $password = null);
19215
19216
19217
19218
19219
19220
19221 public function loadConfiguration(Config $config);
19222 }
19223 <?php
19224
19225
19226
19227
19228
19229
19230
19231
19232
19233
19234
19235 namespace Composer\IO;
19236
19237
19238
19239
19240
19241
19242 class NullIO extends BaseIO
19243 {
19244
19245
19246
19247 public function isInteractive()
19248 {
19249 return false;
19250 }
19251
19252
19253
19254
19255 public function isVerbose()
19256 {
19257 return false;
19258 }
19259
19260
19261
19262
19263 public function isVeryVerbose()
19264 {
19265 return false;
19266 }
19267
19268
19269
19270
19271 public function isDebug()
19272 {
19273 return false;
19274 }
19275
19276
19277
19278
19279 public function isDecorated()
19280 {
19281 return false;
19282 }
19283
19284
19285
19286
19287 public function write($messages, $newline = true, $verbosity = self::NORMAL)
19288 {
19289 }
19290
19291
19292
19293
19294 public function writeError($messages, $newline = true, $verbosity = self::NORMAL)
19295 {
19296 }
19297
19298
19299
19300
19301 public function overwrite($messages, $newline = true, $size = 80, $verbosity = self::NORMAL)
19302 {
19303 }
19304
19305
19306
19307
19308 public function overwriteError($messages, $newline = true, $size = 80, $verbosity = self::NORMAL)
19309 {
19310 }
19311
19312
19313
19314
19315 public function ask($question, $default = null)
19316 {
19317 return $default;
19318 }
19319
19320
19321
19322
19323 public function askConfirmation($question, $default = true)
19324 {
19325 return $default;
19326 }
19327
19328
19329
19330
19331 public function askAndValidate($question, $validator, $attempts = false, $default = null)
19332 {
19333 return $default;
19334 }
19335
19336
19337
19338
19339 public function askAndHideAnswer($question)
19340 {
19341 return null;
19342 }
19343
19344
19345
19346
19347 public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
19348 {
19349 return $default;
19350 }
19351 }
19352 <?php
19353
19354
19355
19356
19357
19358
19359
19360
19361
19362
19363
19364 namespace Composer;
19365
19366 use Composer\Autoload\AutoloadGenerator;
19367 use Composer\DependencyResolver\DefaultPolicy;
19368 use Composer\DependencyResolver\Operation\UpdateOperation;
19369 use Composer\DependencyResolver\Operation\InstallOperation;
19370 use Composer\DependencyResolver\Operation\UninstallOperation;
19371 use Composer\DependencyResolver\Operation\OperationInterface;
19372 use Composer\DependencyResolver\PolicyInterface;
19373 use Composer\DependencyResolver\Pool;
19374 use Composer\DependencyResolver\Request;
19375 use Composer\DependencyResolver\Rule;
19376 use Composer\DependencyResolver\Solver;
19377 use Composer\DependencyResolver\SolverProblemsException;
19378 use Composer\Downloader\DownloadManager;
19379 use Composer\EventDispatcher\EventDispatcher;
19380 use Composer\Installer\InstallationManager;
19381 use Composer\Installer\InstallerEvents;
19382 use Composer\Installer\NoopInstaller;
19383 use Composer\Installer\SuggestedPackagesReporter;
19384 use Composer\IO\IOInterface;
19385 use Composer\Package\AliasPackage;
19386 use Composer\Package\CompletePackage;
19387 use Composer\Package\Link;
19388 use Composer\Package\Loader\ArrayLoader;
19389 use Composer\Package\Dumper\ArrayDumper;
19390 use Composer\Semver\Constraint\Constraint;
19391 use Composer\Package\Locker;
19392 use Composer\Package\PackageInterface;
19393 use Composer\Package\RootPackageInterface;
19394 use Composer\Repository\CompositeRepository;
19395 use Composer\Repository\InstalledArrayRepository;
19396 use Composer\Repository\PlatformRepository;
19397 use Composer\Repository\RepositoryInterface;
19398 use Composer\Repository\RepositoryManager;
19399 use Composer\Repository\WritableRepositoryInterface;
19400 use Composer\Script\ScriptEvents;
19401
19402
19403
19404
19405
19406
19407
19408 class Installer
19409 {
19410
19411
19412
19413 protected $io;
19414
19415
19416
19417
19418 protected $config;
19419
19420
19421
19422
19423 protected $package;
19424
19425
19426
19427
19428 protected $downloadManager;
19429
19430
19431
19432
19433 protected $repositoryManager;
19434
19435
19436
19437
19438 protected $locker;
19439
19440
19441
19442
19443 protected $installationManager;
19444
19445
19446
19447
19448 protected $eventDispatcher;
19449
19450
19451
19452
19453 protected $autoloadGenerator;
19454
19455 protected $preferSource = false;
19456 protected $preferDist = false;
19457 protected $optimizeAutoloader = false;
19458 protected $classMapAuthoritative = false;
19459 protected $apcuAutoloader = false;
19460 protected $devMode = false;
19461 protected $dryRun = false;
19462 protected $verbose = false;
19463 protected $update = false;
19464 protected $dumpAutoloader = true;
19465 protected $runScripts = true;
19466 protected $ignorePlatformReqs = false;
19467 protected $preferStable = false;
19468 protected $preferLowest = false;
19469 protected $skipSuggest = false;
19470 protected $writeLock = true;
19471 protected $executeOperations = true;
19472
19473
19474
19475
19476
19477
19478 protected $updateWhitelist = null;
19479 protected $whitelistDependencies = false;
19480
19481
19482
19483
19484 protected $suggestedPackagesReporter;
19485
19486
19487
19488
19489 protected $additionalInstalledRepository;
19490
19491
19492
19493
19494
19495
19496
19497
19498
19499
19500
19501
19502
19503
19504 public function __construct(IOInterface $io, Config $config, RootPackageInterface $package, DownloadManager $downloadManager, RepositoryManager $repositoryManager, Locker $locker, InstallationManager $installationManager, EventDispatcher $eventDispatcher, AutoloadGenerator $autoloadGenerator)
19505 {
19506 $this->io = $io;
19507 $this->config = $config;
19508 $this->package = $package;
19509 $this->downloadManager = $downloadManager;
19510 $this->repositoryManager = $repositoryManager;
19511 $this->locker = $locker;
19512 $this->installationManager = $installationManager;
19513 $this->eventDispatcher = $eventDispatcher;
19514 $this->autoloadGenerator = $autoloadGenerator;
19515 }
19516
19517
19518
19519
19520
19521
19522
19523 public function run()
19524 {
19525
19526  
19527  
19528  
19529  gc_collect_cycles();
19530 gc_disable();
19531
19532
19533  if (!$this->update && !$this->locker->isLocked()) {
19534 $this->update = true;
19535 }
19536
19537 if ($this->dryRun) {
19538 $this->verbose = true;
19539 $this->runScripts = false;
19540 $this->executeOperations = false;
19541 $this->writeLock = false;
19542 $this->dumpAutoloader = false;
19543 $this->installationManager->addInstaller(new NoopInstaller);
19544 $this->mockLocalRepositories($this->repositoryManager);
19545 }
19546
19547 if ($this->runScripts) {
19548
19549  $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD;
19550 $this->eventDispatcher->dispatchScript($eventName, $this->devMode);
19551 }
19552
19553 $this->downloadManager->setPreferSource($this->preferSource);
19554 $this->downloadManager->setPreferDist($this->preferDist);
19555
19556
19557  $localRepo = $this->repositoryManager->getLocalRepository();
19558 if ($this->update) {
19559 $platformOverrides = $this->config->get('platform') ?: array();
19560 } else {
19561 $platformOverrides = $this->locker->getPlatformOverrides();
19562 }
19563 $platformRepo = new PlatformRepository(array(), $platformOverrides);
19564 $installedRepo = $this->createInstalledRepo($localRepo, $platformRepo);
19565
19566 $aliases = $this->getRootAliases();
19567 $this->aliasPlatformPackages($platformRepo, $aliases);
19568
19569 if (!$this->suggestedPackagesReporter) {
19570 $this->suggestedPackagesReporter = new SuggestedPackagesReporter($this->io);
19571 }
19572
19573 try {
19574 list($res, $devPackages) = $this->doInstall($localRepo, $installedRepo, $platformRepo, $aliases);
19575 if ($res !== 0) {
19576 return $res;
19577 }
19578 } catch (\Exception $e) {
19579 if ($this->executeOperations) {
19580 $this->installationManager->notifyInstalls($this->io);
19581 }
19582
19583 throw $e;
19584 }
19585 if ($this->executeOperations) {
19586 $this->installationManager->notifyInstalls($this->io);
19587 }
19588
19589
19590  if ($this->devMode && !$this->skipSuggest) {
19591 $this->suggestedPackagesReporter->output($installedRepo);
19592 }
19593
19594
19595  foreach ($localRepo->getPackages() as $package) {
19596 if (!$package instanceof CompletePackage || !$package->isAbandoned()) {
19597 continue;
19598 }
19599
19600 $replacement = (is_string($package->getReplacementPackage()))
19601 ? 'Use ' . $package->getReplacementPackage() . ' instead'
19602 : 'No replacement was suggested';
19603
19604 $this->io->writeError(
19605 sprintf(
19606 "<warning>Package %s is abandoned, you should avoid using it. %s.</warning>",
19607 $package->getPrettyName(),
19608 $replacement
19609 )
19610 );
19611 }
19612
19613
19614  if ($this->update && $this->writeLock) {
19615 $localRepo->reload();
19616
19617 $platformReqs = $this->extractPlatformRequirements($this->package->getRequires());
19618 $platformDevReqs = $this->extractPlatformRequirements($this->package->getDevRequires());
19619
19620 $updatedLock = $this->locker->setLockData(
19621 array_diff($localRepo->getCanonicalPackages(), $devPackages),
19622 $devPackages,
19623 $platformReqs,
19624 $platformDevReqs,
19625 $aliases,
19626 $this->package->getMinimumStability(),
19627 $this->package->getStabilityFlags(),
19628 $this->preferStable || $this->package->getPreferStable(),
19629 $this->preferLowest,
19630 $this->config->get('platform') ?: array()
19631 );
19632 if ($updatedLock) {
19633 $this->io->writeError('<info>Writing lock file</info>');
19634 }
19635 }
19636
19637 if ($this->dumpAutoloader) {
19638
19639  if ($this->optimizeAutoloader) {
19640 $this->io->writeError('<info>Generating optimized autoload files</info>');
19641 } else {
19642 $this->io->writeError('<info>Generating autoload files</info>');
19643 }
19644
19645 $this->autoloadGenerator->setDevMode($this->devMode);
19646 $this->autoloadGenerator->setClassMapAuthoritative($this->classMapAuthoritative);
19647 $this->autoloadGenerator->setApcu($this->apcuAutoloader);
19648 $this->autoloadGenerator->setRunScripts($this->runScripts);
19649 $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader);
19650 }
19651
19652 if ($this->runScripts) {
19653 $devMode = (int) $this->devMode;
19654 putenv("COMPOSER_DEV_MODE=$devMode");
19655
19656
19657  $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD;
19658 $this->eventDispatcher->dispatchScript($eventName, $this->devMode);
19659 }
19660
19661 if ($this->executeOperations) {
19662
19663  foreach ($localRepo->getPackages() as $package) {
19664 $this->installationManager->ensureBinariesPresence($package);
19665 }
19666
19667 $vendorDir = $this->config->get('vendor-dir');
19668 if (is_dir($vendorDir)) {
19669
19670  
19671  @touch($vendorDir);
19672 }
19673 }
19674
19675
19676  if (!defined('HHVM_VERSION')) {
19677 gc_enable();
19678 }
19679
19680 return 0;
19681 }
19682
19683
19684
19685
19686
19687
19688
19689
19690 protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases)
19691 {
19692
19693  $lockedRepository = null;
19694 $repositories = null;
19695
19696
19697  
19698  
19699  if (!$this->update || (!empty($this->updateWhitelist) && $this->locker->isLocked())) {
19700 try {
19701 $lockedRepository = $this->locker->getLockedRepository($this->devMode);
19702 } catch (\RuntimeException $e) {
19703
19704  if ($this->package->getDevRequires()) {
19705 throw $e;
19706 }
19707
19708  $lockedRepository = $this->locker->getLockedRepository();
19709 }
19710 }
19711
19712 $this->whitelistUpdateDependencies(
19713 $localRepo,
19714 $this->package->getRequires(),
19715 $this->package->getDevRequires()
19716 );
19717
19718 $this->io->writeError('<info>Loading composer repositories with package information</info>');
19719
19720
19721  $policy = $this->createPolicy();
19722 $pool = $this->createPool($this->update ? null : $lockedRepository);
19723 $pool->addRepository($installedRepo, $aliases);
19724 if ($this->update) {
19725 $repositories = $this->repositoryManager->getRepositories();
19726 foreach ($repositories as $repository) {
19727 $pool->addRepository($repository, $aliases);
19728 }
19729 }
19730
19731  
19732  
19733  if ($lockedRepository) {
19734 $pool->addRepository($lockedRepository, $aliases);
19735 }
19736
19737
19738  $request = $this->createRequest($this->package, $platformRepo);
19739
19740 if ($this->update) {
19741
19742  $removedUnstablePackages = array();
19743 foreach ($localRepo->getPackages() as $package) {
19744 if (
19745 !$pool->isPackageAcceptable($package->getNames(), $package->getStability())
19746 && $this->installationManager->isPackageInstalled($localRepo, $package)
19747 ) {
19748 $removedUnstablePackages[$package->getName()] = true;
19749 $request->remove($package->getName(), new Constraint('=', $package->getVersion()));
19750 }
19751 }
19752
19753 $this->io->writeError('<info>Updating dependencies'.($this->devMode ? ' (including require-dev)' : '').'</info>');
19754
19755 $request->updateAll();
19756
19757 $links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
19758
19759 foreach ($links as $link) {
19760 $request->install($link->getTarget(), $link->getConstraint());
19761 }
19762
19763
19764  
19765  if ($this->updateWhitelist) {
19766 $currentPackages = $this->getCurrentPackages($installedRepo);
19767
19768
19769  $candidates = array();
19770 foreach ($links as $link) {
19771 $candidates[$link->getTarget()] = true;
19772 $rootRequires[$link->getTarget()] = $link;
19773 }
19774 foreach ($currentPackages as $package) {
19775 $candidates[$package->getName()] = true;
19776 }
19777
19778
19779  foreach ($candidates as $candidate => $dummy) {
19780 foreach ($currentPackages as $curPackage) {
19781 if ($curPackage->getName() === $candidate) {
19782 if (!$this->isUpdateable($curPackage) && !isset($removedUnstablePackages[$curPackage->getName()])) {
19783 $constraint = new Constraint('=', $curPackage->getVersion());
19784 $description = $this->locker->isLocked() ? '(locked at' : '(installed at';
19785 $requiredAt = isset($rootRequires[$candidate]) ? ', required as ' . $rootRequires[$candidate]->getPrettyConstraint() : '';
19786 $constraint->setPrettyString($description . ' ' . $curPackage->getPrettyVersion() . $requiredAt . ')');
19787 $request->install($curPackage->getName(), $constraint);
19788 }
19789 break;
19790 }
19791 }
19792 }
19793 }
19794 } else {
19795 $this->io->writeError('<info>Installing dependencies'.($this->devMode ? ' (including require-dev)' : '').' from lock file</info>');
19796
19797 if (!$this->locker->isFresh()) {
19798 $this->io->writeError('<warning>Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.</warning>', true, IOInterface::QUIET);
19799 }
19800
19801 foreach ($lockedRepository->getPackages() as $package) {
19802 $version = $package->getVersion();
19803 if (isset($aliases[$package->getName()][$version])) {
19804 $version = $aliases[$package->getName()][$version]['alias_normalized'];
19805 }
19806 $constraint = new Constraint('=', $version);
19807 $constraint->setPrettyString($package->getPrettyVersion());
19808 $request->install($package->getName(), $constraint);
19809 }
19810
19811 foreach ($this->locker->getPlatformRequirements($this->devMode) as $link) {
19812 $request->install($link->getTarget(), $link->getConstraint());
19813 }
19814 }
19815
19816
19817  $this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, 'force-links');
19818
19819
19820  $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request);
19821 $solver = new Solver($policy, $pool, $installedRepo, $this->io);
19822 try {
19823 $operations = $solver->solve($request, $this->ignorePlatformReqs);
19824 } catch (SolverProblemsException $e) {
19825 $this->io->writeError('<error>Your requirements could not be resolved to an installable set of packages.</error>', true, IOInterface::QUIET);
19826 $this->io->writeError($e->getMessage());
19827
19828 return array(max(1, $e->getCode()), array());
19829 }
19830
19831
19832  $operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, 'force-updates', $operations);
19833
19834 $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request, $operations);
19835
19836 $this->io->writeError("Analyzed ".count($pool)." packages to resolve dependencies", true, IOInterface::VERBOSE);
19837 $this->io->writeError("Analyzed ".$solver->getRuleSetSize()." rules to resolve dependencies", true, IOInterface::VERBOSE);
19838
19839
19840  if (!$operations) {
19841 $this->io->writeError('Nothing to install or update');
19842 }
19843
19844 $operations = $this->movePluginsToFront($operations);
19845 $operations = $this->moveUninstallsToFront($operations);
19846
19847
19848  
19849  if ($this->update) {
19850 $devPackages = $this->extractDevPackages($operations, $localRepo, $platformRepo, $aliases);
19851 if (!$this->devMode) {
19852 $operations = $this->filterDevPackageOperations($devPackages, $operations, $localRepo);
19853 }
19854 } else {
19855 $devPackages = null;
19856 }
19857
19858 if ($operations) {
19859 $installs = $updates = $uninstalls = array();
19860 foreach ($operations as $operation) {
19861 if ($operation instanceof InstallOperation) {
19862 $installs[] = $operation->getPackage()->getPrettyName().':'.$operation->getPackage()->getFullPrettyVersion();
19863 } elseif ($operation instanceof UpdateOperation) {
19864 $updates[] = $operation->getTargetPackage()->getPrettyName().':'.$operation->getTargetPackage()->getFullPrettyVersion();
19865 } elseif ($operation instanceof UninstallOperation) {
19866 $uninstalls[] = $operation->getPackage()->getPrettyName();
19867 }
19868 }
19869
19870 $this->io->writeError(
19871 sprintf("<info>Package operations: %d install%s, %d update%s, %d removal%s</info>",
19872 count($installs),
19873 1 === count($installs) ? '' : 's',
19874 count($updates),
19875 1 === count($updates) ? '' : 's',
19876 count($uninstalls),
19877 1 === count($uninstalls) ? '' : 's')
19878 );
19879 if ($installs) {
19880 $this->io->writeError("Installs: ".implode(', ', $installs), true, IOInterface::VERBOSE);
19881 }
19882 if ($updates) {
19883 $this->io->writeError("Updates: ".implode(', ', $updates), true, IOInterface::VERBOSE);
19884 }
19885 if ($uninstalls) {
19886 $this->io->writeError("Removals: ".implode(', ', $uninstalls), true, IOInterface::VERBOSE);
19887 }
19888 }
19889
19890 foreach ($operations as $operation) {
19891
19892  if ('install' === $operation->getJobType()) {
19893 $this->suggestedPackagesReporter->addSuggestionsFromPackage($operation->getPackage());
19894 }
19895
19896
19897  if ($this->update) {
19898 $package = null;
19899 if ('update' === $operation->getJobType()) {
19900 $package = $operation->getTargetPackage();
19901 } elseif ('install' === $operation->getJobType()) {
19902 $package = $operation->getPackage();
19903 }
19904 if ($package && $package->isDev()) {
19905 $references = $this->package->getReferences();
19906 if (isset($references[$package->getName()])) {
19907 $this->updateInstallReferences($package, $references[$package->getName()]);
19908 }
19909 }
19910 if ('update' === $operation->getJobType()
19911 && $operation->getTargetPackage()->isDev()
19912 && $operation->getTargetPackage()->getVersion() === $operation->getInitialPackage()->getVersion()
19913 && (!$operation->getTargetPackage()->getSourceReference() || $operation->getTargetPackage()->getSourceReference() === $operation->getInitialPackage()->getSourceReference())
19914 && (!$operation->getTargetPackage()->getDistReference() || $operation->getTargetPackage()->getDistReference() === $operation->getInitialPackage()->getDistReference())
19915 ) {
19916 $this->io->writeError('  - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version', true, IOInterface::DEBUG);
19917 $this->io->writeError('', true, IOInterface::DEBUG);
19918
19919 continue;
19920 }
19921 }
19922
19923 $event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_'.strtoupper($operation->getJobType());
19924 if (defined($event) && $this->runScripts) {
19925 $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation);
19926 }
19927
19928
19929  if (!$this->executeOperations && false === strpos($operation->getJobType(), 'Alias')) {
19930 $this->io->writeError('  - ' . $operation);
19931 } elseif ($this->io->isDebug() && false !== strpos($operation->getJobType(), 'Alias')) {
19932 $this->io->writeError('  - ' . $operation);
19933 }
19934
19935 $this->installationManager->execute($localRepo, $operation);
19936
19937
19938  if ($this->verbose && $this->io->isVeryVerbose() && in_array($operation->getJobType(), array('install', 'update'))) {
19939 $reason = $operation->getReason();
19940 if ($reason instanceof Rule) {
19941 switch ($reason->getReason()) {
19942 case Rule::RULE_JOB_INSTALL:
19943 $this->io->writeError('    REASON: Required by the root package: '.$reason->getPrettyString($pool));
19944 $this->io->writeError('');
19945 break;
19946 case Rule::RULE_PACKAGE_REQUIRES:
19947 $this->io->writeError('    REASON: '.$reason->getPrettyString($pool));
19948 $this->io->writeError('');
19949 break;
19950 }
19951 }
19952 }
19953
19954 $event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($operation->getJobType());
19955 if (defined($event) && $this->runScripts) {
19956 $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation);
19957 }
19958
19959 if ($this->executeOperations || $this->writeLock) {
19960 $localRepo->write();
19961 }
19962 }
19963
19964 if ($this->executeOperations) {
19965
19966  $this->processPackageUrls($pool, $policy, $localRepo, $repositories);
19967 $localRepo->write();
19968 }
19969
19970 return array(0, $devPackages);
19971 }
19972
19973
19974
19975
19976
19977
19978
19979
19980
19981
19982
19983 private function extractDevPackages(array $operations, RepositoryInterface $localRepo, PlatformRepository $platformRepo, array $aliases)
19984 {
19985 if (!$this->package->getDevRequires()) {
19986 return array();
19987 }
19988
19989
19990  $tempLocalRepo = clone $localRepo;
19991 foreach ($operations as $operation) {
19992 switch ($operation->getJobType()) {
19993 case 'install':
19994 case 'markAliasInstalled':
19995 if (!$tempLocalRepo->hasPackage($operation->getPackage())) {
19996 $tempLocalRepo->addPackage(clone $operation->getPackage());
19997 }
19998 break;
19999
20000 case 'uninstall':
20001 case 'markAliasUninstalled':
20002 $tempLocalRepo->removePackage($operation->getPackage());
20003 break;
20004
20005 case 'update':
20006 $tempLocalRepo->removePackage($operation->getInitialPackage());
20007 if (!$tempLocalRepo->hasPackage($operation->getTargetPackage())) {
20008 $tempLocalRepo->addPackage(clone $operation->getTargetPackage());
20009 }
20010 break;
20011
20012 default:
20013 throw new \LogicException('Unknown type: '.$operation->getJobType());
20014 }
20015 }
20016
20017
20018  
20019  
20020  $localRepo = new InstalledArrayRepository(array());
20021 $loader = new ArrayLoader(null, true);
20022 $dumper = new ArrayDumper();
20023 foreach ($tempLocalRepo->getCanonicalPackages() as $pkg) {
20024 $localRepo->addPackage($loader->load($dumper->dump($pkg)));
20025 }
20026 unset($tempLocalRepo, $loader, $dumper);
20027
20028 $policy = $this->createPolicy();
20029 $pool = $this->createPool();
20030 $installedRepo = $this->createInstalledRepo($localRepo, $platformRepo);
20031 $pool->addRepository($installedRepo, $aliases);
20032
20033
20034  $request = $this->createRequest($this->package, $platformRepo);
20035 $request->updateAll();
20036 foreach ($this->package->getRequires() as $link) {
20037 $request->install($link->getTarget(), $link->getConstraint());
20038 }
20039
20040
20041  $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request);
20042 $solver = new Solver($policy, $pool, $installedRepo, $this->io);
20043 $ops = $solver->solve($request, $this->ignorePlatformReqs);
20044 $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request, $ops);
20045
20046 $devPackages = array();
20047 foreach ($ops as $op) {
20048 if ($op->getJobType() === 'uninstall') {
20049 $devPackages[] = $op->getPackage();
20050 }
20051 }
20052
20053 return $devPackages;
20054 }
20055
20056
20057
20058
20059 private function filterDevPackageOperations(array $devPackages, array $operations, RepositoryInterface $localRepo)
20060 {
20061 $finalOps = array();
20062 $packagesToSkip = array();
20063 foreach ($devPackages as $pkg) {
20064 $packagesToSkip[$pkg->getName()] = true;
20065 if ($installedDevPkg = $localRepo->findPackage($pkg->getName(), '*')) {
20066 $finalOps[] = new UninstallOperation($installedDevPkg, 'non-dev install removing it');
20067 }
20068 }
20069
20070
20071  foreach ($operations as $op) {
20072 $package = $op->getJobType() === 'update' ? $op->getTargetPackage() : $op->getPackage();
20073 if (isset($packagesToSkip[$package->getName()])) {
20074 continue;
20075 }
20076
20077 $finalOps[] = $op;
20078 }
20079
20080 return $finalOps;
20081 }
20082
20083
20084
20085
20086
20087
20088
20089
20090
20091
20092
20093
20094
20095
20096 private function movePluginsToFront(array $operations)
20097 {
20098 $installerOps = array();
20099 foreach ($operations as $idx => $op) {
20100 if ($op instanceof InstallOperation) {
20101 $package = $op->getPackage();
20102 } elseif ($op instanceof UpdateOperation) {
20103 $package = $op->getTargetPackage();
20104 } else {
20105 continue;
20106 }
20107
20108 if ($package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer') {
20109
20110  $requires = array_keys($package->getRequires());
20111 foreach ($requires as $index => $req) {
20112 if ($req === 'composer-plugin-api' || preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $req)) {
20113 unset($requires[$index]);
20114 }
20115 }
20116
20117  if (!count($requires)) {
20118 $installerOps[] = $op;
20119 unset($operations[$idx]);
20120 }
20121 }
20122 }
20123
20124 return array_merge($installerOps, $operations);
20125 }
20126
20127
20128
20129
20130
20131
20132
20133
20134 private function moveUninstallsToFront(array $operations)
20135 {
20136 $uninstOps = array();
20137 foreach ($operations as $idx => $op) {
20138 if ($op instanceof UninstallOperation) {
20139 $uninstOps[] = $op;
20140 unset($operations[$idx]);
20141 }
20142 }
20143
20144 return array_merge($uninstOps, $operations);
20145 }
20146
20147
20148
20149
20150 private function createInstalledRepo(RepositoryInterface $localRepo, PlatformRepository $platformRepo)
20151 {
20152
20153  
20154  
20155  $installedRootPackage = clone $this->package;
20156 $installedRootPackage->setRequires(array());
20157 $installedRootPackage->setDevRequires(array());
20158
20159 $repos = array(
20160 $localRepo,
20161 new InstalledArrayRepository(array($installedRootPackage)),
20162 $platformRepo,
20163 );
20164 $installedRepo = new CompositeRepository($repos);
20165 if ($this->additionalInstalledRepository) {
20166 $installedRepo->addRepository($this->additionalInstalledRepository);
20167 }
20168
20169 return $installedRepo;
20170 }
20171
20172
20173
20174
20175
20176 private function createPool(RepositoryInterface $lockedRepository = null)
20177 {
20178 if ($this->update) {
20179 $minimumStability = $this->package->getMinimumStability();
20180 $stabilityFlags = $this->package->getStabilityFlags();
20181
20182 $requires = array_merge($this->package->getRequires(), $this->package->getDevRequires());
20183 } else {
20184 $minimumStability = $this->locker->getMinimumStability();
20185 $stabilityFlags = $this->locker->getStabilityFlags();
20186
20187 $requires = array();
20188 foreach ($lockedRepository->getPackages() as $package) {
20189 $constraint = new Constraint('=', $package->getVersion());
20190 $constraint->setPrettyString($package->getPrettyVersion());
20191 $requires[$package->getName()] = $constraint;
20192 }
20193 }
20194
20195 $rootConstraints = array();
20196 foreach ($requires as $req => $constraint) {
20197
20198  if ($this->ignorePlatformReqs && preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $req)) {
20199 continue;
20200 }
20201 if ($constraint instanceof Link) {
20202 $rootConstraints[$req] = $constraint->getConstraint();
20203 } else {
20204 $rootConstraints[$req] = $constraint;
20205 }
20206 }
20207
20208 return new Pool($minimumStability, $stabilityFlags, $rootConstraints);
20209 }
20210
20211
20212
20213
20214 private function createPolicy()
20215 {
20216 $preferStable = null;
20217 $preferLowest = null;
20218 if (!$this->update) {
20219 $preferStable = $this->locker->getPreferStable();
20220 $preferLowest = $this->locker->getPreferLowest();
20221 }
20222
20223  
20224  if (null === $preferStable) {
20225 $preferStable = $this->preferStable || $this->package->getPreferStable();
20226 }
20227 if (null === $preferLowest) {
20228 $preferLowest = $this->preferLowest;
20229 }
20230
20231 return new DefaultPolicy($preferStable, $preferLowest);
20232 }
20233
20234
20235
20236
20237
20238
20239 private function createRequest(RootPackageInterface $rootPackage, PlatformRepository $platformRepo)
20240 {
20241 $request = new Request();
20242
20243 $constraint = new Constraint('=', $rootPackage->getVersion());
20244 $constraint->setPrettyString($rootPackage->getPrettyVersion());
20245 $request->install($rootPackage->getName(), $constraint);
20246
20247 $fixedPackages = $platformRepo->getPackages();
20248 if ($this->additionalInstalledRepository) {
20249 $additionalFixedPackages = $this->additionalInstalledRepository->getPackages();
20250 $fixedPackages = array_merge($fixedPackages, $additionalFixedPackages);
20251 }
20252
20253
20254  
20255  $provided = $rootPackage->getProvides();
20256 foreach ($fixedPackages as $package) {
20257 $constraint = new Constraint('=', $package->getVersion());
20258 $constraint->setPrettyString($package->getPrettyVersion());
20259
20260
20261  if ($package->getRepository() !== $platformRepo
20262 || !isset($provided[$package->getName()])
20263 || !$provided[$package->getName()]->getConstraint()->matches($constraint)
20264 ) {
20265 $request->fix($package->getName(), $constraint);
20266 }
20267 }
20268
20269 return $request;
20270 }
20271
20272
20273
20274
20275
20276
20277
20278
20279
20280
20281
20282
20283 private function processDevPackages($localRepo, $pool, $policy, $repositories, $installedRepo, $lockedRepository, $task, array $operations = null)
20284 {
20285 if ($task === 'force-updates' && null === $operations) {
20286 throw new \InvalidArgumentException('Missing operations argument');
20287 }
20288 if ($task === 'force-links') {
20289 $operations = array();
20290 }
20291
20292 if ($this->update && $this->updateWhitelist) {
20293 $currentPackages = $this->getCurrentPackages($installedRepo);
20294 }
20295
20296 foreach ($localRepo->getCanonicalPackages() as $package) {
20297
20298  if (!$package->isDev()) {
20299 continue;
20300 }
20301
20302
20303  foreach ($operations as $operation) {
20304 if (('update' === $operation->getJobType() && $operation->getInitialPackage()->equals($package))
20305 || ('uninstall' === $operation->getJobType() && $operation->getPackage()->equals($package))
20306 ) {
20307 continue 2;
20308 }
20309 }
20310
20311 if ($this->update) {
20312
20313  if ($this->updateWhitelist && !$this->isUpdateable($package)) {
20314
20315  foreach ($currentPackages as $curPackage) {
20316 if ($curPackage->isDev() && $curPackage->getName() === $package->getName() && $curPackage->getVersion() === $package->getVersion()) {
20317 if ($task === 'force-links') {
20318 $package->setRequires($curPackage->getRequires());
20319 $package->setConflicts($curPackage->getConflicts());
20320 $package->setProvides($curPackage->getProvides());
20321 $package->setReplaces($curPackage->getReplaces());
20322 } elseif ($task === 'force-updates') {
20323 if (($curPackage->getSourceReference() && $curPackage->getSourceReference() !== $package->getSourceReference())
20324 || ($curPackage->getDistReference() && $curPackage->getDistReference() !== $package->getDistReference())
20325 ) {
20326 $operations[] = new UpdateOperation($package, $curPackage);
20327 }
20328 }
20329
20330 break;
20331 }
20332 }
20333
20334 continue;
20335 }
20336
20337
20338  $matches = $pool->whatProvides($package->getName(), new Constraint('=', $package->getVersion()));
20339 foreach ($matches as $index => $match) {
20340
20341  if (!in_array($match->getRepository(), $repositories, true)) {
20342 unset($matches[$index]);
20343 continue;
20344 }
20345
20346
20347  if ($match->getName() !== $package->getName()) {
20348 unset($matches[$index]);
20349 continue;
20350 }
20351
20352 $matches[$index] = $match->getId();
20353 }
20354
20355
20356  if ($matches && $matches = $policy->selectPreferredPackages($pool, array(), $matches)) {
20357 $newPackage = $pool->literalToPackage($matches[0]);
20358
20359 if ($task === 'force-links' && $newPackage) {
20360 $package->setRequires($newPackage->getRequires());
20361 $package->setConflicts($newPackage->getConflicts());
20362 $package->setProvides($newPackage->getProvides());
20363 $package->setReplaces($newPackage->getReplaces());
20364 }
20365
20366 if ($task === 'force-updates' && $newPackage && (
20367 (($newPackage->getSourceReference() && $newPackage->getSourceReference() !== $package->getSourceReference())
20368 || ($newPackage->getDistReference() && $newPackage->getDistReference() !== $package->getDistReference())
20369 )
20370 )) {
20371 $operations[] = new UpdateOperation($package, $newPackage);
20372
20373 continue;
20374 }
20375 }
20376
20377 if ($task === 'force-updates') {
20378
20379  $references = $this->package->getReferences();
20380
20381 if (isset($references[$package->getName()]) && $references[$package->getName()] !== $package->getSourceReference()) {
20382
20383  $operations[] = new UpdateOperation($package, clone $package);
20384 }
20385 }
20386 } else {
20387
20388  foreach ($lockedRepository->findPackages($package->getName()) as $lockedPackage) {
20389 if ($lockedPackage->isDev() && $lockedPackage->getVersion() === $package->getVersion()) {
20390 if ($task === 'force-links') {
20391 $package->setRequires($lockedPackage->getRequires());
20392 $package->setConflicts($lockedPackage->getConflicts());
20393 $package->setProvides($lockedPackage->getProvides());
20394 $package->setReplaces($lockedPackage->getReplaces());
20395 } elseif ($task === 'force-updates') {
20396 if (($lockedPackage->getSourceReference() && $lockedPackage->getSourceReference() !== $package->getSourceReference())
20397 || ($lockedPackage->getDistReference() && $lockedPackage->getDistReference() !== $package->getDistReference())
20398 ) {
20399 $operations[] = new UpdateOperation($package, $lockedPackage);
20400 }
20401 }
20402
20403 break;
20404 }
20405 }
20406 }
20407 }
20408
20409 return $operations;
20410 }
20411
20412
20413
20414
20415
20416
20417 private function getCurrentPackages($installedRepo)
20418 {
20419 if ($this->locker->isLocked()) {
20420 try {
20421 return $this->locker->getLockedRepository(true)->getPackages();
20422 } catch (\RuntimeException $e) {
20423
20424  return $this->locker->getLockedRepository()->getPackages();
20425 }
20426 }
20427
20428 return $installedRepo->getPackages();
20429 }
20430
20431
20432
20433
20434 private function getRootAliases()
20435 {
20436 if ($this->update) {
20437 $aliases = $this->package->getAliases();
20438 } else {
20439 $aliases = $this->locker->getAliases();
20440 }
20441
20442 $normalizedAliases = array();
20443
20444 foreach ($aliases as $alias) {
20445 $normalizedAliases[$alias['package']][$alias['version']] = array(
20446 'alias' => $alias['alias'],
20447 'alias_normalized' => $alias['alias_normalized'],
20448 );
20449 }
20450
20451 return $normalizedAliases;
20452 }
20453
20454
20455
20456
20457
20458
20459
20460 private function processPackageUrls($pool, $policy, $localRepo, $repositories)
20461 {
20462 if (!$this->update) {
20463 return;
20464 }
20465
20466 $rootRefs = $this->package->getReferences();
20467
20468 foreach ($localRepo->getCanonicalPackages() as $package) {
20469
20470  $matches = $pool->whatProvides($package->getName(), new Constraint('=', $package->getVersion()));
20471 foreach ($matches as $index => $match) {
20472
20473  if (!in_array($match->getRepository(), $repositories, true)) {
20474 unset($matches[$index]);
20475 continue;
20476 }
20477
20478
20479  if ($match->getName() !== $package->getName()) {
20480 unset($matches[$index]);
20481 continue;
20482 }
20483
20484 $matches[$index] = $match->getId();
20485 }
20486
20487
20488  if ($matches && $matches = $policy->selectPreferredPackages($pool, array(), $matches)) {
20489 $newPackage = $pool->literalToPackage($matches[0]);
20490
20491
20492  $sourceUrl = $package->getSourceUrl();
20493 $newSourceUrl = $newPackage->getSourceUrl();
20494 $newReference = $newPackage->getSourceReference();
20495
20496 if ($package->isDev() && isset($rootRefs[$package->getName()]) && $package->getSourceReference() === $rootRefs[$package->getName()]) {
20497 $newReference = $rootRefs[$package->getName()];
20498 }
20499
20500 $this->updatePackageUrl($package, $newSourceUrl, $newPackage->getSourceType(), $newReference, $newPackage->getDistUrl());
20501
20502 if ($package instanceof CompletePackage && $newPackage instanceof CompletePackage) {
20503 $package->setAbandoned($newPackage->getReplacementPackage() ?: $newPackage->isAbandoned());
20504 }
20505
20506 $package->setDistMirrors($newPackage->getDistMirrors());
20507 $package->setSourceMirrors($newPackage->getSourceMirrors());
20508 }
20509 }
20510 }
20511
20512 private function updatePackageUrl(PackageInterface $package, $sourceUrl, $sourceType, $sourceReference, $distUrl)
20513 {
20514 $oldSourceRef = $package->getSourceReference();
20515
20516 if ($package->getSourceUrl() !== $sourceUrl) {
20517 $package->setSourceType($sourceType);
20518 $package->setSourceUrl($sourceUrl);
20519 $package->setSourceReference($sourceReference);
20520 }
20521
20522
20523  
20524  if (preg_match('{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com)/}i', $distUrl)) {
20525 $package->setDistUrl($distUrl);
20526 $this->updateInstallReferences($package, $sourceReference);
20527 }
20528
20529 if ($this->updateWhitelist && !$this->isUpdateable($package)) {
20530 $this->updateInstallReferences($package, $oldSourceRef);
20531 }
20532 }
20533
20534 private function updateInstallReferences(PackageInterface $package, $reference)
20535 {
20536 if (!$reference) {
20537 return;
20538 }
20539
20540 $package->setSourceReference($reference);
20541 $package->setDistReference($reference);
20542
20543 if (preg_match('{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com)/}i', $package->getDistUrl())) {
20544 $package->setDistUrl(preg_replace('{(?<=/)[a-f0-9]{40}(?=/|$)}i', $reference, $package->getDistUrl()));
20545 }
20546 }
20547
20548
20549
20550
20551
20552 private function aliasPlatformPackages(PlatformRepository $platformRepo, $aliases)
20553 {
20554 foreach ($aliases as $package => $versions) {
20555 foreach ($versions as $version => $alias) {
20556 $packages = $platformRepo->findPackages($package, $version);
20557 foreach ($packages as $package) {
20558 $aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']);
20559 $aliasPackage->setRootPackageAlias(true);
20560 $platformRepo->addPackage($aliasPackage);
20561 }
20562 }
20563 }
20564 }
20565
20566
20567
20568
20569
20570 private function isUpdateable(PackageInterface $package)
20571 {
20572 if (!$this->updateWhitelist) {
20573 throw new \LogicException('isUpdateable should only be called when a whitelist is present');
20574 }
20575
20576 foreach ($this->updateWhitelist as $whiteListedPattern => $void) {
20577 $patternRegexp = $this->packageNameToRegexp($whiteListedPattern);
20578 if (preg_match($patternRegexp, $package->getName())) {
20579 return true;
20580 }
20581 }
20582
20583 return false;
20584 }
20585
20586
20587
20588
20589
20590
20591
20592 private function packageNameToRegexp($whiteListedPattern)
20593 {
20594 $cleanedWhiteListedPattern = str_replace('\\*', '.*', preg_quote($whiteListedPattern));
20595
20596 return "{^" . $cleanedWhiteListedPattern . "$}i";
20597 }
20598
20599
20600
20601
20602
20603 private function extractPlatformRequirements($links)
20604 {
20605 $platformReqs = array();
20606 foreach ($links as $link) {
20607 if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $link->getTarget())) {
20608 $platformReqs[$link->getTarget()] = $link->getPrettyConstraint();
20609 }
20610 }
20611
20612 return $platformReqs;
20613 }
20614
20615
20616
20617
20618
20619
20620
20621
20622
20623
20624
20625
20626 private function whitelistUpdateDependencies($localRepo, array $rootRequires, array $rootDevRequires)
20627 {
20628 if (!$this->updateWhitelist) {
20629 return;
20630 }
20631
20632 $rootRequires = array_merge($rootRequires, $rootDevRequires);
20633
20634 $requiredPackageNames = array();
20635 foreach ($rootRequires as $require) {
20636 $requiredPackageNames[] = $require->getTarget();
20637 }
20638
20639 $skipPackages = array();
20640 foreach ($rootRequires as $require) {
20641 $skipPackages[$require->getTarget()] = true;
20642 }
20643
20644 $pool = new Pool;
20645 $pool->addRepository($localRepo);
20646
20647 $seen = array();
20648
20649 $rootRequiredPackageNames = array_keys($rootRequires);
20650
20651 foreach ($this->updateWhitelist as $packageName => $void) {
20652 $packageQueue = new \SplQueue;
20653
20654 $depPackages = $pool->whatProvides($packageName);
20655
20656 $nameMatchesRequiredPackage = in_array($packageName, $requiredPackageNames, true);
20657
20658
20659  if (!$nameMatchesRequiredPackage) {
20660 $whitelistPatternRegexp = $this->packageNameToRegexp($packageName);
20661 foreach ($rootRequiredPackageNames as $rootRequiredPackageName) {
20662 if (preg_match($whitelistPatternRegexp, $rootRequiredPackageName)) {
20663 $nameMatchesRequiredPackage = true;
20664 break;
20665 }
20666 }
20667 }
20668
20669 if (count($depPackages) == 0 && !$nameMatchesRequiredPackage && !in_array($packageName, array('nothing', 'lock', 'mirrors'))) {
20670 $this->io->writeError('<warning>Package "' . $packageName . '" listed for update is not installed. Ignoring.</warning>');
20671 }
20672
20673 foreach ($depPackages as $depPackage) {
20674 $packageQueue->enqueue($depPackage);
20675 }
20676
20677 while (!$packageQueue->isEmpty()) {
20678 $package = $packageQueue->dequeue();
20679 if (isset($seen[$package->getId()])) {
20680 continue;
20681 }
20682
20683 $seen[$package->getId()] = true;
20684 $this->updateWhitelist[$package->getName()] = true;
20685
20686 if (!$this->whitelistDependencies) {
20687 continue;
20688 }
20689
20690 $requires = $package->getRequires();
20691
20692 foreach ($requires as $require) {
20693 $requirePackages = $pool->whatProvides($require->getTarget());
20694
20695 foreach ($requirePackages as $requirePackage) {
20696 if (isset($this->updateWhitelist[$requirePackage->getName()])) {
20697 continue;
20698 }
20699
20700 if (isset($skipPackages[$requirePackage->getName()])) {
20701 $this->io->writeError('<warning>Dependency "' . $requirePackage->getName() . '" is also a root requirement, but is not explicitly whitelisted. Ignoring.</warning>');
20702 continue;
20703 }
20704
20705 $packageQueue->enqueue($requirePackage);
20706 }
20707 }
20708 }
20709 }
20710 }
20711
20712
20713
20714
20715
20716
20717
20718
20719 private function mockLocalRepositories(RepositoryManager $rm)
20720 {
20721 $packages = array();
20722 foreach ($rm->getLocalRepository()->getPackages() as $package) {
20723 $packages[(string) $package] = clone $package;
20724 }
20725 foreach ($packages as $key => $package) {
20726 if ($package instanceof AliasPackage) {
20727 $alias = (string) $package->getAliasOf();
20728 $packages[$key] = new AliasPackage($packages[$alias], $package->getVersion(), $package->getPrettyVersion());
20729 }
20730 }
20731 $rm->setLocalRepository(
20732 new InstalledArrayRepository($packages)
20733 );
20734 }
20735
20736
20737
20738
20739
20740
20741
20742
20743 public static function create(IOInterface $io, Composer $composer)
20744 {
20745 return new static(
20746 $io,
20747 $composer->getConfig(),
20748 $composer->getPackage(),
20749 $composer->getDownloadManager(),
20750 $composer->getRepositoryManager(),
20751 $composer->getLocker(),
20752 $composer->getInstallationManager(),
20753 $composer->getEventDispatcher(),
20754 $composer->getAutoloadGenerator()
20755 );
20756 }
20757
20758
20759
20760
20761
20762 public function setAdditionalInstalledRepository(RepositoryInterface $additionalInstalledRepository)
20763 {
20764 $this->additionalInstalledRepository = $additionalInstalledRepository;
20765
20766 return $this;
20767 }
20768
20769
20770
20771
20772
20773
20774
20775 public function setDryRun($dryRun = true)
20776 {
20777 $this->dryRun = (bool) $dryRun;
20778
20779 return $this;
20780 }
20781
20782
20783
20784
20785
20786
20787 public function isDryRun()
20788 {
20789 return $this->dryRun;
20790 }
20791
20792
20793
20794
20795
20796
20797
20798 public function setPreferSource($preferSource = true)
20799 {
20800 $this->preferSource = (bool) $preferSource;
20801
20802 return $this;
20803 }
20804
20805
20806
20807
20808
20809
20810
20811 public function setPreferDist($preferDist = true)
20812 {
20813 $this->preferDist = (bool) $preferDist;
20814
20815 return $this;
20816 }
20817
20818
20819
20820
20821
20822
20823
20824 public function setOptimizeAutoloader($optimizeAutoloader = false)
20825 {
20826 $this->optimizeAutoloader = (bool) $optimizeAutoloader;
20827 if (!$this->optimizeAutoloader) {
20828
20829  
20830  $this->setClassMapAuthoritative(false);
20831 }
20832
20833 return $this;
20834 }
20835
20836
20837
20838
20839
20840
20841
20842
20843 public function setClassMapAuthoritative($classMapAuthoritative = false)
20844 {
20845 $this->classMapAuthoritative = (bool) $classMapAuthoritative;
20846 if ($this->classMapAuthoritative) {
20847
20848  $this->setOptimizeAutoloader(true);
20849 }
20850
20851 return $this;
20852 }
20853
20854
20855
20856
20857
20858
20859
20860 public function setApcuAutoloader($apcuAutoloader = false)
20861 {
20862 $this->apcuAutoloader = (bool) $apcuAutoloader;
20863
20864 return $this;
20865 }
20866
20867
20868
20869
20870
20871
20872
20873 public function setUpdate($update = true)
20874 {
20875 $this->update = (bool) $update;
20876
20877 return $this;
20878 }
20879
20880
20881
20882
20883
20884
20885
20886 public function setDevMode($devMode = true)
20887 {
20888 $this->devMode = (bool) $devMode;
20889
20890 return $this;
20891 }
20892
20893
20894
20895
20896
20897
20898
20899
20900
20901 public function setDumpAutoloader($dumpAutoloader = true)
20902 {
20903 $this->dumpAutoloader = (bool) $dumpAutoloader;
20904
20905 return $this;
20906 }
20907
20908
20909
20910
20911
20912
20913
20914
20915
20916 public function setRunScripts($runScripts = true)
20917 {
20918 $this->runScripts = (bool) $runScripts;
20919
20920 return $this;
20921 }
20922
20923
20924
20925
20926
20927
20928
20929 public function setConfig(Config $config)
20930 {
20931 $this->config = $config;
20932
20933 return $this;
20934 }
20935
20936
20937
20938
20939
20940
20941
20942 public function setVerbose($verbose = true)
20943 {
20944 $this->verbose = (bool) $verbose;
20945
20946 return $this;
20947 }
20948
20949
20950
20951
20952
20953
20954 public function isVerbose()
20955 {
20956 return $this->verbose;
20957 }
20958
20959
20960
20961
20962
20963
20964
20965 public function setIgnorePlatformRequirements($ignorePlatformReqs = false)
20966 {
20967 $this->ignorePlatformReqs = (bool) $ignorePlatformReqs;
20968
20969 return $this;
20970 }
20971
20972
20973
20974
20975
20976
20977
20978
20979 public function setUpdateWhitelist(array $packages)
20980 {
20981 $this->updateWhitelist = array_flip(array_map('strtolower', $packages));
20982
20983 return $this;
20984 }
20985
20986
20987
20988
20989
20990
20991
20992 public function setWhitelistDependencies($updateDependencies = true)
20993 {
20994 $this->whitelistDependencies = (bool) $updateDependencies;
20995
20996 return $this;
20997 }
20998
20999
21000
21001
21002
21003
21004
21005 public function setPreferStable($preferStable = true)
21006 {
21007 $this->preferStable = (bool) $preferStable;
21008
21009 return $this;
21010 }
21011
21012
21013
21014
21015
21016
21017
21018 public function setPreferLowest($preferLowest = true)
21019 {
21020 $this->preferLowest = (bool) $preferLowest;
21021
21022 return $this;
21023 }
21024
21025
21026
21027
21028
21029
21030
21031
21032
21033 public function setWriteLock($writeLock = true)
21034 {
21035 $this->writeLock = (bool) $writeLock;
21036
21037 return $this;
21038 }
21039
21040
21041
21042
21043
21044
21045
21046
21047
21048 public function setExecuteOperations($executeOperations = true)
21049 {
21050 $this->executeOperations = (bool) $executeOperations;
21051
21052 return $this;
21053 }
21054
21055
21056
21057
21058
21059
21060
21061 public function setSkipSuggest($skipSuggest = true)
21062 {
21063 $this->skipSuggest = (bool) $skipSuggest;
21064
21065 return $this;
21066 }
21067
21068
21069
21070
21071
21072
21073
21074
21075
21076
21077 public function disablePlugins()
21078 {
21079 $this->installationManager->disablePlugins();
21080
21081 return $this;
21082 }
21083
21084
21085
21086
21087
21088 public function setSuggestedPackagesReporter(SuggestedPackagesReporter $suggestedPackagesReporter)
21089 {
21090 $this->suggestedPackagesReporter = $suggestedPackagesReporter;
21091
21092 return $this;
21093 }
21094 }
21095 <?php
21096
21097
21098
21099
21100
21101
21102
21103
21104
21105
21106
21107 namespace Composer\Installer;
21108
21109 use Composer\IO\IOInterface;
21110 use Composer\Package\PackageInterface;
21111 use Composer\Util\Filesystem;
21112 use Composer\Util\Platform;
21113 use Composer\Util\ProcessExecutor;
21114 use Composer\Util\Silencer;
21115
21116
21117
21118
21119
21120
21121
21122
21123 class BinaryInstaller
21124 {
21125 protected $binDir;
21126 protected $binCompat;
21127 protected $io;
21128 protected $filesystem;
21129
21130
21131
21132
21133
21134
21135
21136 public function __construct(IOInterface $io, $binDir, $binCompat, Filesystem $filesystem = null)
21137 {
21138 $this->binDir = $binDir;
21139 $this->binCompat = $binCompat;
21140 $this->io = $io;
21141 $this->filesystem = $filesystem ?: new Filesystem();
21142 }
21143
21144 public function installBinaries(PackageInterface $package, $installPath, $warnOnOverwrite = true)
21145 {
21146 $binaries = $this->getBinaries($package);
21147 if (!$binaries) {
21148 return;
21149 }
21150 foreach ($binaries as $bin) {
21151 $binPath = $installPath.'/'.$bin;
21152 if (!file_exists($binPath)) {
21153 $this->io->writeError('    <warning>Skipped installation of bin '.$bin.' for package '.$package->getName().': file not found in package</warning>');
21154 continue;
21155 }
21156
21157
21158  
21159  
21160  
21161  $binPath = realpath($binPath);
21162
21163 $this->initializeBinDir();
21164 $link = $this->binDir.'/'.basename($bin);
21165 if (file_exists($link)) {
21166 if (is_link($link)) {
21167
21168  
21169  
21170  Silencer::call('chmod', $link, 0777 & ~umask());
21171 }
21172 if ($warnOnOverwrite) {
21173 $this->io->writeError('    Skipped installation of bin '.$bin.' for package '.$package->getName().': name conflicts with an existing file');
21174 }
21175 continue;
21176 }
21177
21178 if ($this->binCompat === "auto") {
21179 if (Platform::isWindows()) {
21180 $this->installFullBinaries($binPath, $link, $bin, $package);
21181 } else {
21182 $this->installSymlinkBinaries($binPath, $link);
21183 }
21184 } elseif ($this->binCompat === "full") {
21185 $this->installFullBinaries($binPath, $link, $bin, $package);
21186 }
21187 Silencer::call('chmod', $link, 0777 & ~umask());
21188 }
21189 }
21190
21191 public function removeBinaries(PackageInterface $package)
21192 {
21193 $this->initializeBinDir();
21194
21195 $binaries = $this->getBinaries($package);
21196 if (!$binaries) {
21197 return;
21198 }
21199 foreach ($binaries as $bin) {
21200 $link = $this->binDir.'/'.basename($bin);
21201 if (is_link($link) || file_exists($link)) {
21202 $this->filesystem->unlink($link);
21203 }
21204 if (file_exists($link.'.bat')) {
21205 $this->filesystem->unlink($link.'.bat');
21206 }
21207 }
21208
21209
21210  if ((is_dir($this->binDir)) && ($this->filesystem->isDirEmpty($this->binDir))) {
21211 Silencer::call('rmdir', $this->binDir);
21212 }
21213 }
21214
21215 public static function determineBinaryCaller($bin)
21216 {
21217 if ('.bat' === substr($bin, -4) || '.exe' === substr($bin, -4)) {
21218 return 'call';
21219 }
21220
21221 $handle = fopen($bin, 'r');
21222 $line = fgets($handle);
21223 fclose($handle);
21224 if (preg_match('{^#!/(?:usr/bin/env )?(?:[^/]+/)*(.+)$}m', $line, $match)) {
21225 return trim($match[1]);
21226 }
21227
21228 return 'php';
21229 }
21230
21231 protected function getBinaries(PackageInterface $package)
21232 {
21233 return $package->getBinaries();
21234 }
21235
21236 protected function installFullBinaries($binPath, $link, $bin, PackageInterface $package)
21237 {
21238
21239  if ('.bat' !== substr($binPath, -4)) {
21240 $this->installUnixyProxyBinaries($binPath, $link);
21241 @chmod($link, 0777 & ~umask());
21242 $link .= '.bat';
21243 if (file_exists($link)) {
21244 $this->io->writeError('    Skipped installation of bin '.$bin.'.bat proxy for package '.$package->getName().': a .bat proxy was already installed');
21245 }
21246 }
21247 if (!file_exists($link)) {
21248 file_put_contents($link, $this->generateWindowsProxyCode($binPath, $link));
21249 }
21250 }
21251
21252 protected function installSymlinkBinaries($binPath, $link)
21253 {
21254 if (!$this->filesystem->relativeSymlink($binPath, $link)) {
21255 $this->installUnixyProxyBinaries($binPath, $link);
21256 }
21257 }
21258
21259 protected function installUnixyProxyBinaries($binPath, $link)
21260 {
21261 file_put_contents($link, $this->generateUnixyProxyCode($binPath, $link));
21262 }
21263
21264 protected function initializeBinDir()
21265 {
21266 $this->filesystem->ensureDirectoryExists($this->binDir);
21267 $this->binDir = realpath($this->binDir);
21268 }
21269
21270 protected function generateWindowsProxyCode($bin, $link)
21271 {
21272 $binPath = $this->filesystem->findShortestPath($link, $bin);
21273 $caller = self::determineBinaryCaller($bin);
21274
21275 return "@ECHO OFF\r\n".
21276 "setlocal DISABLEDELAYEDEXPANSION\r\n".
21277 "SET BIN_TARGET=%~dp0/".trim(ProcessExecutor::escape($binPath), '"\'')."\r\n".
21278 "{$caller} \"%BIN_TARGET%\" %*\r\n";
21279 }
21280
21281 protected function generateUnixyProxyCode($bin, $link)
21282 {
21283 $binPath = $this->filesystem->findShortestPath($link, $bin);
21284
21285 $binDir = ProcessExecutor::escape(dirname($binPath));
21286 $binFile = basename($binPath);
21287
21288 $proxyCode = <<<PROXY
21289 #!/usr/bin/env sh
21290
21291 dir=$(d=\${0%[/\\\\]*}; cd "\$d"; cd $binDir && pwd)
21292
21293 # See if we are running in Cygwin by checking for cygpath program
21294 if command -v 'cygpath' >/dev/null 2>&1; then
21295         # Cygwin paths start with /cygdrive/ which will break windows PHP,
21296         # so we need to translate the dir path to windows format. However
21297         # we could be using cygwin PHP which does not require this, so we
21298         # test if the path to PHP starts with /cygdrive/ rather than /usr/bin
21299         if [[ $(which php) == /cygdrive/* ]]; then
21300                 dir=$(cygpath -m "\$dir");
21301         fi
21302 fi
21303
21304 dir=$(echo \$dir | sed 's/ /\ /g')
21305 "\${dir}/$binFile" "$@"
21306
21307 PROXY;
21308
21309 return $proxyCode;
21310 }
21311 }
21312 <?php
21313
21314
21315
21316
21317
21318
21319
21320
21321
21322
21323
21324 namespace Composer\Installer;
21325
21326 use Composer\Package\PackageInterface;
21327
21328
21329
21330
21331
21332
21333 interface BinaryPresenceInterface
21334 {
21335
21336
21337
21338
21339
21340 public function ensureBinariesPresence(PackageInterface $package);
21341 }
21342 <?php
21343
21344
21345
21346
21347
21348
21349
21350
21351
21352
21353
21354 namespace Composer\Installer;
21355
21356 use Composer\IO\IOInterface;
21357 use Composer\Package\PackageInterface;
21358 use Composer\Package\AliasPackage;
21359 use Composer\Repository\RepositoryInterface;
21360 use Composer\Repository\InstalledRepositoryInterface;
21361 use Composer\DependencyResolver\Operation\OperationInterface;
21362 use Composer\DependencyResolver\Operation\InstallOperation;
21363 use Composer\DependencyResolver\Operation\UpdateOperation;
21364 use Composer\DependencyResolver\Operation\UninstallOperation;
21365 use Composer\DependencyResolver\Operation\MarkAliasInstalledOperation;
21366 use Composer\DependencyResolver\Operation\MarkAliasUninstalledOperation;
21367 use Composer\Util\StreamContextFactory;
21368
21369
21370
21371
21372
21373
21374
21375
21376 class InstallationManager
21377 {
21378 private $installers = array();
21379 private $cache = array();
21380 private $notifiablePackages = array();
21381
21382 public function reset()
21383 {
21384 $this->notifiablePackages = array();
21385 }
21386
21387
21388
21389
21390
21391
21392 public function addInstaller(InstallerInterface $installer)
21393 {
21394 array_unshift($this->installers, $installer);
21395 $this->cache = array();
21396 }
21397
21398
21399
21400
21401
21402
21403 public function removeInstaller(InstallerInterface $installer)
21404 {
21405 if (false !== ($key = array_search($installer, $this->installers, true))) {
21406 array_splice($this->installers, $key, 1);
21407 $this->cache = array();
21408 }
21409 }
21410
21411
21412
21413
21414
21415
21416
21417
21418 public function disablePlugins()
21419 {
21420 foreach ($this->installers as $i => $installer) {
21421 if (!$installer instanceof PluginInstaller) {
21422 continue;
21423 }
21424
21425 unset($this->installers[$i]);
21426 }
21427 }
21428
21429
21430
21431
21432
21433
21434
21435
21436
21437 public function getInstaller($type)
21438 {
21439 $type = strtolower($type);
21440
21441 if (isset($this->cache[$type])) {
21442 return $this->cache[$type];
21443 }
21444
21445 foreach ($this->installers as $installer) {
21446 if ($installer->supports($type)) {
21447 return $this->cache[$type] = $installer;
21448 }
21449 }
21450
21451 throw new \InvalidArgumentException('Unknown installer type: '.$type);
21452 }
21453
21454
21455
21456
21457
21458
21459
21460
21461
21462 public function isPackageInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
21463 {
21464 if ($package instanceof AliasPackage) {
21465 return $repo->hasPackage($package) && $this->isPackageInstalled($repo, $package->getAliasOf());
21466 }
21467
21468 return $this->getInstaller($package->getType())->isInstalled($repo, $package);
21469 }
21470
21471
21472
21473
21474
21475
21476
21477 public function ensureBinariesPresence(PackageInterface $package)
21478 {
21479 try {
21480 $installer = $this->getInstaller($package->getType());
21481 } catch (\InvalidArgumentException $e) {
21482
21483  return;
21484 }
21485
21486
21487  if ($installer instanceof BinaryPresenceInterface) {
21488 $installer->ensureBinariesPresence($package);
21489 }
21490 }
21491
21492
21493
21494
21495
21496
21497
21498 public function execute(RepositoryInterface $repo, OperationInterface $operation)
21499 {
21500 $method = $operation->getJobType();
21501 $this->$method($repo, $operation);
21502 }
21503
21504
21505
21506
21507
21508
21509
21510 public function install(RepositoryInterface $repo, InstallOperation $operation)
21511 {
21512 $package = $operation->getPackage();
21513 $installer = $this->getInstaller($package->getType());
21514 $installer->install($repo, $package);
21515 $this->markForNotification($package);
21516 }
21517
21518
21519
21520
21521
21522
21523
21524 public function update(RepositoryInterface $repo, UpdateOperation $operation)
21525 {
21526 $initial = $operation->getInitialPackage();
21527 $target = $operation->getTargetPackage();
21528
21529 $initialType = $initial->getType();
21530 $targetType = $target->getType();
21531
21532 if ($initialType === $targetType) {
21533 $installer = $this->getInstaller($initialType);
21534 $installer->update($repo, $initial, $target);
21535 $this->markForNotification($target);
21536 } else {
21537 $this->getInstaller($initialType)->uninstall($repo, $initial);
21538 $this->getInstaller($targetType)->install($repo, $target);
21539 }
21540 }
21541
21542
21543
21544
21545
21546
21547
21548 public function uninstall(RepositoryInterface $repo, UninstallOperation $operation)
21549 {
21550 $package = $operation->getPackage();
21551 $installer = $this->getInstaller($package->getType());
21552 $installer->uninstall($repo, $package);
21553 }
21554
21555
21556
21557
21558
21559
21560
21561 public function markAliasInstalled(RepositoryInterface $repo, MarkAliasInstalledOperation $operation)
21562 {
21563 $package = $operation->getPackage();
21564
21565 if (!$repo->hasPackage($package)) {
21566 $repo->addPackage(clone $package);
21567 }
21568 }
21569
21570
21571
21572
21573
21574
21575
21576 public function markAliasUninstalled(RepositoryInterface $repo, MarkAliasUninstalledOperation $operation)
21577 {
21578 $package = $operation->getPackage();
21579
21580 $repo->removePackage($package);
21581 }
21582
21583
21584
21585
21586
21587
21588
21589 public function getInstallPath(PackageInterface $package)
21590 {
21591 $installer = $this->getInstaller($package->getType());
21592
21593 return $installer->getInstallPath($package);
21594 }
21595
21596 public function notifyInstalls(IOInterface $io)
21597 {
21598 foreach ($this->notifiablePackages as $repoUrl => $packages) {
21599 $repositoryName = parse_url($repoUrl, PHP_URL_HOST);
21600 if ($io->hasAuthentication($repositoryName)) {
21601 $auth = $io->getAuthentication($repositoryName);
21602 $authStr = base64_encode($auth['username'] . ':' . $auth['password']);
21603 $authHeader = 'Authorization: Basic '.$authStr;
21604 }
21605
21606
21607  if (strpos($repoUrl, '%package%')) {
21608 foreach ($packages as $package) {
21609 $url = str_replace('%package%', $package->getPrettyName(), $repoUrl);
21610
21611 $params = array(
21612 'version' => $package->getPrettyVersion(),
21613 'version_normalized' => $package->getVersion(),
21614 );
21615 $opts = array('http' =>
21616 array(
21617 'method' => 'POST',
21618 'header' => array('Content-type: application/x-www-form-urlencoded'),
21619 'content' => http_build_query($params, '', '&'),
21620 'timeout' => 3,
21621 ),
21622 );
21623 if (isset($authHeader)) {
21624 $opts['http']['header'][] = $authHeader;
21625 }
21626
21627 $context = StreamContextFactory::getContext($url, $opts);
21628 @file_get_contents($url, false, $context);
21629 }
21630
21631 continue;
21632 }
21633
21634 $postData = array('downloads' => array());
21635 foreach ($packages as $package) {
21636 $postData['downloads'][] = array(
21637 'name' => $package->getPrettyName(),
21638 'version' => $package->getVersion(),
21639 );
21640 }
21641
21642 $opts = array('http' =>
21643 array(
21644 'method' => 'POST',
21645 'header' => array('Content-Type: application/json'),
21646 'content' => json_encode($postData),
21647 'timeout' => 6,
21648 ),
21649 );
21650 if (isset($authHeader)) {
21651 $opts['http']['header'][] = $authHeader;
21652 }
21653
21654 $context = StreamContextFactory::getContext($repoUrl, $opts);
21655 @file_get_contents($repoUrl, false, $context);
21656 }
21657
21658 $this->reset();
21659 }
21660
21661 private function markForNotification(PackageInterface $package)
21662 {
21663 if ($package->getNotificationUrl()) {
21664 $this->notifiablePackages[$package->getNotificationUrl()][$package->getName()] = $package;
21665 }
21666 }
21667 }
21668 <?php
21669
21670
21671
21672
21673
21674
21675
21676
21677
21678
21679
21680 namespace Composer\Installer;
21681
21682 use Composer\Composer;
21683 use Composer\DependencyResolver\PolicyInterface;
21684 use Composer\DependencyResolver\Operation\OperationInterface;
21685 use Composer\DependencyResolver\Pool;
21686 use Composer\DependencyResolver\Request;
21687 use Composer\EventDispatcher\Event;
21688 use Composer\IO\IOInterface;
21689 use Composer\Repository\CompositeRepository;
21690
21691
21692
21693
21694
21695
21696 class InstallerEvent extends Event
21697 {
21698
21699
21700
21701 private $composer;
21702
21703
21704
21705
21706 private $io;
21707
21708
21709
21710
21711 private $devMode;
21712
21713
21714
21715
21716 private $policy;
21717
21718
21719
21720
21721 private $pool;
21722
21723
21724
21725
21726 private $installedRepo;
21727
21728
21729
21730
21731 private $request;
21732
21733
21734
21735
21736 private $operations;
21737
21738
21739
21740
21741
21742
21743
21744
21745
21746
21747
21748
21749
21750
21751 public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
21752 {
21753 parent::__construct($eventName);
21754
21755 $this->composer = $composer;
21756 $this->io = $io;
21757 $this->devMode = $devMode;
21758 $this->policy = $policy;
21759 $this->pool = $pool;
21760 $this->installedRepo = $installedRepo;
21761 $this->request = $request;
21762 $this->operations = $operations;
21763 }
21764
21765
21766
21767
21768 public function getComposer()
21769 {
21770 return $this->composer;
21771 }
21772
21773
21774
21775
21776 public function getIO()
21777 {
21778 return $this->io;
21779 }
21780
21781
21782
21783
21784 public function isDevMode()
21785 {
21786 return $this->devMode;
21787 }
21788
21789
21790
21791
21792 public function getPolicy()
21793 {
21794 return $this->policy;
21795 }
21796
21797
21798
21799
21800 public function getPool()
21801 {
21802 return $this->pool;
21803 }
21804
21805
21806
21807
21808 public function getInstalledRepo()
21809 {
21810 return $this->installedRepo;
21811 }
21812
21813
21814
21815
21816 public function getRequest()
21817 {
21818 return $this->request;
21819 }
21820
21821
21822
21823
21824 public function getOperations()
21825 {
21826 return $this->operations;
21827 }
21828 }
21829 <?php
21830
21831
21832
21833
21834
21835
21836
21837
21838
21839
21840
21841 namespace Composer\Installer;
21842
21843
21844
21845
21846
21847
21848 class InstallerEvents
21849 {
21850
21851
21852
21853
21854
21855
21856
21857
21858
21859 const PRE_DEPENDENCIES_SOLVING = 'pre-dependencies-solving';
21860
21861
21862
21863
21864
21865
21866
21867
21868
21869
21870 const POST_DEPENDENCIES_SOLVING = 'post-dependencies-solving';
21871 }
21872 <?php
21873
21874
21875
21876
21877
21878
21879
21880
21881
21882
21883
21884 namespace Composer\Installer;
21885
21886 use Composer\Package\PackageInterface;
21887 use Composer\Repository\InstalledRepositoryInterface;
21888 use InvalidArgumentException;
21889
21890
21891
21892
21893
21894
21895
21896 interface InstallerInterface
21897 {
21898
21899
21900
21901
21902
21903
21904 public function supports($packageType);
21905
21906
21907
21908
21909
21910
21911
21912
21913
21914 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package);
21915
21916
21917
21918
21919
21920
21921
21922 public function install(InstalledRepositoryInterface $repo, PackageInterface $package);
21923
21924
21925
21926
21927
21928
21929
21930
21931
21932
21933 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target);
21934
21935
21936
21937
21938
21939
21940
21941 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package);
21942
21943
21944
21945
21946
21947
21948
21949 public function getInstallPath(PackageInterface $package);
21950 }
21951 <?php
21952
21953
21954
21955
21956
21957
21958
21959
21960
21961
21962
21963 namespace Composer\Installer;
21964
21965 use Composer\Composer;
21966 use Composer\IO\IOInterface;
21967 use Composer\Repository\InstalledRepositoryInterface;
21968 use Composer\Package\PackageInterface;
21969 use Composer\Util\Filesystem;
21970 use Composer\Util\Silencer;
21971
21972
21973
21974
21975
21976
21977
21978 class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
21979 {
21980 protected $composer;
21981 protected $vendorDir;
21982 protected $binDir;
21983 protected $downloadManager;
21984 protected $io;
21985 protected $type;
21986 protected $filesystem;
21987 protected $binCompat;
21988 protected $binaryInstaller;
21989
21990
21991
21992
21993
21994
21995
21996
21997
21998
21999 public function __construct(IOInterface $io, Composer $composer, $type = 'library', Filesystem $filesystem = null, BinaryInstaller $binaryInstaller = null)
22000 {
22001 $this->composer = $composer;
22002 $this->downloadManager = $composer->getDownloadManager();
22003 $this->io = $io;
22004 $this->type = $type;
22005
22006 $this->filesystem = $filesystem ?: new Filesystem();
22007 $this->vendorDir = rtrim($composer->getConfig()->get('vendor-dir'), '/');
22008 $this->binaryInstaller = $binaryInstaller ?: new BinaryInstaller($this->io, rtrim($composer->getConfig()->get('bin-dir'), '/'), $composer->getConfig()->get('bin-compat'), $this->filesystem);
22009 }
22010
22011
22012
22013
22014 public function supports($packageType)
22015 {
22016 return $packageType === $this->type || null === $this->type;
22017 }
22018
22019
22020
22021
22022 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
22023 {
22024 return $repo->hasPackage($package) && is_readable($this->getInstallPath($package));
22025 }
22026
22027
22028
22029
22030 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
22031 {
22032 $this->initializeVendorDir();
22033 $downloadPath = $this->getInstallPath($package);
22034
22035
22036  if (!is_readable($downloadPath) && $repo->hasPackage($package)) {
22037 $this->binaryInstaller->removeBinaries($package);
22038 }
22039
22040 $this->installCode($package);
22041 $this->binaryInstaller->installBinaries($package, $this->getInstallPath($package));
22042 if (!$repo->hasPackage($package)) {
22043 $repo->addPackage(clone $package);
22044 }
22045 }
22046
22047
22048
22049
22050 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
22051 {
22052 if (!$repo->hasPackage($initial)) {
22053 throw new \InvalidArgumentException('Package is not installed: '.$initial);
22054 }
22055
22056 $this->initializeVendorDir();
22057
22058 $this->binaryInstaller->removeBinaries($initial);
22059 $this->updateCode($initial, $target);
22060 $this->binaryInstaller->installBinaries($target, $this->getInstallPath($target));
22061 $repo->removePackage($initial);
22062 if (!$repo->hasPackage($target)) {
22063 $repo->addPackage(clone $target);
22064 }
22065 }
22066
22067
22068
22069
22070 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
22071 {
22072 if (!$repo->hasPackage($package)) {
22073 throw new \InvalidArgumentException('Package is not installed: '.$package);
22074 }
22075
22076 $this->removeCode($package);
22077 $this->binaryInstaller->removeBinaries($package);
22078 $repo->removePackage($package);
22079
22080 $downloadPath = $this->getPackageBasePath($package);
22081 if (strpos($package->getName(), '/')) {
22082 $packageVendorDir = dirname($downloadPath);
22083 if (is_dir($packageVendorDir) && $this->filesystem->isDirEmpty($packageVendorDir)) {
22084 Silencer::call('rmdir', $packageVendorDir);
22085 }
22086 }
22087 }
22088
22089
22090
22091
22092 public function getInstallPath(PackageInterface $package)
22093 {
22094 $this->initializeVendorDir();
22095
22096 $basePath = ($this->vendorDir ? $this->vendorDir.'/' : '') . $package->getPrettyName();
22097 $targetDir = $package->getTargetDir();
22098
22099 return $basePath . ($targetDir ? '/'.$targetDir : '');
22100 }
22101
22102
22103
22104
22105
22106
22107 public function ensureBinariesPresence(PackageInterface $package)
22108 {
22109 $this->binaryInstaller->installBinaries($package, $this->getInstallPath($package), false);
22110 }
22111
22112
22113
22114
22115
22116
22117
22118
22119
22120
22121 protected function getPackageBasePath(PackageInterface $package)
22122 {
22123 $installPath = $this->getInstallPath($package);
22124 $targetDir = $package->getTargetDir();
22125
22126 if ($targetDir) {
22127 return preg_replace('{/*'.str_replace('/', '/+', preg_quote($targetDir)).'/?$}', '', $installPath);
22128 }
22129
22130 return $installPath;
22131 }
22132
22133 protected function installCode(PackageInterface $package)
22134 {
22135 $downloadPath = $this->getInstallPath($package);
22136 $this->downloadManager->download($package, $downloadPath);
22137 }
22138
22139 protected function updateCode(PackageInterface $initial, PackageInterface $target)
22140 {
22141 $initialDownloadPath = $this->getInstallPath($initial);
22142 $targetDownloadPath = $this->getInstallPath($target);
22143 if ($targetDownloadPath !== $initialDownloadPath) {
22144
22145  
22146  if (substr($initialDownloadPath, 0, strlen($targetDownloadPath)) === $targetDownloadPath
22147 || substr($targetDownloadPath, 0, strlen($initialDownloadPath)) === $initialDownloadPath
22148 ) {
22149 $this->removeCode($initial);
22150 $this->installCode($target);
22151
22152 return;
22153 }
22154
22155 $this->filesystem->rename($initialDownloadPath, $targetDownloadPath);
22156 }
22157 $this->downloadManager->update($initial, $target, $targetDownloadPath);
22158 }
22159
22160 protected function removeCode(PackageInterface $package)
22161 {
22162 $downloadPath = $this->getPackageBasePath($package);
22163 $this->downloadManager->remove($package, $downloadPath);
22164 }
22165
22166 protected function initializeVendorDir()
22167 {
22168 $this->filesystem->ensureDirectoryExists($this->vendorDir);
22169 $this->vendorDir = realpath($this->vendorDir);
22170 }
22171 }
22172 <?php
22173
22174
22175
22176
22177
22178
22179
22180
22181
22182
22183
22184 namespace Composer\Installer;
22185
22186 use Composer\Repository\InstalledRepositoryInterface;
22187 use Composer\Package\PackageInterface;
22188
22189
22190
22191
22192
22193
22194 class MetapackageInstaller implements InstallerInterface
22195 {
22196
22197
22198
22199 public function supports($packageType)
22200 {
22201 return $packageType === 'metapackage';
22202 }
22203
22204
22205
22206
22207 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
22208 {
22209 return $repo->hasPackage($package);
22210 }
22211
22212
22213
22214
22215 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
22216 {
22217 $repo->addPackage(clone $package);
22218 }
22219
22220
22221
22222
22223 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
22224 {
22225 if (!$repo->hasPackage($initial)) {
22226 throw new \InvalidArgumentException('Package is not installed: '.$initial);
22227 }
22228
22229 $repo->removePackage($initial);
22230 $repo->addPackage(clone $target);
22231 }
22232
22233
22234
22235
22236 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
22237 {
22238 if (!$repo->hasPackage($package)) {
22239 throw new \InvalidArgumentException('Package is not installed: '.$package);
22240 }
22241
22242 $repo->removePackage($package);
22243 }
22244
22245
22246
22247
22248 public function getInstallPath(PackageInterface $package)
22249 {
22250 return '';
22251 }
22252 }
22253 <?php
22254
22255
22256
22257
22258
22259
22260
22261
22262
22263
22264
22265 namespace Composer\Installer;
22266
22267 use Composer\Repository\InstalledRepositoryInterface;
22268 use Composer\Package\PackageInterface;
22269
22270
22271
22272
22273
22274
22275
22276
22277 class NoopInstaller implements InstallerInterface
22278 {
22279
22280
22281
22282 public function supports($packageType)
22283 {
22284 return true;
22285 }
22286
22287
22288
22289
22290 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
22291 {
22292 return $repo->hasPackage($package);
22293 }
22294
22295
22296
22297
22298 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
22299 {
22300 if (!$repo->hasPackage($package)) {
22301 $repo->addPackage(clone $package);
22302 }
22303 }
22304
22305
22306
22307
22308 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
22309 {
22310 if (!$repo->hasPackage($initial)) {
22311 throw new \InvalidArgumentException('Package is not installed: '.$initial);
22312 }
22313
22314 $repo->removePackage($initial);
22315 if (!$repo->hasPackage($target)) {
22316 $repo->addPackage(clone $target);
22317 }
22318 }
22319
22320
22321
22322
22323 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
22324 {
22325 if (!$repo->hasPackage($package)) {
22326 throw new \InvalidArgumentException('Package is not installed: '.$package);
22327 }
22328 $repo->removePackage($package);
22329 }
22330
22331
22332
22333
22334 public function getInstallPath(PackageInterface $package)
22335 {
22336 $targetDir = $package->getTargetDir();
22337
22338 return $package->getPrettyName() . ($targetDir ? '/'.$targetDir : '');
22339 }
22340 }
22341 <?php
22342
22343
22344
22345
22346
22347
22348
22349
22350
22351
22352
22353 namespace Composer\Installer;
22354
22355 use Composer\Composer;
22356 use Composer\IO\IOInterface;
22357 use Composer\DependencyResolver\Operation\OperationInterface;
22358 use Composer\DependencyResolver\PolicyInterface;
22359 use Composer\DependencyResolver\Pool;
22360 use Composer\DependencyResolver\Request;
22361 use Composer\Repository\CompositeRepository;
22362
22363
22364
22365
22366
22367
22368 class PackageEvent extends InstallerEvent
22369 {
22370
22371
22372
22373 private $operation;
22374
22375
22376
22377
22378
22379
22380
22381
22382
22383
22384
22385
22386
22387
22388
22389 public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation)
22390 {
22391 parent::__construct($eventName, $composer, $io, $devMode, $policy, $pool, $installedRepo, $request, $operations);
22392
22393 $this->operation = $operation;
22394 }
22395
22396
22397
22398
22399
22400
22401 public function getOperation()
22402 {
22403 return $this->operation;
22404 }
22405 }
22406 <?php
22407
22408
22409
22410
22411
22412
22413
22414
22415
22416
22417
22418 namespace Composer\Installer;
22419
22420
22421
22422
22423
22424
22425 class PackageEvents
22426 {
22427
22428
22429
22430
22431
22432
22433
22434 const PRE_PACKAGE_INSTALL = 'pre-package-install';
22435
22436
22437
22438
22439
22440
22441
22442
22443 const POST_PACKAGE_INSTALL = 'post-package-install';
22444
22445
22446
22447
22448
22449
22450
22451
22452 const PRE_PACKAGE_UPDATE = 'pre-package-update';
22453
22454
22455
22456
22457
22458
22459
22460
22461 const POST_PACKAGE_UPDATE = 'post-package-update';
22462
22463
22464
22465
22466
22467
22468
22469
22470 const PRE_PACKAGE_UNINSTALL = 'pre-package-uninstall';
22471
22472
22473
22474
22475
22476
22477
22478
22479 const POST_PACKAGE_UNINSTALL = 'post-package-uninstall';
22480 }
22481 <?php
22482
22483
22484
22485
22486
22487
22488
22489
22490
22491
22492
22493 namespace Composer\Installer;
22494
22495 use Composer\IO\IOInterface;
22496 use Composer\Package\PackageInterface;
22497 use Composer\Util\Filesystem;
22498 use Composer\Util\ProcessExecutor;
22499
22500
22501
22502
22503
22504
22505 class PearBinaryInstaller extends BinaryInstaller
22506 {
22507 private $installer;
22508 private $vendorDir;
22509
22510
22511
22512
22513
22514
22515
22516
22517
22518 public function __construct(IOInterface $io, $binDir, $vendorDir, $binCompat, Filesystem $filesystem, PearInstaller $installer)
22519 {
22520 parent::__construct($io, $binDir, $binCompat, $filesystem);
22521 $this->installer = $installer;
22522 $this->vendorDir = $vendorDir;
22523 }
22524
22525 protected function getBinaries(PackageInterface $package)
22526 {
22527 $binariesPath = $this->installer->getInstallPath($package) . '/bin/';
22528 $binaries = array();
22529 if (file_exists($binariesPath)) {
22530 foreach (new \FilesystemIterator($binariesPath, \FilesystemIterator::KEY_AS_FILENAME | \FilesystemIterator::CURRENT_AS_FILEINFO) as $fileName => $value) {
22531 if (!$value->isDir()) {
22532 $binaries[] = 'bin/'.$fileName;
22533 }
22534 }
22535 }
22536
22537 return $binaries;
22538 }
22539
22540 protected function initializeBinDir()
22541 {
22542 parent::initializeBinDir();
22543 file_put_contents($this->binDir.'/composer-php', $this->generateUnixyPhpProxyCode());
22544 @chmod($this->binDir.'/composer-php', 0777);
22545 file_put_contents($this->binDir.'/composer-php.bat', $this->generateWindowsPhpProxyCode());
22546 @chmod($this->binDir.'/composer-php.bat', 0777);
22547 }
22548
22549 protected function generateWindowsProxyCode($bin, $link)
22550 {
22551 $binPath = $this->filesystem->findShortestPath($link, $bin);
22552 if ('.bat' === substr($bin, -4)) {
22553 $caller = 'call';
22554 } else {
22555 $handle = fopen($bin, 'r');
22556 $line = fgets($handle);
22557 fclose($handle);
22558 if (preg_match('{^#!/(?:usr/bin/env )?(?:[^/]+/)*(.+)$}m', $line, $match)) {
22559 $caller = trim($match[1]);
22560 } else {
22561 $caller = 'php';
22562 }
22563
22564 if ($caller === 'php') {
22565 return "@echo off\r\n".
22566 "pushd .\r\n".
22567 "cd %~dp0\r\n".
22568 "set PHP_PROXY=%CD%\\composer-php.bat\r\n".
22569 "cd ".ProcessExecutor::escape(dirname($binPath))."\r\n".
22570 "set BIN_TARGET=%CD%\\".basename($binPath)."\r\n".
22571 "popd\r\n".
22572 "%PHP_PROXY% \"%BIN_TARGET%\" %*\r\n";
22573 }
22574 }
22575
22576 return "@echo off\r\n".
22577 "pushd .\r\n".
22578 "cd %~dp0\r\n".
22579 "cd ".ProcessExecutor::escape(dirname($binPath))."\r\n".
22580 "set BIN_TARGET=%CD%\\".basename($binPath)."\r\n".
22581 "popd\r\n".
22582 $caller." \"%BIN_TARGET%\" %*\r\n";
22583 }
22584
22585 private function generateWindowsPhpProxyCode()
22586 {
22587 $binToVendor = $this->filesystem->findShortestPath($this->binDir, $this->vendorDir, true);
22588
22589 return
22590 "@echo off\r\n" .
22591 "setlocal enabledelayedexpansion\r\n" .
22592 "set BIN_DIR=%~dp0\r\n" .
22593 "set VENDOR_DIR=%BIN_DIR%\\".$binToVendor."\r\n" .
22594 "set DIRS=.\r\n" .
22595 "FOR /D %%V IN (%VENDOR_DIR%\\*) DO (\r\n" .
22596 "    FOR /D %%P IN (%%V\\*) DO (\r\n" .
22597 "        set DIRS=!DIRS!;%%~fP\r\n" .
22598 "    )\r\n" .
22599 ")\r\n" .
22600 "php.exe -d include_path=!DIRS! %*\r\n";
22601 }
22602
22603 private function generateUnixyPhpProxyCode()
22604 {
22605 $binToVendor = $this->filesystem->findShortestPath($this->binDir, $this->vendorDir, true);
22606
22607 return
22608 "#!/usr/bin/env sh\n".
22609 "SRC_DIR=`pwd`\n".
22610 "BIN_DIR=`dirname $0`\n".
22611 "VENDOR_DIR=\$BIN_DIR/".escapeshellarg($binToVendor)."\n".
22612 "DIRS=\"\"\n".
22613 "for vendor in \$VENDOR_DIR/*; do\n".
22614 "    if [ -d \"\$vendor\" ]; then\n".
22615 "        for package in \$vendor/*; do\n".
22616 "            if [ -d \"\$package\" ]; then\n".
22617 "                DIRS=\"\${DIRS}:\${package}\"\n".
22618 "            fi\n".
22619 "        done\n".
22620 "    fi\n".
22621 "done\n".
22622 "php -d include_path=\".\$DIRS\" $@\n";
22623 }
22624 }
22625 <?php
22626
22627
22628
22629
22630
22631
22632
22633
22634
22635
22636
22637 namespace Composer\Installer;
22638
22639 use Composer\IO\IOInterface;
22640 use Composer\Composer;
22641 use Composer\Downloader\PearPackageExtractor;
22642 use Composer\Repository\InstalledRepositoryInterface;
22643 use Composer\Package\PackageInterface;
22644 use Composer\Util\Platform;
22645 use Composer\Util\Filesystem;
22646
22647
22648
22649
22650
22651
22652
22653 class PearInstaller extends LibraryInstaller
22654 {
22655
22656
22657
22658
22659
22660
22661
22662 public function __construct(IOInterface $io, Composer $composer, $type = 'pear-library')
22663 {
22664 $filesystem = new Filesystem();
22665 $binaryInstaller = new PearBinaryInstaller($io, rtrim($composer->getConfig()->get('bin-dir'), '/'), rtrim($composer->getConfig()->get('vendor-dir'), '/'), $composer->getConfig()->get('bin-compat'), $filesystem, $this);
22666
22667 parent::__construct($io, $composer, $type, $filesystem, $binaryInstaller);
22668 }
22669
22670
22671
22672
22673 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
22674 {
22675 $this->uninstall($repo, $initial);
22676 $this->install($repo, $target);
22677 }
22678
22679 protected function installCode(PackageInterface $package)
22680 {
22681 parent::installCode($package);
22682
22683 $isWindows = Platform::isWindows();
22684 $php_bin = $this->binDir . ($isWindows ? '/composer-php.bat' : '/composer-php');
22685
22686 if (!$isWindows) {
22687 $php_bin = '/usr/bin/env ' . $php_bin;
22688 }
22689
22690 $installPath = $this->getInstallPath($package);
22691 $vars = array(
22692 'os' => $isWindows ? 'windows' : 'linux',
22693 'php_bin' => $php_bin,
22694 'pear_php' => $installPath,
22695 'php_dir' => $installPath,
22696 'bin_dir' => $installPath . '/bin',
22697 'data_dir' => $installPath . '/data',
22698 'version' => $package->getPrettyVersion(),
22699 );
22700
22701 $packageArchive = $this->getInstallPath($package).'/'.pathinfo($package->getDistUrl(), PATHINFO_BASENAME);
22702 $pearExtractor = new PearPackageExtractor($packageArchive);
22703 $pearExtractor->extractTo($this->getInstallPath($package), array('php' => '/', 'script' => '/bin', 'data' => '/data'), $vars);
22704
22705 $this->io->writeError('    Cleaning up', true, IOInterface::VERBOSE);
22706 $this->filesystem->unlink($packageArchive);
22707 }
22708 }
22709 <?php
22710
22711
22712
22713
22714
22715
22716
22717
22718
22719
22720
22721 namespace Composer\Installer;
22722
22723 use Composer\Composer;
22724 use Composer\IO\IOInterface;
22725 use Composer\Repository\InstalledRepositoryInterface;
22726 use Composer\Package\PackageInterface;
22727
22728
22729
22730
22731
22732
22733
22734 class PluginInstaller extends LibraryInstaller
22735 {
22736 private $installationManager;
22737
22738
22739
22740
22741
22742
22743
22744
22745 public function __construct(IOInterface $io, Composer $composer, $type = 'library')
22746 {
22747 parent::__construct($io, $composer, 'composer-plugin');
22748 $this->installationManager = $composer->getInstallationManager();
22749 }
22750
22751
22752
22753
22754 public function supports($packageType)
22755 {
22756 return $packageType === 'composer-plugin' || $packageType === 'composer-installer';
22757 }
22758
22759
22760
22761
22762 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
22763 {
22764 $extra = $package->getExtra();
22765 if (empty($extra['class'])) {
22766 throw new \UnexpectedValueException('Error while installing '.$package->getPrettyName().', composer-plugin packages should have a class defined in their extra key to be usable.');
22767 }
22768
22769 parent::install($repo, $package);
22770 try {
22771 $this->composer->getPluginManager()->registerPackage($package, true);
22772 } catch (\Exception $e) {
22773
22774  $this->io->writeError('Plugin installation failed, rolling back');
22775 parent::uninstall($repo, $package);
22776 throw $e;
22777 }
22778 }
22779
22780
22781
22782
22783 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
22784 {
22785 $extra = $target->getExtra();
22786 if (empty($extra['class'])) {
22787 throw new \UnexpectedValueException('Error while installing '.$target->getPrettyName().', composer-plugin packages should have a class defined in their extra key to be usable.');
22788 }
22789
22790 parent::update($repo, $initial, $target);
22791 $this->composer->getPluginManager()->registerPackage($target, true);
22792 }
22793 }
22794 <?php
22795
22796
22797
22798
22799
22800
22801
22802
22803
22804
22805
22806 namespace Composer\Installer;
22807
22808 use Composer\Package\PackageInterface;
22809 use Composer\Downloader\DownloadManager;
22810 use Composer\Repository\InstalledRepositoryInterface;
22811 use Composer\Util\Filesystem;
22812
22813
22814
22815
22816
22817
22818
22819 class ProjectInstaller implements InstallerInterface
22820 {
22821 private $installPath;
22822 private $downloadManager;
22823 private $filesystem;
22824
22825 public function __construct($installPath, DownloadManager $dm)
22826 {
22827 $this->installPath = rtrim(strtr($installPath, '\\', '/'), '/').'/';
22828 $this->downloadManager = $dm;
22829 $this->filesystem = new Filesystem;
22830 }
22831
22832
22833
22834
22835
22836
22837
22838 public function supports($packageType)
22839 {
22840 return true;
22841 }
22842
22843
22844
22845
22846 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
22847 {
22848 return false;
22849 }
22850
22851
22852
22853
22854 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
22855 {
22856 $installPath = $this->installPath;
22857 if (file_exists($installPath) && !$this->filesystem->isDirEmpty($installPath)) {
22858 throw new \InvalidArgumentException("Project directory $installPath is not empty.");
22859 }
22860 if (!is_dir($installPath)) {
22861 mkdir($installPath, 0777, true);
22862 }
22863 $this->downloadManager->download($package, $installPath);
22864 }
22865
22866
22867
22868
22869 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
22870 {
22871 throw new \InvalidArgumentException("not supported");
22872 }
22873
22874
22875
22876
22877 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
22878 {
22879 throw new \InvalidArgumentException("not supported");
22880 }
22881
22882
22883
22884
22885
22886
22887
22888 public function getInstallPath(PackageInterface $package)
22889 {
22890 return $this->installPath;
22891 }
22892 }
22893 <?php
22894
22895
22896
22897
22898
22899
22900
22901
22902
22903
22904
22905 namespace Composer\Installer;
22906
22907 use Composer\IO\IOInterface;
22908 use Composer\Package\PackageInterface;
22909 use Composer\Repository\RepositoryInterface;
22910
22911
22912
22913
22914
22915
22916 class SuggestedPackagesReporter
22917 {
22918
22919
22920
22921 protected $suggestedPackages = array();
22922
22923
22924
22925
22926 private $io;
22927
22928 public function __construct(IOInterface $io)
22929 {
22930 $this->io = $io;
22931 }
22932
22933
22934
22935
22936 public function getPackages()
22937 {
22938 return $this->suggestedPackages;
22939 }
22940
22941
22942
22943
22944
22945
22946
22947
22948
22949
22950
22951
22952 public function addPackage($source, $target, $reason)
22953 {
22954 $this->suggestedPackages[] = array(
22955 'source' => $source,
22956 'target' => $target,
22957 'reason' => $reason,
22958 );
22959
22960 return $this;
22961 }
22962
22963
22964
22965
22966
22967
22968
22969 public function addSuggestionsFromPackage(PackageInterface $package)
22970 {
22971 $source = $package->getPrettyName();
22972 foreach ($package->getSuggests() as $target => $reason) {
22973 $this->addPackage(
22974 $source,
22975 $target,
22976 $reason
22977 );
22978 }
22979
22980 return $this;
22981 }
22982
22983
22984
22985
22986
22987
22988
22989
22990 public function output(RepositoryInterface $installedRepo = null)
22991 {
22992 $suggestedPackages = $this->getPackages();
22993 $installedPackages = array();
22994 if (null !== $installedRepo && ! empty($suggestedPackages)) {
22995 foreach ($installedRepo->getPackages() as $package) {
22996 $installedPackages = array_merge(
22997 $installedPackages,
22998 $package->getNames()
22999 );
23000 }
23001 }
23002
23003 foreach ($suggestedPackages as $suggestion) {
23004 if (in_array($suggestion['target'], $installedPackages)) {
23005 continue;
23006 }
23007
23008 $this->io->writeError(sprintf(
23009 '%s suggests installing %s (%s)',
23010 $suggestion['source'],
23011 $suggestion['target'],
23012 $suggestion['reason']
23013 ));
23014 }
23015
23016 return $this;
23017 }
23018 }
23019 <?php
23020
23021
23022
23023
23024
23025
23026
23027
23028
23029
23030
23031 namespace Composer\Json;
23032
23033 use JsonSchema\Validator;
23034 use Seld\JsonLint\JsonParser;
23035 use Seld\JsonLint\ParsingException;
23036 use Composer\Util\RemoteFilesystem;
23037 use Composer\IO\IOInterface;
23038 use Composer\Downloader\TransportException;
23039
23040
23041
23042
23043
23044
23045
23046 class JsonFile
23047 {
23048 const LAX_SCHEMA = 1;
23049 const STRICT_SCHEMA = 2;
23050
23051 const JSON_UNESCAPED_SLASHES = 64;
23052 const JSON_PRETTY_PRINT = 128;
23053 const JSON_UNESCAPED_UNICODE = 256;
23054
23055 private $path;
23056 private $rfs;
23057 private $io;
23058
23059
23060
23061
23062
23063
23064
23065
23066
23067 public function __construct($path, RemoteFilesystem $rfs = null, IOInterface $io = null)
23068 {
23069 $this->path = $path;
23070
23071 if (null === $rfs && preg_match('{^https?://}i', $path)) {
23072 throw new \InvalidArgumentException('http urls require a RemoteFilesystem instance to be passed');
23073 }
23074 $this->rfs = $rfs;
23075 $this->io = $io;
23076 }
23077
23078
23079
23080
23081 public function getPath()
23082 {
23083 return $this->path;
23084 }
23085
23086
23087
23088
23089
23090
23091 public function exists()
23092 {
23093 return is_file($this->path);
23094 }
23095
23096
23097
23098
23099
23100
23101
23102 public function read()
23103 {
23104 try {
23105 if ($this->rfs) {
23106 $json = $this->rfs->getContents($this->path, $this->path, false);
23107 } else {
23108 if ($this->io && $this->io->isDebug()) {
23109 $this->io->writeError('Reading ' . $this->path);
23110 }
23111 $json = file_get_contents($this->path);
23112 }
23113 } catch (TransportException $e) {
23114 throw new \RuntimeException($e->getMessage(), 0, $e);
23115 } catch (\Exception $e) {
23116 throw new \RuntimeException('Could not read '.$this->path."\n\n".$e->getMessage());
23117 }
23118
23119 return static::parseJson($json, $this->path);
23120 }
23121
23122
23123
23124
23125
23126
23127
23128
23129 public function write(array $hash, $options = 448)
23130 {
23131 $dir = dirname($this->path);
23132 if (!is_dir($dir)) {
23133 if (file_exists($dir)) {
23134 throw new \UnexpectedValueException(
23135 $dir.' exists and is not a directory.'
23136 );
23137 }
23138 if (!@mkdir($dir, 0777, true)) {
23139 throw new \UnexpectedValueException(
23140 $dir.' does not exist and could not be created.'
23141 );
23142 }
23143 }
23144
23145 $retries = 3;
23146 while ($retries--) {
23147 try {
23148 file_put_contents($this->path, static::encode($hash, $options). ($options & self::JSON_PRETTY_PRINT ? "\n" : ''));
23149 break;
23150 } catch (\Exception $e) {
23151 if ($retries) {
23152 usleep(500000);
23153 continue;
23154 }
23155
23156 throw $e;
23157 }
23158 }
23159 }
23160
23161
23162
23163
23164
23165
23166
23167
23168 public function validateSchema($schema = self::STRICT_SCHEMA)
23169 {
23170 $content = file_get_contents($this->path);
23171 $data = json_decode($content);
23172
23173 if (null === $data && 'null' !== $content) {
23174 self::validateSyntax($content, $this->path);
23175 }
23176
23177 $schemaFile = __DIR__ . '/../../../res/composer-schema.json';
23178
23179
23180  if (false === strpos($schemaFile, '://')) {
23181 $schemaFile = 'file://' . $schemaFile;
23182 }
23183
23184 $schemaData = (object) array('$ref' => $schemaFile);
23185
23186 if ($schema === self::LAX_SCHEMA) {
23187 $schemaData->additionalProperties = true;
23188 $schemaData->required = array();
23189 }
23190
23191 $validator = new Validator();
23192 $validator->check($data, $schemaData);
23193
23194
23195
23196 if (!$validator->isValid()) {
23197 $errors = array();
23198 foreach ((array) $validator->getErrors() as $error) {
23199 $errors[] = ($error['property'] ? $error['property'].' : ' : '').$error['message'];
23200 }
23201 throw new JsonValidationException('"'.$this->path.'" does not match the expected JSON schema', $errors);
23202 }
23203
23204 return true;
23205 }
23206
23207
23208
23209
23210
23211
23212
23213
23214 public static function encode($data, $options = 448)
23215 {
23216 if (PHP_VERSION_ID >= 50400) {
23217 $json = json_encode($data, $options);
23218 if (false === $json) {
23219 self::throwEncodeError(json_last_error());
23220 }
23221
23222
23223  if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512) || (defined('JSON_C_VERSION') && version_compare(phpversion('json'), '1.3.6', '<'))) {
23224 $json = preg_replace('/\[\s+\]/', '[]', $json);
23225 $json = preg_replace('/\{\s+\}/', '{}', $json);
23226 }
23227
23228 return $json;
23229 }
23230
23231 $json = json_encode($data);
23232 if (false === $json) {
23233 self::throwEncodeError(json_last_error());
23234 }
23235
23236 $prettyPrint = (bool) ($options & self::JSON_PRETTY_PRINT);
23237 $unescapeUnicode = (bool) ($options & self::JSON_UNESCAPED_UNICODE);
23238 $unescapeSlashes = (bool) ($options & self::JSON_UNESCAPED_SLASHES);
23239
23240 if (!$prettyPrint && !$unescapeUnicode && !$unescapeSlashes) {
23241 return $json;
23242 }
23243
23244 $result = JsonFormatter::format($json, $unescapeUnicode, $unescapeSlashes);
23245
23246 return $result;
23247 }
23248
23249
23250
23251
23252
23253
23254
23255 private static function throwEncodeError($code)
23256 {
23257 switch ($code) {
23258 case JSON_ERROR_DEPTH:
23259 $msg = 'Maximum stack depth exceeded';
23260 break;
23261 case JSON_ERROR_STATE_MISMATCH:
23262 $msg = 'Underflow or the modes mismatch';
23263 break;
23264 case JSON_ERROR_CTRL_CHAR:
23265 $msg = 'Unexpected control character found';
23266 break;
23267 case JSON_ERROR_UTF8:
23268 $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
23269 break;
23270 default:
23271 $msg = 'Unknown error';
23272 }
23273
23274 throw new \RuntimeException('JSON encoding failed: '.$msg);
23275 }
23276
23277
23278
23279
23280
23281
23282
23283
23284
23285 public static function parseJson($json, $file = null)
23286 {
23287 if (null === $json) {
23288 return;
23289 }
23290 $data = json_decode($json, true);
23291 if (null === $data && JSON_ERROR_NONE !== json_last_error()) {
23292 self::validateSyntax($json, $file);
23293 }
23294
23295 return $data;
23296 }
23297
23298
23299
23300
23301
23302
23303
23304
23305
23306
23307
23308 protected static function validateSyntax($json, $file = null)
23309 {
23310 $parser = new JsonParser();
23311 $result = $parser->lint($json);
23312 if (null === $result) {
23313 if (defined('JSON_ERROR_UTF8') && JSON_ERROR_UTF8 === json_last_error()) {
23314 throw new \UnexpectedValueException('"'.$file.'" is not UTF-8, could not parse as JSON');
23315 }
23316
23317 return true;
23318 }
23319
23320 throw new ParsingException('"'.$file.'" does not contain valid JSON'."\n".$result->getMessage(), $result->getDetails());
23321 }
23322 }
23323 <?php
23324
23325
23326
23327
23328
23329
23330
23331
23332
23333
23334
23335 namespace Composer\Json;
23336
23337
23338
23339
23340
23341
23342
23343
23344
23345 class JsonFormatter
23346 {
23347
23348
23349
23350
23351
23352
23353
23354
23355
23356
23357
23358
23359 public static function format($json, $unescapeUnicode, $unescapeSlashes)
23360 {
23361 $result = '';
23362 $pos = 0;
23363 $strLen = strlen($json);
23364 $indentStr = '    ';
23365 $newLine = "\n";
23366 $outOfQuotes = true;
23367 $buffer = '';
23368 $noescape = true;
23369
23370 for ($i = 0; $i < $strLen; $i++) {
23371
23372  $char = substr($json, $i, 1);
23373
23374
23375  if ('"' === $char && $noescape) {
23376 $outOfQuotes = !$outOfQuotes;
23377 }
23378
23379 if (!$outOfQuotes) {
23380 $buffer .= $char;
23381 $noescape = '\\' === $char ? !$noescape : true;
23382 continue;
23383 } elseif ('' !== $buffer) {
23384 if ($unescapeSlashes) {
23385 $buffer = str_replace('\\/', '/', $buffer);
23386 }
23387
23388 if ($unescapeUnicode && function_exists('mb_convert_encoding')) {
23389
23390  $buffer = preg_replace_callback('/(\\\\+)u([0-9a-f]{4})/i', function ($match) {
23391 $l = strlen($match[1]);
23392
23393 if ($l % 2) {
23394 return str_repeat('\\', $l - 1) . mb_convert_encoding(
23395 pack('H*', $match[2]),
23396 'UTF-8',
23397 'UCS-2BE'
23398 );
23399 }
23400
23401 return $match[0];
23402 }, $buffer);
23403 }
23404
23405 $result .= $buffer.$char;
23406 $buffer = '';
23407 continue;
23408 }
23409
23410 if (':' === $char) {
23411
23412  $char .= ' ';
23413 } elseif (('}' === $char || ']' === $char)) {
23414 $pos--;
23415 $prevChar = substr($json, $i - 1, 1);
23416
23417 if ('{' !== $prevChar && '[' !== $prevChar) {
23418
23419  
23420  $result .= $newLine;
23421 for ($j = 0; $j < $pos; $j++) {
23422 $result .= $indentStr;
23423 }
23424 } else {
23425
23426  $result = rtrim($result);
23427 }
23428 }
23429
23430 $result .= $char;
23431
23432
23433  
23434  if (',' === $char || '{' === $char || '[' === $char) {
23435 $result .= $newLine;
23436
23437 if ('{' === $char || '[' === $char) {
23438 $pos++;
23439 }
23440
23441 for ($j = 0; $j < $pos; $j++) {
23442 $result .= $indentStr;
23443 }
23444 }
23445 }
23446
23447 return $result;
23448 }
23449 }
23450 <?php
23451
23452
23453
23454
23455
23456
23457
23458
23459
23460
23461
23462 namespace Composer\Json;
23463
23464 use Composer\Repository\PlatformRepository;
23465
23466
23467
23468
23469 class JsonManipulator
23470 {
23471 private static $DEFINES = '(?(DEFINE)
23472        (?<number>   -? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)? )
23473        (?<boolean>   true | false | null )
23474        (?<string>    " ([^"\\\\]* | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9a-f]{4} )* " )
23475        (?<array>     \[  (?:  (?&json) \s* (?: , (?&json) \s* )*  )?  \s* \] )
23476        (?<pair>      \s* (?&string) \s* : (?&json) \s* )
23477        (?<object>    \{  (?:  (?&pair)  (?: , (?&pair)  )*  )?  \s* \} )
23478        (?<json>   \s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) )
23479     )';
23480
23481 private $contents;
23482 private $newline;
23483 private $indent;
23484
23485 public function __construct($contents)
23486 {
23487 $contents = trim($contents);
23488 if ($contents === '') {
23489 $contents = '{}';
23490 }
23491 if (!$this->pregMatch('#^\{(.*)\}$#s', $contents)) {
23492 throw new \InvalidArgumentException('The json file must be an object ({})');
23493 }
23494 $this->newline = false !== strpos($contents, "\r\n") ? "\r\n" : "\n";
23495 $this->contents = $contents === '{}' ? '{' . $this->newline . '}' : $contents;
23496 $this->detectIndenting();
23497 }
23498
23499 public function getContents()
23500 {
23501 return $this->contents . $this->newline;
23502 }
23503
23504 public function addLink($type, $package, $constraint, $sortPackages = false)
23505 {
23506 $decoded = JsonFile::parseJson($this->contents);
23507
23508
23509  if (!isset($decoded[$type])) {
23510 return $this->addMainKey($type, array($package => $constraint));
23511 }
23512
23513 $regex = '{'.self::$DEFINES.'^(?P<start>\s*\{\s*(?:(?&string)\s*:\s*(?&json)\s*,\s*)*?)'.
23514 '(?P<property>'.preg_quote(JsonFile::encode($type)).'\s*:\s*)(?P<value>(?&json))(?P<end>.*)}sx';
23515 if (!$this->pregMatch($regex, $this->contents, $matches)) {
23516 return false;
23517 }
23518
23519 $links = $matches['value'];
23520
23521 if (isset($decoded[$type][$package])) {
23522
23523  $packageRegex = str_replace('/', '\\\\?/', preg_quote($package));
23524 $links = preg_replace_callback('{'.self::$DEFINES.'"'.$packageRegex.'"(?P<separator>\s*:\s*)(?&string)}ix', function ($m) use ($package, $constraint) {
23525 return JsonFile::encode($package) . $m['separator'] . '"' . $constraint . '"';
23526 }, $links);
23527 } else {
23528 if ($this->pregMatch('#^\s*\{\s*\S+.*?(\s*\}\s*)$#s', $links, $match)) {
23529
23530  $links = preg_replace(
23531 '{'.preg_quote($match[1]).'$}',
23532
23533  addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $match[1], '\\$'),
23534 $links
23535 );
23536 } else {
23537
23538  $links = '{' . $this->newline .
23539 $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $this->newline .
23540 $this->indent . '}';
23541 }
23542 }
23543
23544 if (true === $sortPackages) {
23545 $requirements = json_decode($links, true);
23546 $this->sortPackages($requirements);
23547 $links = $this->format($requirements);
23548 }
23549
23550 $this->contents = $matches['start'] . $matches['property'] . $links . $matches['end'];
23551
23552 return true;
23553 }
23554
23555
23556
23557
23558
23559
23560
23561
23562 private function sortPackages(array &$packages = array())
23563 {
23564 $prefix = function ($requirement) {
23565 if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $requirement)) {
23566 return preg_replace(
23567 array(
23568 '/^php/',
23569 '/^hhvm/',
23570 '/^ext/',
23571 '/^lib/',
23572 '/^\D/',
23573 ),
23574 array(
23575 '0-$0',
23576 '1-$0',
23577 '2-$0',
23578 '3-$0',
23579 '4-$0',
23580 ),
23581 $requirement
23582 );
23583 }
23584
23585 return '5-'.$requirement;
23586 };
23587
23588 uksort($packages, function ($a, $b) use ($prefix) {
23589 return strnatcmp($prefix($a), $prefix($b));
23590 });
23591 }
23592
23593 public function addRepository($name, $config)
23594 {
23595 return $this->addSubNode('repositories', $name, $config);
23596 }
23597
23598 public function removeRepository($name)
23599 {
23600 return $this->removeSubNode('repositories', $name);
23601 }
23602
23603 public function addConfigSetting($name, $value)
23604 {
23605 return $this->addSubNode('config', $name, $value);
23606 }
23607
23608 public function removeConfigSetting($name)
23609 {
23610 return $this->removeSubNode('config', $name);
23611 }
23612
23613 public function addProperty($name, $value)
23614 {
23615 if (substr($name, 0, 6) === 'extra.') {
23616 return $this->addSubNode('extra', substr($name, 6), $value);
23617 }
23618
23619 return $this->addMainKey($name, $value);
23620 }
23621
23622 public function removeProperty($name)
23623 {
23624 if (substr($name, 0, 6) === 'extra.') {
23625 return $this->removeSubNode('extra', substr($name, 6));
23626 }
23627
23628 return $this->removeMainKey($name);
23629 }
23630
23631 public function addSubNode($mainNode, $name, $value)
23632 {
23633 $decoded = JsonFile::parseJson($this->contents);
23634
23635 $subName = null;
23636 if (in_array($mainNode, array('config', 'repositories', 'extra')) && false !== strpos($name, '.')) {
23637 list($name, $subName) = explode('.', $name, 2);
23638 }
23639
23640
23641  if (!isset($decoded[$mainNode])) {
23642 if ($subName !== null) {
23643 $this->addMainKey($mainNode, array($name => array($subName => $value)));
23644 } else {
23645 $this->addMainKey($mainNode, array($name => $value));
23646 }
23647
23648 return true;
23649 }
23650
23651
23652  $nodeRegex = '{'.self::$DEFINES.'^(?P<start> \s* \{ \s* (?: (?&string) \s* : (?&json) \s* , \s* )*?'.
23653 preg_quote(JsonFile::encode($mainNode)).'\s*:\s*)(?P<content>(?&object))(?P<end>.*)}sx';
23654
23655 try {
23656 if (!$this->pregMatch($nodeRegex, $this->contents, $match)) {
23657 return false;
23658 }
23659 } catch (\RuntimeException $e) {
23660 if ($e->getCode() === PREG_BACKTRACK_LIMIT_ERROR) {
23661 return false;
23662 }
23663 throw $e;
23664 }
23665
23666 $children = $match['content'];
23667
23668  if (!@json_decode($children)) {
23669 return false;
23670 }
23671
23672 $that = $this;
23673
23674
23675  $childRegex = '{'.self::$DEFINES.'(?P<start>"'.preg_quote($name).'"\s*:\s*)(?P<content>(?&json))(?P<end>,?)}x';
23676 if ($this->pregMatch($childRegex, $children, $matches)) {
23677 $children = preg_replace_callback($childRegex, function ($matches) use ($name, $subName, $value, $that) {
23678 if ($subName !== null) {
23679 $curVal = json_decode($matches['content'], true);
23680 if (!is_array($curVal)) {
23681 $curVal = array();
23682 }
23683 $curVal[$subName] = $value;
23684 $value = $curVal;
23685 }
23686
23687 return $matches['start'] . $that->format($value, 1) . $matches['end'];
23688 }, $children);
23689 } else {
23690 $this->pregMatch('#^{ \s*? (?P<content>\S+.*?)? (?P<trailingspace>\s*) }$#sx', $children, $match);
23691
23692 $whitespace = '';
23693 if (!empty($match['trailingspace'])) {
23694 $whitespace = $match['trailingspace'];
23695 }
23696
23697 if (!empty($match['content'])) {
23698 if ($subName !== null) {
23699 $value = array($subName => $value);
23700 }
23701
23702
23703  $children = preg_replace(
23704 '#'.$whitespace.'}$#',
23705 addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $whitespace . '}', '\\$'),
23706 $children
23707 );
23708 } else {
23709 if ($subName !== null) {
23710 $value = array($subName => $value);
23711 }
23712
23713
23714  $children = '{' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $whitespace . '}';
23715 }
23716 }
23717
23718 $this->contents = preg_replace_callback($nodeRegex, function ($m) use ($children) {
23719 return $m['start'] . $children . $m['end'];
23720 }, $this->contents);
23721
23722 return true;
23723 }
23724
23725 public function removeSubNode($mainNode, $name)
23726 {
23727 $decoded = JsonFile::parseJson($this->contents);
23728
23729
23730  if (empty($decoded[$mainNode])) {
23731 return true;
23732 }
23733
23734
23735  $nodeRegex = '{'.self::$DEFINES.'^(?P<start> \s* \{ \s* (?: (?&string) \s* : (?&json) \s* , \s* )*?'.
23736 preg_quote(JsonFile::encode($mainNode)).'\s*:\s*)(?P<content>(?&object))(?P<end>.*)}sx';
23737 try {
23738 if (!$this->pregMatch($nodeRegex, $this->contents, $match)) {
23739 return false;
23740 }
23741 } catch (\RuntimeException $e) {
23742 if ($e->getCode() === PREG_BACKTRACK_LIMIT_ERROR) {
23743 return false;
23744 }
23745 throw $e;
23746 }
23747
23748 $children = $match['content'];
23749
23750
23751  if (!@json_decode($children, true)) {
23752 return false;
23753 }
23754
23755 $subName = null;
23756 if (in_array($mainNode, array('config', 'repositories', 'extra')) && false !== strpos($name, '.')) {
23757 list($name, $subName) = explode('.', $name, 2);
23758 }
23759
23760
23761  if (!isset($decoded[$mainNode][$name]) || ($subName && !isset($decoded[$mainNode][$name][$subName]))) {
23762 return true;
23763 }
23764
23765
23766  if ($this->pregMatch('{"'.preg_quote($name).'"\s*:}i', $children)) {
23767
23768  if (preg_match_all('{'.self::$DEFINES.'"'.preg_quote($name).'"\s*:\s*(?:(?&json))}x', $children, $matches)) {
23769 $bestMatch = '';
23770 foreach ($matches[0] as $match) {
23771 if (strlen($bestMatch) < strlen($match)) {
23772 $bestMatch = $match;
23773 }
23774 }
23775 $childrenClean = preg_replace('{,\s*'.preg_quote($bestMatch).'}i', '', $children, -1, $count);
23776 if (1 !== $count) {
23777 $childrenClean = preg_replace('{'.preg_quote($bestMatch).'\s*,?\s*}i', '', $childrenClean, -1, $count);
23778 if (1 !== $count) {
23779 return false;
23780 }
23781 }
23782 }
23783 } else {
23784 $childrenClean = $children;
23785 }
23786
23787
23788  $this->pregMatch('#^{ \s*? (?P<content>\S+.*?)? (?P<trailingspace>\s*) }$#sx', $childrenClean, $match);
23789 if (empty($match['content'])) {
23790 $newline = $this->newline;
23791 $indent = $this->indent;
23792
23793 $this->contents = preg_replace_callback($nodeRegex, function ($matches) use ($indent, $newline) {
23794 return $matches['start'] . '{' . $newline . $indent . '}' . $matches['end'];
23795 }, $this->contents);
23796
23797
23798  if ($subName !== null) {
23799 $curVal = json_decode($children, true);
23800 unset($curVal[$name][$subName]);
23801 $this->addSubNode($mainNode, $name, $curVal[$name]);
23802 }
23803
23804 return true;
23805 }
23806
23807 $that = $this;
23808 $this->contents = preg_replace_callback($nodeRegex, function ($matches) use ($that, $name, $subName, $childrenClean) {
23809 if ($subName !== null) {
23810 $curVal = json_decode($matches['content'], true);
23811 unset($curVal[$name][$subName]);
23812 $childrenClean = $that->format($curVal, 0);
23813 }
23814
23815 return $matches['start'] . $childrenClean . $matches['end'];
23816 }, $this->contents);
23817
23818 return true;
23819 }
23820
23821 public function addMainKey($key, $content)
23822 {
23823 $decoded = JsonFile::parseJson($this->contents);
23824 $content = $this->format($content);
23825
23826
23827  $regex = '{'.self::$DEFINES.'^(?P<start>\s*\{\s*(?:(?&string)\s*:\s*(?&json)\s*,\s*)*?)'.
23828 '(?P<key>'.preg_quote(JsonFile::encode($key)).'\s*:\s*(?&json))(?P<end>.*)}sx';
23829 if (isset($decoded[$key]) && $this->pregMatch($regex, $this->contents, $matches)) {
23830
23831  if (!@json_decode('{'.$matches['key'].'}')) {
23832 return false;
23833 }
23834
23835 $this->contents = $matches['start'] . JsonFile::encode($key).': '.$content . $matches['end'];
23836
23837 return true;
23838 }
23839
23840
23841  if ($this->pregMatch('#[^{\s](\s*)\}$#', $this->contents, $match)) {
23842 $this->contents = preg_replace(
23843 '#'.$match[1].'\}$#',
23844 addcslashes(',' . $this->newline . $this->indent . JsonFile::encode($key). ': '. $content . $this->newline . '}', '\\$'),
23845 $this->contents
23846 );
23847
23848 return true;
23849 }
23850
23851
23852  $this->contents = preg_replace(
23853 '#\}$#',
23854 addcslashes($this->indent . JsonFile::encode($key). ': '.$content . $this->newline . '}', '\\$'),
23855 $this->contents
23856 );
23857
23858 return true;
23859 }
23860
23861 public function removeMainKey($key)
23862 {
23863 $decoded = JsonFile::parseJson($this->contents);
23864
23865 if (!isset($decoded[$key])) {
23866 return true;
23867 }
23868
23869
23870  $regex = '{'.self::$DEFINES.'^(?P<start>\s*\{\s*(?:(?&string)\s*:\s*(?&json)\s*,\s*)*?)'.
23871 '(?P<removal>'.preg_quote(JsonFile::encode($key)).'\s*:\s*(?&json))\s*,?\s*(?P<end>.*)}sx';
23872 if ($this->pregMatch($regex, $this->contents, $matches)) {
23873
23874  if (!@json_decode('{'.$matches['removal'].'}')) {
23875 return false;
23876 }
23877
23878 $this->contents = $matches['start'] . $matches['end'];
23879 if (preg_match('#^\{\s*\}\s*$#', $this->contents)) {
23880 $this->contents = "{\n}";
23881 }
23882
23883 return true;
23884 }
23885
23886 return false;
23887 }
23888
23889 public function format($data, $depth = 0)
23890 {
23891 if (is_array($data)) {
23892 reset($data);
23893
23894 if (is_numeric(key($data))) {
23895 foreach ($data as $key => $val) {
23896 $data[$key] = $this->format($val, $depth + 1);
23897 }
23898
23899 return '['.implode(', ', $data).']';
23900 }
23901
23902 $out = '{' . $this->newline;
23903 $elems = array();
23904 foreach ($data as $key => $val) {
23905 $elems[] = str_repeat($this->indent, $depth + 2) . JsonFile::encode($key). ': '.$this->format($val, $depth + 1);
23906 }
23907
23908 return $out . implode(','.$this->newline, $elems) . $this->newline . str_repeat($this->indent, $depth + 1) . '}';
23909 }
23910
23911 return JsonFile::encode($data);
23912 }
23913
23914 protected function detectIndenting()
23915 {
23916 if ($this->pregMatch('{^([ \t]+)"}m', $this->contents, $match)) {
23917 $this->indent = $match[1];
23918 } else {
23919 $this->indent = '    ';
23920 }
23921 }
23922
23923 protected function pregMatch($re, $str, &$matches = array())
23924 {
23925 $count = preg_match($re, $str, $matches);
23926
23927 if ($count === false) {
23928 switch (preg_last_error()) {
23929 case PREG_NO_ERROR:
23930 throw new \RuntimeException('Failed to execute regex: PREG_NO_ERROR', PREG_NO_ERROR);
23931 case PREG_INTERNAL_ERROR:
23932 throw new \RuntimeException('Failed to execute regex: PREG_INTERNAL_ERROR', PREG_INTERNAL_ERROR);
23933 case PREG_BACKTRACK_LIMIT_ERROR:
23934 throw new \RuntimeException('Failed to execute regex: PREG_BACKTRACK_LIMIT_ERROR', PREG_BACKTRACK_LIMIT_ERROR);
23935 case PREG_RECURSION_LIMIT_ERROR:
23936 throw new \RuntimeException('Failed to execute regex: PREG_RECURSION_LIMIT_ERROR', PREG_RECURSION_LIMIT_ERROR);
23937 case PREG_BAD_UTF8_ERROR:
23938 throw new \RuntimeException('Failed to execute regex: PREG_BAD_UTF8_ERROR', PREG_BAD_UTF8_ERROR);
23939 case PREG_BAD_UTF8_OFFSET_ERROR:
23940 throw new \RuntimeException('Failed to execute regex: PREG_BAD_UTF8_OFFSET_ERROR', PREG_BAD_UTF8_OFFSET_ERROR);
23941 case 6: 
23942  if (PHP_VERSION_ID > 70000) {
23943 throw new \RuntimeException('Failed to execute regex: PREG_JIT_STACKLIMIT_ERROR', 6);
23944 }
23945
23946
23947 default:
23948 throw new \RuntimeException('Failed to execute regex: Unknown error');
23949 }
23950 }
23951
23952 return $count;
23953 }
23954 }
23955 <?php
23956
23957
23958
23959
23960
23961
23962
23963
23964
23965
23966
23967 namespace Composer\Json;
23968
23969 use Exception;
23970
23971
23972
23973
23974 class JsonValidationException extends Exception
23975 {
23976 protected $errors;
23977
23978 public function __construct($message, $errors = array(), Exception $previous = null)
23979 {
23980 $this->errors = $errors;
23981 parent::__construct($message, 0, $previous);
23982 }
23983
23984 public function getErrors()
23985 {
23986 return $this->errors;
23987 }
23988 }
23989 <?php
23990
23991
23992
23993
23994
23995
23996
23997
23998
23999
24000
24001 namespace Composer\Package;
24002
24003 use Composer\Semver\Constraint\Constraint;
24004 use Composer\Package\Version\VersionParser;
24005
24006
24007
24008
24009 class AliasPackage extends BasePackage implements CompletePackageInterface
24010 {
24011 protected $version;
24012 protected $prettyVersion;
24013 protected $dev;
24014 protected $rootPackageAlias = false;
24015 protected $stability;
24016
24017
24018 protected $aliasOf;
24019
24020 protected $requires;
24021
24022 protected $devRequires;
24023
24024 protected $conflicts;
24025
24026 protected $provides;
24027
24028 protected $replaces;
24029
24030
24031
24032
24033
24034
24035
24036
24037 public function __construct(PackageInterface $aliasOf, $version, $prettyVersion)
24038 {
24039 parent::__construct($aliasOf->getName());
24040
24041 $this->version = $version;
24042 $this->prettyVersion = $prettyVersion;
24043 $this->aliasOf = $aliasOf;
24044 $this->stability = VersionParser::parseStability($version);
24045 $this->dev = $this->stability === 'dev';
24046
24047 foreach (array('requires', 'devRequires', 'conflicts', 'provides', 'replaces') as $type) {
24048 $links = $aliasOf->{'get' . ucfirst($type)}();
24049 $this->$type = $this->replaceSelfVersionDependencies($links, $type);
24050 }
24051 }
24052
24053
24054
24055
24056 public function getAliasOf()
24057 {
24058 return $this->aliasOf;
24059 }
24060
24061
24062
24063
24064 public function getVersion()
24065 {
24066 return $this->version;
24067 }
24068
24069
24070
24071
24072 public function getStability()
24073 {
24074 return $this->stability;
24075 }
24076
24077
24078
24079
24080 public function getPrettyVersion()
24081 {
24082 return $this->prettyVersion;
24083 }
24084
24085
24086
24087
24088 public function isDev()
24089 {
24090 return $this->dev;
24091 }
24092
24093
24094
24095
24096 public function getRequires()
24097 {
24098 return $this->requires;
24099 }
24100
24101
24102
24103
24104 public function getConflicts()
24105 {
24106 return $this->conflicts;
24107 }
24108
24109
24110
24111
24112 public function getProvides()
24113 {
24114 return $this->provides;
24115 }
24116
24117
24118
24119
24120 public function getReplaces()
24121 {
24122 return $this->replaces;
24123 }
24124
24125
24126
24127
24128 public function getDevRequires()
24129 {
24130 return $this->devRequires;
24131 }
24132
24133
24134
24135
24136
24137
24138
24139
24140
24141
24142 public function setRootPackageAlias($value)
24143 {
24144 return $this->rootPackageAlias = $value;
24145 }
24146
24147
24148
24149
24150
24151 public function isRootPackageAlias()
24152 {
24153 return $this->rootPackageAlias;
24154 }
24155
24156
24157
24158
24159
24160
24161
24162 protected function replaceSelfVersionDependencies(array $links, $linkType)
24163 {
24164 if (in_array($linkType, array('conflicts', 'provides', 'replaces'), true)) {
24165 $newLinks = array();
24166 foreach ($links as $link) {
24167
24168  if ('self.version' === $link->getPrettyConstraint()) {
24169 $newLinks[] = new Link($link->getSource(), $link->getTarget(), new Constraint('=', $this->version), $linkType, $this->prettyVersion);
24170 }
24171 }
24172 $links = array_merge($links, $newLinks);
24173 } else {
24174 foreach ($links as $index => $link) {
24175 if ('self.version' === $link->getPrettyConstraint()) {
24176 $links[$index] = new Link($link->getSource(), $link->getTarget(), new Constraint('=', $this->version), $linkType, $this->prettyVersion);
24177 }
24178 }
24179 }
24180
24181 return $links;
24182 }
24183
24184
24185
24186
24187
24188 public function getType()
24189 {
24190 return $this->aliasOf->getType();
24191 }
24192
24193 public function getTargetDir()
24194 {
24195 return $this->aliasOf->getTargetDir();
24196 }
24197
24198 public function getExtra()
24199 {
24200 return $this->aliasOf->getExtra();
24201 }
24202
24203 public function setInstallationSource($type)
24204 {
24205 $this->aliasOf->setInstallationSource($type);
24206 }
24207
24208 public function getInstallationSource()
24209 {
24210 return $this->aliasOf->getInstallationSource();
24211 }
24212
24213 public function getSourceType()
24214 {
24215 return $this->aliasOf->getSourceType();
24216 }
24217
24218 public function getSourceUrl()
24219 {
24220 return $this->aliasOf->getSourceUrl();
24221 }
24222
24223 public function getSourceUrls()
24224 {
24225 return $this->aliasOf->getSourceUrls();
24226 }
24227
24228 public function getSourceReference()
24229 {
24230 return $this->aliasOf->getSourceReference();
24231 }
24232
24233 public function setSourceReference($reference)
24234 {
24235 return $this->aliasOf->setSourceReference($reference);
24236 }
24237
24238 public function setSourceMirrors($mirrors)
24239 {
24240 return $this->aliasOf->setSourceMirrors($mirrors);
24241 }
24242
24243 public function getSourceMirrors()
24244 {
24245 return $this->aliasOf->getSourceMirrors();
24246 }
24247
24248 public function getDistType()
24249 {
24250 return $this->aliasOf->getDistType();
24251 }
24252
24253 public function getDistUrl()
24254 {
24255 return $this->aliasOf->getDistUrl();
24256 }
24257
24258 public function getDistUrls()
24259 {
24260 return $this->aliasOf->getDistUrls();
24261 }
24262
24263 public function getDistReference()
24264 {
24265 return $this->aliasOf->getDistReference();
24266 }
24267
24268 public function setDistReference($reference)
24269 {
24270 return $this->aliasOf->setDistReference($reference);
24271 }
24272
24273 public function getDistSha1Checksum()
24274 {
24275 return $this->aliasOf->getDistSha1Checksum();
24276 }
24277
24278 public function setTransportOptions(array $options)
24279 {
24280 return $this->aliasOf->setTransportOptions($options);
24281 }
24282
24283 public function getTransportOptions()
24284 {
24285 return $this->aliasOf->getTransportOptions();
24286 }
24287
24288 public function setDistMirrors($mirrors)
24289 {
24290 return $this->aliasOf->setDistMirrors($mirrors);
24291 }
24292
24293 public function getDistMirrors()
24294 {
24295 return $this->aliasOf->getDistMirrors();
24296 }
24297
24298 public function getScripts()
24299 {
24300 return $this->aliasOf->getScripts();
24301 }
24302
24303 public function getLicense()
24304 {
24305 return $this->aliasOf->getLicense();
24306 }
24307
24308 public function getAutoload()
24309 {
24310 return $this->aliasOf->getAutoload();
24311 }
24312
24313 public function getDevAutoload()
24314 {
24315 return $this->aliasOf->getDevAutoload();
24316 }
24317
24318 public function getIncludePaths()
24319 {
24320 return $this->aliasOf->getIncludePaths();
24321 }
24322
24323 public function getRepositories()
24324 {
24325 return $this->aliasOf->getRepositories();
24326 }
24327
24328 public function getReleaseDate()
24329 {
24330 return $this->aliasOf->getReleaseDate();
24331 }
24332
24333 public function getBinaries()
24334 {
24335 return $this->aliasOf->getBinaries();
24336 }
24337
24338 public function getKeywords()
24339 {
24340 return $this->aliasOf->getKeywords();
24341 }
24342
24343 public function getDescription()
24344 {
24345 return $this->aliasOf->getDescription();
24346 }
24347
24348 public function getHomepage()
24349 {
24350 return $this->aliasOf->getHomepage();
24351 }
24352
24353 public function getSuggests()
24354 {
24355 return $this->aliasOf->getSuggests();
24356 }
24357
24358 public function getAuthors()
24359 {
24360 return $this->aliasOf->getAuthors();
24361 }
24362
24363 public function getSupport()
24364 {
24365 return $this->aliasOf->getSupport();
24366 }
24367
24368 public function getNotificationUrl()
24369 {
24370 return $this->aliasOf->getNotificationUrl();
24371 }
24372
24373 public function getArchiveExcludes()
24374 {
24375 return $this->aliasOf->getArchiveExcludes();
24376 }
24377
24378 public function isAbandoned()
24379 {
24380 return $this->aliasOf->isAbandoned();
24381 }
24382
24383 public function getReplacementPackage()
24384 {
24385 return $this->aliasOf->getReplacementPackage();
24386 }
24387
24388 public function __toString()
24389 {
24390 return parent::__toString().' (alias of '.$this->aliasOf->getVersion().')';
24391 }
24392 }
24393 <?php
24394
24395
24396
24397
24398
24399
24400
24401
24402
24403
24404
24405 namespace Composer\Package\Archiver;
24406
24407 use FilterIterator;
24408 use PharData;
24409
24410 class ArchivableFilesFilter extends FilterIterator
24411 {
24412 private $dirs = array();
24413
24414
24415
24416
24417 public function accept()
24418 {
24419 $file = $this->getInnerIterator()->current();
24420 if ($file->isDir()) {
24421 $this->dirs[] = (string) $file;
24422
24423 return false;
24424 }
24425
24426 return true;
24427 }
24428
24429 public function addEmptyDir(PharData $phar, $sources)
24430 {
24431 foreach ($this->dirs as $filepath) {
24432 $localname = str_replace($sources . "/", '', $filepath);
24433 $phar->addEmptyDir($localname);
24434 }
24435 }
24436 }
24437 <?php
24438
24439
24440
24441
24442
24443
24444
24445
24446
24447
24448
24449 namespace Composer\Package\Archiver;
24450
24451 use Composer\Util\Filesystem;
24452 use FilesystemIterator;
24453 use Symfony\Component\Finder\Finder;
24454 use Symfony\Component\Finder\SplFileInfo;
24455
24456
24457
24458
24459
24460
24461
24462
24463
24464 class ArchivableFilesFinder extends \FilterIterator
24465 {
24466
24467
24468
24469 protected $finder;
24470
24471
24472
24473
24474
24475
24476
24477
24478 public function __construct($sources, array $excludes, $ignoreFilters = false)
24479 {
24480 $fs = new Filesystem();
24481
24482 $sources = $fs->normalizePath($sources);
24483
24484 if ($ignoreFilters) {
24485 $filters = array();
24486 } else {
24487 $filters = array(
24488 new HgExcludeFilter($sources),
24489 new GitExcludeFilter($sources),
24490 new ComposerExcludeFilter($sources, $excludes),
24491 );
24492 }
24493
24494 $this->finder = new Finder();
24495
24496 $filter = function (\SplFileInfo $file) use ($sources, $filters, $fs) {
24497 if ($file->isLink() && strpos($file->getLinkTarget(), $sources) !== 0) {
24498 return false;
24499 }
24500
24501 $relativePath = preg_replace(
24502 '#^'.preg_quote($sources, '#').'#',
24503 '',
24504 $fs->normalizePath($file->getRealPath())
24505 );
24506
24507 $exclude = false;
24508 foreach ($filters as $filter) {
24509 $exclude = $filter->filter($relativePath, $exclude);
24510 }
24511
24512 return !$exclude;
24513 };
24514
24515 if (method_exists($filter, 'bindTo')) {
24516 $filter = $filter->bindTo(null);
24517 }
24518
24519 $this->finder
24520 ->in($sources)
24521 ->filter($filter)
24522 ->ignoreVCS(true)
24523 ->ignoreDotFiles(false);
24524
24525 parent::__construct($this->finder->getIterator());
24526 }
24527
24528 public function accept()
24529 {
24530
24531 $current = $this->getInnerIterator()->current();
24532
24533 if (!$current->isDir()) {
24534 return true;
24535 }
24536
24537 $iterator = new FilesystemIterator($current, FilesystemIterator::SKIP_DOTS);
24538
24539 return !$iterator->valid();
24540 }
24541 }
24542 <?php
24543
24544
24545
24546
24547
24548
24549
24550
24551
24552
24553
24554 namespace Composer\Package\Archiver;
24555
24556 use Composer\Downloader\DownloadManager;
24557 use Composer\Package\PackageInterface;
24558 use Composer\Package\RootPackageInterface;
24559 use Composer\Util\Filesystem;
24560 use Composer\Json\JsonFile;
24561
24562
24563
24564
24565
24566 class ArchiveManager
24567 {
24568 protected $downloadManager;
24569
24570 protected $archivers = array();
24571
24572
24573
24574
24575 protected $overwriteFiles = true;
24576
24577
24578
24579
24580 public function __construct(DownloadManager $downloadManager)
24581 {
24582 $this->downloadManager = $downloadManager;
24583 }
24584
24585
24586
24587
24588 public function addArchiver(ArchiverInterface $archiver)
24589 {
24590 $this->archivers[] = $archiver;
24591 }
24592
24593
24594
24595
24596
24597
24598
24599
24600 public function setOverwriteFiles($overwriteFiles)
24601 {
24602 $this->overwriteFiles = $overwriteFiles;
24603
24604 return $this;
24605 }
24606
24607
24608
24609
24610
24611
24612
24613
24614 public function getPackageFilename(PackageInterface $package)
24615 {
24616 $nameParts = array(preg_replace('#[^a-z0-9-_]#i', '-', $package->getName()));
24617
24618 if (preg_match('{^[a-f0-9]{40}$}', $package->getDistReference())) {
24619 $nameParts = array_merge($nameParts, array($package->getDistReference(), $package->getDistType()));
24620 } else {
24621 $nameParts = array_merge($nameParts, array($package->getPrettyVersion(), $package->getDistReference()));
24622 }
24623
24624 if ($package->getSourceReference()) {
24625 $nameParts[] = substr(sha1($package->getSourceReference()), 0, 6);
24626 }
24627
24628 $name = implode('-', array_filter($nameParts, function ($p) {
24629 return !empty($p);
24630 }));
24631
24632 return str_replace('/', '-', $name);
24633 }
24634
24635
24636
24637
24638
24639
24640
24641
24642
24643
24644
24645
24646
24647
24648 public function archive(PackageInterface $package, $format, $targetDir, $fileName = null, $ignoreFilters = false)
24649 {
24650 if (empty($format)) {
24651 throw new \InvalidArgumentException('Format must be specified');
24652 }
24653
24654
24655  $usableArchiver = null;
24656 foreach ($this->archivers as $archiver) {
24657 if ($archiver->supports($format, $package->getSourceType())) {
24658 $usableArchiver = $archiver;
24659 break;
24660 }
24661 }
24662
24663
24664  if (null === $usableArchiver) {
24665 throw new \RuntimeException(sprintf('No archiver found to support %s format', $format));
24666 }
24667
24668 $filesystem = new Filesystem();
24669 if (null === $fileName) {
24670 $packageName = $this->getPackageFilename($package);
24671 } else {
24672 $packageName = $fileName;
24673 }
24674
24675
24676  $filesystem->ensureDirectoryExists($targetDir);
24677 $target = realpath($targetDir).'/'.$packageName.'.'.$format;
24678 $filesystem->ensureDirectoryExists(dirname($target));
24679
24680 if (!$this->overwriteFiles && file_exists($target)) {
24681 return $target;
24682 }
24683
24684 if ($package instanceof RootPackageInterface) {
24685 $sourcePath = realpath('.');
24686 } else {
24687
24688  $sourcePath = sys_get_temp_dir().'/composer_archive'.uniqid();
24689 $filesystem->ensureDirectoryExists($sourcePath);
24690
24691
24692  $this->downloadManager->download($package, $sourcePath);
24693
24694
24695  if (file_exists($composerJsonPath = $sourcePath.'/composer.json')) {
24696 $jsonFile = new JsonFile($composerJsonPath);
24697 $jsonData = $jsonFile->read();
24698 if (!empty($jsonData['archive']['exclude'])) {
24699 $package->setArchiveExcludes($jsonData['archive']['exclude']);
24700 }
24701 }
24702 }
24703
24704
24705  $tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format;
24706 $filesystem->ensureDirectoryExists(dirname($tempTarget));
24707
24708 $archivePath = $usableArchiver->archive($sourcePath, $tempTarget, $format, $package->getArchiveExcludes(), $ignoreFilters);
24709 $filesystem->rename($archivePath, $target);
24710
24711
24712  if (!$package instanceof RootPackageInterface) {
24713 $filesystem->removeDirectory($sourcePath);
24714 }
24715 $filesystem->remove($tempTarget);
24716
24717 return $target;
24718 }
24719 }
24720 <?php
24721
24722
24723
24724
24725
24726
24727
24728
24729
24730
24731
24732 namespace Composer\Package\Archiver;
24733
24734
24735
24736
24737
24738
24739 interface ArchiverInterface
24740 {
24741
24742
24743
24744
24745
24746
24747
24748
24749
24750
24751 public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false);
24752
24753
24754
24755
24756
24757
24758
24759
24760
24761 public function supports($format, $sourceType);
24762 }
24763 <?php
24764
24765
24766
24767
24768
24769
24770
24771
24772
24773
24774
24775 namespace Composer\Package\Archiver;
24776
24777 use Symfony\Component\Finder;
24778
24779
24780
24781
24782 abstract class BaseExcludeFilter
24783 {
24784
24785
24786
24787 protected $sourcePath;
24788
24789
24790
24791
24792 protected $excludePatterns;
24793
24794
24795
24796
24797 public function __construct($sourcePath)
24798 {
24799 $this->sourcePath = $sourcePath;
24800 $this->excludePatterns = array();
24801 }
24802
24803
24804
24805
24806
24807
24808
24809
24810
24811
24812
24813 public function filter($relativePath, $exclude)
24814 {
24815 foreach ($this->excludePatterns as $patternData) {
24816 list($pattern, $negate, $stripLeadingSlash) = $patternData;
24817
24818 if ($stripLeadingSlash) {
24819 $path = substr($relativePath, 1);
24820 } else {
24821 $path = $relativePath;
24822 }
24823
24824 if (preg_match($pattern, $path)) {
24825 $exclude = !$negate;
24826 }
24827 }
24828
24829 return $exclude;
24830 }
24831
24832
24833
24834
24835
24836
24837
24838
24839
24840 protected function parseLines(array $lines, $lineParser)
24841 {
24842 return array_filter(
24843 array_map(
24844 function ($line) use ($lineParser) {
24845 $line = trim($line);
24846
24847 if (!$line || 0 === strpos($line, '#')) {
24848 return null;
24849 }
24850
24851 return call_user_func($lineParser, $line);
24852 },
24853 $lines
24854 ),
24855 function ($pattern) {
24856 return $pattern !== null;
24857 }
24858 );
24859 }
24860
24861
24862
24863
24864
24865
24866
24867
24868 protected function generatePatterns($rules)
24869 {
24870 $patterns = array();
24871 foreach ($rules as $rule) {
24872 $patterns[] = $this->generatePattern($rule);
24873 }
24874
24875 return $patterns;
24876 }
24877
24878
24879
24880
24881
24882
24883
24884
24885 protected function generatePattern($rule)
24886 {
24887 $negate = false;
24888 $pattern = '{';
24889
24890 if (strlen($rule) && $rule[0] === '!') {
24891 $negate = true;
24892 $rule = substr($rule, 1);
24893 }
24894
24895 if (strlen($rule) && $rule[0] === '/') {
24896 $pattern .= '^/';
24897 $rule = substr($rule, 1);
24898 } elseif (strlen($rule) - 1 === strpos($rule, '/')) {
24899 $pattern .= '/';
24900 $rule = substr($rule, 0, -1);
24901 } elseif (false === strpos($rule, '/')) {
24902 $pattern .= '/';
24903 }
24904
24905
24906  $pattern .= substr(Finder\Glob::toRegex($rule), 2, -2) . '(?=$|/)';
24907
24908 return array($pattern . '}', $negate, false);
24909 }
24910 }
24911 <?php
24912
24913
24914
24915
24916
24917
24918
24919
24920
24921
24922
24923 namespace Composer\Package\Archiver;
24924
24925
24926
24927
24928
24929
24930 class ComposerExcludeFilter extends BaseExcludeFilter
24931 {
24932
24933
24934
24935
24936 public function __construct($sourcePath, array $excludeRules)
24937 {
24938 parent::__construct($sourcePath);
24939 $this->excludePatterns = $this->generatePatterns($excludeRules);
24940 }
24941 }
24942 <?php
24943
24944
24945
24946
24947
24948
24949
24950
24951
24952
24953
24954 namespace Composer\Package\Archiver;
24955
24956
24957
24958
24959
24960
24961
24962
24963 class GitExcludeFilter extends BaseExcludeFilter
24964 {
24965
24966
24967
24968
24969
24970 public function __construct($sourcePath)
24971 {
24972 parent::__construct($sourcePath);
24973
24974 if (file_exists($sourcePath.'/.gitignore')) {
24975 $this->excludePatterns = $this->parseLines(
24976 file($sourcePath.'/.gitignore'),
24977 array($this, 'parseGitIgnoreLine')
24978 );
24979 }
24980 if (file_exists($sourcePath.'/.gitattributes')) {
24981 $this->excludePatterns = array_merge(
24982 $this->excludePatterns,
24983 $this->parseLines(
24984 file($sourcePath.'/.gitattributes'),
24985 array($this, 'parseGitAttributesLine')
24986 ));
24987 }
24988 }
24989
24990
24991
24992
24993
24994
24995
24996
24997 public function parseGitIgnoreLine($line)
24998 {
24999 return $this->generatePattern($line);
25000 }
25001
25002
25003
25004
25005
25006
25007
25008
25009 public function parseGitAttributesLine($line)
25010 {
25011 $parts = preg_split('#\s+#', $line);
25012
25013 if (count($parts) == 2 && $parts[1] === 'export-ignore') {
25014 return $this->generatePattern($parts[0]);
25015 }
25016
25017 return null;
25018 }
25019 }
25020 <?php
25021
25022
25023
25024
25025
25026
25027
25028
25029
25030
25031
25032 namespace Composer\Package\Archiver;
25033
25034 use Symfony\Component\Finder;
25035
25036
25037
25038
25039
25040
25041 class HgExcludeFilter extends BaseExcludeFilter
25042 {
25043 const HG_IGNORE_REGEX = 1;
25044 const HG_IGNORE_GLOB = 2;
25045
25046
25047
25048
25049
25050 protected $patternMode;
25051
25052
25053
25054
25055
25056
25057 public function __construct($sourcePath)
25058 {
25059 parent::__construct($sourcePath);
25060
25061 $this->patternMode = self::HG_IGNORE_REGEX;
25062
25063 if (file_exists($sourcePath.'/.hgignore')) {
25064 $this->excludePatterns = $this->parseLines(
25065 file($sourcePath.'/.hgignore'),
25066 array($this, 'parseHgIgnoreLine')
25067 );
25068 }
25069 }
25070
25071
25072
25073
25074
25075
25076
25077
25078 public function parseHgIgnoreLine($line)
25079 {
25080 if (preg_match('#^syntax\s*:\s*(glob|regexp)$#', $line, $matches)) {
25081 if ($matches[1] === 'glob') {
25082 $this->patternMode = self::HG_IGNORE_GLOB;
25083 } else {
25084 $this->patternMode = self::HG_IGNORE_REGEX;
25085 }
25086
25087 return null;
25088 }
25089
25090 if ($this->patternMode == self::HG_IGNORE_GLOB) {
25091 return $this->patternFromGlob($line);
25092 } else {
25093 return $this->patternFromRegex($line);
25094 }
25095 }
25096
25097
25098
25099
25100
25101
25102
25103
25104 protected function patternFromGlob($line)
25105 {
25106 $pattern = '#'.substr(Finder\Glob::toRegex($line), 2, -1).'#';
25107 $pattern = str_replace('[^/]*', '.*', $pattern);
25108
25109 return array($pattern, false, true);
25110 }
25111
25112
25113
25114
25115
25116
25117
25118
25119 public function patternFromRegex($line)
25120 {
25121
25122  $pattern = '#'.preg_replace('/((?:\\\\\\\\)*)(\\\\?)#/', '\1\2\2\\#', $line).'#';
25123
25124 return array($pattern, false, true);
25125 }
25126 }
25127 <?php
25128
25129
25130
25131
25132
25133
25134
25135
25136
25137
25138
25139 namespace Composer\Package\Archiver;
25140
25141
25142
25143
25144
25145
25146 class PharArchiver implements ArchiverInterface
25147 {
25148 protected static $formats = array(
25149 'zip' => \Phar::ZIP,
25150 'tar' => \Phar::TAR,
25151 'tar.gz' => \Phar::TAR,
25152 'tar.bz2' => \Phar::TAR,
25153 );
25154
25155 protected static $compressFormats = array(
25156 'tar.gz' => \Phar::GZ,
25157 'tar.bz2' => \Phar::BZ2,
25158 );
25159
25160
25161
25162
25163 public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false)
25164 {
25165 $sources = realpath($sources);
25166
25167
25168  if (file_exists($target)) {
25169 unlink($target);
25170 }
25171
25172 try {
25173 $filename = substr($target, 0, strrpos($target, $format) - 1);
25174
25175
25176  if (isset(static::$compressFormats[$format])) {
25177
25178  $target = $filename . '.tar';
25179 }
25180
25181 $phar = new \PharData($target, null, null, static::$formats[$format]);
25182 $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
25183 $filesOnly = new ArchivableFilesFilter($files);
25184 $phar->buildFromIterator($filesOnly, $sources);
25185 $filesOnly->addEmptyDir($phar, $sources);
25186
25187 if (isset(static::$compressFormats[$format])) {
25188
25189  if (!$phar->canCompress(static::$compressFormats[$format])) {
25190 throw new \RuntimeException(sprintf('Can not compress to %s format', $format));
25191 }
25192
25193
25194  unlink($target);
25195
25196
25197  $phar->compress(static::$compressFormats[$format]);
25198
25199
25200  $target = $filename . '.' . $format;
25201 }
25202
25203 return $target;
25204 } catch (\UnexpectedValueException $e) {
25205 $message = sprintf("Could not create archive '%s' from '%s': %s",
25206 $target,
25207 $sources,
25208 $e->getMessage()
25209 );
25210
25211 throw new \RuntimeException($message, $e->getCode(), $e);
25212 }
25213 }
25214
25215
25216
25217
25218 public function supports($format, $sourceType)
25219 {
25220 return isset(static::$formats[$format]);
25221 }
25222 }
25223 <?php
25224
25225
25226
25227
25228
25229
25230
25231
25232
25233
25234
25235 namespace Composer\Package\Archiver;
25236
25237 use ZipArchive;
25238 use Composer\Util\Filesystem;
25239
25240
25241
25242
25243 class ZipArchiver implements ArchiverInterface
25244 {
25245 protected static $formats = array(
25246 'zip' => 1,
25247 );
25248
25249
25250
25251
25252 public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false)
25253 {
25254 $fs = new Filesystem();
25255 $sources = $fs->normalizePath($sources);
25256
25257 $zip = new ZipArchive();
25258 $res = $zip->open($target, ZipArchive::CREATE);
25259 if ($res === true) {
25260 $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
25261 foreach ($files as $file) {
25262
25263 $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/');
25264 $localname = str_replace($sources.'/', '', $filepath);
25265 if ($file->isDir()) {
25266 $zip->addEmptyDir($localname);
25267 } else {
25268 $zip->addFile($filepath, $localname);
25269 }
25270 }
25271 if ($zip->close()) {
25272 return $target;
25273 }
25274 }
25275 $message = sprintf("Could not create archive '%s' from '%s': %s",
25276 $target,
25277 $sources,
25278 $zip->getStatusString()
25279 );
25280 throw new \RuntimeException($message);
25281 }
25282
25283
25284
25285
25286 public function supports($format, $sourceType)
25287 {
25288 return isset(static::$formats[$format]) && $this->compressionAvailable();
25289 }
25290
25291 private function compressionAvailable()
25292 {
25293 return class_exists('ZipArchive');
25294 }
25295 }
25296 <?php
25297
25298
25299
25300
25301
25302
25303
25304
25305
25306
25307
25308 namespace Composer\Package;
25309
25310 use Composer\Repository\RepositoryInterface;
25311 use Composer\Repository\PlatformRepository;
25312
25313
25314
25315
25316
25317
25318 abstract class BasePackage implements PackageInterface
25319 {
25320 public static $supportedLinkTypes = array(
25321 'require' => array('description' => 'requires', 'method' => 'requires'),
25322 'conflict' => array('description' => 'conflicts', 'method' => 'conflicts'),
25323 'provide' => array('description' => 'provides', 'method' => 'provides'),
25324 'replace' => array('description' => 'replaces', 'method' => 'replaces'),
25325 'require-dev' => array('description' => 'requires (for development)', 'method' => 'devRequires'),
25326 );
25327
25328 const STABILITY_STABLE = 0;
25329 const STABILITY_RC = 5;
25330 const STABILITY_BETA = 10;
25331 const STABILITY_ALPHA = 15;
25332 const STABILITY_DEV = 20;
25333
25334 public static $stabilities = array(
25335 'stable' => self::STABILITY_STABLE,
25336 'RC' => self::STABILITY_RC,
25337 'beta' => self::STABILITY_BETA,
25338 'alpha' => self::STABILITY_ALPHA,
25339 'dev' => self::STABILITY_DEV,
25340 );
25341
25342
25343
25344
25345
25346 public $id;
25347
25348 protected $name;
25349
25350 protected $prettyName;
25351
25352 protected $repository;
25353
25354 protected $transportOptions = array();
25355
25356
25357
25358
25359
25360
25361 public function __construct($name)
25362 {
25363 $this->prettyName = $name;
25364 $this->name = strtolower($name);
25365 $this->id = -1;
25366 }
25367
25368
25369
25370
25371 public function getName()
25372 {
25373 return $this->name;
25374 }
25375
25376
25377
25378
25379 public function getPrettyName()
25380 {
25381 return $this->prettyName;
25382 }
25383
25384
25385
25386
25387 public function getNames()
25388 {
25389 $names = array(
25390 $this->getName() => true,
25391 );
25392
25393 foreach ($this->getProvides() as $link) {
25394 $names[$link->getTarget()] = true;
25395 }
25396
25397 foreach ($this->getReplaces() as $link) {
25398 $names[$link->getTarget()] = true;
25399 }
25400
25401 return array_keys($names);
25402 }
25403
25404
25405
25406
25407 public function setId($id)
25408 {
25409 $this->id = $id;
25410 }
25411
25412
25413
25414
25415 public function getId()
25416 {
25417 return $this->id;
25418 }
25419
25420
25421
25422
25423 public function setRepository(RepositoryInterface $repository)
25424 {
25425 if ($this->repository && $repository !== $this->repository) {
25426 throw new \LogicException('A package can only be added to one repository');
25427 }
25428 $this->repository = $repository;
25429 }
25430
25431
25432
25433
25434 public function getRepository()
25435 {
25436 return $this->repository;
25437 }
25438
25439
25440
25441
25442 public function getTransportOptions()
25443 {
25444 return $this->transportOptions;
25445 }
25446
25447
25448
25449
25450
25451
25452 public function setTransportOptions(array $options)
25453 {
25454 $this->transportOptions = $options;
25455 }
25456
25457
25458
25459
25460
25461
25462 public function isPlatform()
25463 {
25464 return $this->getRepository() instanceof PlatformRepository;
25465 }
25466
25467
25468
25469
25470
25471
25472 public function getUniqueName()
25473 {
25474 return $this->getName().'-'.$this->getVersion();
25475 }
25476
25477 public function equals(PackageInterface $package)
25478 {
25479 $self = $this;
25480 if ($this instanceof AliasPackage) {
25481 $self = $this->getAliasOf();
25482 }
25483 if ($package instanceof AliasPackage) {
25484 $package = $package->getAliasOf();
25485 }
25486
25487 return $package === $self;
25488 }
25489
25490
25491
25492
25493
25494
25495 public function __toString()
25496 {
25497 return $this->getUniqueName();
25498 }
25499
25500 public function getPrettyString()
25501 {
25502 return $this->getPrettyName().' '.$this->getPrettyVersion();
25503 }
25504
25505
25506
25507
25508 public function getFullPrettyVersion($truncate = true)
25509 {
25510 if (!$this->isDev() || !in_array($this->getSourceType(), array('hg', 'git'))) {
25511 return $this->getPrettyVersion();
25512 }
25513
25514
25515  if ($truncate && strlen($this->getSourceReference()) === 40) {
25516 return $this->getPrettyVersion() . ' ' . substr($this->getSourceReference(), 0, 7);
25517 }
25518
25519 return $this->getPrettyVersion() . ' ' . $this->getSourceReference();
25520 }
25521
25522 public function getStabilityPriority()
25523 {
25524 return self::$stabilities[$this->getStability()];
25525 }
25526
25527 public function __clone()
25528 {
25529 $this->repository = null;
25530 $this->id = -1;
25531 }
25532 }
25533 <?php
25534
25535
25536
25537
25538
25539
25540
25541
25542
25543
25544
25545 namespace Composer\Package;
25546
25547
25548
25549
25550
25551
25552 class CompletePackage extends Package implements CompletePackageInterface
25553 {
25554 protected $repositories;
25555 protected $license = array();
25556 protected $keywords;
25557 protected $authors;
25558 protected $description;
25559 protected $homepage;
25560 protected $scripts = array();
25561 protected $support = array();
25562 protected $abandoned = false;
25563
25564
25565
25566
25567 public function setScripts(array $scripts)
25568 {
25569 $this->scripts = $scripts;
25570 }
25571
25572
25573
25574
25575 public function getScripts()
25576 {
25577 return $this->scripts;
25578 }
25579
25580
25581
25582
25583
25584
25585 public function setRepositories($repositories)
25586 {
25587 $this->repositories = $repositories;
25588 }
25589
25590
25591
25592
25593 public function getRepositories()
25594 {
25595 return $this->repositories;
25596 }
25597
25598
25599
25600
25601
25602
25603 public function setLicense(array $license)
25604 {
25605 $this->license = $license;
25606 }
25607
25608
25609
25610
25611 public function getLicense()
25612 {
25613 return $this->license;
25614 }
25615
25616
25617
25618
25619
25620
25621 public function setKeywords(array $keywords)
25622 {
25623 $this->keywords = $keywords;
25624 }
25625
25626
25627
25628
25629 public function getKeywords()
25630 {
25631 return $this->keywords;
25632 }
25633
25634
25635
25636
25637
25638
25639 public function setAuthors(array $authors)
25640 {
25641 $this->authors = $authors;
25642 }
25643
25644
25645
25646
25647 public function getAuthors()
25648 {
25649 return $this->authors;
25650 }
25651
25652
25653
25654
25655
25656
25657 public function setDescription($description)
25658 {
25659 $this->description = $description;
25660 }
25661
25662
25663
25664
25665 public function getDescription()
25666 {
25667 return $this->description;
25668 }
25669
25670
25671
25672
25673
25674
25675 public function setHomepage($homepage)
25676 {
25677 $this->homepage = $homepage;
25678 }
25679
25680
25681
25682
25683 public function getHomepage()
25684 {
25685 return $this->homepage;
25686 }
25687
25688
25689
25690
25691
25692
25693 public function setSupport(array $support)
25694 {
25695 $this->support = $support;
25696 }
25697
25698
25699
25700
25701 public function getSupport()
25702 {
25703 return $this->support;
25704 }
25705
25706
25707
25708
25709 public function isAbandoned()
25710 {
25711 return (bool) $this->abandoned;
25712 }
25713
25714
25715
25716
25717 public function setAbandoned($abandoned)
25718 {
25719 $this->abandoned = $abandoned;
25720 }
25721
25722
25723
25724
25725
25726
25727 public function getReplacementPackage()
25728 {
25729 return is_string($this->abandoned) ? $this->abandoned : null;
25730 }
25731 }
25732 <?php
25733
25734
25735
25736
25737
25738
25739
25740
25741
25742
25743
25744 namespace Composer\Package;
25745
25746
25747
25748
25749
25750
25751 interface CompletePackageInterface extends PackageInterface
25752 {
25753
25754
25755
25756
25757
25758 public function getScripts();
25759
25760
25761
25762
25763
25764
25765
25766
25767 public function getRepositories();
25768
25769
25770
25771
25772
25773
25774 public function getLicense();
25775
25776
25777
25778
25779
25780
25781 public function getKeywords();
25782
25783
25784
25785
25786
25787
25788 public function getDescription();
25789
25790
25791
25792
25793
25794
25795 public function getHomepage();
25796
25797
25798
25799
25800
25801
25802
25803
25804 public function getAuthors();
25805
25806
25807
25808
25809
25810
25811 public function getSupport();
25812
25813
25814
25815
25816
25817
25818 public function isAbandoned();
25819
25820
25821
25822
25823
25824
25825 public function getReplacementPackage();
25826 }
25827 <?php
25828
25829
25830
25831
25832
25833
25834
25835
25836
25837
25838
25839 namespace Composer\Package\Dumper;
25840
25841 use Composer\Package\BasePackage;
25842 use Composer\Package\PackageInterface;
25843 use Composer\Package\CompletePackageInterface;
25844 use Composer\Package\RootPackageInterface;
25845
25846
25847
25848
25849
25850 class ArrayDumper
25851 {
25852 public function dump(PackageInterface $package)
25853 {
25854 $keys = array(
25855 'binaries' => 'bin',
25856 'type',
25857 'extra',
25858 'installationSource' => 'installation-source',
25859 'autoload',
25860 'devAutoload' => 'autoload-dev',
25861 'notificationUrl' => 'notification-url',
25862 'includePaths' => 'include-path',
25863 );
25864
25865 $data = array();
25866 $data['name'] = $package->getPrettyName();
25867 $data['version'] = $package->getPrettyVersion();
25868 $data['version_normalized'] = $package->getVersion();
25869
25870 if ($package->getTargetDir()) {
25871 $data['target-dir'] = $package->getTargetDir();
25872 }
25873
25874 if ($package->getSourceType()) {
25875 $data['source']['type'] = $package->getSourceType();
25876 $data['source']['url'] = $package->getSourceUrl();
25877 $data['source']['reference'] = $package->getSourceReference();
25878 if ($mirrors = $package->getSourceMirrors()) {
25879 $data['source']['mirrors'] = $mirrors;
25880 }
25881 }
25882
25883 if ($package->getDistType()) {
25884 $data['dist']['type'] = $package->getDistType();
25885 $data['dist']['url'] = $package->getDistUrl();
25886 $data['dist']['reference'] = $package->getDistReference();
25887 $data['dist']['shasum'] = $package->getDistSha1Checksum();
25888 if ($mirrors = $package->getDistMirrors()) {
25889 $data['dist']['mirrors'] = $mirrors;
25890 }
25891 }
25892
25893 if ($package->getArchiveExcludes()) {
25894 $data['archive']['exclude'] = $package->getArchiveExcludes();
25895 }
25896
25897 foreach (BasePackage::$supportedLinkTypes as $type => $opts) {
25898 if ($links = $package->{'get'.ucfirst($opts['method'])}()) {
25899 foreach ($links as $link) {
25900 $data[$type][$link->getTarget()] = $link->getPrettyConstraint();
25901 }
25902 ksort($data[$type]);
25903 }
25904 }
25905
25906 if ($packages = $package->getSuggests()) {
25907 ksort($packages);
25908 $data['suggest'] = $packages;
25909 }
25910
25911 if ($package->getReleaseDate()) {
25912 $data['time'] = $package->getReleaseDate()->format(DATE_RFC3339);
25913 }
25914
25915 $data = $this->dumpValues($package, $keys, $data);
25916
25917 if ($package instanceof CompletePackageInterface) {
25918 $keys = array(
25919 'scripts',
25920 'license',
25921 'authors',
25922 'description',
25923 'homepage',
25924 'keywords',
25925 'repositories',
25926 'support',
25927 );
25928
25929 $data = $this->dumpValues($package, $keys, $data);
25930
25931 if (isset($data['keywords']) && is_array($data['keywords'])) {
25932 sort($data['keywords']);
25933 }
25934
25935 if ($package->isAbandoned()) {
25936 $data['abandoned'] = $package->getReplacementPackage() ?: true;
25937 }
25938 }
25939
25940 if ($package instanceof RootPackageInterface) {
25941 $minimumStability = $package->getMinimumStability();
25942 if ($minimumStability) {
25943 $data['minimum-stability'] = $minimumStability;
25944 }
25945 }
25946
25947 if (count($package->getTransportOptions()) > 0) {
25948 $data['transport-options'] = $package->getTransportOptions();
25949 }
25950
25951 return $data;
25952 }
25953
25954 private function dumpValues(PackageInterface $package, array $keys, array $data)
25955 {
25956 foreach ($keys as $method => $key) {
25957 if (is_numeric($method)) {
25958 $method = $key;
25959 }
25960
25961 $getter = 'get'.ucfirst($method);
25962 $value = $package->$getter();
25963
25964 if (null !== $value && !(is_array($value) && 0 === count($value))) {
25965 $data[$key] = $value;
25966 }
25967 }
25968
25969 return $data;
25970 }
25971 }
25972 <?php
25973
25974
25975
25976
25977
25978
25979
25980
25981
25982
25983
25984 namespace Composer\Package;
25985
25986 use Composer\Semver\Constraint\ConstraintInterface;
25987
25988
25989
25990
25991
25992
25993 class Link
25994 {
25995
25996
25997
25998 protected $source;
25999
26000
26001
26002
26003 protected $target;
26004
26005
26006
26007
26008 protected $constraint;
26009
26010
26011
26012
26013 protected $description;
26014
26015
26016
26017
26018 protected $prettyConstraint;
26019
26020
26021
26022
26023
26024
26025
26026
26027
26028
26029 public function __construct($source, $target, ConstraintInterface $constraint = null, $description = 'relates to', $prettyConstraint = null)
26030 {
26031 $this->source = strtolower($source);
26032 $this->target = strtolower($target);
26033 $this->constraint = $constraint;
26034 $this->description = $description;
26035 $this->prettyConstraint = $prettyConstraint;
26036 }
26037
26038
26039
26040
26041 public function getDescription()
26042 {
26043 return $this->description;
26044 }
26045
26046
26047
26048
26049 public function getSource()
26050 {
26051 return $this->source;
26052 }
26053
26054
26055
26056
26057 public function getTarget()
26058 {
26059 return $this->target;
26060 }
26061
26062
26063
26064
26065 public function getConstraint()
26066 {
26067 return $this->constraint;
26068 }
26069
26070
26071
26072
26073
26074 public function getPrettyConstraint()
26075 {
26076 if (null === $this->prettyConstraint) {
26077 throw new \UnexpectedValueException(sprintf('Link %s has been misconfigured and had no prettyConstraint given.', $this));
26078 }
26079
26080 return $this->prettyConstraint;
26081 }
26082
26083
26084
26085
26086 public function __toString()
26087 {
26088 return $this->source.' '.$this->description.' '.$this->target.' ('.$this->constraint.')';
26089 }
26090
26091
26092
26093
26094
26095 public function getPrettyString(PackageInterface $sourcePackage)
26096 {
26097 return $sourcePackage->getPrettyString().' '.$this->description.' '.$this->target.' '.$this->constraint->getPrettyString().'';
26098 }
26099 }
26100 <?php
26101
26102
26103
26104
26105
26106
26107
26108
26109
26110
26111
26112 namespace Composer\Package\LinkConstraint;
26113
26114 use Composer\Semver\Constraint\EmptyConstraint as SemverEmptyConstraint;
26115
26116 trigger_error('The ' . __NAMESPACE__ . '\EmptyConstraint class is deprecated, use Composer\Semver\Constraint\EmptyConstraint instead.', E_USER_DEPRECATED);
26117
26118
26119
26120
26121 class EmptyConstraint extends SemverEmptyConstraint implements LinkConstraintInterface
26122 {
26123 }
26124 <?php
26125
26126
26127
26128
26129
26130
26131
26132
26133
26134
26135
26136 namespace Composer\Package\LinkConstraint;
26137
26138 use Composer\Semver\Constraint\ConstraintInterface;
26139
26140 trigger_error('The ' . __NAMESPACE__ . '\LinkConstraintInterface interface is deprecated, use Composer\Semver\Constraint\ConstraintInterface instead.', E_USER_DEPRECATED);
26141
26142
26143
26144
26145 interface LinkConstraintInterface extends ConstraintInterface
26146 {
26147 }
26148 <?php
26149
26150
26151
26152
26153
26154
26155
26156
26157
26158
26159
26160 namespace Composer\Package\LinkConstraint;
26161
26162 use Composer\Semver\Constraint\MultiConstraint as SemverMultiConstraint;
26163
26164 trigger_error('The ' . __NAMESPACE__ . '\MultiConstraint class is deprecated, use Composer\Semver\Constraint\MultiConstraint instead.', E_USER_DEPRECATED);
26165
26166
26167
26168
26169 class MultiConstraint extends SemverMultiConstraint implements LinkConstraintInterface
26170 {
26171 }
26172 <?php
26173
26174
26175
26176
26177
26178
26179
26180
26181
26182
26183
26184 namespace Composer\Package\LinkConstraint;
26185
26186 use Composer\Semver\Constraint\AbstractConstraint;
26187
26188 trigger_error('The ' . __NAMESPACE__ . '\SpecificConstraint abstract class is deprecated, there is no replacement for it.', E_USER_DEPRECATED);
26189
26190
26191
26192
26193 abstract class SpecificConstraint extends AbstractConstraint implements LinkConstraintInterface
26194 {
26195 }
26196 <?php
26197
26198
26199
26200
26201
26202
26203
26204
26205
26206
26207
26208 namespace Composer\Package\LinkConstraint;
26209
26210 use Composer\Semver\Constraint\Constraint;
26211
26212 trigger_error('The ' . __NAMESPACE__ . '\VersionConstraint class is deprecated, use Composer\Semver\Constraint\Constraint instead.', E_USER_DEPRECATED);
26213
26214
26215
26216
26217 class VersionConstraint extends Constraint implements LinkConstraintInterface
26218 {
26219 }
26220 <?php
26221
26222
26223
26224
26225
26226
26227
26228
26229
26230
26231
26232 namespace Composer\Package\Loader;
26233
26234 use Composer\Package;
26235 use Composer\Package\AliasPackage;
26236 use Composer\Package\Link;
26237 use Composer\Package\RootAliasPackage;
26238 use Composer\Package\RootPackageInterface;
26239 use Composer\Package\Version\VersionParser;
26240 use Composer\Semver\VersionParser as SemverVersionParser;
26241
26242
26243
26244
26245
26246 class ArrayLoader implements LoaderInterface
26247 {
26248 protected $versionParser;
26249 protected $loadOptions;
26250
26251 public function __construct(SemverVersionParser $parser = null, $loadOptions = false)
26252 {
26253 if (!$parser) {
26254 $parser = new VersionParser;
26255 }
26256 $this->versionParser = $parser;
26257 $this->loadOptions = $loadOptions;
26258 }
26259
26260 public function load(array $config, $class = 'Composer\Package\CompletePackage')
26261 {
26262 if (!isset($config['name'])) {
26263 throw new \UnexpectedValueException('Unknown package has no name defined ('.json_encode($config).').');
26264 }
26265 if (!isset($config['version'])) {
26266 throw new \UnexpectedValueException('Package '.$config['name'].' has no version defined.');
26267 }
26268
26269
26270  if (isset($config['version_normalized'])) {
26271 $version = $config['version_normalized'];
26272 } else {
26273 $version = $this->versionParser->normalize($config['version']);
26274 }
26275 $package = new $class($config['name'], $version, $config['version']);
26276 $package->setType(isset($config['type']) ? strtolower($config['type']) : 'library');
26277
26278 if (isset($config['target-dir'])) {
26279 $package->setTargetDir($config['target-dir']);
26280 }
26281
26282 if (isset($config['extra']) && is_array($config['extra'])) {
26283 $package->setExtra($config['extra']);
26284 }
26285
26286 if (isset($config['bin'])) {
26287 if (!is_array($config['bin'])) {
26288 throw new \UnexpectedValueException('Package '.$config['name'].'\'s bin key should be an array, '.gettype($config['bin']).' given.');
26289 }
26290 foreach ($config['bin'] as $key => $bin) {
26291 $config['bin'][$key] = ltrim($bin, '/');
26292 }
26293 $package->setBinaries($config['bin']);
26294 }
26295
26296 if (isset($config['installation-source'])) {
26297 $package->setInstallationSource($config['installation-source']);
26298 }
26299
26300 if (isset($config['source'])) {
26301 if (!isset($config['source']['type']) || !isset($config['source']['url']) || !isset($config['source']['reference'])) {
26302 throw new \UnexpectedValueException(sprintf(
26303 "Package %s's source key should be specified as {\"type\": ..., \"url\": ..., \"reference\": ...},\n%s given.",
26304 $config['name'],
26305 json_encode($config['source'])
26306 ));
26307 }
26308 $package->setSourceType($config['source']['type']);
26309 $package->setSourceUrl($config['source']['url']);
26310 $package->setSourceReference($config['source']['reference']);
26311 if (isset($config['source']['mirrors'])) {
26312 $package->setSourceMirrors($config['source']['mirrors']);
26313 }
26314 }
26315
26316 if (isset($config['dist'])) {
26317 if (!isset($config['dist']['type'])
26318 || !isset($config['dist']['url'])) {
26319 throw new \UnexpectedValueException(sprintf(
26320 "Package %s's dist key should be specified as ".
26321 "{\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...},\n%s given.",
26322 $config['name'],
26323 json_encode($config['dist'])
26324 ));
26325 }
26326 $package->setDistType($config['dist']['type']);
26327 $package->setDistUrl($config['dist']['url']);
26328 $package->setDistReference(isset($config['dist']['reference']) ? $config['dist']['reference'] : null);
26329 $package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null);
26330 if (isset($config['dist']['mirrors'])) {
26331 $package->setDistMirrors($config['dist']['mirrors']);
26332 }
26333 }
26334
26335 foreach (Package\BasePackage::$supportedLinkTypes as $type => $opts) {
26336 if (isset($config[$type])) {
26337 $method = 'set'.ucfirst($opts['method']);
26338 $package->{$method}(
26339 $this->parseLinks(
26340 $package->getName(),
26341 $package->getPrettyVersion(),
26342 $opts['description'],
26343 $config[$type]
26344 )
26345 );
26346 }
26347 }
26348
26349 if (isset($config['suggest']) && is_array($config['suggest'])) {
26350 foreach ($config['suggest'] as $target => $reason) {
26351 if ('self.version' === trim($reason)) {
26352 $config['suggest'][$target] = $package->getPrettyVersion();
26353 }
26354 }
26355 $package->setSuggests($config['suggest']);
26356 }
26357
26358 if (isset($config['autoload'])) {
26359 $package->setAutoload($config['autoload']);
26360 }
26361
26362 if (isset($config['autoload-dev'])) {
26363 $package->setDevAutoload($config['autoload-dev']);
26364 }
26365
26366 if (isset($config['include-path'])) {
26367 $package->setIncludePaths($config['include-path']);
26368 }
26369
26370 if (!empty($config['time'])) {
26371 $time = preg_match('/^\d++$/D', $config['time']) ? '@'.$config['time'] : $config['time'];
26372
26373 try {
26374 $date = new \DateTime($time, new \DateTimeZone('UTC'));
26375 $package->setReleaseDate($date);
26376 } catch (\Exception $e) {
26377 }
26378 }
26379
26380 if (!empty($config['notification-url'])) {
26381 $package->setNotificationUrl($config['notification-url']);
26382 }
26383
26384 if (!empty($config['archive']['exclude'])) {
26385 $package->setArchiveExcludes($config['archive']['exclude']);
26386 }
26387
26388 if ($package instanceof Package\CompletePackageInterface) {
26389 if (isset($config['scripts']) && is_array($config['scripts'])) {
26390 foreach ($config['scripts'] as $event => $listeners) {
26391 $config['scripts'][$event] = (array) $listeners;
26392 }
26393 if (isset($config['scripts']['composer'])) {
26394 trigger_error('The `composer` script name is reserved for internal use, please avoid defining it', E_USER_DEPRECATED);
26395 }
26396 $package->setScripts($config['scripts']);
26397 }
26398
26399 if (!empty($config['description']) && is_string($config['description'])) {
26400 $package->setDescription($config['description']);
26401 }
26402
26403 if (!empty($config['homepage']) && is_string($config['homepage'])) {
26404 $package->setHomepage($config['homepage']);
26405 }
26406
26407 if (!empty($config['keywords']) && is_array($config['keywords'])) {
26408 $package->setKeywords($config['keywords']);
26409 }
26410
26411 if (!empty($config['license'])) {
26412 $package->setLicense(is_array($config['license']) ? $config['license'] : array($config['license']));
26413 }
26414
26415 if (!empty($config['authors']) && is_array($config['authors'])) {
26416 $package->setAuthors($config['authors']);
26417 }
26418
26419 if (isset($config['support'])) {
26420 $package->setSupport($config['support']);
26421 }
26422
26423 if (isset($config['abandoned'])) {
26424 $package->setAbandoned($config['abandoned']);
26425 }
26426 }
26427
26428 if ($aliasNormalized = $this->getBranchAlias($config)) {
26429 if ($package instanceof RootPackageInterface) {
26430 $package = new RootAliasPackage($package, $aliasNormalized, preg_replace('{(\.9{7})+}', '.x', $aliasNormalized));
26431 } else {
26432 $package = new AliasPackage($package, $aliasNormalized, preg_replace('{(\.9{7})+}', '.x', $aliasNormalized));
26433 }
26434 }
26435
26436 if ($this->loadOptions && isset($config['transport-options'])) {
26437 $package->setTransportOptions($config['transport-options']);
26438 }
26439
26440 return $package;
26441 }
26442
26443
26444
26445
26446
26447
26448
26449
26450 public function parseLinks($source, $sourceVersion, $description, $links)
26451 {
26452 $res = array();
26453 foreach ($links as $target => $constraint) {
26454 if (!is_string($constraint)) {
26455 throw new \UnexpectedValueException('Link constraint in '.$source.' '.$description.' > '.$target.' should be a string, got '.gettype($constraint) . ' (' . var_export($constraint, true) . ')');
26456 }
26457 if ('self.version' === $constraint) {
26458 $parsedConstraint = $this->versionParser->parseConstraints($sourceVersion);
26459 } else {
26460 $parsedConstraint = $this->versionParser->parseConstraints($constraint);
26461 }
26462
26463 $res[strtolower($target)] = new Link($source, $target, $parsedConstraint, $description, $constraint);
26464 }
26465
26466 return $res;
26467 }
26468
26469
26470
26471
26472
26473
26474
26475 public function getBranchAlias(array $config)
26476 {
26477 if (('dev-' !== substr($config['version'], 0, 4) && '-dev' !== substr($config['version'], -4))
26478 || !isset($config['extra']['branch-alias'])
26479 || !is_array($config['extra']['branch-alias'])
26480 ) {
26481 return;
26482 }
26483
26484 foreach ($config['extra']['branch-alias'] as $sourceBranch => $targetBranch) {
26485
26486  if ('-dev' !== substr($targetBranch, -4)) {
26487 continue;
26488 }
26489
26490
26491  $validatedTargetBranch = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4));
26492 if ('-dev' !== substr($validatedTargetBranch, -4)) {
26493 continue;
26494 }
26495
26496
26497  if (strtolower($config['version']) !== strtolower($sourceBranch)) {
26498 continue;
26499 }
26500
26501
26502  if (($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
26503 && ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
26504 && (stripos($targetPrefix, $sourcePrefix) !== 0)
26505 ) {
26506 continue;
26507 }
26508
26509 return $validatedTargetBranch;
26510 }
26511 }
26512 }
26513 <?php
26514
26515
26516
26517
26518
26519
26520
26521
26522
26523
26524
26525 namespace Composer\Package\Loader;
26526
26527
26528
26529
26530 class InvalidPackageException extends \Exception
26531 {
26532 private $errors;
26533 private $warnings;
26534 private $data;
26535
26536 public function __construct(array $errors, array $warnings, array $data)
26537 {
26538 $this->errors = $errors;
26539 $this->warnings = $warnings;
26540 $this->data = $data;
26541 parent::__construct("Invalid package information: \n".implode("\n", array_merge($errors, $warnings)));
26542 }
26543
26544 public function getData()
26545 {
26546 return $this->data;
26547 }
26548
26549 public function getErrors()
26550 {
26551 return $this->errors;
26552 }
26553
26554 public function getWarnings()
26555 {
26556 return $this->warnings;
26557 }
26558 }
26559 <?php
26560
26561
26562
26563
26564
26565
26566
26567
26568
26569
26570
26571 namespace Composer\Package\Loader;
26572
26573 use Composer\Json\JsonFile;
26574
26575
26576
26577
26578 class JsonLoader
26579 {
26580 private $loader;
26581
26582 public function __construct(LoaderInterface $loader)
26583 {
26584 $this->loader = $loader;
26585 }
26586
26587
26588
26589
26590
26591 public function load($json)
26592 {
26593 if ($json instanceof JsonFile) {
26594 $config = $json->read();
26595 } elseif (file_exists($json)) {
26596 $config = JsonFile::parseJson(file_get_contents($json), $json);
26597 } elseif (is_string($json)) {
26598 $config = JsonFile::parseJson($json);
26599 }
26600
26601 return $this->loader->load($config);
26602 }
26603 }
26604 <?php
26605
26606
26607
26608
26609
26610
26611
26612
26613
26614
26615
26616 namespace Composer\Package\Loader;
26617
26618
26619
26620
26621
26622
26623 interface LoaderInterface
26624 {
26625
26626
26627
26628
26629
26630
26631
26632 public function load(array $package, $class = 'Composer\Package\CompletePackage');
26633 }
26634 <?php
26635
26636
26637
26638
26639
26640
26641
26642
26643
26644
26645
26646 namespace Composer\Package\Loader;
26647
26648 use Composer\Package\BasePackage;
26649 use Composer\Package\AliasPackage;
26650 use Composer\Config;
26651 use Composer\Package\RootPackageInterface;
26652 use Composer\Repository\RepositoryFactory;
26653 use Composer\Package\Version\VersionGuesser;
26654 use Composer\Package\Version\VersionParser;
26655 use Composer\Repository\RepositoryManager;
26656 use Composer\Util\ProcessExecutor;
26657
26658
26659
26660
26661
26662
26663
26664
26665 class RootPackageLoader extends ArrayLoader
26666 {
26667
26668
26669
26670 private $manager;
26671
26672
26673
26674
26675 private $config;
26676
26677
26678
26679
26680 private $versionGuesser;
26681
26682 public function __construct(RepositoryManager $manager, Config $config, VersionParser $parser = null, VersionGuesser $versionGuesser = null)
26683 {
26684 parent::__construct($parser);
26685
26686 $this->manager = $manager;
26687 $this->config = $config;
26688 $this->versionGuesser = $versionGuesser ?: new VersionGuesser($config, new ProcessExecutor(), $this->versionParser);
26689 }
26690
26691
26692
26693
26694
26695
26696
26697 public function load(array $config, $class = 'Composer\Package\RootPackage', $cwd = null)
26698 {
26699 if (!isset($config['name'])) {
26700 $config['name'] = '__root__';
26701 }
26702 $autoVersioned = false;
26703 if (!isset($config['version'])) {
26704
26705  if (getenv('COMPOSER_ROOT_VERSION')) {
26706 $version = getenv('COMPOSER_ROOT_VERSION');
26707 $commit = null;
26708 } else {
26709 $versionData = $this->versionGuesser->guessVersion($config, $cwd ?: getcwd());
26710 $version = $versionData['version'];
26711 $commit = $versionData['commit'];
26712 }
26713
26714 if (!$version) {
26715 $version = '1.0.0';
26716 $autoVersioned = true;
26717 }
26718
26719 $config['version'] = $version;
26720 if ($commit) {
26721 $config['source'] = array(
26722 'type' => '',
26723 'url' => '',
26724 'reference' => $commit,
26725 );
26726 $config['dist'] = array(
26727 'type' => '',
26728 'url' => '',
26729 'reference' => $commit,
26730 );
26731 }
26732 }
26733
26734 $realPackage = $package = parent::load($config, $class);
26735 if ($realPackage instanceof AliasPackage) {
26736 $realPackage = $package->getAliasOf();
26737 }
26738
26739 if ($autoVersioned) {
26740 $realPackage->replaceVersion($realPackage->getVersion(), 'No version set (parsed as 1.0.0)');
26741 }
26742
26743 if (isset($config['minimum-stability'])) {
26744 $realPackage->setMinimumStability(VersionParser::normalizeStability($config['minimum-stability']));
26745 }
26746
26747 $aliases = array();
26748 $stabilityFlags = array();
26749 $references = array();
26750 foreach (array('require', 'require-dev') as $linkType) {
26751 if (isset($config[$linkType])) {
26752 $linkInfo = BasePackage::$supportedLinkTypes[$linkType];
26753 $method = 'get'.ucfirst($linkInfo['method']);
26754 $links = array();
26755 foreach ($realPackage->$method() as $link) {
26756 $links[$link->getTarget()] = $link->getConstraint()->getPrettyString();
26757 }
26758 $aliases = $this->extractAliases($links, $aliases);
26759 $stabilityFlags = $this->extractStabilityFlags($links, $stabilityFlags, $realPackage->getMinimumStability());
26760 $references = $this->extractReferences($links, $references);
26761 }
26762 }
26763
26764 if (isset($links[$config['name']])) {
26765 throw new \InvalidArgumentException(sprintf('Root package \'%s\' cannot require itself in its composer.json' . PHP_EOL .
26766 'Did you accidentally name your root package after an external package?', $config['name']));
26767 }
26768
26769 $realPackage->setAliases($aliases);
26770 $realPackage->setStabilityFlags($stabilityFlags);
26771 $realPackage->setReferences($references);
26772
26773 if (isset($config['prefer-stable'])) {
26774 $realPackage->setPreferStable((bool) $config['prefer-stable']);
26775 }
26776
26777 if (isset($config['config'])) {
26778 $realPackage->setConfig($config['config']);
26779 }
26780
26781 $repos = RepositoryFactory::defaultRepos(null, $this->config, $this->manager);
26782 foreach ($repos as $repo) {
26783 $this->manager->addRepository($repo);
26784 }
26785 $realPackage->setRepositories($this->config->getRepositories());
26786
26787 return $package;
26788 }
26789
26790 private function extractAliases(array $requires, array $aliases)
26791 {
26792 foreach ($requires as $reqName => $reqVersion) {
26793 if (preg_match('{^([^,\s#]+)(?:#[^ ]+)? +as +([^,\s]+)$}', $reqVersion, $match)) {
26794 $aliases[] = array(
26795 'package' => strtolower($reqName),
26796 'version' => $this->versionParser->normalize($match[1], $reqVersion),
26797 'alias' => $match[2],
26798 'alias_normalized' => $this->versionParser->normalize($match[2], $reqVersion),
26799 );
26800 }
26801 }
26802
26803 return $aliases;
26804 }
26805
26806 private function extractStabilityFlags(array $requires, array $stabilityFlags, $minimumStability)
26807 {
26808 $stabilities = BasePackage::$stabilities;
26809 $minimumStability = $stabilities[$minimumStability];
26810 foreach ($requires as $reqName => $reqVersion) {
26811 $constraints = array();
26812
26813
26814  $orSplit = preg_split('{\s*\|\|?\s*}', trim($reqVersion));
26815 foreach ($orSplit as $orConstraint) {
26816 $andSplit = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $orConstraint);
26817 foreach ($andSplit as $andConstraint) {
26818 $constraints[] = $andConstraint;
26819 }
26820 }
26821
26822
26823  $match = false;
26824 foreach ($constraints as $constraint) {
26825 if (preg_match('{^[^@]*?@('.implode('|', array_keys($stabilities)).')$}i', $constraint, $match)) {
26826 $name = strtolower($reqName);
26827 $stability = $stabilities[VersionParser::normalizeStability($match[1])];
26828
26829 if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) {
26830 continue;
26831 }
26832 $stabilityFlags[$name] = $stability;
26833 $match = true;
26834 }
26835 }
26836
26837 if ($match) {
26838 continue;
26839 }
26840
26841 foreach ($constraints as $constraint) {
26842
26843  
26844  $reqVersion = preg_replace('{^([^,\s@]+) as .+$}', '$1', $constraint);
26845 if (preg_match('{^[^,\s@]+$}', $reqVersion) && 'stable' !== ($stabilityName = VersionParser::parseStability($reqVersion))) {
26846 $name = strtolower($reqName);
26847 $stability = $stabilities[$stabilityName];
26848 if ((isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) || ($minimumStability > $stability)) {
26849 continue;
26850 }
26851 $stabilityFlags[$name] = $stability;
26852 }
26853 }
26854 }
26855
26856 return $stabilityFlags;
26857 }
26858
26859 private function extractReferences(array $requires, array $references)
26860 {
26861 foreach ($requires as $reqName => $reqVersion) {
26862 $reqVersion = preg_replace('{^([^,\s@]+) as .+$}', '$1', $reqVersion);
26863 if (preg_match('{^[^,\s@]+?#([a-f0-9]+)$}', $reqVersion, $match) && 'dev' === ($stabilityName = VersionParser::parseStability($reqVersion))) {
26864 $name = strtolower($reqName);
26865 $references[$name] = $match[1];
26866 }
26867 }
26868
26869 return $references;
26870 }
26871 }
26872 <?php
26873
26874
26875
26876
26877
26878
26879
26880
26881
26882
26883
26884 namespace Composer\Package\Loader;
26885
26886 use Composer\Package;
26887 use Composer\Package\BasePackage;
26888 use Composer\Semver\Constraint\Constraint;
26889 use Composer\Package\Version\VersionParser;
26890 use Composer\Repository\PlatformRepository;
26891
26892
26893
26894
26895 class ValidatingArrayLoader implements LoaderInterface
26896 {
26897 const CHECK_ALL = 3;
26898 const CHECK_UNBOUND_CONSTRAINTS = 1;
26899 const CHECK_STRICT_CONSTRAINTS = 2;
26900
26901 private $loader;
26902 private $versionParser;
26903 private $errors;
26904 private $warnings;
26905 private $config;
26906 private $strictName;
26907 private $flags;
26908
26909 public function __construct(LoaderInterface $loader, $strictName = true, VersionParser $parser = null, $flags = 0)
26910 {
26911 $this->loader = $loader;
26912 $this->versionParser = $parser ?: new VersionParser();
26913 $this->strictName = $strictName;
26914 $this->flags = $flags;
26915 }
26916
26917 public function load(array $config, $class = 'Composer\Package\CompletePackage')
26918 {
26919 $this->errors = array();
26920 $this->warnings = array();
26921 $this->config = $config;
26922
26923 if ($this->strictName) {
26924 $this->validateRegex('name', '[A-Za-z0-9][A-Za-z0-9_.-]*/[A-Za-z0-9][A-Za-z0-9_.-]*', true);
26925 } else {
26926 $this->validateString('name', true);
26927 }
26928
26929 if (!empty($this->config['version'])) {
26930 try {
26931 $this->versionParser->normalize($this->config['version']);
26932 } catch (\Exception $e) {
26933 $this->errors[] = 'version : invalid value ('.$this->config['version'].'): '.$e->getMessage();
26934 unset($this->config['version']);
26935 }
26936 }
26937
26938 $this->validateRegex('type', '[A-Za-z0-9-]+');
26939 $this->validateString('target-dir');
26940 $this->validateArray('extra');
26941 $this->validateFlatArray('bin');
26942 $this->validateArray('scripts'); 
26943  $this->validateString('description');
26944 $this->validateUrl('homepage');
26945 $this->validateFlatArray('keywords', '[\p{N}\p{L} ._-]+');
26946
26947 if (isset($this->config['license'])) {
26948 if (is_string($this->config['license'])) {
26949 $this->validateRegex('license', '[A-Za-z0-9+. ()-]+');
26950 } else {
26951 $this->validateFlatArray('license', '[A-Za-z0-9+. ()-]+');
26952 }
26953 }
26954
26955 $this->validateString('time');
26956 if (!empty($this->config['time'])) {
26957 try {
26958 $date = new \DateTime($this->config['time'], new \DateTimeZone('UTC'));
26959 } catch (\Exception $e) {
26960 $this->errors[] = 'time : invalid value ('.$this->config['time'].'): '.$e->getMessage();
26961 unset($this->config['time']);
26962 }
26963 }
26964
26965 if ($this->validateArray('authors') && !empty($this->config['authors'])) {
26966 foreach ($this->config['authors'] as $key => $author) {
26967 if (!is_array($author)) {
26968 $this->errors[] = 'authors.'.$key.' : should be an array, '.gettype($author).' given';
26969 unset($this->config['authors'][$key]);
26970 continue;
26971 }
26972 foreach (array('homepage', 'email', 'name', 'role') as $authorData) {
26973 if (isset($author[$authorData]) && !is_string($author[$authorData])) {
26974 $this->errors[] = 'authors.'.$key.'.'.$authorData.' : invalid value, must be a string';
26975 unset($this->config['authors'][$key][$authorData]);
26976 }
26977 }
26978 if (isset($author['homepage']) && !$this->filterUrl($author['homepage'])) {
26979 $this->warnings[] = 'authors.'.$key.'.homepage : invalid value ('.$author['homepage'].'), must be an http/https URL';
26980 unset($this->config['authors'][$key]['homepage']);
26981 }
26982 if (isset($author['email']) && !filter_var($author['email'], FILTER_VALIDATE_EMAIL)) {
26983 $this->warnings[] = 'authors.'.$key.'.email : invalid value ('.$author['email'].'), must be a valid email address';
26984 unset($this->config['authors'][$key]['email']);
26985 }
26986 if (empty($this->config['authors'][$key])) {
26987 unset($this->config['authors'][$key]);
26988 }
26989 }
26990 if (empty($this->config['authors'])) {
26991 unset($this->config['authors']);
26992 }
26993 }
26994
26995 if ($this->validateArray('support') && !empty($this->config['support'])) {
26996 foreach (array('issues', 'forum', 'wiki', 'source', 'email', 'irc', 'docs', 'rss') as $key) {
26997 if (isset($this->config['support'][$key]) && !is_string($this->config['support'][$key])) {
26998 $this->errors[] = 'support.'.$key.' : invalid value, must be a string';
26999 unset($this->config['support'][$key]);
27000 }
27001 }
27002
27003 if (isset($this->config['support']['email']) && !filter_var($this->config['support']['email'], FILTER_VALIDATE_EMAIL)) {
27004 $this->warnings[] = 'support.email : invalid value ('.$this->config['support']['email'].'), must be a valid email address';
27005 unset($this->config['support']['email']);
27006 }
27007
27008 if (isset($this->config['support']['irc']) && !$this->filterUrl($this->config['support']['irc'], array('irc'))) {
27009 $this->warnings[] = 'support.irc : invalid value ('.$this->config['support']['irc'].'), must be a irc://<server>/<channel> URL';
27010 unset($this->config['support']['irc']);
27011 }
27012
27013 foreach (array('issues', 'forum', 'wiki', 'source', 'docs') as $key) {
27014 if (isset($this->config['support'][$key]) && !$this->filterUrl($this->config['support'][$key])) {
27015 $this->warnings[] = 'support.'.$key.' : invalid value ('.$this->config['support'][$key].'), must be an http/https URL';
27016 unset($this->config['support'][$key]);
27017 }
27018 }
27019 if (empty($this->config['support'])) {
27020 unset($this->config['support']);
27021 }
27022 }
27023
27024 $unboundConstraint = new Constraint('=', $this->versionParser->normalize('dev-master'));
27025 $stableConstraint = new Constraint('=', '1.0.0');
27026
27027 foreach (array_keys(BasePackage::$supportedLinkTypes) as $linkType) {
27028 if ($this->validateArray($linkType) && isset($this->config[$linkType])) {
27029 foreach ($this->config[$linkType] as $package => $constraint) {
27030 if (!preg_match('{^[A-Za-z0-9_./-]+$}', $package)) {
27031 $this->warnings[] = $linkType.'.'.$package.' : invalid key, package names must be strings containing only [A-Za-z0-9_./-]';
27032 }
27033 if (!is_string($constraint)) {
27034 $this->errors[] = $linkType.'.'.$package.' : invalid value, must be a string containing a version constraint';
27035 unset($this->config[$linkType][$package]);
27036 } elseif ('self.version' !== $constraint) {
27037 try {
27038 $linkConstraint = $this->versionParser->parseConstraints($constraint);
27039 } catch (\Exception $e) {
27040 $this->errors[] = $linkType.'.'.$package.' : invalid version constraint ('.$e->getMessage().')';
27041 unset($this->config[$linkType][$package]);
27042 continue;
27043 }
27044
27045
27046  if (
27047 ($this->flags & self::CHECK_UNBOUND_CONSTRAINTS)
27048 && 'require' === $linkType
27049 && $linkConstraint->matches($unboundConstraint)
27050 && !preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $package)
27051 ) {
27052 $this->warnings[] = $linkType.'.'.$package.' : unbound version constraints ('.$constraint.') should be avoided';
27053 } elseif (
27054
27055  ($this->flags & self::CHECK_STRICT_CONSTRAINTS)
27056 && 'require' === $linkType
27057 && substr($linkConstraint, 0, 1) === '='
27058 && $stableConstraint->versionCompare($stableConstraint, $linkConstraint, '<=')
27059 ) {
27060 $this->warnings[] = $linkType.'.'.$package.' : exact version constraints ('.$constraint.') should be avoided if the package follows semantic versioning';
27061 }
27062 }
27063 }
27064 }
27065 }
27066
27067 if ($this->validateArray('suggest') && !empty($this->config['suggest'])) {
27068 foreach ($this->config['suggest'] as $package => $description) {
27069 if (!is_string($description)) {
27070 $this->errors[] = 'suggest.'.$package.' : invalid value, must be a string describing why the package is suggested';
27071 unset($this->config['suggest'][$package]);
27072 }
27073 }
27074 }
27075
27076 if ($this->validateString('minimum-stability') && !empty($this->config['minimum-stability'])) {
27077 if (!isset(BasePackage::$stabilities[$this->config['minimum-stability']])) {
27078 $this->errors[] = 'minimum-stability : invalid value ('.$this->config['minimum-stability'].'), must be one of '.implode(', ', array_keys(BasePackage::$stabilities));
27079 unset($this->config['minimum-stability']);
27080 }
27081 }
27082
27083 if ($this->validateArray('autoload') && !empty($this->config['autoload'])) {
27084 $types = array('psr-0', 'psr-4', 'classmap', 'files', 'exclude-from-classmap');
27085 foreach ($this->config['autoload'] as $type => $typeConfig) {
27086 if (!in_array($type, $types)) {
27087 $this->errors[] = 'autoload : invalid value ('.$type.'), must be one of '.implode(', ', $types);
27088 unset($this->config['autoload'][$type]);
27089 }
27090 if ($type === 'psr-4') {
27091 foreach ($typeConfig as $namespace => $dirs) {
27092 if ($namespace !== '' && '\\' !== substr($namespace, -1)) {
27093 $this->errors[] = 'autoload.psr-4 : invalid value ('.$namespace.'), namespaces must end with a namespace separator, should be '.$namespace.'\\\\';
27094 }
27095 }
27096 }
27097 }
27098 }
27099
27100 if (!empty($this->config['autoload']['psr-4']) && !empty($this->config['target-dir'])) {
27101 $this->errors[] = 'target-dir : this can not be used together with the autoload.psr-4 setting, remove target-dir to upgrade to psr-4';
27102
27103  
27104  unset($this->config['autoload']['psr-4']);
27105 }
27106
27107
27108  
27109
27110
27111  
27112
27113 $this->validateFlatArray('include-path');
27114 $this->validateArray('transport-options');
27115
27116
27117  if (isset($this->config['extra']['branch-alias'])) {
27118 if (!is_array($this->config['extra']['branch-alias'])) {
27119 $this->errors[] = 'extra.branch-alias : must be an array of versions => aliases';
27120 } else {
27121 foreach ($this->config['extra']['branch-alias'] as $sourceBranch => $targetBranch) {
27122
27123  if ('-dev' !== substr($targetBranch, -4)) {
27124 $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') must end in -dev';
27125 unset($this->config['extra']['branch-alias'][$sourceBranch]);
27126
27127 continue;
27128 }
27129
27130
27131  $validatedTargetBranch = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4));
27132 if ('-dev' !== substr($validatedTargetBranch, -4)) {
27133 $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') must be a parseable number like 2.0-dev';
27134 unset($this->config['extra']['branch-alias'][$sourceBranch]);
27135
27136 continue;
27137 }
27138
27139
27140  if (($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
27141 && ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
27142 && (stripos($targetPrefix, $sourcePrefix) !== 0)
27143 ) {
27144 $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') is not a valid numeric alias for this version';
27145 unset($this->config['extra']['branch-alias'][$sourceBranch]);
27146 }
27147 }
27148 }
27149 }
27150
27151 if ($this->errors) {
27152 throw new InvalidPackageException($this->errors, $this->warnings, $config);
27153 }
27154
27155 $package = $this->loader->load($this->config, $class);
27156 $this->config = null;
27157
27158 return $package;
27159 }
27160
27161 public function getWarnings()
27162 {
27163 return $this->warnings;
27164 }
27165
27166 public function getErrors()
27167 {
27168 return $this->errors;
27169 }
27170
27171 private function validateRegex($property, $regex, $mandatory = false)
27172 {
27173 if (!$this->validateString($property, $mandatory)) {
27174 return false;
27175 }
27176
27177 if (!preg_match('{^'.$regex.'$}u', $this->config[$property])) {
27178 $message = $property.' : invalid value ('.$this->config[$property].'), must match '.$regex;
27179 if ($mandatory) {
27180 $this->errors[] = $message;
27181 } else {
27182 $this->warnings[] = $message;
27183 }
27184 unset($this->config[$property]);
27185
27186 return false;
27187 }
27188
27189 return true;
27190 }
27191
27192 private function validateString($property, $mandatory = false)
27193 {
27194 if (isset($this->config[$property]) && !is_string($this->config[$property])) {
27195 $this->errors[] = $property.' : should be a string, '.gettype($this->config[$property]).' given';
27196 unset($this->config[$property]);
27197
27198 return false;
27199 }
27200
27201 if (!isset($this->config[$property]) || trim($this->config[$property]) === '') {
27202 if ($mandatory) {
27203 $this->errors[] = $property.' : must be present';
27204 }
27205 unset($this->config[$property]);
27206
27207 return false;
27208 }
27209
27210 return true;
27211 }
27212
27213 private function validateArray($property, $mandatory = false)
27214 {
27215 if (isset($this->config[$property]) && !is_array($this->config[$property])) {
27216 $this->errors[] = $property.' : should be an array, '.gettype($this->config[$property]).' given';
27217 unset($this->config[$property]);
27218
27219 return false;
27220 }
27221
27222 if (!isset($this->config[$property]) || !count($this->config[$property])) {
27223 if ($mandatory) {
27224 $this->errors[] = $property.' : must be present and contain at least one element';
27225 }
27226 unset($this->config[$property]);
27227
27228 return false;
27229 }
27230
27231 return true;
27232 }
27233
27234 private function validateFlatArray($property, $regex = null, $mandatory = false)
27235 {
27236 if (!$this->validateArray($property, $mandatory)) {
27237 return false;
27238 }
27239
27240 $pass = true;
27241 foreach ($this->config[$property] as $key => $value) {
27242 if (!is_string($value) && !is_numeric($value)) {
27243 $this->errors[] = $property.'.'.$key.' : must be a string or int, '.gettype($value).' given';
27244 unset($this->config[$property][$key]);
27245 $pass = false;
27246
27247 continue;
27248 }
27249
27250 if ($regex && !preg_match('{^'.$regex.'$}u', $value)) {
27251 $this->warnings[] = $property.'.'.$key.' : invalid value ('.$value.'), must match '.$regex;
27252 unset($this->config[$property][$key]);
27253 $pass = false;
27254 }
27255 }
27256
27257 return $pass;
27258 }
27259
27260 private function validateUrl($property, $mandatory = false)
27261 {
27262 if (!$this->validateString($property, $mandatory)) {
27263 return false;
27264 }
27265
27266 if (!$this->filterUrl($this->config[$property])) {
27267 $this->warnings[] = $property.' : invalid value ('.$this->config[$property].'), must be an http/https URL';
27268 unset($this->config[$property]);
27269
27270 return false;
27271 }
27272
27273 return true;
27274 }
27275
27276 private function filterUrl($value, array $schemes = array('http', 'https'))
27277 {
27278 if ($value === '') {
27279 return true;
27280 }
27281
27282 $bits = parse_url($value);
27283 if (empty($bits['scheme']) || empty($bits['host'])) {
27284 return false;
27285 }
27286
27287 if (!in_array($bits['scheme'], $schemes, true)) {
27288 return false;
27289 }
27290
27291 return true;
27292 }
27293 }
27294 <?php
27295
27296
27297
27298
27299
27300
27301
27302
27303
27304
27305
27306 namespace Composer\Package;
27307
27308 use Composer\Json\JsonFile;
27309 use Composer\Installer\InstallationManager;
27310 use Composer\Repository\RepositoryManager;
27311 use Composer\Util\ProcessExecutor;
27312 use Composer\Repository\ArrayRepository;
27313 use Composer\Package\Dumper\ArrayDumper;
27314 use Composer\Package\Loader\ArrayLoader;
27315 use Composer\Util\Git as GitUtil;
27316 use Composer\IO\IOInterface;
27317 use Seld\JsonLint\ParsingException;
27318
27319
27320
27321
27322
27323
27324
27325 class Locker
27326 {
27327 private $lockFile;
27328 private $repositoryManager;
27329 private $installationManager;
27330 private $hash;
27331 private $contentHash;
27332 private $loader;
27333 private $dumper;
27334 private $process;
27335 private $lockDataCache;
27336
27337
27338
27339
27340
27341
27342
27343
27344
27345
27346 public function __construct(IOInterface $io, JsonFile $lockFile, RepositoryManager $repositoryManager, InstallationManager $installationManager, $composerFileContents)
27347 {
27348 $this->lockFile = $lockFile;
27349 $this->repositoryManager = $repositoryManager;
27350 $this->installationManager = $installationManager;
27351 $this->hash = md5($composerFileContents);
27352 $this->contentHash = self::getContentHash($composerFileContents);
27353 $this->loader = new ArrayLoader(null, true);
27354 $this->dumper = new ArrayDumper();
27355 $this->process = new ProcessExecutor($io);
27356 }
27357
27358
27359
27360
27361
27362
27363
27364
27365 public static function getContentHash($composerFileContents)
27366 {
27367 $content = json_decode($composerFileContents, true);
27368
27369 $relevantKeys = array(
27370 'name',
27371 'version',
27372 'require',
27373 'require-dev',
27374 'conflict',
27375 'replace',
27376 'provide',
27377 'minimum-stability',
27378 'prefer-stable',
27379 'repositories',
27380 'extra',
27381 );
27382
27383 $relevantContent = array();
27384
27385 foreach (array_intersect($relevantKeys, array_keys($content)) as $key) {
27386 $relevantContent[$key] = $content[$key];
27387 }
27388 if (isset($content['config']['platform'])) {
27389 $relevantContent['config']['platform'] = $content['config']['platform'];
27390 }
27391
27392 ksort($relevantContent);
27393
27394 return md5(json_encode($relevantContent));
27395 }
27396
27397
27398
27399
27400
27401
27402 public function isLocked()
27403 {
27404 if (!$this->lockFile->exists()) {
27405 return false;
27406 }
27407
27408 $data = $this->getLockData();
27409
27410 return isset($data['packages']);
27411 }
27412
27413
27414
27415
27416
27417
27418 public function isFresh()
27419 {
27420 $lock = $this->lockFile->read();
27421
27422 if (!empty($lock['content-hash'])) {
27423
27424  return $this->contentHash === $lock['content-hash'];
27425 }
27426
27427
27428  if (!empty($lock['hash'])) {
27429 return $this->hash === $lock['hash'];
27430 }
27431
27432
27433  return false;
27434 }
27435
27436
27437
27438
27439
27440
27441
27442
27443 public function getLockedRepository($withDevReqs = false)
27444 {
27445 $lockData = $this->getLockData();
27446 $packages = new ArrayRepository();
27447
27448 $lockedPackages = $lockData['packages'];
27449 if ($withDevReqs) {
27450 if (isset($lockData['packages-dev'])) {
27451 $lockedPackages = array_merge($lockedPackages, $lockData['packages-dev']);
27452 } else {
27453 throw new \RuntimeException('The lock file does not contain require-dev information, run install with the --no-dev option or run update to install those packages.');
27454 }
27455 }
27456
27457 if (empty($lockedPackages)) {
27458 return $packages;
27459 }
27460
27461 if (isset($lockedPackages[0]['name'])) {
27462 foreach ($lockedPackages as $info) {
27463 $packages->addPackage($this->loader->load($info));
27464 }
27465
27466 return $packages;
27467 }
27468
27469 throw new \RuntimeException('Your composer.lock was created before 2012-09-15, and is not supported anymore. Run "composer update" to generate a new one.');
27470 }
27471
27472
27473
27474
27475
27476
27477
27478 public function getPlatformRequirements($withDevReqs = false)
27479 {
27480 $lockData = $this->getLockData();
27481 $requirements = array();
27482
27483 if (!empty($lockData['platform'])) {
27484 $requirements = $this->loader->parseLinks(
27485 '__ROOT__',
27486 '1.0.0',
27487 'requires',
27488 isset($lockData['platform']) ? $lockData['platform'] : array()
27489 );
27490 }
27491
27492 if ($withDevReqs && !empty($lockData['platform-dev'])) {
27493 $devRequirements = $this->loader->parseLinks(
27494 '__ROOT__',
27495 '1.0.0',
27496 'requires',
27497 isset($lockData['platform-dev']) ? $lockData['platform-dev'] : array()
27498 );
27499
27500 $requirements = array_merge($requirements, $devRequirements);
27501 }
27502
27503 return $requirements;
27504 }
27505
27506 public function getMinimumStability()
27507 {
27508 $lockData = $this->getLockData();
27509
27510 return isset($lockData['minimum-stability']) ? $lockData['minimum-stability'] : 'stable';
27511 }
27512
27513 public function getStabilityFlags()
27514 {
27515 $lockData = $this->getLockData();
27516
27517 return isset($lockData['stability-flags']) ? $lockData['stability-flags'] : array();
27518 }
27519
27520 public function getPreferStable()
27521 {
27522 $lockData = $this->getLockData();
27523
27524
27525  
27526  return isset($lockData['prefer-stable']) ? $lockData['prefer-stable'] : null;
27527 }
27528
27529 public function getPreferLowest()
27530 {
27531 $lockData = $this->getLockData();
27532
27533
27534  
27535  return isset($lockData['prefer-lowest']) ? $lockData['prefer-lowest'] : null;
27536 }
27537
27538 public function getPlatformOverrides()
27539 {
27540 $lockData = $this->getLockData();
27541
27542 return isset($lockData['platform-overrides']) ? $lockData['platform-overrides'] : array();
27543 }
27544
27545 public function getAliases()
27546 {
27547 $lockData = $this->getLockData();
27548
27549 return isset($lockData['aliases']) ? $lockData['aliases'] : array();
27550 }
27551
27552 public function getLockData()
27553 {
27554 if (null !== $this->lockDataCache) {
27555 return $this->lockDataCache;
27556 }
27557
27558 if (!$this->lockFile->exists()) {
27559 throw new \LogicException('No lockfile found. Unable to read locked packages');
27560 }
27561
27562 return $this->lockDataCache = $this->lockFile->read();
27563 }
27564
27565
27566
27567
27568
27569
27570
27571
27572
27573
27574
27575
27576
27577
27578
27579
27580
27581 public function setLockData(array $packages, $devPackages, array $platformReqs, $platformDevReqs, array $aliases, $minimumStability, array $stabilityFlags, $preferStable, $preferLowest, array $platformOverrides)
27582 {
27583 $lock = array(
27584 '_readme' => array('This file locks the dependencies of your project to a known state',
27585 'Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file',
27586 'This file is @gener'.'ated automatically', ),
27587 'content-hash' => $this->contentHash,
27588 'packages' => null,
27589 'packages-dev' => null,
27590 'aliases' => array(),
27591 'minimum-stability' => $minimumStability,
27592 'stability-flags' => $stabilityFlags,
27593 'prefer-stable' => $preferStable,
27594 'prefer-lowest' => $preferLowest,
27595 );
27596
27597 foreach ($aliases as $package => $versions) {
27598 foreach ($versions as $version => $alias) {
27599 $lock['aliases'][] = array(
27600 'alias' => $alias['alias'],
27601 'alias_normalized' => $alias['alias_normalized'],
27602 'version' => $version,
27603 'package' => $package,
27604 );
27605 }
27606 }
27607
27608 $lock['packages'] = $this->lockPackages($packages);
27609 if (null !== $devPackages) {
27610 $lock['packages-dev'] = $this->lockPackages($devPackages);
27611 }
27612
27613 $lock['platform'] = $platformReqs;
27614 $lock['platform-dev'] = $platformDevReqs;
27615 if ($platformOverrides) {
27616 $lock['platform-overrides'] = $platformOverrides;
27617 }
27618
27619 if (empty($lock['packages']) && empty($lock['packages-dev']) && empty($lock['platform']) && empty($lock['platform-dev'])) {
27620 if ($this->lockFile->exists()) {
27621 unlink($this->lockFile->getPath());
27622 }
27623
27624 return false;
27625 }
27626
27627 try {
27628 $isLocked = $this->isLocked();
27629 } catch (ParsingException $e) {
27630 $isLocked = false;
27631 }
27632 if (!$isLocked || $lock !== $this->getLockData()) {
27633 $this->lockFile->write($lock);
27634 $this->lockDataCache = null;
27635
27636 return true;
27637 }
27638
27639 return false;
27640 }
27641
27642 private function lockPackages(array $packages)
27643 {
27644 $locked = array();
27645
27646 foreach ($packages as $package) {
27647 if ($package instanceof AliasPackage) {
27648 continue;
27649 }
27650
27651 $name = $package->getPrettyName();
27652 $version = $package->getPrettyVersion();
27653
27654 if (!$name || !$version) {
27655 throw new \LogicException(sprintf(
27656 'Package "%s" has no version or name and can not be locked', $package
27657 ));
27658 }
27659
27660 $spec = $this->dumper->dump($package);
27661 unset($spec['version_normalized']);
27662
27663
27664  $time = isset($spec['time']) ? $spec['time'] : null;
27665 unset($spec['time']);
27666 if ($package->isDev() && $package->getInstallationSource() === 'source') {
27667
27668  $time = $this->getPackageTime($package) ?: $time;
27669 }
27670 if (null !== $time) {
27671 $spec['time'] = $time;
27672 }
27673
27674 unset($spec['installation-source']);
27675
27676 $locked[] = $spec;
27677 }
27678
27679 usort($locked, function ($a, $b) {
27680 $comparison = strcmp($a['name'], $b['name']);
27681
27682 if (0 !== $comparison) {
27683 return $comparison;
27684 }
27685
27686
27687  return strcmp($a['version'], $b['version']);
27688 });
27689
27690 return $locked;
27691 }
27692
27693
27694
27695
27696
27697
27698
27699 private function getPackageTime(PackageInterface $package)
27700 {
27701 if (!function_exists('proc_open')) {
27702 return null;
27703 }
27704
27705 $path = realpath($this->installationManager->getInstallPath($package));
27706 $sourceType = $package->getSourceType();
27707 $datetime = null;
27708
27709 if ($path && in_array($sourceType, array('git', 'hg'))) {
27710 $sourceRef = $package->getSourceReference() ?: $package->getDistReference();
27711 switch ($sourceType) {
27712 case 'git':
27713 GitUtil::cleanEnv();
27714
27715 if (0 === $this->process->execute('git log -n1 --pretty=%ct '.ProcessExecutor::escape($sourceRef), $output, $path) && preg_match('{^\s*\d+\s*$}', $output)) {
27716 $datetime = new \DateTime('@'.trim($output), new \DateTimeZone('UTC'));
27717 }
27718 break;
27719
27720 case 'hg':
27721 if (0 === $this->process->execute('hg log --template "{date|hgdate}" -r '.ProcessExecutor::escape($sourceRef), $output, $path) && preg_match('{^\s*(\d+)\s*}', $output, $match)) {
27722 $datetime = new \DateTime('@'.$match[1], new \DateTimeZone('UTC'));
27723 }
27724 break;
27725 }
27726 }
27727
27728 return $datetime ? $datetime->format('Y-m-d H:i:s') : null;
27729 }
27730 }
27731 <?php
27732
27733
27734
27735
27736
27737
27738
27739
27740
27741
27742
27743 namespace Composer\Package;
27744
27745 use Composer\Package\Version\VersionParser;
27746 use Composer\Util\ComposerMirror;
27747
27748
27749
27750
27751
27752
27753 class Package extends BasePackage
27754 {
27755 protected $type;
27756 protected $targetDir;
27757 protected $installationSource;
27758 protected $sourceType;
27759 protected $sourceUrl;
27760 protected $sourceReference;
27761 protected $sourceMirrors;
27762 protected $distType;
27763 protected $distUrl;
27764 protected $distReference;
27765 protected $distSha1Checksum;
27766 protected $distMirrors;
27767 protected $version;
27768 protected $prettyVersion;
27769 protected $releaseDate;
27770 protected $extra = array();
27771 protected $binaries = array();
27772 protected $dev;
27773 protected $stability;
27774 protected $notificationUrl;
27775
27776
27777 protected $requires = array();
27778
27779 protected $conflicts = array();
27780
27781 protected $provides = array();
27782
27783 protected $replaces = array();
27784
27785 protected $devRequires = array();
27786 protected $suggests = array();
27787 protected $autoload = array();
27788 protected $devAutoload = array();
27789 protected $includePaths = array();
27790 protected $archiveExcludes = array();
27791
27792
27793
27794
27795
27796
27797
27798
27799 public function __construct($name, $version, $prettyVersion)
27800 {
27801 parent::__construct($name);
27802
27803 $this->version = $version;
27804 $this->prettyVersion = $prettyVersion;
27805
27806 $this->stability = VersionParser::parseStability($version);
27807 $this->dev = $this->stability === 'dev';
27808 }
27809
27810
27811
27812
27813 public function isDev()
27814 {
27815 return $this->dev;
27816 }
27817
27818
27819
27820
27821 public function setType($type)
27822 {
27823 $this->type = $type;
27824 }
27825
27826
27827
27828
27829 public function getType()
27830 {
27831 return $this->type ?: 'library';
27832 }
27833
27834
27835
27836
27837 public function getStability()
27838 {
27839 return $this->stability;
27840 }
27841
27842
27843
27844
27845 public function setTargetDir($targetDir)
27846 {
27847 $this->targetDir = $targetDir;
27848 }
27849
27850
27851
27852
27853 public function getTargetDir()
27854 {
27855 if (null === $this->targetDir) {
27856 return;
27857 }
27858
27859 return ltrim(preg_replace('{ (?:^|[\\\\/]+) \.\.? (?:[\\\\/]+|$) (?:\.\.? (?:[\\\\/]+|$) )*}x', '/', $this->targetDir), '/');
27860 }
27861
27862
27863
27864
27865 public function setExtra(array $extra)
27866 {
27867 $this->extra = $extra;
27868 }
27869
27870
27871
27872
27873 public function getExtra()
27874 {
27875 return $this->extra;
27876 }
27877
27878
27879
27880
27881 public function setBinaries(array $binaries)
27882 {
27883 $this->binaries = $binaries;
27884 }
27885
27886
27887
27888
27889 public function getBinaries()
27890 {
27891 return $this->binaries;
27892 }
27893
27894
27895
27896
27897 public function setInstallationSource($type)
27898 {
27899 $this->installationSource = $type;
27900 }
27901
27902
27903
27904
27905 public function getInstallationSource()
27906 {
27907 return $this->installationSource;
27908 }
27909
27910
27911
27912
27913 public function setSourceType($type)
27914 {
27915 $this->sourceType = $type;
27916 }
27917
27918
27919
27920
27921 public function getSourceType()
27922 {
27923 return $this->sourceType;
27924 }
27925
27926
27927
27928
27929 public function setSourceUrl($url)
27930 {
27931 $this->sourceUrl = $url;
27932 }
27933
27934
27935
27936
27937 public function getSourceUrl()
27938 {
27939 return $this->sourceUrl;
27940 }
27941
27942
27943
27944
27945 public function setSourceReference($reference)
27946 {
27947 $this->sourceReference = $reference;
27948 }
27949
27950
27951
27952
27953 public function getSourceReference()
27954 {
27955 return $this->sourceReference;
27956 }
27957
27958
27959
27960
27961 public function setSourceMirrors($mirrors)
27962 {
27963 $this->sourceMirrors = $mirrors;
27964 }
27965
27966
27967
27968
27969 public function getSourceMirrors()
27970 {
27971 return $this->sourceMirrors;
27972 }
27973
27974
27975
27976
27977 public function getSourceUrls()
27978 {
27979 return $this->getUrls($this->sourceUrl, $this->sourceMirrors, $this->sourceReference, $this->sourceType, 'source');
27980 }
27981
27982
27983
27984
27985 public function setDistType($type)
27986 {
27987 $this->distType = $type;
27988 }
27989
27990
27991
27992
27993 public function getDistType()
27994 {
27995 return $this->distType;
27996 }
27997
27998
27999
28000
28001 public function setDistUrl($url)
28002 {
28003 $this->distUrl = $url;
28004 }
28005
28006
28007
28008
28009 public function getDistUrl()
28010 {
28011 return $this->distUrl;
28012 }
28013
28014
28015
28016
28017 public function setDistReference($reference)
28018 {
28019 $this->distReference = $reference;
28020 }
28021
28022
28023
28024
28025 public function getDistReference()
28026 {
28027 return $this->distReference;
28028 }
28029
28030
28031
28032
28033 public function setDistSha1Checksum($sha1checksum)
28034 {
28035 $this->distSha1Checksum = $sha1checksum;
28036 }
28037
28038
28039
28040
28041 public function getDistSha1Checksum()
28042 {
28043 return $this->distSha1Checksum;
28044 }
28045
28046
28047
28048
28049 public function setDistMirrors($mirrors)
28050 {
28051 $this->distMirrors = $mirrors;
28052 }
28053
28054
28055
28056
28057 public function getDistMirrors()
28058 {
28059 return $this->distMirrors;
28060 }
28061
28062
28063
28064
28065 public function getDistUrls()
28066 {
28067 return $this->getUrls($this->distUrl, $this->distMirrors, $this->distReference, $this->distType, 'dist');
28068 }
28069
28070
28071
28072
28073 public function getVersion()
28074 {
28075 return $this->version;
28076 }
28077
28078
28079
28080
28081 public function getPrettyVersion()
28082 {
28083 return $this->prettyVersion;
28084 }
28085
28086
28087
28088
28089
28090
28091 public function setReleaseDate(\DateTime $releaseDate)
28092 {
28093 $this->releaseDate = $releaseDate;
28094 }
28095
28096
28097
28098
28099 public function getReleaseDate()
28100 {
28101 return $this->releaseDate;
28102 }
28103
28104
28105
28106
28107
28108
28109 public function setRequires(array $requires)
28110 {
28111 $this->requires = $requires;
28112 }
28113
28114
28115
28116
28117 public function getRequires()
28118 {
28119 return $this->requires;
28120 }
28121
28122
28123
28124
28125
28126
28127 public function setConflicts(array $conflicts)
28128 {
28129 $this->conflicts = $conflicts;
28130 }
28131
28132
28133
28134
28135 public function getConflicts()
28136 {
28137 return $this->conflicts;
28138 }
28139
28140
28141
28142
28143
28144
28145 public function setProvides(array $provides)
28146 {
28147 $this->provides = $provides;
28148 }
28149
28150
28151
28152
28153 public function getProvides()
28154 {
28155 return $this->provides;
28156 }
28157
28158
28159
28160
28161
28162
28163 public function setReplaces(array $replaces)
28164 {
28165 $this->replaces = $replaces;
28166 }
28167
28168
28169
28170
28171 public function getReplaces()
28172 {
28173 return $this->replaces;
28174 }
28175
28176
28177
28178
28179
28180
28181 public function setDevRequires(array $devRequires)
28182 {
28183 $this->devRequires = $devRequires;
28184 }
28185
28186
28187
28188
28189 public function getDevRequires()
28190 {
28191 return $this->devRequires;
28192 }
28193
28194
28195
28196
28197
28198
28199 public function setSuggests(array $suggests)
28200 {
28201 $this->suggests = $suggests;
28202 }
28203
28204
28205
28206
28207 public function getSuggests()
28208 {
28209 return $this->suggests;
28210 }
28211
28212
28213
28214
28215
28216
28217 public function setAutoload(array $autoload)
28218 {
28219 $this->autoload = $autoload;
28220 }
28221
28222
28223
28224
28225 public function getAutoload()
28226 {
28227 return $this->autoload;
28228 }
28229
28230
28231
28232
28233
28234
28235 public function setDevAutoload(array $devAutoload)
28236 {
28237 $this->devAutoload = $devAutoload;
28238 }
28239
28240
28241
28242
28243 public function getDevAutoload()
28244 {
28245 return $this->devAutoload;
28246 }
28247
28248
28249
28250
28251
28252
28253 public function setIncludePaths(array $includePaths)
28254 {
28255 $this->includePaths = $includePaths;
28256 }
28257
28258
28259
28260
28261 public function getIncludePaths()
28262 {
28263 return $this->includePaths;
28264 }
28265
28266
28267
28268
28269
28270
28271 public function setNotificationUrl($notificationUrl)
28272 {
28273 $this->notificationUrl = $notificationUrl;
28274 }
28275
28276
28277
28278
28279 public function getNotificationUrl()
28280 {
28281 return $this->notificationUrl;
28282 }
28283
28284
28285
28286
28287
28288
28289 public function setArchiveExcludes(array $excludes)
28290 {
28291 $this->archiveExcludes = $excludes;
28292 }
28293
28294
28295
28296
28297 public function getArchiveExcludes()
28298 {
28299 return $this->archiveExcludes;
28300 }
28301
28302
28303
28304
28305
28306
28307
28308
28309 public function replaceVersion($version, $prettyVersion)
28310 {
28311 $this->version = $version;
28312 $this->prettyVersion = $prettyVersion;
28313
28314 $this->stability = VersionParser::parseStability($version);
28315 $this->dev = $this->stability === 'dev';
28316 }
28317
28318 protected function getUrls($url, $mirrors, $ref, $type, $urlType)
28319 {
28320 if (!$url) {
28321 return array();
28322 }
28323 $urls = array($url);
28324 if ($mirrors) {
28325 foreach ($mirrors as $mirror) {
28326 if ($urlType === 'dist') {
28327 $mirrorUrl = ComposerMirror::processUrl($mirror['url'], $this->name, $this->version, $ref, $type);
28328 } elseif ($urlType === 'source' && $type === 'git') {
28329 $mirrorUrl = ComposerMirror::processGitUrl($mirror['url'], $this->name, $url, $type);
28330 } elseif ($urlType === 'source' && $type === 'hg') {
28331 $mirrorUrl = ComposerMirror::processHgUrl($mirror['url'], $this->name, $url, $type);
28332 }
28333 if (!in_array($mirrorUrl, $urls)) {
28334 $func = $mirror['preferred'] ? 'array_unshift' : 'array_push';
28335 $func($urls, $mirrorUrl);
28336 }
28337 }
28338 }
28339
28340 return $urls;
28341 }
28342 }
28343 <?php
28344
28345
28346
28347
28348
28349
28350
28351
28352
28353
28354
28355 namespace Composer\Package;
28356
28357 use Composer\Repository\RepositoryInterface;
28358
28359
28360
28361
28362
28363
28364 interface PackageInterface
28365 {
28366
28367
28368
28369
28370
28371 public function getName();
28372
28373
28374
28375
28376
28377
28378 public function getPrettyName();
28379
28380
28381
28382
28383
28384
28385
28386
28387
28388 public function getNames();
28389
28390
28391
28392
28393
28394
28395 public function setId($id);
28396
28397
28398
28399
28400
28401
28402 public function getId();
28403
28404
28405
28406
28407
28408
28409 public function isDev();
28410
28411
28412
28413
28414
28415
28416 public function getType();
28417
28418
28419
28420
28421
28422
28423 public function getTargetDir();
28424
28425
28426
28427
28428
28429
28430 public function getExtra();
28431
28432
28433
28434
28435
28436
28437 public function setInstallationSource($type);
28438
28439
28440
28441
28442
28443
28444 public function getInstallationSource();
28445
28446
28447
28448
28449
28450
28451 public function getSourceType();
28452
28453
28454
28455
28456
28457
28458 public function getSourceUrl();
28459
28460
28461
28462
28463
28464
28465 public function getSourceUrls();
28466
28467
28468
28469
28470
28471
28472 public function getSourceReference();
28473
28474
28475
28476
28477
28478
28479 public function getSourceMirrors();
28480
28481
28482
28483
28484
28485
28486 public function getDistType();
28487
28488
28489
28490
28491
28492
28493 public function getDistUrl();
28494
28495
28496
28497
28498
28499
28500 public function getDistUrls();
28501
28502
28503
28504
28505
28506
28507 public function getDistReference();
28508
28509
28510
28511
28512
28513
28514 public function getDistSha1Checksum();
28515
28516
28517
28518
28519
28520
28521 public function getDistMirrors();
28522
28523
28524
28525
28526
28527
28528 public function getVersion();
28529
28530
28531
28532
28533
28534
28535 public function getPrettyVersion();
28536
28537
28538
28539
28540
28541
28542
28543
28544
28545 public function getFullPrettyVersion($truncate = true);
28546
28547
28548
28549
28550
28551
28552 public function getReleaseDate();
28553
28554
28555
28556
28557
28558
28559 public function getStability();
28560
28561
28562
28563
28564
28565
28566
28567 public function getRequires();
28568
28569
28570
28571
28572
28573
28574
28575 public function getConflicts();
28576
28577
28578
28579
28580
28581
28582
28583 public function getProvides();
28584
28585
28586
28587
28588
28589
28590
28591 public function getReplaces();
28592
28593
28594
28595
28596
28597
28598
28599 public function getDevRequires();
28600
28601
28602
28603
28604
28605
28606
28607 public function getSuggests();
28608
28609
28610
28611
28612
28613
28614
28615
28616
28617
28618
28619 public function getAutoload();
28620
28621
28622
28623
28624
28625
28626
28627
28628
28629
28630
28631 public function getDevAutoload();
28632
28633
28634
28635
28636
28637
28638
28639 public function getIncludePaths();
28640
28641
28642
28643
28644
28645
28646 public function setRepository(RepositoryInterface $repository);
28647
28648
28649
28650
28651
28652
28653 public function getRepository();
28654
28655
28656
28657
28658
28659
28660 public function getBinaries();
28661
28662
28663
28664
28665
28666
28667 public function getUniqueName();
28668
28669
28670
28671
28672
28673
28674 public function getNotificationUrl();
28675
28676
28677
28678
28679
28680
28681 public function __toString();
28682
28683
28684
28685
28686
28687
28688 public function getPrettyString();
28689
28690
28691
28692
28693
28694
28695 public function getArchiveExcludes();
28696
28697
28698
28699
28700
28701
28702 public function getTransportOptions();
28703 }
28704 <?php
28705
28706
28707
28708
28709
28710
28711
28712
28713
28714
28715
28716 namespace Composer\Package;
28717
28718
28719
28720
28721 class RootAliasPackage extends AliasPackage implements RootPackageInterface
28722 {
28723 public function __construct(RootPackageInterface $aliasOf, $version, $prettyVersion)
28724 {
28725 parent::__construct($aliasOf, $version, $prettyVersion);
28726 }
28727
28728
28729
28730
28731 public function getAliases()
28732 {
28733 return $this->aliasOf->getAliases();
28734 }
28735
28736
28737
28738
28739 public function getMinimumStability()
28740 {
28741 return $this->aliasOf->getMinimumStability();
28742 }
28743
28744
28745
28746
28747 public function getStabilityFlags()
28748 {
28749 return $this->aliasOf->getStabilityFlags();
28750 }
28751
28752
28753
28754
28755 public function getReferences()
28756 {
28757 return $this->aliasOf->getReferences();
28758 }
28759
28760
28761
28762
28763 public function getPreferStable()
28764 {
28765 return $this->aliasOf->getPreferStable();
28766 }
28767
28768
28769
28770
28771 public function getConfig()
28772 {
28773 return $this->aliasOf->getConfig();
28774 }
28775
28776
28777
28778
28779 public function setRequires(array $require)
28780 {
28781 $this->requires = $this->replaceSelfVersionDependencies($require, 'requires');
28782
28783 $this->aliasOf->setRequires($require);
28784 }
28785
28786
28787
28788
28789 public function setDevRequires(array $devRequire)
28790 {
28791 $this->devRequires = $this->replaceSelfVersionDependencies($devRequire, 'devRequires');
28792
28793 $this->aliasOf->setDevRequires($devRequire);
28794 }
28795
28796
28797
28798
28799 public function setConflicts(array $conflicts)
28800 {
28801 $this->conflicts = $this->replaceSelfVersionDependencies($conflicts, 'conflicts');
28802 $this->aliasOf->setConflicts($conflicts);
28803 }
28804
28805
28806
28807
28808 public function setProvides(array $provides)
28809 {
28810 $this->provides = $this->replaceSelfVersionDependencies($provides, 'provides');
28811 $this->aliasOf->setProvides($provides);
28812 }
28813
28814
28815
28816
28817 public function setReplaces(array $replaces)
28818 {
28819 $this->replaces = $this->replaceSelfVersionDependencies($replaces, 'replaces');
28820 $this->aliasOf->setReplaces($replaces);
28821 }
28822
28823
28824
28825
28826 public function setRepositories($repositories)
28827 {
28828 $this->aliasOf->setRepositories($repositories);
28829 }
28830
28831
28832
28833
28834 public function setAutoload(array $autoload)
28835 {
28836 $this->aliasOf->setAutoload($autoload);
28837 }
28838
28839
28840
28841
28842 public function setDevAutoload(array $devAutoload)
28843 {
28844 $this->aliasOf->setDevAutoload($devAutoload);
28845 }
28846
28847
28848
28849
28850 public function setStabilityFlags(array $stabilityFlags)
28851 {
28852 $this->aliasOf->setStabilityFlags($stabilityFlags);
28853 }
28854
28855
28856
28857
28858 public function setSuggests(array $suggests)
28859 {
28860 $this->aliasOf->setSuggests($suggests);
28861 }
28862
28863
28864
28865
28866 public function setExtra(array $extra)
28867 {
28868 $this->aliasOf->setExtra($extra);
28869 }
28870
28871 public function __clone()
28872 {
28873 parent::__clone();
28874 $this->aliasOf = clone $this->aliasOf;
28875 }
28876 }
28877 <?php
28878
28879
28880
28881
28882
28883
28884
28885
28886
28887
28888
28889 namespace Composer\Package;
28890
28891
28892
28893
28894
28895
28896 class RootPackage extends CompletePackage implements RootPackageInterface
28897 {
28898 protected $minimumStability = 'stable';
28899 protected $preferStable = false;
28900 protected $stabilityFlags = array();
28901 protected $config = array();
28902 protected $references = array();
28903 protected $aliases = array();
28904
28905
28906
28907
28908
28909
28910 public function setMinimumStability($minimumStability)
28911 {
28912 $this->minimumStability = $minimumStability;
28913 }
28914
28915
28916
28917
28918 public function getMinimumStability()
28919 {
28920 return $this->minimumStability;
28921 }
28922
28923
28924
28925
28926
28927
28928 public function setStabilityFlags(array $stabilityFlags)
28929 {
28930 $this->stabilityFlags = $stabilityFlags;
28931 }
28932
28933
28934
28935
28936 public function getStabilityFlags()
28937 {
28938 return $this->stabilityFlags;
28939 }
28940
28941
28942
28943
28944
28945
28946 public function setPreferStable($preferStable)
28947 {
28948 $this->preferStable = $preferStable;
28949 }
28950
28951
28952
28953
28954 public function getPreferStable()
28955 {
28956 return $this->preferStable;
28957 }
28958
28959
28960
28961
28962
28963
28964 public function setConfig(array $config)
28965 {
28966 $this->config = $config;
28967 }
28968
28969
28970
28971
28972 public function getConfig()
28973 {
28974 return $this->config;
28975 }
28976
28977
28978
28979
28980
28981
28982 public function setReferences(array $references)
28983 {
28984 $this->references = $references;
28985 }
28986
28987
28988
28989
28990 public function getReferences()
28991 {
28992 return $this->references;
28993 }
28994
28995
28996
28997
28998
28999
29000 public function setAliases(array $aliases)
29001 {
29002 $this->aliases = $aliases;
29003 }
29004
29005
29006
29007
29008 public function getAliases()
29009 {
29010 return $this->aliases;
29011 }
29012 }
29013 <?php
29014
29015
29016
29017
29018
29019
29020
29021
29022
29023
29024
29025 namespace Composer\Package;
29026
29027
29028
29029
29030
29031
29032 interface RootPackageInterface extends CompletePackageInterface
29033 {
29034
29035
29036
29037
29038
29039 public function getAliases();
29040
29041
29042
29043
29044
29045
29046 public function getMinimumStability();
29047
29048
29049
29050
29051
29052
29053
29054
29055 public function getStabilityFlags();
29056
29057
29058
29059
29060
29061
29062
29063
29064 public function getReferences();
29065
29066
29067
29068
29069
29070
29071 public function getPreferStable();
29072
29073
29074
29075
29076
29077
29078 public function getConfig();
29079
29080
29081
29082
29083
29084
29085 public function setRequires(array $requires);
29086
29087
29088
29089
29090
29091
29092 public function setDevRequires(array $devRequires);
29093
29094
29095
29096
29097
29098
29099 public function setConflicts(array $conflicts);
29100
29101
29102
29103
29104
29105
29106 public function setProvides(array $provides);
29107
29108
29109
29110
29111
29112
29113 public function setReplaces(array $replaces);
29114
29115
29116
29117
29118
29119
29120 public function setRepositories($repositories);
29121
29122
29123
29124
29125
29126
29127 public function setAutoload(array $autoload);
29128
29129
29130
29131
29132
29133
29134 public function setDevAutoload(array $devAutoload);
29135
29136
29137
29138
29139
29140
29141 public function setStabilityFlags(array $stabilityFlags);
29142
29143
29144
29145
29146
29147
29148 public function setSuggests(array $suggests);
29149
29150
29151
29152
29153 public function setExtra(array $extra);
29154 }
29155 <?php
29156
29157
29158
29159
29160
29161
29162
29163
29164
29165
29166
29167 namespace Composer\Package\Version;
29168
29169 use Composer\Config;
29170 use Composer\Repository\Vcs\HgDriver;
29171 use Composer\IO\NullIO;
29172 use Composer\Semver\VersionParser as SemverVersionParser;
29173 use Composer\Util\Git as GitUtil;
29174 use Composer\Util\ProcessExecutor;
29175 use Composer\Util\Svn as SvnUtil;
29176
29177
29178
29179
29180
29181
29182
29183 class VersionGuesser
29184 {
29185
29186
29187
29188 private $config;
29189
29190
29191
29192
29193 private $process;
29194
29195
29196
29197
29198 private $versionParser;
29199
29200
29201
29202
29203
29204
29205 public function __construct(Config $config, ProcessExecutor $process, SemverVersionParser $versionParser)
29206 {
29207 $this->config = $config;
29208 $this->process = $process;
29209 $this->versionParser = $versionParser;
29210 }
29211
29212
29213
29214
29215
29216
29217
29218 public function guessVersion(array $packageConfig, $path)
29219 {
29220 if (function_exists('proc_open')) {
29221 $versionData = $this->guessGitVersion($packageConfig, $path);
29222 if (null !== $versionData && null !== $versionData['version']) {
29223 return $versionData;
29224 }
29225
29226 $versionData = $this->guessHgVersion($packageConfig, $path);
29227 if (null !== $versionData && null !== $versionData['version']) {
29228 return $versionData;
29229 }
29230
29231 $versionData = $this->guessFossilVersion($packageConfig, $path);
29232 if (null !== $versionData && null !== $versionData['version']) {
29233 return $versionData;
29234 }
29235
29236 return $this->guessSvnVersion($packageConfig, $path);
29237 }
29238 }
29239
29240 private function guessGitVersion(array $packageConfig, $path)
29241 {
29242 GitUtil::cleanEnv();
29243 $commit = null;
29244 $version = null;
29245 $prettyVersion = null;
29246 $isDetached = false;
29247
29248
29249  if (0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output, $path)) {
29250 $branches = array();
29251 $isFeatureBranch = false;
29252
29253
29254  foreach ($this->process->splitLines($output) as $branch) {
29255 if ($branch && preg_match('{^(?:\* ) *(\(no branch\)|\(detached from \S+\)|\(HEAD detached at FETCH_HEAD\)|\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
29256 if ($match[1] === '(no branch)' || substr($match[1], 0, 10) === '(detached ' || substr($match[1], 0, 17) === '(HEAD detached at') {
29257 $version = 'dev-' . $match[2];
29258 $prettyVersion = $version;
29259 $isFeatureBranch = true;
29260 $isDetached = true;
29261 } else {
29262 $version = $this->versionParser->normalizeBranch($match[1]);
29263 $prettyVersion = 'dev-' . $match[1];
29264 $isFeatureBranch = 0 === strpos($version, 'dev-');
29265 if ('9999999-dev' === $version) {
29266 $version = $prettyVersion;
29267 }
29268 }
29269
29270 if ($match[2]) {
29271 $commit = $match[2];
29272 }
29273 }
29274
29275 if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
29276 if (preg_match('{^(?:\* )? *(\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
29277 $branches[] = $match[1];
29278 }
29279 }
29280 }
29281
29282 if ($isFeatureBranch) {
29283
29284  $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path);
29285 $version = $result['version'];
29286 $prettyVersion = $result['pretty_version'];
29287 }
29288 }
29289
29290 if (!$version || $isDetached) {
29291 $result = $this->versionFromGitTags($path);
29292 if ($result) {
29293 $version = $result['version'];
29294 $prettyVersion = $result['pretty_version'];
29295 }
29296 }
29297
29298 if (!$commit) {
29299 $command = 'git log --pretty="%H" -n1 HEAD';
29300 if (0 === $this->process->execute($command, $output, $path)) {
29301 $commit = trim($output) ?: null;
29302 }
29303 }
29304
29305 return array('version' => $version, 'commit' => $commit, 'pretty_version' => $prettyVersion);
29306 }
29307
29308 private function versionFromGitTags($path)
29309 {
29310
29311  if (0 === $this->process->execute('git describe --exact-match --tags', $output, $path)) {
29312 try {
29313 $version = $this->versionParser->normalize(trim($output));
29314
29315 return array('version' => $version, 'pretty_version' => trim($output));
29316 } catch (\Exception $e) {
29317 }
29318 }
29319
29320 return null;
29321 }
29322
29323 private function guessHgVersion(array $packageConfig, $path)
29324 {
29325
29326  if (0 === $this->process->execute('hg branch', $output, $path)) {
29327 $branch = trim($output);
29328 $version = $this->versionParser->normalizeBranch($branch);
29329 $isFeatureBranch = 0 === strpos($version, 'dev-');
29330
29331 if ('9999999-dev' === $version) {
29332 $version = 'dev-' . $branch;
29333 }
29334
29335 if (!$isFeatureBranch) {
29336 return array('version' => $version, 'commit' => null, 'pretty_version' => $version);
29337 }
29338
29339
29340  $driver = new HgDriver(array('url' => $path), new NullIO(), $this->config, $this->process);
29341 $branches = array_keys($driver->getBranches());
29342
29343
29344  $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path);
29345 $result['commit'] = '';
29346
29347 return $result;
29348 }
29349 }
29350
29351 private function guessFeatureVersion(array $packageConfig, $version, array $branches, $scmCmdline, $path)
29352 {
29353 $prettyVersion = $version;
29354
29355
29356  
29357  if ((isset($packageConfig['extra']['branch-alias']) && !isset($packageConfig['extra']['branch-alias'][$version]))
29358 || strpos(json_encode($packageConfig), '"self.version"')
29359 ) {
29360 $branch = preg_replace('{^dev-}', '', $version);
29361 $length = PHP_INT_MAX;
29362
29363 $nonFeatureBranches = '';
29364 if (!empty($packageConfig['non-feature-branches'])) {
29365 $nonFeatureBranches = implode('|', $packageConfig['non-feature-branches']);
29366 }
29367
29368 foreach ($branches as $candidate) {
29369
29370  if ($candidate === $branch && preg_match('{^(' . $nonFeatureBranches . ')$}', $candidate)) {
29371 break;
29372 }
29373
29374
29375  if ($candidate === $branch || !preg_match('{^(master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) {
29376 continue;
29377 }
29378
29379 $cmdLine = str_replace(array('%candidate%', '%branch%'), array($candidate, $branch), $scmCmdline);
29380 if (0 !== $this->process->execute($cmdLine, $output, $path)) {
29381 continue;
29382 }
29383
29384 if (strlen($output) < $length) {
29385 $length = strlen($output);
29386 $version = $this->versionParser->normalizeBranch($candidate);
29387 $prettyVersion = 'dev-' . $match[1];
29388 if ('9999999-dev' === $version) {
29389 $version = $prettyVersion;
29390 }
29391 }
29392 }
29393 }
29394
29395 return array('version' => $version, 'pretty_version' => $prettyVersion);
29396 }
29397
29398 private function guessFossilVersion(array $packageConfig, $path)
29399 {
29400 $version = null;
29401 $prettyVersion = null;
29402
29403
29404  if (0 === $this->process->execute('fossil branch list', $output, $path)) {
29405 $branch = trim($output);
29406 $version = $this->versionParser->normalizeBranch($branch);
29407 $prettyVersion = 'dev-' . $branch;
29408
29409 if ('9999999-dev' === $version) {
29410 $version = $prettyVersion;
29411 }
29412 }
29413
29414
29415  if (0 === $this->process->execute('fossil tag list', $output, $path)) {
29416 try {
29417 $version = $this->versionParser->normalize(trim($output));
29418 $prettyVersion = trim($output);
29419 } catch (\Exception $e) {
29420 }
29421 }
29422
29423 return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion);
29424 }
29425
29426 private function guessSvnVersion(array $packageConfig, $path)
29427 {
29428 SvnUtil::cleanEnv();
29429
29430
29431  if (0 === $this->process->execute('svn info --xml', $output, $path)) {
29432 $trunkPath = isset($packageConfig['trunk-path']) ? preg_quote($packageConfig['trunk-path'], '#') : 'trunk';
29433 $branchesPath = isset($packageConfig['branches-path']) ? preg_quote($packageConfig['branches-path'], '#') : 'branches';
29434 $tagsPath = isset($packageConfig['tags-path']) ? preg_quote($packageConfig['tags-path'], '#') : 'tags';
29435
29436 $urlPattern = '#<url>.*/(' . $trunkPath . '|(' . $branchesPath . '|' . $tagsPath . ')/(.*))</url>#';
29437
29438 if (preg_match($urlPattern, $output, $matches)) {
29439 if (isset($matches[2]) && ($branchesPath === $matches[2] || $tagsPath === $matches[2])) {
29440
29441  $version = $this->versionParser->normalizeBranch($matches[3]);
29442 $prettyVersion = 'dev-' . $matches[3];
29443 if ('9999999-dev' === $version) {
29444 $version = $prettyVersion;
29445 }
29446
29447 return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion);
29448 }
29449
29450 $prettyVersion = trim($matches[1]);
29451 $version = $this->versionParser->normalize($prettyVersion);
29452
29453 return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion);
29454 }
29455 }
29456 }
29457 }
29458 <?php
29459
29460
29461
29462
29463
29464
29465
29466
29467
29468
29469
29470 namespace Composer\Package\Version;
29471
29472 use Composer\Semver\VersionParser as SemverVersionParser;
29473
29474 class VersionParser extends SemverVersionParser
29475 {
29476 private static $constraints = array();
29477
29478
29479
29480
29481 public function parseConstraints($constraints)
29482 {
29483 if (!isset(self::$constraints[$constraints])) {
29484 self::$constraints[$constraints] = parent::parseConstraints($constraints);
29485 }
29486
29487 return self::$constraints[$constraints];
29488 }
29489
29490
29491
29492
29493
29494
29495
29496
29497
29498
29499
29500 public function parseNameVersionPairs(array $pairs)
29501 {
29502 $pairs = array_values($pairs);
29503 $result = array();
29504
29505 for ($i = 0, $count = count($pairs); $i < $count; $i++) {
29506 $pair = preg_replace('{^([^=: ]+)[=: ](.*)$}', '$1 $2', trim($pairs[$i]));
29507 if (false === strpos($pair, ' ') && isset($pairs[$i + 1]) && false === strpos($pairs[$i + 1], '/')) {
29508 $pair .= ' '.$pairs[$i + 1];
29509 $i++;
29510 }
29511
29512 if (strpos($pair, ' ')) {
29513 list($name, $version) = explode(" ", $pair, 2);
29514 $result[] = array('name' => $name, 'version' => $version);
29515 } else {
29516 $result[] = array('name' => $pair);
29517 }
29518 }
29519
29520 return $result;
29521 }
29522 }
29523 <?php
29524
29525
29526
29527
29528
29529
29530
29531
29532
29533
29534
29535 namespace Composer\Package\Version;
29536
29537 use Composer\DependencyResolver\Pool;
29538 use Composer\Package\BasePackage;
29539 use Composer\Package\PackageInterface;
29540 use Composer\Package\Loader\ArrayLoader;
29541 use Composer\Package\Dumper\ArrayDumper;
29542 use Composer\Semver\Constraint\Constraint;
29543
29544
29545
29546
29547
29548
29549
29550 class VersionSelector
29551 {
29552 private $pool;
29553
29554 private $parser;
29555
29556 public function __construct(Pool $pool)
29557 {
29558 $this->pool = $pool;
29559 }
29560
29561
29562
29563
29564
29565
29566
29567
29568
29569
29570
29571 public function findBestCandidate($packageName, $targetPackageVersion = null, $targetPhpVersion = null, $preferredStability = 'stable')
29572 {
29573 $constraint = $targetPackageVersion ? $this->getParser()->parseConstraints($targetPackageVersion) : null;
29574 $candidates = $this->pool->whatProvides(strtolower($packageName), $constraint, true);
29575
29576 if ($targetPhpVersion) {
29577 $phpConstraint = new Constraint('==', $this->getParser()->normalize($targetPhpVersion));
29578 $candidates = array_filter($candidates, function ($pkg) use ($phpConstraint) {
29579 $reqs = $pkg->getRequires();
29580
29581 return !isset($reqs['php']) || $reqs['php']->getConstraint()->matches($phpConstraint);
29582 });
29583 }
29584
29585 if (!$candidates) {
29586 return false;
29587 }
29588
29589
29590  $package = reset($candidates);
29591 $minPriority = BasePackage::$stabilities[$preferredStability];
29592 foreach ($candidates as $candidate) {
29593 $candidatePriority = $candidate->getStabilityPriority();
29594 $currentPriority = $package->getStabilityPriority();
29595
29596
29597  
29598  if ($minPriority < $candidatePriority && $currentPriority < $candidatePriority) {
29599 continue;
29600 }
29601
29602
29603  
29604  if ($minPriority < $candidatePriority && $candidatePriority < $currentPriority) {
29605 $package = $candidate;
29606 continue;
29607 }
29608
29609
29610  
29611  if ($minPriority >= $candidatePriority && $minPriority < $currentPriority) {
29612 $package = $candidate;
29613 continue;
29614 }
29615
29616
29617  if (version_compare($package->getVersion(), $candidate->getVersion(), '<')) {
29618 $package = $candidate;
29619 }
29620 }
29621
29622 return $package;
29623 }
29624
29625
29626
29627
29628
29629
29630
29631
29632
29633
29634
29635
29636
29637
29638
29639
29640 public function findRecommendedRequireVersion(PackageInterface $package)
29641 {
29642 $version = $package->getVersion();
29643 if (!$package->isDev()) {
29644 return $this->transformVersion($version, $package->getPrettyVersion(), $package->getStability());
29645 }
29646
29647 $loader = new ArrayLoader($this->getParser());
29648 $dumper = new ArrayDumper();
29649 $extra = $loader->getBranchAlias($dumper->dump($package));
29650 if ($extra) {
29651 $extra = preg_replace('{^(\d+\.\d+\.\d+)(\.9999999)-dev$}', '$1.0', $extra, -1, $count);
29652 if ($count) {
29653 $extra = str_replace('.9999999', '.0', $extra);
29654
29655 return $this->transformVersion($extra, $extra, 'dev');
29656 }
29657 }
29658
29659 return $package->getPrettyVersion();
29660 }
29661
29662 private function transformVersion($version, $prettyVersion, $stability)
29663 {
29664
29665  
29666  $semanticVersionParts = explode('.', $version);
29667
29668
29669  if (count($semanticVersionParts) == 4 && preg_match('{^0\D?}', $semanticVersionParts[3])) {
29670
29671  if ($semanticVersionParts[0] === '0') {
29672 unset($semanticVersionParts[3]);
29673 } else {
29674 unset($semanticVersionParts[2], $semanticVersionParts[3]);
29675 }
29676 $version = implode('.', $semanticVersionParts);
29677 } else {
29678 return $prettyVersion;
29679 }
29680
29681
29682  if ($stability != 'stable') {
29683 $version .= '@'.$stability;
29684 }
29685
29686
29687  return '^' . $version;
29688 }
29689
29690 private function getParser()
29691 {
29692 if ($this->parser === null) {
29693 $this->parser = new VersionParser();
29694 }
29695
29696 return $this->parser;
29697 }
29698 }
29699 <?php
29700
29701
29702
29703
29704
29705
29706
29707
29708
29709
29710
29711 namespace Composer\Plugin\Capability;
29712
29713
29714
29715
29716
29717
29718
29719 interface Capability
29720 {
29721 }
29722 <?php
29723
29724
29725
29726
29727
29728
29729
29730
29731
29732
29733
29734 namespace Composer\Plugin\Capability;
29735
29736
29737
29738
29739
29740
29741
29742
29743
29744
29745
29746 interface CommandProvider extends Capability
29747 {
29748
29749
29750
29751
29752
29753 public function getCommands();
29754 }
29755 <?php
29756
29757
29758
29759
29760
29761
29762
29763
29764
29765
29766
29767 namespace Composer\Plugin;
29768
29769
29770
29771
29772
29773
29774
29775
29776 interface Capable
29777 {
29778
29779
29780
29781
29782
29783
29784
29785
29786
29787
29788
29789
29790
29791
29792
29793
29794
29795
29796 public function getCapabilities();
29797 }
29798 <?php
29799
29800
29801
29802
29803
29804
29805
29806
29807
29808
29809
29810 namespace Composer\Plugin;
29811
29812 use Composer\EventDispatcher\Event;
29813 use Symfony\Component\Console\Input\InputInterface;
29814 use Symfony\Component\Console\Output\OutputInterface;
29815
29816
29817
29818
29819
29820
29821 class CommandEvent extends Event
29822 {
29823
29824
29825
29826 private $commandName;
29827
29828
29829
29830
29831 private $input;
29832
29833
29834
29835
29836 private $output;
29837
29838
29839
29840
29841
29842
29843
29844
29845
29846
29847
29848 public function __construct($name, $commandName, $input, $output, array $args = array(), array $flags = array())
29849 {
29850 parent::__construct($name, $args, $flags);
29851 $this->commandName = $commandName;
29852 $this->input = $input;
29853 $this->output = $output;
29854 }
29855
29856
29857
29858
29859
29860
29861 public function getInput()
29862 {
29863 return $this->input;
29864 }
29865
29866
29867
29868
29869
29870
29871 public function getOutput()
29872 {
29873 return $this->output;
29874 }
29875
29876
29877
29878
29879
29880
29881 public function getCommandName()
29882 {
29883 return $this->commandName;
29884 }
29885 }
29886 <?php
29887
29888
29889
29890
29891
29892
29893
29894
29895
29896
29897
29898 namespace Composer\Plugin;
29899
29900
29901
29902
29903
29904
29905 class PluginEvents
29906 {
29907
29908
29909
29910
29911
29912
29913
29914
29915 const INIT = 'init';
29916
29917
29918
29919
29920
29921
29922
29923
29924
29925 const COMMAND = 'command';
29926
29927
29928
29929
29930
29931
29932
29933
29934
29935 const PRE_FILE_DOWNLOAD = 'pre-file-download';
29936 }
29937 <?php
29938
29939
29940
29941
29942
29943
29944
29945
29946
29947
29948
29949 namespace Composer\Plugin;
29950
29951 use Composer\Composer;
29952 use Composer\IO\IOInterface;
29953
29954
29955
29956
29957
29958
29959 interface PluginInterface
29960 {
29961
29962
29963
29964
29965
29966 const PLUGIN_API_VERSION = '1.1.0';
29967
29968
29969
29970
29971
29972
29973
29974 public function activate(Composer $composer, IOInterface $io);
29975 }
29976 <?php
29977
29978
29979
29980
29981
29982
29983
29984
29985
29986
29987
29988 namespace Composer\Plugin;
29989
29990 use Composer\Composer;
29991 use Composer\EventDispatcher\EventSubscriberInterface;
29992 use Composer\IO\IOInterface;
29993 use Composer\Package\Package;
29994 use Composer\Package\Version\VersionParser;
29995 use Composer\Repository\RepositoryInterface;
29996 use Composer\Package\AliasPackage;
29997 use Composer\Package\PackageInterface;
29998 use Composer\Package\Link;
29999 use Composer\Semver\Constraint\Constraint;
30000 use Composer\DependencyResolver\Pool;
30001 use Composer\Plugin\Capability\Capability;
30002
30003
30004
30005
30006
30007
30008
30009 class PluginManager
30010 {
30011 protected $composer;
30012 protected $io;
30013 protected $globalComposer;
30014 protected $versionParser;
30015 protected $disablePlugins = false;
30016
30017 protected $plugins = array();
30018 protected $registeredPlugins = array();
30019
30020 private static $classCounter = 0;
30021
30022
30023
30024
30025
30026
30027
30028
30029
30030 public function __construct(IOInterface $io, Composer $composer, Composer $globalComposer = null, $disablePlugins = false)
30031 {
30032 $this->io = $io;
30033 $this->composer = $composer;
30034 $this->globalComposer = $globalComposer;
30035 $this->versionParser = new VersionParser();
30036 $this->disablePlugins = $disablePlugins;
30037 }
30038
30039
30040
30041
30042 public function loadInstalledPlugins()
30043 {
30044 if ($this->disablePlugins) {
30045 return;
30046 }
30047
30048 $repo = $this->composer->getRepositoryManager()->getLocalRepository();
30049 $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null;
30050 if ($repo) {
30051 $this->loadRepository($repo);
30052 }
30053 if ($globalRepo) {
30054 $this->loadRepository($globalRepo);
30055 }
30056 }
30057
30058
30059
30060
30061
30062
30063 public function getPlugins()
30064 {
30065 return $this->plugins;
30066 }
30067
30068
30069
30070
30071
30072
30073 public function getGlobalComposer()
30074 {
30075 return $this->globalComposer;
30076 }
30077
30078
30079
30080
30081
30082
30083
30084
30085
30086
30087
30088
30089 public function registerPackage(PackageInterface $package, $failOnMissingClasses = false)
30090 {
30091 if ($this->disablePlugins) {
30092 return;
30093 }
30094
30095 if ($package->getType() === 'composer-plugin') {
30096 $requiresComposer = null;
30097 foreach ($package->getRequires() as $link) { 
30098 if ('composer-plugin-api' === $link->getTarget()) {
30099 $requiresComposer = $link->getConstraint();
30100 break;
30101 }
30102 }
30103
30104 if (!$requiresComposer) {
30105 throw new \RuntimeException("Plugin ".$package->getName()." is missing a require statement for a version of the composer-plugin-api package.");
30106 }
30107
30108 $currentPluginApiVersion = $this->getPluginApiVersion();
30109 $currentPluginApiConstraint = new Constraint('==', $this->versionParser->normalize($currentPluginApiVersion));
30110
30111 if ($requiresComposer->getPrettyString() === '1.0.0' && $this->getPluginApiVersion() === '1.0.0') {
30112 $this->io->writeError('<warning>The "' . $package->getName() . '" plugin requires composer-plugin-api 1.0.0, this *WILL* break in the future and it should be fixed ASAP (require ^1.0 for example).</warning>');
30113 } elseif (!$requiresComposer->matches($currentPluginApiConstraint)) {
30114 $this->io->writeError('<warning>The "' . $package->getName() . '" plugin was skipped because it requires a Plugin API version ("' . $requiresComposer->getPrettyString() . '") that does not match your Composer installation ("' . $currentPluginApiVersion . '"). You may need to run composer update with the "--no-plugins" option.</warning>');
30115
30116 return;
30117 }
30118 }
30119
30120 $oldInstallerPlugin = ($package->getType() === 'composer-installer');
30121
30122 if (in_array($package->getName(), $this->registeredPlugins)) {
30123 return;
30124 }
30125
30126 $extra = $package->getExtra();
30127 if (empty($extra['class'])) {
30128 throw new \UnexpectedValueException('Error while installing '.$package->getPrettyName().', composer-plugin packages should have a class defined in their extra key to be usable.');
30129 }
30130 $classes = is_array($extra['class']) ? $extra['class'] : array($extra['class']);
30131
30132 $localRepo = $this->composer->getRepositoryManager()->getLocalRepository();
30133 $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null;
30134
30135 $pool = new Pool('dev');
30136 $pool->addRepository($localRepo);
30137 if ($globalRepo) {
30138 $pool->addRepository($globalRepo);
30139 }
30140
30141 $autoloadPackages = array($package->getName() => $package);
30142 $autoloadPackages = $this->collectDependencies($pool, $autoloadPackages, $package);
30143
30144 $generator = $this->composer->getAutoloadGenerator();
30145 $autoloads = array();
30146 foreach ($autoloadPackages as $autoloadPackage) {
30147 $downloadPath = $this->getInstallPath($autoloadPackage, ($globalRepo && $globalRepo->hasPackage($autoloadPackage)));
30148 $autoloads[] = array($autoloadPackage, $downloadPath);
30149 }
30150
30151 $map = $generator->parseAutoloads($autoloads, new Package('dummy', '1.0.0.0', '1.0.0'));
30152 $classLoader = $generator->createLoader($map);
30153 $classLoader->register();
30154
30155 foreach ($classes as $class) {
30156 if (class_exists($class, false)) {
30157 $class = trim($class, '\\');
30158 $path = $classLoader->findFile($class);
30159 $code = file_get_contents($path);
30160 $separatorPos = strrpos($class, '\\');
30161 $className = $class;
30162 if ($separatorPos) {
30163 $className = substr($class, $separatorPos + 1);
30164 }
30165 $code = preg_replace('{^((?:final\s+)?(?:\s*))class\s+('.preg_quote($className).')}mi', '$1class $2_composer_tmp'.self::$classCounter, $code, 1);
30166 $code = str_replace('__FILE__', var_export($path, true), $code);
30167 $code = str_replace('__DIR__', var_export(dirname($path), true), $code);
30168 $code = str_replace('__CLASS__', var_export($class, true), $code);
30169 $code = preg_replace('/^\s*<\?(php)?/i', '', $code, 1);
30170 eval($code);
30171 $class .= '_composer_tmp'.self::$classCounter;
30172 self::$classCounter++;
30173 }
30174
30175 if ($oldInstallerPlugin) {
30176 $installer = new $class($this->io, $this->composer);
30177 $this->composer->getInstallationManager()->addInstaller($installer);
30178 } elseif (class_exists($class)) {
30179 $plugin = new $class();
30180 $this->addPlugin($plugin);
30181 $this->registeredPlugins[] = $package->getName();
30182 } elseif ($failOnMissingClasses) {
30183 throw new \UnexpectedValueException('Plugin '.$package->getName().' could not be initialized, class not found: '.$class);
30184 }
30185 }
30186 }
30187
30188
30189
30190
30191
30192
30193 protected function getPluginApiVersion()
30194 {
30195 return PluginInterface::PLUGIN_API_VERSION;
30196 }
30197
30198
30199
30200
30201
30202
30203
30204
30205
30206
30207 public function addPlugin(PluginInterface $plugin)
30208 {
30209 $this->io->writeError('Loading plugin '.get_class($plugin), true, IOInterface::DEBUG);
30210 $this->plugins[] = $plugin;
30211 $plugin->activate($this->composer, $this->io);
30212
30213 if ($plugin instanceof EventSubscriberInterface) {
30214 $this->composer->getEventDispatcher()->addSubscriber($plugin);
30215 }
30216 }
30217
30218
30219
30220
30221
30222
30223
30224
30225
30226
30227
30228
30229 private function loadRepository(RepositoryInterface $repo)
30230 {
30231 foreach ($repo->getPackages() as $package) { 
30232 if ($package instanceof AliasPackage) {
30233 continue;
30234 }
30235 if ('composer-plugin' === $package->getType()) {
30236 $this->registerPackage($package);
30237
30238  } elseif ('composer-installer' === $package->getType()) {
30239 $this->registerPackage($package);
30240 }
30241 }
30242 }
30243
30244
30245
30246
30247
30248
30249
30250
30251
30252
30253 private function collectDependencies(Pool $pool, array $collected, PackageInterface $package)
30254 {
30255 $requires = array_merge(
30256 $package->getRequires(),
30257 $package->getDevRequires()
30258 );
30259
30260 foreach ($requires as $requireLink) {
30261 $requiredPackage = $this->lookupInstalledPackage($pool, $requireLink);
30262 if ($requiredPackage && !isset($collected[$requiredPackage->getName()])) {
30263 $collected[$requiredPackage->getName()] = $requiredPackage;
30264 $collected = $this->collectDependencies($pool, $collected, $requiredPackage);
30265 }
30266 }
30267
30268 return $collected;
30269 }
30270
30271
30272
30273
30274
30275
30276
30277
30278
30279
30280
30281 private function lookupInstalledPackage(Pool $pool, Link $link)
30282 {
30283 $packages = $pool->whatProvides($link->getTarget(), $link->getConstraint());
30284
30285 return (!empty($packages)) ? $packages[0] : null;
30286 }
30287
30288
30289
30290
30291
30292
30293
30294
30295
30296 private function getInstallPath(PackageInterface $package, $global = false)
30297 {
30298 if (!$global) {
30299 return $this->composer->getInstallationManager()->getInstallPath($package);
30300 }
30301
30302 return $this->globalComposer->getInstallationManager()->getInstallPath($package);
30303 }
30304
30305
30306
30307
30308
30309
30310
30311 protected function getCapabilityImplementationClassName(PluginInterface $plugin, $capability)
30312 {
30313 if (!($plugin instanceof Capable)) {
30314 return null;
30315 }
30316
30317 $capabilities = (array) $plugin->getCapabilities();
30318
30319 if (!empty($capabilities[$capability]) && is_string($capabilities[$capability]) && trim($capabilities[$capability])) {
30320 return trim($capabilities[$capability]);
30321 }
30322
30323 if (
30324 array_key_exists($capability, $capabilities)
30325 && (empty($capabilities[$capability]) || !is_string($capabilities[$capability]) || !trim($capabilities[$capability]))
30326 ) {
30327 throw new \UnexpectedValueException('Plugin '.get_class($plugin).' provided invalid capability class name(s), got '.var_export($capabilities[$capability], 1));
30328 }
30329 }
30330
30331
30332
30333
30334
30335
30336
30337
30338
30339 public function getPluginCapability(PluginInterface $plugin, $capabilityClassName, array $ctorArgs = array())
30340 {
30341 if ($capabilityClass = $this->getCapabilityImplementationClassName($plugin, $capabilityClassName)) {
30342 if (!class_exists($capabilityClass)) {
30343 throw new \RuntimeException("Cannot instantiate Capability, as class $capabilityClass from plugin ".get_class($plugin)." does not exist.");
30344 }
30345
30346 $ctorArgs['plugin'] = $plugin;
30347 $capabilityObj = new $capabilityClass($ctorArgs);
30348
30349
30350  if (!$capabilityObj instanceof Capability || !$capabilityObj instanceof $capabilityClassName) {
30351 throw new \RuntimeException(
30352 'Class ' . $capabilityClass . ' must implement both Composer\Plugin\Capability\Capability and '. $capabilityClassName . '.'
30353 );
30354 }
30355
30356 return $capabilityObj;
30357 }
30358 }
30359
30360
30361
30362
30363
30364
30365
30366
30367 public function getPluginCapabilities($capabilityClassName, array $ctorArgs = array())
30368 {
30369 $capabilities = array();
30370 foreach ($this->getPlugins() as $plugin) {
30371 if ($capability = $this->getPluginCapability($plugin, $capabilityClassName, $ctorArgs)) {
30372 $capabilities[] = $capability;
30373 }
30374 }
30375
30376 return $capabilities;
30377 }
30378 }
30379 <?php
30380
30381
30382
30383
30384
30385
30386
30387
30388
30389
30390
30391 namespace Composer\Plugin;
30392
30393 use Composer\EventDispatcher\Event;
30394 use Composer\Util\RemoteFilesystem;
30395
30396
30397
30398
30399
30400
30401 class PreFileDownloadEvent extends Event
30402 {
30403
30404
30405
30406 private $rfs;
30407
30408
30409
30410
30411 private $processedUrl;
30412
30413
30414
30415
30416
30417
30418
30419
30420 public function __construct($name, RemoteFilesystem $rfs, $processedUrl)
30421 {
30422 parent::__construct($name);
30423 $this->rfs = $rfs;
30424 $this->processedUrl = $processedUrl;
30425 }
30426
30427
30428
30429
30430
30431
30432 public function getRemoteFilesystem()
30433 {
30434 return $this->rfs;
30435 }
30436
30437
30438
30439
30440
30441
30442 public function setRemoteFilesystem(RemoteFilesystem $rfs)
30443 {
30444 $this->rfs = $rfs;
30445 }
30446
30447
30448
30449
30450
30451
30452 public function getProcessedUrl()
30453 {
30454 return $this->processedUrl;
30455 }
30456 }
30457 <?php
30458
30459
30460
30461
30462
30463
30464
30465
30466
30467
30468
30469 namespace Composer\Repository;
30470
30471 use Composer\Package\AliasPackage;
30472 use Composer\Package\PackageInterface;
30473 use Composer\Package\CompletePackageInterface;
30474 use Composer\Package\Version\VersionParser;
30475 use Composer\Semver\Constraint\ConstraintInterface;
30476 use Composer\Semver\Constraint\Constraint;
30477
30478
30479
30480
30481
30482
30483 class ArrayRepository extends BaseRepository
30484 {
30485
30486 protected $packages;
30487
30488 public function __construct(array $packages = array())
30489 {
30490 foreach ($packages as $package) {
30491 $this->addPackage($package);
30492 }
30493 }
30494
30495
30496
30497
30498 public function findPackage($name, $constraint)
30499 {
30500 $name = strtolower($name);
30501
30502 if (!$constraint instanceof ConstraintInterface) {
30503 $versionParser = new VersionParser();
30504 $constraint = $versionParser->parseConstraints($constraint);
30505 }
30506
30507 foreach ($this->getPackages() as $package) {
30508 if ($name === $package->getName()) {
30509 $pkgConstraint = new Constraint('==', $package->getVersion());
30510 if ($constraint->matches($pkgConstraint)) {
30511 return $package;
30512 }
30513 }
30514 }
30515
30516 return null;
30517 }
30518
30519
30520
30521
30522 public function findPackages($name, $constraint = null)
30523 {
30524
30525  $name = strtolower($name);
30526 $packages = array();
30527
30528 if (null !== $constraint && !$constraint instanceof ConstraintInterface) {
30529 $versionParser = new VersionParser();
30530 $constraint = $versionParser->parseConstraints($constraint);
30531 }
30532
30533 foreach ($this->getPackages() as $package) {
30534 if ($name === $package->getName()) {
30535 $pkgConstraint = new Constraint('==', $package->getVersion());
30536 if (null === $constraint || $constraint->matches($pkgConstraint)) {
30537 $packages[] = $package;
30538 }
30539 }
30540 }
30541
30542 return $packages;
30543 }
30544
30545
30546
30547
30548 public function search($query, $mode = 0, $type = null)
30549 {
30550 $regex = '{(?:'.implode('|', preg_split('{\s+}', $query)).')}i';
30551
30552 $matches = array();
30553 foreach ($this->getPackages() as $package) {
30554 $name = $package->getName();
30555 if (isset($matches[$name])) {
30556 continue;
30557 }
30558 if (preg_match($regex, $name)
30559 || ($mode === self::SEARCH_FULLTEXT && $package instanceof CompletePackageInterface && preg_match($regex, implode(' ', (array) $package->getKeywords()) . ' ' . $package->getDescription()))
30560 ) {
30561 if (null !== $type && $package->getType() !== $type) {
30562 continue;
30563 }
30564
30565 $matches[$name] = array(
30566 'name' => $package->getPrettyName(),
30567 'description' => $package instanceof CompletePackageInterface ? $package->getDescription() : null,
30568 );
30569 }
30570 }
30571
30572 return array_values($matches);
30573 }
30574
30575
30576
30577
30578 public function hasPackage(PackageInterface $package)
30579 {
30580 $packageId = $package->getUniqueName();
30581
30582 foreach ($this->getPackages() as $repoPackage) {
30583 if ($packageId === $repoPackage->getUniqueName()) {
30584 return true;
30585 }
30586 }
30587
30588 return false;
30589 }
30590
30591
30592
30593
30594
30595
30596 public function addPackage(PackageInterface $package)
30597 {
30598 if (null === $this->packages) {
30599 $this->initialize();
30600 }
30601 $package->setRepository($this);
30602 $this->packages[] = $package;
30603
30604 if ($package instanceof AliasPackage) {
30605 $aliasedPackage = $package->getAliasOf();
30606 if (null === $aliasedPackage->getRepository()) {
30607 $this->addPackage($aliasedPackage);
30608 }
30609 }
30610 }
30611
30612 protected function createAliasPackage(PackageInterface $package, $alias, $prettyAlias)
30613 {
30614 return new AliasPackage($package instanceof AliasPackage ? $package->getAliasOf() : $package, $alias, $prettyAlias);
30615 }
30616
30617
30618
30619
30620
30621
30622 public function removePackage(PackageInterface $package)
30623 {
30624 $packageId = $package->getUniqueName();
30625
30626 foreach ($this->getPackages() as $key => $repoPackage) {
30627 if ($packageId === $repoPackage->getUniqueName()) {
30628 array_splice($this->packages, $key, 1);
30629
30630 return;
30631 }
30632 }
30633 }
30634
30635
30636
30637
30638 public function getPackages()
30639 {
30640 if (null === $this->packages) {
30641 $this->initialize();
30642 }
30643
30644 return $this->packages;
30645 }
30646
30647
30648
30649
30650
30651
30652 public function count()
30653 {
30654 return count($this->packages);
30655 }
30656
30657
30658
30659
30660 protected function initialize()
30661 {
30662 $this->packages = array();
30663 }
30664 }
30665 <?php
30666
30667
30668
30669
30670
30671
30672
30673
30674
30675
30676
30677 namespace Composer\Repository;
30678
30679 use Composer\IO\IOInterface;
30680 use Composer\Json\JsonFile;
30681 use Composer\Package\Loader\ArrayLoader;
30682 use Composer\Package\Loader\LoaderInterface;
30683
30684
30685
30686
30687 class ArtifactRepository extends ArrayRepository implements ConfigurableRepositoryInterface
30688 {
30689
30690 protected $loader;
30691
30692 protected $lookup;
30693 protected $repoConfig;
30694 private $io;
30695
30696 public function __construct(array $repoConfig, IOInterface $io)
30697 {
30698 parent::__construct();
30699 if (!extension_loaded('zip')) {
30700 throw new \RuntimeException('The artifact repository requires PHP\'s zip extension');
30701 }
30702
30703 $this->loader = new ArrayLoader();
30704 $this->lookup = $repoConfig['url'];
30705 $this->io = $io;
30706 $this->repoConfig = $repoConfig;
30707 }
30708
30709 public function getRepoConfig()
30710 {
30711 return $this->repoConfig;
30712 }
30713
30714 protected function initialize()
30715 {
30716 parent::initialize();
30717
30718 $this->scanDirectory($this->lookup);
30719 }
30720
30721 private function scanDirectory($path)
30722 {
30723 $io = $this->io;
30724
30725 $directory = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
30726 $iterator = new \RecursiveIteratorIterator($directory);
30727 $regex = new \RegexIterator($iterator, '/^.+\.(zip|phar)$/i');
30728 foreach ($regex as $file) {
30729
30730 if (!$file->isFile()) {
30731 continue;
30732 }
30733
30734 $package = $this->getComposerInformation($file);
30735 if (!$package) {
30736 $io->writeError("File <comment>{$file->getBasename()}</comment> doesn't seem to hold a package", true, IOInterface::VERBOSE);
30737 continue;
30738 }
30739
30740 $template = 'Found package <info>%s</info> (<comment>%s</comment>) in file <info>%s</info>';
30741 $io->writeError(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename()), true, IOInterface::VERBOSE);
30742
30743 $this->addPackage($package);
30744 }
30745 }
30746
30747
30748
30749
30750
30751
30752
30753
30754 private function locateFile(\ZipArchive $zip, $filename)
30755 {
30756 $indexOfShortestMatch = false;
30757 $lengthOfShortestMatch = -1;
30758
30759 for ($i = 0; $i < $zip->numFiles; $i++) {
30760 $stat = $zip->statIndex($i);
30761 if (strcmp(basename($stat['name']), $filename) === 0) {
30762 $directoryName = dirname($stat['name']);
30763 if ($directoryName == '.') {
30764
30765  
30766  return $i;
30767 }
30768
30769 if (strpos($directoryName, '\\') !== false ||
30770 strpos($directoryName, '/') !== false) {
30771
30772  continue;
30773 }
30774
30775 $length = strlen($stat['name']);
30776 if ($indexOfShortestMatch === false || $length < $lengthOfShortestMatch) {
30777
30778  $contents = $zip->getFromIndex($i);
30779 if ($contents !== false) {
30780 $indexOfShortestMatch = $i;
30781 $lengthOfShortestMatch = $length;
30782 }
30783 }
30784 }
30785 }
30786
30787 return $indexOfShortestMatch;
30788 }
30789
30790 private function getComposerInformation(\SplFileInfo $file)
30791 {
30792 $zip = new \ZipArchive();
30793 $zip->open($file->getPathname());
30794
30795 if (0 == $zip->numFiles) {
30796 return false;
30797 }
30798
30799 $foundFileIndex = $this->locateFile($zip, 'composer.json');
30800 if (false === $foundFileIndex) {
30801 return false;
30802 }
30803
30804 $configurationFileName = $zip->getNameIndex($foundFileIndex);
30805
30806 $composerFile = "zip://{$file->getPathname()}#$configurationFileName";
30807 $json = file_get_contents($composerFile);
30808
30809 $package = JsonFile::parseJson($json, $composerFile);
30810 $package['dist'] = array(
30811 'type' => 'zip',
30812 'url' => strtr($file->getPathname(), '\\', '/'),
30813 'shasum' => sha1_file($file->getRealPath()),
30814 );
30815
30816 try {
30817 $package = $this->loader->load($package);
30818 } catch (\UnexpectedValueException $e) {
30819 throw new \UnexpectedValueException('Failed loading package in '.$file.': '.$e->getMessage(), 0, $e);
30820 }
30821
30822 return $package;
30823 }
30824 }
30825 <?php
30826
30827
30828
30829
30830
30831
30832
30833
30834
30835
30836
30837 namespace Composer\Repository;
30838
30839 use Composer\Package\RootPackageInterface;
30840 use Composer\Semver\Constraint\ConstraintInterface;
30841 use Composer\Semver\Constraint\Constraint;
30842 use Composer\Package\Link;
30843
30844
30845
30846
30847
30848
30849 abstract class BaseRepository implements RepositoryInterface
30850 {
30851
30852
30853
30854
30855
30856
30857
30858
30859
30860
30861
30862
30863
30864 public function getDependents($needle, $constraint = null, $invert = false, $recurse = true, $packagesFound = null)
30865 {
30866 $needles = (array) $needle;
30867 $results = array();
30868
30869
30870  if (null === $packagesFound) {
30871 $packagesFound = $needles;
30872 }
30873
30874
30875  $rootPackage = null;
30876 foreach ($this->getPackages() as $package) {
30877 if ($package instanceof RootPackageInterface) {
30878 $rootPackage = $package;
30879 break;
30880 }
30881 }
30882
30883
30884  foreach ($this->getPackages() as $package) {
30885 $links = $package->getRequires();
30886
30887
30888  
30889  $packagesInTree = $packagesFound;
30890
30891
30892  if (!$invert) {
30893 $links += $package->getReplaces();
30894 }
30895
30896
30897  if ($package instanceof RootPackageInterface) {
30898 $links += $package->getDevRequires();
30899 }
30900
30901
30902  foreach ($links as $link) {
30903 foreach ($needles as $needle) {
30904 if ($link->getTarget() === $needle) {
30905 if (is_null($constraint) || (($link->getConstraint()->matches($constraint) === !$invert))) {
30906
30907  if (in_array($link->getSource(), $packagesInTree)) {
30908 $results[$link->getSource()] = array($package, $link, false);
30909 continue;
30910 }
30911 $packagesInTree[] = $link->getSource();
30912 $dependents = $recurse ? $this->getDependents($link->getSource(), null, false, true, $packagesInTree) : array();
30913 $results[$link->getSource()] = array($package, $link, $dependents);
30914 }
30915 }
30916 }
30917 }
30918
30919
30920  if ($invert && in_array($package->getName(), $needles)) {
30921 foreach ($package->getConflicts() as $link) {
30922 foreach ($this->findPackages($link->getTarget()) as $pkg) {
30923 $version = new Constraint('=', $pkg->getVersion());
30924 if ($link->getConstraint()->matches($version) === $invert) {
30925 $results[] = array($package, $link, false);
30926 }
30927 }
30928 }
30929 }
30930
30931
30932  if ($invert && $constraint && in_array($package->getName(), $needles) && $constraint->matches(new Constraint('=', $package->getVersion()))) {
30933 foreach ($package->getRequires() as $link) {
30934 if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $link->getTarget())) {
30935 if ($this->findPackage($link->getTarget(), $link->getConstraint())) {
30936 continue;
30937 }
30938
30939 $platformPkg = $this->findPackage($link->getTarget(), '*');
30940 $description = $platformPkg ? 'but '.$platformPkg->getPrettyVersion().' is installed' : 'but it is missing';
30941 $results[] = array($package, new Link($package->getName(), $link->getTarget(), null, 'requires', $link->getPrettyConstraint().' '.$description), false);
30942
30943 continue;
30944 }
30945
30946 foreach ($this->getPackages() as $pkg) {
30947 if (!in_array($link->getTarget(), $pkg->getNames())) {
30948 continue;
30949 }
30950
30951 $version = new Constraint('=', $pkg->getVersion());
30952 if (!$link->getConstraint()->matches($version)) {
30953
30954  
30955  if ($rootPackage) {
30956 foreach (array_merge($rootPackage->getRequires(), $rootPackage->getDevRequires()) as $rootReq) {
30957 if (in_array($rootReq->getTarget(), $pkg->getNames()) && !$rootReq->getConstraint()->matches($link->getConstraint())) {
30958 $results[] = array($package, $link, false);
30959 $results[] = array($rootPackage, $rootReq, false);
30960 continue 3;
30961 }
30962 }
30963 $results[] = array($package, $link, false);
30964 $results[] = array($rootPackage, new Link($rootPackage->getName(), $link->getTarget(), null, 'does not require', 'but ' . $pkg->getPrettyVersion() . ' is installed'), false);
30965 } else {
30966
30967  $results[] = array($package, $link, false);
30968 }
30969 }
30970
30971 continue 2;
30972 }
30973 }
30974 }
30975 }
30976
30977 ksort($results);
30978
30979 return $results;
30980 }
30981 }
30982 <?php
30983
30984
30985
30986
30987
30988
30989
30990
30991
30992
30993
30994 namespace Composer\Repository;
30995
30996 use Composer\Package\Loader\ArrayLoader;
30997 use Composer\Package\PackageInterface;
30998 use Composer\Package\AliasPackage;
30999 use Composer\Package\Version\VersionParser;
31000 use Composer\DependencyResolver\Pool;
31001 use Composer\Json\JsonFile;
31002 use Composer\Cache;
31003 use Composer\Config;
31004 use Composer\Factory;
31005 use Composer\IO\IOInterface;
31006 use Composer\Util\RemoteFilesystem;
31007 use Composer\Plugin\PluginEvents;
31008 use Composer\Plugin\PreFileDownloadEvent;
31009 use Composer\EventDispatcher\EventDispatcher;
31010 use Composer\Downloader\TransportException;
31011 use Composer\Semver\Constraint\ConstraintInterface;
31012 use Composer\Semver\Constraint\Constraint;
31013
31014
31015
31016
31017 class ComposerRepository extends ArrayRepository implements ConfigurableRepositoryInterface
31018 {
31019 protected $config;
31020 protected $repoConfig;
31021 protected $options;
31022 protected $url;
31023 protected $baseUrl;
31024 protected $io;
31025 protected $rfs;
31026 protected $cache;
31027 protected $notifyUrl;
31028 protected $searchUrl;
31029 protected $hasProviders = false;
31030 protected $providersUrl;
31031 protected $lazyProvidersUrl;
31032 protected $providerListing;
31033 protected $providers = array();
31034 protected $providersByUid = array();
31035 protected $loader;
31036 protected $rootAliases;
31037 protected $allowSslDowngrade = false;
31038 protected $eventDispatcher;
31039 protected $sourceMirrors;
31040 protected $distMirrors;
31041 private $degradedMode = false;
31042 private $rootData;
31043 private $hasPartialPackages;
31044 private $partialPackagesByName;
31045
31046 public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
31047 {
31048 parent::__construct();
31049 if (!preg_match('{^[\w.]+\??://}', $repoConfig['url'])) {
31050
31051  $repoConfig['url'] = 'http://'.$repoConfig['url'];
31052 }
31053 $repoConfig['url'] = rtrim($repoConfig['url'], '/');
31054
31055 if ('https?' === substr($repoConfig['url'], 0, 6)) {
31056 $repoConfig['url'] = (extension_loaded('openssl') ? 'https' : 'http') . substr($repoConfig['url'], 6);
31057 }
31058
31059 $urlBits = parse_url($repoConfig['url']);
31060 if ($urlBits === false || empty($urlBits['scheme'])) {
31061 throw new \UnexpectedValueException('Invalid url given for Composer repository: '.$repoConfig['url']);
31062 }
31063
31064 if (!isset($repoConfig['options'])) {
31065 $repoConfig['options'] = array();
31066 }
31067 if (isset($repoConfig['allow_ssl_downgrade']) && true === $repoConfig['allow_ssl_downgrade']) {
31068 $this->allowSslDowngrade = true;
31069 }
31070
31071 $this->config = $config;
31072 $this->options = $repoConfig['options'];
31073 $this->url = $repoConfig['url'];
31074 $this->baseUrl = rtrim(preg_replace('{(?:/[^/\\\\]+\.json)?(?:[?#].*)?$}', '', $this->url), '/');
31075 $this->io = $io;
31076 $this->cache = new Cache($io, $config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url), 'a-z0-9.$');
31077 $this->loader = new ArrayLoader();
31078 if ($rfs && $this->options) {
31079 $rfs = clone $rfs;
31080 $rfs->setOptions($this->options);
31081 }
31082 $this->rfs = $rfs ?: Factory::createRemoteFilesystem($this->io, $this->config, $this->options);
31083 $this->eventDispatcher = $eventDispatcher;
31084 $this->repoConfig = $repoConfig;
31085 }
31086
31087 public function getRepoConfig()
31088 {
31089 return $this->repoConfig;
31090 }
31091
31092 public function setRootAliases(array $rootAliases)
31093 {
31094 $this->rootAliases = $rootAliases;
31095 }
31096
31097
31098
31099
31100 public function findPackage($name, $constraint)
31101 {
31102 if (!$this->hasProviders()) {
31103 return parent::findPackage($name, $constraint);
31104 }
31105
31106 $name = strtolower($name);
31107 if (!$constraint instanceof ConstraintInterface) {
31108 $versionParser = new VersionParser();
31109 $constraint = $versionParser->parseConstraints($constraint);
31110 }
31111
31112 foreach ($this->getProviderNames() as $providerName) {
31113 if ($name === $providerName) {
31114 $packages = $this->whatProvides(new Pool('dev'), $providerName);
31115 foreach ($packages as $package) {
31116 if ($name === $package->getName()) {
31117 $pkgConstraint = new Constraint('==', $package->getVersion());
31118 if ($constraint->matches($pkgConstraint)) {
31119 return $package;
31120 }
31121 }
31122 }
31123 break;
31124 }
31125 }
31126 }
31127
31128
31129
31130
31131 public function findPackages($name, $constraint = null)
31132 {
31133 if (!$this->hasProviders()) {
31134 return parent::findPackages($name, $constraint);
31135 }
31136
31137  $name = strtolower($name);
31138
31139 if (null !== $constraint && !$constraint instanceof ConstraintInterface) {
31140 $versionParser = new VersionParser();
31141 $constraint = $versionParser->parseConstraints($constraint);
31142 }
31143
31144 $packages = array();
31145
31146 foreach ($this->getProviderNames() as $providerName) {
31147 if ($name === $providerName) {
31148 $candidates = $this->whatProvides(new Pool('dev'), $providerName);
31149 foreach ($candidates as $package) {
31150 if ($name === $package->getName()) {
31151 $pkgConstraint = new Constraint('==', $package->getVersion());
31152 if (null === $constraint || $constraint->matches($pkgConstraint)) {
31153 $packages[] = $package;
31154 }
31155 }
31156 }
31157 break;
31158 }
31159 }
31160
31161 return $packages;
31162 }
31163
31164 public function getPackages()
31165 {
31166 if ($this->hasProviders()) {
31167 throw new \LogicException('Composer repositories that have providers can not load the complete list of packages, use getProviderNames instead.');
31168 }
31169
31170 return parent::getPackages();
31171 }
31172
31173
31174
31175
31176 public function search($query, $mode = 0, $type = null)
31177 {
31178 $this->loadRootServerFile();
31179
31180 if ($this->searchUrl && $mode === self::SEARCH_FULLTEXT) {
31181 $url = str_replace(array('%query%', '%type%'), array($query, $type), $this->searchUrl);
31182
31183 $hostname = parse_url($url, PHP_URL_HOST) ?: $url;
31184 $json = $this->rfs->getContents($hostname, $url, false);
31185 $results = JsonFile::parseJson($json, $url);
31186
31187 return $results['results'];
31188 }
31189
31190 if ($this->hasProviders()) {
31191 $results = array();
31192 $regex = '{(?:'.implode('|', preg_split('{\s+}', $query)).')}i';
31193
31194 foreach ($this->getProviderNames() as $name) {
31195 if (preg_match($regex, $name)) {
31196 $results[] = array('name' => $name);
31197 }
31198 }
31199
31200 return $results;
31201 }
31202
31203 return parent::search($query, $mode);
31204 }
31205
31206 public function getProviderNames()
31207 {
31208 $this->loadRootServerFile();
31209
31210 if (null === $this->providerListing) {
31211 $this->loadProviderListings($this->loadRootServerFile());
31212 }
31213
31214 if ($this->lazyProvidersUrl) {
31215
31216  return array();
31217 }
31218
31219 if ($this->providersUrl) {
31220 return array_keys($this->providerListing);
31221 }
31222
31223 return array();
31224 }
31225
31226 protected function configurePackageTransportOptions(PackageInterface $package)
31227 {
31228 foreach ($package->getDistUrls() as $url) {
31229 if (strpos($url, $this->baseUrl) === 0) {
31230 $package->setTransportOptions($this->options);
31231
31232 return;
31233 }
31234 }
31235 }
31236
31237 public function hasProviders()
31238 {
31239 $this->loadRootServerFile();
31240
31241 return $this->hasProviders;
31242 }
31243
31244 public function resetPackageIds()
31245 {
31246 foreach ($this->providersByUid as $package) {
31247 if ($package instanceof AliasPackage) {
31248 $package->getAliasOf()->setId(-1);
31249 }
31250 $package->setId(-1);
31251 }
31252 }
31253
31254
31255
31256
31257
31258
31259
31260 public function whatProvides(Pool $pool, $name, $bypassFilters = false)
31261 {
31262 if (isset($this->providers[$name]) && !$bypassFilters) {
31263 return $this->providers[$name];
31264 }
31265
31266 if ($this->hasPartialPackages && null === $this->partialPackagesByName) {
31267 $this->initializePartialPackages();
31268 }
31269
31270 if (!$this->hasPartialPackages || !isset($this->partialPackagesByName[$name])) {
31271
31272  if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name) || '__root__' === $name || 'composer-plugin-api' === $name) {
31273 return array();
31274 }
31275
31276 if (null === $this->providerListing) {
31277 $this->loadProviderListings($this->loadRootServerFile());
31278 }
31279
31280 $useLastModifiedCheck = false;
31281 if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
31282 $hash = null;
31283 $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
31284 $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
31285 $useLastModifiedCheck = true;
31286 } elseif ($this->providersUrl) {
31287
31288  if (!isset($this->providerListing[$name])) {
31289 return array();
31290 }
31291
31292 $hash = $this->providerListing[$name]['sha256'];
31293 $url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
31294 $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
31295 } else {
31296 return array();
31297 }
31298
31299 $packages = null;
31300 if ($cacheKey) {
31301 if (!$useLastModifiedCheck && $hash && $this->cache->sha256($cacheKey) === $hash) {
31302 $packages = json_decode($this->cache->read($cacheKey), true);
31303 } elseif ($useLastModifiedCheck) {
31304 if ($contents = $this->cache->read($cacheKey)) {
31305 $contents = json_decode($contents, true);
31306 if (isset($contents['last-modified'])) {
31307 $response = $this->fetchFileIfLastModified($url, $cacheKey, $contents['last-modified']);
31308 if (true === $response) {
31309 $packages = $contents;
31310 } elseif ($response) {
31311 $packages = $response;
31312 }
31313 }
31314 }
31315 }
31316 }
31317
31318 if (!$packages) {
31319 try {
31320 $packages = $this->fetchFile($url, $cacheKey, $hash, $useLastModifiedCheck);
31321 } catch (TransportException $e) {
31322
31323  if ($e->getStatusCode() === 404 && $this->lazyProvidersUrl) {
31324 $packages = array('packages' => array());
31325 } else {
31326 throw $e;
31327 }
31328 }
31329 }
31330
31331 $loadingPartialPackage = false;
31332 } else {
31333 $packages = array('packages' => array('versions' => $this->partialPackagesByName[$name]));
31334 $loadingPartialPackage = true;
31335 }
31336
31337 $this->providers[$name] = array();
31338 foreach ($packages['packages'] as $versions) {
31339 foreach ($versions as $version) {
31340 if (!$loadingPartialPackage && $this->hasPartialPackages && isset($this->partialPackagesByName[$version['name']])) {
31341 continue;
31342 }
31343
31344
31345  if (isset($this->providersByUid[$version['uid']])) {
31346
31347  if (!isset($this->providers[$name][$version['uid']])) {
31348
31349  if ($this->providersByUid[$version['uid']] instanceof AliasPackage) {
31350 $this->providers[$name][$version['uid']] = $this->providersByUid[$version['uid']]->getAliasOf();
31351 $this->providers[$name][$version['uid'].'-alias'] = $this->providersByUid[$version['uid']];
31352 } else {
31353 $this->providers[$name][$version['uid']] = $this->providersByUid[$version['uid']];
31354 }
31355
31356  if (isset($this->providersByUid[$version['uid'].'-root'])) {
31357 $this->providers[$name][$version['uid'].'-root'] = $this->providersByUid[$version['uid'].'-root'];
31358 }
31359 }
31360 } else {
31361 if (!$bypassFilters && !$pool->isPackageAcceptable(strtolower($version['name']), VersionParser::parseStability($version['version']))) {
31362 continue;
31363 }
31364
31365
31366  $package = $this->createPackage($version, 'Composer\Package\CompletePackage');
31367 $package->setRepository($this);
31368
31369 if ($package instanceof AliasPackage) {
31370 $aliased = $package->getAliasOf();
31371 $aliased->setRepository($this);
31372
31373 $this->providers[$name][$version['uid']] = $aliased;
31374 $this->providers[$name][$version['uid'].'-alias'] = $package;
31375
31376
31377  $this->providersByUid[$version['uid']] = $package;
31378 } else {
31379 $this->providers[$name][$version['uid']] = $package;
31380 $this->providersByUid[$version['uid']] = $package;
31381 }
31382
31383
31384  unset($rootAliasData);
31385
31386 if (isset($this->rootAliases[$package->getName()][$package->getVersion()])) {
31387 $rootAliasData = $this->rootAliases[$package->getName()][$package->getVersion()];
31388 } elseif ($package instanceof AliasPackage && isset($this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()])) {
31389 $rootAliasData = $this->rootAliases[$package->getName()][$package->getAliasOf()->getVersion()];
31390 }
31391
31392 if (isset($rootAliasData)) {
31393 $alias = $this->createAliasPackage($package, $rootAliasData['alias_normalized'], $rootAliasData['alias']);
31394 $alias->setRepository($this);
31395
31396 $this->providers[$name][$version['uid'].'-root'] = $alias;
31397 $this->providersByUid[$version['uid'].'-root'] = $alias;
31398 }
31399 }
31400 }
31401 }
31402
31403 $result = $this->providers[$name];
31404
31405
31406  
31407  if ($bypassFilters) {
31408 foreach ($this->providers[$name] as $uid => $provider) {
31409 unset($this->providersByUid[$uid]);
31410 }
31411 unset($this->providers[$name]);
31412 }
31413
31414 return $result;
31415 }
31416
31417
31418
31419
31420 protected function initialize()
31421 {
31422 parent::initialize();
31423
31424 $repoData = $this->loadDataFromServer();
31425
31426 foreach ($repoData as $package) {
31427 $this->addPackage($this->createPackage($package, 'Composer\Package\CompletePackage'));
31428 }
31429 }
31430
31431
31432
31433
31434
31435
31436 public function addPackage(PackageInterface $package)
31437 {
31438 parent::addPackage($package);
31439 $this->configurePackageTransportOptions($package);
31440 }
31441
31442 protected function loadRootServerFile()
31443 {
31444 if (null !== $this->rootData) {
31445 return $this->rootData;
31446 }
31447
31448 if (!extension_loaded('openssl') && 'https' === substr($this->url, 0, 5)) {
31449 throw new \RuntimeException('You must enable the openssl extension in your php.ini to load information from '.$this->url);
31450 }
31451
31452 $jsonUrlParts = parse_url($this->url);
31453
31454 if (isset($jsonUrlParts['path']) && false !== strpos($jsonUrlParts['path'], '.json')) {
31455 $jsonUrl = $this->url;
31456 } else {
31457 $jsonUrl = $this->url . '/packages.json';
31458 }
31459
31460 $data = $this->fetchFile($jsonUrl, 'packages.json');
31461
31462 if (!empty($data['notify-batch'])) {
31463 $this->notifyUrl = $this->canonicalizeUrl($data['notify-batch']);
31464 } elseif (!empty($data['notify'])) {
31465 $this->notifyUrl = $this->canonicalizeUrl($data['notify']);
31466 }
31467
31468 if (!empty($data['search'])) {
31469 $this->searchUrl = $this->canonicalizeUrl($data['search']);
31470 }
31471
31472 if (!empty($data['mirrors'])) {
31473 foreach ($data['mirrors'] as $mirror) {
31474 if (!empty($mirror['git-url'])) {
31475 $this->sourceMirrors['git'][] = array('url' => $mirror['git-url'], 'preferred' => !empty($mirror['preferred']));
31476 }
31477 if (!empty($mirror['hg-url'])) {
31478 $this->sourceMirrors['hg'][] = array('url' => $mirror['hg-url'], 'preferred' => !empty($mirror['preferred']));
31479 }
31480 if (!empty($mirror['dist-url'])) {
31481 $this->distMirrors[] = array('url' => $mirror['dist-url'], 'preferred' => !empty($mirror['preferred']));
31482 }
31483 }
31484 }
31485
31486 if (!empty($data['providers-lazy-url'])) {
31487 $this->lazyProvidersUrl = $this->canonicalizeUrl($data['providers-lazy-url']);
31488 $this->hasProviders = true;
31489
31490 $this->hasPartialPackages = !empty($data['packages']) && is_array($data['packages']);
31491 }
31492
31493 if ($this->allowSslDowngrade) {
31494 $this->url = str_replace('https://', 'http://', $this->url);
31495 $this->baseUrl = str_replace('https://', 'http://', $this->baseUrl);
31496 }
31497
31498 if (!empty($data['providers-url'])) {
31499 $this->providersUrl = $this->canonicalizeUrl($data['providers-url']);
31500 $this->hasProviders = true;
31501 }
31502
31503 if (!empty($data['providers']) || !empty($data['providers-includes'])) {
31504 $this->hasProviders = true;
31505 }
31506
31507
31508  if (preg_match('{^https?://packagist.org/?$}i', $this->url) && !empty($this->repoConfig['force-lazy-providers'])) {
31509 $this->url = 'https://packagist.org';
31510 $this->baseUrl = 'https://packagist.org';
31511 $this->lazyProvidersUrl = $this->canonicalizeUrl('https://packagist.org/p/%package%.json');
31512 $this->providersUrl = null;
31513 } elseif (!empty($this->repoConfig['force-lazy-providers'])) {
31514 $this->lazyProvidersUrl = $this->canonicalizeUrl('/p/%package%.json');
31515 $this->providersUrl = null;
31516 }
31517
31518 return $this->rootData = $data;
31519 }
31520
31521 protected function canonicalizeUrl($url)
31522 {
31523 if ('/' === $url[0]) {
31524 return preg_replace('{(https?://[^/]+).*}i', '$1' . $url, $this->url);
31525 }
31526
31527 return $url;
31528 }
31529
31530 protected function loadDataFromServer()
31531 {
31532 $data = $this->loadRootServerFile();
31533
31534 return $this->loadIncludes($data);
31535 }
31536
31537 protected function loadProviderListings($data)
31538 {
31539 if (isset($data['providers'])) {
31540 if (!is_array($this->providerListing)) {
31541 $this->providerListing = array();
31542 }
31543 $this->providerListing = array_merge($this->providerListing, $data['providers']);
31544 }
31545
31546 if ($this->providersUrl && isset($data['provider-includes'])) {
31547 $includes = $data['provider-includes'];
31548 foreach ($includes as $include => $metadata) {
31549 $url = $this->baseUrl . '/' . str_replace('%hash%', $metadata['sha256'], $include);
31550 $cacheKey = str_replace(array('%hash%','$'), '', $include);
31551 if ($this->cache->sha256($cacheKey) === $metadata['sha256']) {
31552 $includedData = json_decode($this->cache->read($cacheKey), true);
31553 } else {
31554 $includedData = $this->fetchFile($url, $cacheKey, $metadata['sha256']);
31555 }
31556
31557 $this->loadProviderListings($includedData);
31558 }
31559 }
31560 }
31561
31562 protected function loadIncludes($data)
31563 {
31564 $packages = array();
31565
31566
31567  if (!isset($data['packages']) && !isset($data['includes'])) {
31568 foreach ($data as $pkg) {
31569 foreach ($pkg['versions'] as $metadata) {
31570 $packages[] = $metadata;
31571 }
31572 }
31573
31574 return $packages;
31575 }
31576
31577 if (isset($data['packages'])) {
31578 foreach ($data['packages'] as $package => $versions) {
31579 foreach ($versions as $version => $metadata) {
31580 $packages[] = $metadata;
31581 }
31582 }
31583 }
31584
31585 if (isset($data['includes'])) {
31586 foreach ($data['includes'] as $include => $metadata) {
31587 if ($this->cache->sha1($include) === $metadata['sha1']) {
31588 $includedData = json_decode($this->cache->read($include), true);
31589 } else {
31590 $includedData = $this->fetchFile($include);
31591 }
31592 $packages = array_merge($packages, $this->loadIncludes($includedData));
31593 }
31594 }
31595
31596 return $packages;
31597 }
31598
31599 protected function createPackage(array $data, $class = 'Composer\Package\CompletePackage')
31600 {
31601 try {
31602 if (!isset($data['notification-url'])) {
31603 $data['notification-url'] = $this->notifyUrl;
31604 }
31605
31606 $package = $this->loader->load($data, $class);
31607 if (isset($this->sourceMirrors[$package->getSourceType()])) {
31608 $package->setSourceMirrors($this->sourceMirrors[$package->getSourceType()]);
31609 }
31610 $package->setDistMirrors($this->distMirrors);
31611 $this->configurePackageTransportOptions($package);
31612
31613 return $package;
31614 } catch (\Exception $e) {
31615 throw new \RuntimeException('Could not load package '.(isset($data['name']) ? $data['name'] : json_encode($data)).' in '.$this->url.': ['.get_class($e).'] '.$e->getMessage(), 0, $e);
31616 }
31617 }
31618
31619 protected function fetchFile($filename, $cacheKey = null, $sha256 = null, $storeLastModifiedTime = false)
31620 {
31621 if (null === $cacheKey) {
31622 $cacheKey = $filename;
31623 $filename = $this->baseUrl.'/'.$filename;
31624 }
31625
31626
31627  if (($pos = strpos($filename, '$')) && preg_match('{^https?://.*}i', $filename)) {
31628 $filename = substr($filename, 0, $pos) . '%24' . substr($filename, $pos + 1);
31629 }
31630
31631 $retries = 3;
31632 while ($retries--) {
31633 try {
31634 $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->rfs, $filename);
31635 if ($this->eventDispatcher) {
31636 $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
31637 }
31638
31639 $hostname = parse_url($filename, PHP_URL_HOST) ?: $filename;
31640 $rfs = $preFileDownloadEvent->getRemoteFilesystem();
31641
31642 $json = $rfs->getContents($hostname, $filename, false);
31643 if ($sha256 && $sha256 !== hash('sha256', $json)) {
31644
31645  if ($this->allowSslDowngrade) {
31646 $this->url = str_replace('http://', 'https://', $this->url);
31647 $this->baseUrl = str_replace('http://', 'https://', $this->baseUrl);
31648 $filename = str_replace('http://', 'https://', $filename);
31649 }
31650
31651 if ($retries) {
31652 usleep(100000);
31653
31654 continue;
31655 }
31656
31657
31658  throw new RepositorySecurityException('The contents of '.$filename.' do not match its signature. This should indicate a man-in-the-middle attack. Try running composer again and report this if you think it is a mistake.');
31659 }
31660
31661 $data = JsonFile::parseJson($json, $filename);
31662 if (!empty($data['warning'])) {
31663 $this->io->writeError('<warning>Warning from '.$this->url.': '.$data['warning'].'</warning>');
31664 }
31665 if (!empty($data['info'])) {
31666 $this->io->writeError('<info>Info from '.$this->url.': '.$data['info'].'</info>');
31667 }
31668
31669 if ($cacheKey) {
31670 if ($storeLastModifiedTime) {
31671 $lastModifiedDate = $rfs->findHeaderValue($rfs->getLastHeaders(), 'last-modified');
31672 if ($lastModifiedDate) {
31673 $data['last-modified'] = $lastModifiedDate;
31674 $json = json_encode($data);
31675 }
31676 }
31677 $this->cache->write($cacheKey, $json);
31678 }
31679
31680 break;
31681 } catch (\Exception $e) {
31682 if ($e instanceof TransportException && $e->getStatusCode() === 404) {
31683 throw $e;
31684 }
31685
31686 if ($retries) {
31687 usleep(100000);
31688 continue;
31689 }
31690
31691 if ($e instanceof RepositorySecurityException) {
31692 throw $e;
31693 }
31694
31695 if ($cacheKey && ($contents = $this->cache->read($cacheKey))) {
31696 if (!$this->degradedMode) {
31697 $this->io->writeError('<warning>'.$e->getMessage().'</warning>');
31698 $this->io->writeError('<warning>'.$this->url.' could not be fully loaded, package information was loaded from the local cache and may be out of date</warning>');
31699 }
31700 $this->degradedMode = true;
31701 $data = JsonFile::parseJson($contents, $this->cache->getRoot().$cacheKey);
31702
31703 break;
31704 }
31705
31706 throw $e;
31707 }
31708 }
31709
31710 return $data;
31711 }
31712
31713 protected function fetchFileIfLastModified($filename, $cacheKey, $lastModifiedTime)
31714 {
31715 $retries = 3;
31716 while ($retries--) {
31717 try {
31718 $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->rfs, $filename);
31719 if ($this->eventDispatcher) {
31720 $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
31721 }
31722
31723 $hostname = parse_url($filename, PHP_URL_HOST) ?: $filename;
31724 $rfs = $preFileDownloadEvent->getRemoteFilesystem();
31725 $options = array('http' => array('header' => array('If-Modified-Since: '.$lastModifiedTime)));
31726 $json = $rfs->getContents($hostname, $filename, false, $options);
31727 if ($json === '' && $rfs->findStatusCode($rfs->getLastHeaders()) === 304) {
31728 return true;
31729 }
31730
31731 $data = JsonFile::parseJson($json, $filename);
31732 if (!empty($data['warning'])) {
31733 $this->io->writeError('<warning>Warning from '.$this->url.': '.$data['warning'].'</warning>');
31734 }
31735 if (!empty($data['info'])) {
31736 $this->io->writeError('<info>Info from '.$this->url.': '.$data['info'].'</info>');
31737 }
31738
31739 $lastModifiedDate = $rfs->findHeaderValue($rfs->getLastHeaders(), 'last-modified');
31740 if ($lastModifiedDate) {
31741 $data['last-modified'] = $lastModifiedDate;
31742 $json = json_encode($data);
31743 }
31744 $this->cache->write($cacheKey, $json);
31745
31746 return $data;
31747 } catch (\Exception $e) {
31748 if ($e instanceof TransportException && $e->getStatusCode() === 404) {
31749 throw $e;
31750 }
31751
31752 if ($retries) {
31753 usleep(100000);
31754 continue;
31755 }
31756
31757 if (!$this->degradedMode) {
31758 $this->io->writeError('<warning>'.$e->getMessage().'</warning>');
31759 $this->io->writeError('<warning>'.$this->url.' could not be fully loaded, package information was loaded from the local cache and may be out of date</warning>');
31760 }
31761 $this->degradedMode = true;
31762
31763 return true;
31764 }
31765 }
31766 }
31767
31768
31769
31770
31771
31772
31773 private function initializePartialPackages()
31774 {
31775 $rootData = $this->loadRootServerFile();
31776
31777 $this->partialPackagesByName = array();
31778 foreach ($rootData['packages'] as $package => $versions) {
31779 $package = strtolower($package);
31780 foreach ($versions as $version) {
31781 $this->partialPackagesByName[$package][] = $version;
31782 if (!empty($version['provide']) && is_array($version['provide'])) {
31783 foreach ($version['provide'] as $provided => $providedVersion) {
31784 $this->partialPackagesByName[strtolower($provided)][] = $version;
31785 }
31786 }
31787 if (!empty($version['replace']) && is_array($version['replace'])) {
31788 foreach ($version['replace'] as $provided => $providedVersion) {
31789 $this->partialPackagesByName[strtolower($provided)][] = $version;
31790 }
31791 }
31792 }
31793 }
31794
31795
31796  $this->rootData = true;
31797 }
31798 }
31799 <?php
31800
31801
31802
31803
31804
31805
31806
31807
31808
31809
31810
31811 namespace Composer\Repository;
31812
31813 use Composer\Package\PackageInterface;
31814
31815
31816
31817
31818
31819
31820 class CompositeRepository extends BaseRepository
31821 {
31822
31823
31824
31825
31826 private $repositories;
31827
31828
31829
31830
31831
31832 public function __construct(array $repositories)
31833 {
31834 $this->repositories = array();
31835 foreach ($repositories as $repo) {
31836 $this->addRepository($repo);
31837 }
31838 }
31839
31840
31841
31842
31843
31844
31845 public function getRepositories()
31846 {
31847 return $this->repositories;
31848 }
31849
31850
31851
31852
31853 public function hasPackage(PackageInterface $package)
31854 {
31855 foreach ($this->repositories as $repository) {
31856
31857 if ($repository->hasPackage($package)) {
31858 return true;
31859 }
31860 }
31861
31862 return false;
31863 }
31864
31865
31866
31867
31868 public function findPackage($name, $constraint)
31869 {
31870 foreach ($this->repositories as $repository) {
31871
31872 $package = $repository->findPackage($name, $constraint);
31873 if (null !== $package) {
31874 return $package;
31875 }
31876 }
31877
31878 return null;
31879 }
31880
31881
31882
31883
31884 public function findPackages($name, $constraint = null)
31885 {
31886 $packages = array();
31887 foreach ($this->repositories as $repository) {
31888
31889 $packages[] = $repository->findPackages($name, $constraint);
31890 }
31891
31892 return $packages ? call_user_func_array('array_merge', $packages) : array();
31893 }
31894
31895
31896
31897
31898 public function search($query, $mode = 0, $type = null)
31899 {
31900 $matches = array();
31901 foreach ($this->repositories as $repository) {
31902
31903 $matches[] = $repository->search($query, $mode, $type);
31904 }
31905
31906 return $matches ? call_user_func_array('array_merge', $matches) : array();
31907 }
31908
31909
31910
31911
31912 public function getPackages()
31913 {
31914 $packages = array();
31915 foreach ($this->repositories as $repository) {
31916
31917 $packages[] = $repository->getPackages();
31918 }
31919
31920 return $packages ? call_user_func_array('array_merge', $packages) : array();
31921 }
31922
31923
31924
31925
31926 public function removePackage(PackageInterface $package)
31927 {
31928 foreach ($this->repositories as $repository) {
31929
31930 $repository->removePackage($package);
31931 }
31932 }
31933
31934
31935
31936
31937 public function count()
31938 {
31939 $total = 0;
31940 foreach ($this->repositories as $repository) {
31941
31942 $total += $repository->count();
31943 }
31944
31945 return $total;
31946 }
31947
31948
31949
31950
31951
31952 public function addRepository(RepositoryInterface $repository)
31953 {
31954 if ($repository instanceof self) {
31955 foreach ($repository->getRepositories() as $repo) {
31956 $this->addRepository($repo);
31957 }
31958 } else {
31959 $this->repositories[] = $repository;
31960 }
31961 }
31962 }
31963 <?php
31964
31965
31966
31967
31968
31969
31970
31971
31972
31973
31974
31975 namespace Composer\Repository;
31976
31977
31978
31979
31980
31981
31982 interface ConfigurableRepositoryInterface
31983 {
31984 public function getRepoConfig();
31985 }
31986 <?php
31987
31988
31989
31990
31991
31992
31993
31994
31995
31996
31997
31998 namespace Composer\Repository;
31999
32000 use Composer\Json\JsonFile;
32001 use Composer\Package\Loader\ArrayLoader;
32002 use Composer\Package\Dumper\ArrayDumper;
32003
32004
32005
32006
32007
32008
32009
32010 class FilesystemRepository extends WritableArrayRepository
32011 {
32012 private $file;
32013
32014
32015
32016
32017
32018
32019 public function __construct(JsonFile $repositoryFile)
32020 {
32021 parent::__construct();
32022 $this->file = $repositoryFile;
32023 }
32024
32025
32026
32027
32028 protected function initialize()
32029 {
32030 parent::initialize();
32031
32032 if (!$this->file->exists()) {
32033 return;
32034 }
32035
32036 try {
32037 $packages = $this->file->read();
32038
32039 if (!is_array($packages)) {
32040 throw new \UnexpectedValueException('Could not parse package list from the repository');
32041 }
32042 } catch (\Exception $e) {
32043 throw new InvalidRepositoryException('Invalid repository data in '.$this->file->getPath().', packages could not be loaded: ['.get_class($e).'] '.$e->getMessage());
32044 }
32045
32046 $loader = new ArrayLoader(null, true);
32047 foreach ($packages as $packageData) {
32048 $package = $loader->load($packageData);
32049 $this->addPackage($package);
32050 }
32051 }
32052
32053 public function reload()
32054 {
32055 $this->packages = null;
32056 $this->initialize();
32057 }
32058
32059
32060
32061
32062 public function write()
32063 {
32064 $data = array();
32065 $dumper = new ArrayDumper();
32066
32067 foreach ($this->getCanonicalPackages() as $package) {
32068 $data[] = $dumper->dump($package);
32069 }
32070
32071 $this->file->write($data);
32072 }
32073 }
32074 <?php
32075
32076
32077
32078
32079
32080
32081
32082
32083
32084
32085
32086 namespace Composer\Repository;
32087
32088
32089
32090
32091
32092
32093
32094
32095 class InstalledArrayRepository extends WritableArrayRepository implements InstalledRepositoryInterface
32096 {
32097 }
32098 <?php
32099
32100
32101
32102
32103
32104
32105
32106
32107
32108
32109
32110 namespace Composer\Repository;
32111
32112
32113
32114
32115
32116
32117 class InstalledFilesystemRepository extends FilesystemRepository implements InstalledRepositoryInterface
32118 {
32119 }
32120 <?php
32121
32122
32123
32124
32125
32126
32127
32128
32129
32130
32131
32132 namespace Composer\Repository;
32133
32134
32135
32136
32137
32138
32139
32140
32141 interface InstalledRepositoryInterface extends WritableRepositoryInterface
32142 {
32143 }
32144 <?php
32145
32146
32147
32148
32149
32150
32151
32152
32153
32154
32155
32156 namespace Composer\Repository;
32157
32158
32159
32160
32161
32162
32163 class InvalidRepositoryException extends \Exception
32164 {
32165 }
32166 <?php
32167
32168
32169
32170
32171
32172
32173
32174
32175
32176
32177
32178 namespace Composer\Repository;
32179
32180 use Composer\Package\Loader\ArrayLoader;
32181 use Composer\Package\Loader\ValidatingArrayLoader;
32182
32183
32184
32185
32186
32187
32188 class PackageRepository extends ArrayRepository
32189 {
32190 private $config;
32191
32192
32193
32194
32195
32196
32197 public function __construct(array $config)
32198 {
32199 parent::__construct();
32200 $this->config = $config['package'];
32201
32202
32203  if (!is_numeric(key($this->config))) {
32204 $this->config = array($this->config);
32205 }
32206 }
32207
32208
32209
32210
32211 protected function initialize()
32212 {
32213 parent::initialize();
32214
32215 $loader = new ValidatingArrayLoader(new ArrayLoader(null, true), false);
32216 foreach ($this->config as $package) {
32217 try {
32218 $package = $loader->load($package);
32219 } catch (\Exception $e) {
32220 throw new InvalidRepositoryException('A repository of type "package" contains an invalid package definition: '.$e->getMessage()."\n\nInvalid package definition:\n".json_encode($package));
32221 }
32222
32223 $this->addPackage($package);
32224 }
32225 }
32226 }
32227 <?php
32228
32229
32230
32231
32232
32233
32234
32235
32236
32237
32238
32239 namespace Composer\Repository;
32240
32241 use Composer\Config;
32242 use Composer\IO\IOInterface;
32243 use Composer\Json\JsonFile;
32244 use Composer\Package\Loader\ArrayLoader;
32245 use Composer\Package\Version\VersionGuesser;
32246 use Composer\Package\Version\VersionParser;
32247 use Composer\Util\Platform;
32248 use Composer\Util\ProcessExecutor;
32249
32250
32251
32252
32253
32254
32255
32256
32257
32258
32259
32260
32261
32262
32263
32264
32265
32266
32267
32268
32269
32270
32271
32272
32273
32274
32275
32276
32277
32278
32279
32280
32281
32282
32283
32284
32285 class PathRepository extends ArrayRepository implements ConfigurableRepositoryInterface
32286 {
32287
32288
32289
32290 private $loader;
32291
32292
32293
32294
32295 private $versionGuesser;
32296
32297
32298
32299
32300 private $url;
32301
32302
32303
32304
32305 private $repoConfig;
32306
32307
32308
32309
32310 private $process;
32311
32312
32313
32314
32315 private $options;
32316
32317
32318
32319
32320
32321
32322
32323
32324 public function __construct(array $repoConfig, IOInterface $io, Config $config)
32325 {
32326 if (!isset($repoConfig['url'])) {
32327 throw new \RuntimeException('You must specify the `url` configuration for the path repository');
32328 }
32329
32330 $this->loader = new ArrayLoader(null, true);
32331 $this->url = Platform::expandPath($repoConfig['url']);
32332 $this->process = new ProcessExecutor($io);
32333 $this->versionGuesser = new VersionGuesser($config, $this->process, new VersionParser());
32334 $this->repoConfig = $repoConfig;
32335 $this->options = isset($repoConfig['options']) ? $repoConfig['options'] : array();
32336
32337 parent::__construct();
32338 }
32339
32340 public function getRepoConfig()
32341 {
32342 return $this->repoConfig;
32343 }
32344
32345
32346
32347
32348
32349
32350 protected function initialize()
32351 {
32352 parent::initialize();
32353
32354 foreach ($this->getUrlMatches() as $url) {
32355 $path = realpath($url) . DIRECTORY_SEPARATOR;
32356 $composerFilePath = $path.'composer.json';
32357
32358 if (!file_exists($composerFilePath)) {
32359 continue;
32360 }
32361
32362 $json = file_get_contents($composerFilePath);
32363 $package = JsonFile::parseJson($json, $composerFilePath);
32364 $package['dist'] = array(
32365 'type' => 'path',
32366 'url' => $url,
32367 'reference' => sha1($json . serialize($this->options)),
32368 );
32369 $package['transport-options'] = $this->options;
32370
32371 if (!isset($package['version'])) {
32372 $versionData = $this->versionGuesser->guessVersion($package, $path);
32373 $package['version'] = $versionData['version'] ?: 'dev-master';
32374 }
32375
32376 $output = '';
32377 if (is_dir($path . DIRECTORY_SEPARATOR . '.git') && 0 === $this->process->execute('git log -n1 --pretty=%H', $output, $path)) {
32378 $package['dist']['reference'] = trim($output);
32379 }
32380 $package = $this->loader->load($package);
32381 $this->addPackage($package);
32382 }
32383 }
32384
32385
32386
32387
32388
32389
32390 private function getUrlMatches()
32391 {
32392
32393  return array_map(function ($val) {
32394 return rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $val), '/');
32395 }, glob($this->url, GLOB_MARK | GLOB_ONLYDIR));
32396 }
32397 }
32398 <?php
32399
32400
32401
32402
32403
32404
32405
32406
32407
32408
32409
32410 namespace Composer\Repository\Pear;
32411
32412 use Composer\Util\RemoteFilesystem;
32413
32414
32415
32416
32417
32418
32419
32420
32421 abstract class BaseChannelReader
32422 {
32423
32424
32425
32426 const CHANNEL_NS = 'http://pear.php.net/channel-1.0';
32427 const ALL_CATEGORIES_NS = 'http://pear.php.net/dtd/rest.allcategories';
32428 const CATEGORY_PACKAGES_INFO_NS = 'http://pear.php.net/dtd/rest.categorypackageinfo';
32429 const ALL_PACKAGES_NS = 'http://pear.php.net/dtd/rest.allpackages';
32430 const ALL_RELEASES_NS = 'http://pear.php.net/dtd/rest.allreleases';
32431 const PACKAGE_INFO_NS = 'http://pear.php.net/dtd/rest.package';
32432
32433
32434 private $rfs;
32435
32436 protected function __construct(RemoteFilesystem $rfs)
32437 {
32438 $this->rfs = $rfs;
32439 }
32440
32441
32442
32443
32444
32445
32446
32447
32448
32449 protected function requestContent($origin, $path)
32450 {
32451 $url = rtrim($origin, '/') . '/' . ltrim($path, '/');
32452 $content = $this->rfs->getContents($origin, $url, false);
32453 if (!$content) {
32454 throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.');
32455 }
32456
32457 return str_replace('http://pear.php.net/rest/', 'https://pear.php.net/rest/', $content);
32458 }
32459
32460
32461
32462
32463
32464
32465
32466
32467
32468 protected function requestXml($origin, $path)
32469 {
32470
32471  $xml = simplexml_load_string($this->requestContent($origin, $path), "SimpleXMLElement", LIBXML_NOERROR);
32472
32473 if (false === $xml) {
32474 throw new \UnexpectedValueException(sprintf('The PEAR channel at ' . $origin . ' is broken. (Invalid XML at file `%s`)', $path));
32475 }
32476
32477 return $xml;
32478 }
32479 }
32480 <?php
32481
32482
32483
32484
32485
32486
32487
32488
32489
32490
32491
32492 namespace Composer\Repository\Pear;
32493
32494
32495
32496
32497
32498
32499 class ChannelInfo
32500 {
32501 private $name;
32502 private $alias;
32503 private $packages;
32504
32505
32506
32507
32508
32509
32510 public function __construct($name, $alias, array $packages)
32511 {
32512 $this->name = $name;
32513 $this->alias = $alias;
32514 $this->packages = $packages;
32515 }
32516
32517
32518
32519
32520
32521
32522 public function getName()
32523 {
32524 return $this->name;
32525 }
32526
32527
32528
32529
32530
32531
32532 public function getAlias()
32533 {
32534 return $this->alias;
32535 }
32536
32537
32538
32539
32540
32541
32542 public function getPackages()
32543 {
32544 return $this->packages;
32545 }
32546 }
32547 <?php
32548
32549
32550
32551
32552
32553
32554
32555
32556
32557
32558
32559 namespace Composer\Repository\Pear;
32560
32561 use Composer\Util\RemoteFilesystem;
32562
32563
32564
32565
32566
32567
32568
32569
32570 class ChannelReader extends BaseChannelReader
32571 {
32572
32573 private $readerMap;
32574
32575 public function __construct(RemoteFilesystem $rfs)
32576 {
32577 parent::__construct($rfs);
32578
32579 $rest10reader = new ChannelRest10Reader($rfs);
32580 $rest11reader = new ChannelRest11Reader($rfs);
32581
32582 $this->readerMap = array(
32583 'REST1.3' => $rest11reader,
32584 'REST1.2' => $rest11reader,
32585 'REST1.1' => $rest11reader,
32586 'REST1.0' => $rest10reader,
32587 );
32588 }
32589
32590
32591
32592
32593
32594
32595
32596
32597 public function read($url)
32598 {
32599 $xml = $this->requestXml($url, "/channel.xml");
32600
32601 $channelName = (string) $xml->name;
32602 $channelAlias = (string) $xml->suggestedalias;
32603
32604 $supportedVersions = array_keys($this->readerMap);
32605 $selectedRestVersion = $this->selectRestVersion($xml, $supportedVersions);
32606 if (!$selectedRestVersion) {
32607 throw new \UnexpectedValueException(sprintf('PEAR repository %s does not supports any of %s protocols.', $url, implode(', ', $supportedVersions)));
32608 }
32609
32610 $reader = $this->readerMap[$selectedRestVersion['version']];
32611 $packageDefinitions = $reader->read($selectedRestVersion['baseUrl']);
32612
32613 return new ChannelInfo($channelName, $channelAlias, $packageDefinitions);
32614 }
32615
32616
32617
32618
32619
32620
32621
32622
32623 private function selectRestVersion($channelXml, $supportedVersions)
32624 {
32625 $channelXml->registerXPathNamespace('ns', self::CHANNEL_NS);
32626
32627 foreach ($supportedVersions as $version) {
32628 $xpathTest = "ns:servers/ns:*/ns:rest/ns:baseurl[@type='{$version}']";
32629 $testResult = $channelXml->xpath($xpathTest);
32630
32631 foreach ($testResult as $result) {
32632
32633  $result = (string) $result;
32634 if (preg_match('{^https://}i', $result)) {
32635 return array('version' => $version, 'baseUrl' => $result);
32636 }
32637 }
32638
32639
32640  if (count($testResult) > 0) {
32641 return array('version' => $version, 'baseUrl' => (string) $testResult[0]);
32642 }
32643 }
32644
32645 return null;
32646 }
32647 }
32648 <?php
32649
32650
32651
32652
32653
32654
32655
32656
32657
32658
32659
32660 namespace Composer\Repository\Pear;
32661
32662 use Composer\Downloader\TransportException;
32663
32664
32665
32666
32667
32668
32669
32670
32671
32672
32673
32674
32675 class ChannelRest10Reader extends BaseChannelReader
32676 {
32677 private $dependencyReader;
32678
32679 public function __construct($rfs)
32680 {
32681 parent::__construct($rfs);
32682
32683 $this->dependencyReader = new PackageDependencyParser();
32684 }
32685
32686
32687
32688
32689
32690
32691
32692
32693 public function read($baseUrl)
32694 {
32695 return $this->readPackages($baseUrl);
32696 }
32697
32698
32699
32700
32701
32702
32703
32704
32705 private function readPackages($baseUrl)
32706 {
32707 $result = array();
32708
32709 $xmlPath = '/p/packages.xml';
32710 $xml = $this->requestXml($baseUrl, $xmlPath);
32711 $xml->registerXPathNamespace('ns', self::ALL_PACKAGES_NS);
32712 foreach ($xml->xpath('ns:p') as $node) {
32713 $packageName = (string) $node;
32714 $packageInfo = $this->readPackage($baseUrl, $packageName);
32715 $result[] = $packageInfo;
32716 }
32717
32718 return $result;
32719 }
32720
32721
32722
32723
32724
32725
32726
32727
32728
32729 private function readPackage($baseUrl, $packageName)
32730 {
32731 $xmlPath = '/p/' . strtolower($packageName) . '/info.xml';
32732 $xml = $this->requestXml($baseUrl, $xmlPath);
32733 $xml->registerXPathNamespace('ns', self::PACKAGE_INFO_NS);
32734
32735 $channelName = (string) $xml->c;
32736 $packageName = (string) $xml->n;
32737 $license = (string) $xml->l;
32738 $shortDescription = (string) $xml->s;
32739 $description = (string) $xml->d;
32740
32741 return new PackageInfo(
32742 $channelName,
32743 $packageName,
32744 $license,
32745 $shortDescription,
32746 $description,
32747 $this->readPackageReleases($baseUrl, $packageName)
32748 );
32749 }
32750
32751
32752
32753
32754
32755
32756
32757
32758
32759
32760 private function readPackageReleases($baseUrl, $packageName)
32761 {
32762 $result = array();
32763
32764 try {
32765 $xmlPath = '/r/' . strtolower($packageName) . '/allreleases.xml';
32766 $xml = $this->requestXml($baseUrl, $xmlPath);
32767 $xml->registerXPathNamespace('ns', self::ALL_RELEASES_NS);
32768 foreach ($xml->xpath('ns:r') as $node) {
32769 $releaseVersion = (string) $node->v;
32770 $releaseStability = (string) $node->s;
32771
32772 try {
32773 $result[$releaseVersion] = new ReleaseInfo(
32774 $releaseStability,
32775 $this->readPackageReleaseDependencies($baseUrl, $packageName, $releaseVersion)
32776 );
32777 } catch (TransportException $exception) {
32778 if ($exception->getCode() != 404) {
32779 throw $exception;
32780 }
32781 }
32782 }
32783 } catch (TransportException $exception) {
32784 if ($exception->getCode() != 404) {
32785 throw $exception;
32786 }
32787 }
32788
32789 return $result;
32790 }
32791
32792
32793
32794
32795
32796
32797
32798
32799
32800
32801 private function readPackageReleaseDependencies($baseUrl, $packageName, $version)
32802 {
32803 $dependencyReader = new PackageDependencyParser();
32804
32805 $depthPath = '/r/' . strtolower($packageName) . '/deps.' . $version . '.txt';
32806 $content = $this->requestContent($baseUrl, $depthPath);
32807 $dependencyArray = unserialize($content);
32808 $result = $dependencyReader->buildDependencyInfo($dependencyArray);
32809
32810 return $result;
32811 }
32812 }
32813 <?php
32814
32815
32816
32817
32818
32819
32820
32821
32822
32823
32824
32825 namespace Composer\Repository\Pear;
32826
32827
32828
32829
32830
32831
32832
32833
32834
32835
32836 class ChannelRest11Reader extends BaseChannelReader
32837 {
32838 private $dependencyReader;
32839
32840 public function __construct($rfs)
32841 {
32842 parent::__construct($rfs);
32843
32844 $this->dependencyReader = new PackageDependencyParser();
32845 }
32846
32847
32848
32849
32850
32851
32852
32853
32854 public function read($baseUrl)
32855 {
32856 return $this->readChannelPackages($baseUrl);
32857 }
32858
32859
32860
32861
32862
32863
32864
32865
32866 private function readChannelPackages($baseUrl)
32867 {
32868 $result = array();
32869
32870 $xml = $this->requestXml($baseUrl, "/c/categories.xml");
32871 $xml->registerXPathNamespace('ns', self::ALL_CATEGORIES_NS);
32872 foreach ($xml->xpath('ns:c') as $node) {
32873 $categoryName = (string) $node;
32874 $categoryPackages = $this->readCategoryPackages($baseUrl, $categoryName);
32875 $result = array_merge($result, $categoryPackages);
32876 }
32877
32878 return $result;
32879 }
32880
32881
32882
32883
32884
32885
32886
32887
32888
32889 private function readCategoryPackages($baseUrl, $categoryName)
32890 {
32891 $result = array();
32892
32893 $categoryPath = '/c/'.urlencode($categoryName).'/packagesinfo.xml';
32894 $xml = $this->requestXml($baseUrl, $categoryPath);
32895 $xml->registerXPathNamespace('ns', self::CATEGORY_PACKAGES_INFO_NS);
32896 foreach ($xml->xpath('ns:pi') as $node) {
32897 $packageInfo = $this->parsePackage($node);
32898 $result[] = $packageInfo;
32899 }
32900
32901 return $result;
32902 }
32903
32904
32905
32906
32907
32908
32909
32910 private function parsePackage($packageInfo)
32911 {
32912 $packageInfo->registerXPathNamespace('ns', self::CATEGORY_PACKAGES_INFO_NS);
32913 $channelName = (string) $packageInfo->p->c;
32914 $packageName = (string) $packageInfo->p->n;
32915 $license = (string) $packageInfo->p->l;
32916 $shortDescription = (string) $packageInfo->p->s;
32917 $description = (string) $packageInfo->p->d;
32918
32919 $dependencies = array();
32920 foreach ($packageInfo->xpath('ns:deps') as $node) {
32921 $dependencyVersion = (string) $node->v;
32922 $dependencyArray = unserialize((string) $node->d);
32923
32924 $dependencyInfo = $this->dependencyReader->buildDependencyInfo($dependencyArray);
32925
32926 $dependencies[$dependencyVersion] = $dependencyInfo;
32927 }
32928
32929 $releases = array();
32930 $releasesInfo = $packageInfo->xpath('ns:a/ns:r');
32931 if ($releasesInfo) {
32932 foreach ($releasesInfo as $node) {
32933 $releaseVersion = (string) $node->v;
32934 $releaseStability = (string) $node->s;
32935 $releases[$releaseVersion] = new ReleaseInfo(
32936 $releaseStability,
32937 isset($dependencies[$releaseVersion]) ? $dependencies[$releaseVersion] : new DependencyInfo(array(), array())
32938 );
32939 }
32940 }
32941
32942 return new PackageInfo(
32943 $channelName,
32944 $packageName,
32945 $license,
32946 $shortDescription,
32947 $description,
32948 $releases
32949 );
32950 }
32951 }
32952 <?php
32953
32954
32955
32956
32957
32958
32959
32960
32961
32962
32963
32964 namespace Composer\Repository\Pear;
32965
32966
32967
32968
32969
32970
32971 class DependencyConstraint
32972 {
32973 private $type;
32974 private $constraint;
32975 private $channelName;
32976 private $packageName;
32977
32978
32979
32980
32981
32982
32983
32984 public function __construct($type, $constraint, $channelName, $packageName)
32985 {
32986 $this->type = $type;
32987 $this->constraint = $constraint;
32988 $this->channelName = $channelName;
32989 $this->packageName = $packageName;
32990 }
32991
32992 public function getChannelName()
32993 {
32994 return $this->channelName;
32995 }
32996
32997 public function getConstraint()
32998 {
32999 return $this->constraint;
33000 }
33001
33002 public function getPackageName()
33003 {
33004 return $this->packageName;
33005 }
33006
33007 public function getType()
33008 {
33009 return $this->type;
33010 }
33011 }
33012 <?php
33013
33014
33015
33016
33017
33018
33019
33020
33021
33022
33023
33024 namespace Composer\Repository\Pear;
33025
33026
33027
33028
33029
33030
33031 class DependencyInfo
33032 {
33033 private $requires;
33034 private $optionals;
33035
33036
33037
33038
33039
33040 public function __construct($requires, $optionals)
33041 {
33042 $this->requires = $requires;
33043 $this->optionals = $optionals;
33044 }
33045
33046
33047
33048
33049 public function getRequires()
33050 {
33051 return $this->requires;
33052 }
33053
33054
33055
33056
33057 public function getOptionals()
33058 {
33059 return $this->optionals;
33060 }
33061 }
33062 <?php
33063
33064
33065
33066
33067
33068
33069
33070
33071
33072
33073
33074 namespace Composer\Repository\Pear;
33075
33076
33077
33078
33079
33080
33081 class PackageDependencyParser
33082 {
33083
33084
33085
33086
33087
33088
33089 public function buildDependencyInfo($depArray)
33090 {
33091 if (!is_array($depArray)) {
33092 return new DependencyInfo(array(), array());
33093 }
33094 if (!$this->isHash($depArray)) {
33095 return new DependencyInfo($this->buildDependency10Info($depArray), array());
33096 }
33097
33098 return $this->buildDependency20Info($depArray);
33099 }
33100
33101
33102
33103
33104
33105
33106
33107
33108
33109
33110
33111
33112
33113 private function buildDependency10Info($depArray)
33114 {
33115 static $dep10toOperatorMap = array('has' => '==', 'eq' => '==', 'ge' => '>=', 'gt' => '>', 'le' => '<=', 'lt' => '<', 'not' => '!=');
33116
33117 $result = array();
33118
33119 foreach ($depArray as $depItem) {
33120 if (empty($depItem['rel']) || !array_key_exists($depItem['rel'], $dep10toOperatorMap)) {
33121
33122  continue;
33123 }
33124
33125 $depType = !empty($depItem['optional']) && 'yes' == $depItem['optional']
33126 ? 'optional'
33127 : 'required';
33128 $depType = 'not' == $depItem['rel']
33129 ? 'conflicts'
33130 : $depType;
33131
33132 $depVersion = !empty($depItem['version']) ? $this->parseVersion($depItem['version']) : '*';
33133
33134
33135  $depVersionConstraint = ('has' == $depItem['rel'] || 'not' == $depItem['rel']) && '*' == $depVersion
33136 ? '*'
33137 : $dep10toOperatorMap[$depItem['rel']] . $depVersion;
33138
33139 switch ($depItem['type']) {
33140 case 'php':
33141 $depChannelName = 'php';
33142 $depPackageName = '';
33143 break;
33144 case 'pkg':
33145 $depChannelName = !empty($depItem['channel']) ? $depItem['channel'] : 'pear.php.net';
33146 $depPackageName = $depItem['name'];
33147 break;
33148 case 'ext':
33149 $depChannelName = 'ext';
33150 $depPackageName = $depItem['name'];
33151 break;
33152 case 'os':
33153 case 'sapi':
33154 $depChannelName = '';
33155 $depPackageName = '';
33156 break;
33157 default:
33158 $depChannelName = '';
33159 $depPackageName = '';
33160 break;
33161 }
33162
33163 if ('' != $depChannelName) {
33164 $result[] = new DependencyConstraint(
33165 $depType,
33166 $depVersionConstraint,
33167 $depChannelName,
33168 $depPackageName
33169 );
33170 }
33171 }
33172
33173 return $result;
33174 }
33175
33176
33177
33178
33179
33180
33181
33182 private function buildDependency20Info($depArray)
33183 {
33184 $result = array();
33185 $optionals = array();
33186 $defaultOptionals = array();
33187 foreach ($depArray as $depType => $depTypeGroup) {
33188 if (!is_array($depTypeGroup)) {
33189 continue;
33190 }
33191 if ('required' == $depType || 'optional' == $depType) {
33192 foreach ($depTypeGroup as $depItemType => $depItem) {
33193 switch ($depItemType) {
33194 case 'php':
33195 $result[] = new DependencyConstraint(
33196 $depType,
33197 $this->parse20VersionConstraint($depItem),
33198 'php',
33199 ''
33200 );
33201 break;
33202 case 'package':
33203 $deps = $this->buildDepPackageConstraints($depItem, $depType);
33204 $result = array_merge($result, $deps);
33205 break;
33206 case 'extension':
33207 $deps = $this->buildDepExtensionConstraints($depItem, $depType);
33208 $result = array_merge($result, $deps);
33209 break;
33210 case 'subpackage':
33211 $deps = $this->buildDepPackageConstraints($depItem, 'replaces');
33212 $defaultOptionals += $deps;
33213 break;
33214 case 'os':
33215 case 'pearinstaller':
33216 break;
33217 default:
33218 break;
33219 }
33220 }
33221 } elseif ('group' == $depType) {
33222 if ($this->isHash($depTypeGroup)) {
33223 $depTypeGroup = array($depTypeGroup);
33224 }
33225
33226 foreach ($depTypeGroup as $depItem) {
33227 $groupName = $depItem['attribs']['name'];
33228 if (!isset($optionals[$groupName])) {
33229 $optionals[$groupName] = array();
33230 }
33231
33232 if (isset($depItem['subpackage'])) {
33233 $optionals[$groupName] += $this->buildDepPackageConstraints($depItem['subpackage'], 'replaces');
33234 } else {
33235 $result += $this->buildDepPackageConstraints($depItem['package'], 'optional');
33236 }
33237 }
33238 }
33239 }
33240
33241 if (count($defaultOptionals) > 0) {
33242 $optionals['*'] = $defaultOptionals;
33243 }
33244
33245 return new DependencyInfo($result, $optionals);
33246 }
33247
33248
33249
33250
33251
33252
33253
33254
33255 private function buildDepExtensionConstraints($depItem, $depType)
33256 {
33257 if ($this->isHash($depItem)) {
33258 $depItem = array($depItem);
33259 }
33260
33261 $result = array();
33262 foreach ($depItem as $subDepItem) {
33263 $depChannelName = 'ext';
33264 $depPackageName = $subDepItem['name'];
33265 $depVersionConstraint = $this->parse20VersionConstraint($subDepItem);
33266
33267 $result[] = new DependencyConstraint(
33268 $depType,
33269 $depVersionConstraint,
33270 $depChannelName,
33271 $depPackageName
33272 );
33273 }
33274
33275 return $result;
33276 }
33277
33278
33279
33280
33281
33282
33283
33284
33285 private function buildDepPackageConstraints($depItem, $depType)
33286 {
33287 if ($this->isHash($depItem)) {
33288 $depItem = array($depItem);
33289 }
33290
33291 $result = array();
33292 foreach ($depItem as $subDepItem) {
33293 if (!array_key_exists('channel', $subDepItem)) {
33294 $subDepItem['channel'] = $subDepItem['uri'];
33295 }
33296 $depChannelName = $subDepItem['channel'];
33297 $depPackageName = $subDepItem['name'];
33298 $depVersionConstraint = $this->parse20VersionConstraint($subDepItem);
33299 if (isset($subDepItem['conflicts'])) {
33300 $depType = 'conflicts';
33301 }
33302
33303 $result[] = new DependencyConstraint(
33304 $depType,
33305 $depVersionConstraint,
33306 $depChannelName,
33307 $depPackageName
33308 );
33309 }
33310
33311 return $result;
33312 }
33313
33314
33315
33316
33317
33318
33319
33320 private function parse20VersionConstraint(array $data)
33321 {
33322 static $dep20toOperatorMap = array('has' => '==', 'min' => '>=', 'max' => '<=', 'exclude' => '!=');
33323
33324 $versions = array();
33325 $values = array_intersect_key($data, $dep20toOperatorMap);
33326 if (0 == count($values)) {
33327 return '*';
33328 }
33329 if (isset($values['min']) && isset($values['exclude']) && $data['min'] == $data['exclude']) {
33330 $versions[] = '>' . $this->parseVersion($values['min']);
33331 } elseif (isset($values['max']) && isset($values['exclude']) && $data['max'] == $data['exclude']) {
33332 $versions[] = '<' . $this->parseVersion($values['max']);
33333 } else {
33334 foreach ($values as $op => $version) {
33335 if ('exclude' == $op && is_array($version)) {
33336 foreach ($version as $versionPart) {
33337 $versions[] = $dep20toOperatorMap[$op] . $this->parseVersion($versionPart);
33338 }
33339 } else {
33340 $versions[] = $dep20toOperatorMap[$op] . $this->parseVersion($version);
33341 }
33342 }
33343 }
33344
33345 return implode(',', $versions);
33346 }
33347
33348
33349
33350
33351
33352
33353
33354 private function parseVersion($version)
33355 {
33356 if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?}i', $version, $matches)) {
33357 $version = $matches[1]
33358 .(!empty($matches[2]) ? $matches[2] : '.0')
33359 .(!empty($matches[3]) ? $matches[3] : '.0')
33360 .(!empty($matches[4]) ? $matches[4] : '.0');
33361
33362 return $version;
33363 }
33364
33365 return null;
33366 }
33367
33368
33369
33370
33371
33372
33373
33374 private function isHash(array $array)
33375 {
33376 return !array_key_exists(1, $array) && !array_key_exists(0, $array);
33377 }
33378 }
33379 <?php
33380
33381
33382
33383
33384
33385
33386
33387
33388
33389
33390
33391 namespace Composer\Repository\Pear;
33392
33393
33394
33395
33396
33397
33398 class PackageInfo
33399 {
33400 private $channelName;
33401 private $packageName;
33402 private $license;
33403 private $shortDescription;
33404 private $description;
33405 private $releases;
33406
33407
33408
33409
33410
33411
33412
33413
33414
33415 public function __construct($channelName, $packageName, $license, $shortDescription, $description, $releases)
33416 {
33417 $this->channelName = $channelName;
33418 $this->packageName = $packageName;
33419 $this->license = $license;
33420 $this->shortDescription = $shortDescription;
33421 $this->description = $description;
33422 $this->releases = $releases;
33423 }
33424
33425
33426
33427
33428 public function getChannelName()
33429 {
33430 return $this->channelName;
33431 }
33432
33433
33434
33435
33436 public function getPackageName()
33437 {
33438 return $this->packageName;
33439 }
33440
33441
33442
33443
33444 public function getDescription()
33445 {
33446 return $this->description;
33447 }
33448
33449
33450
33451
33452 public function getShortDescription()
33453 {
33454 return $this->shortDescription;
33455 }
33456
33457
33458
33459
33460 public function getLicense()
33461 {
33462 return $this->license;
33463 }
33464
33465
33466
33467
33468 public function getReleases()
33469 {
33470 return $this->releases;
33471 }
33472 }
33473 <?php
33474
33475
33476
33477
33478
33479
33480
33481
33482
33483
33484
33485 namespace Composer\Repository\Pear;
33486
33487
33488
33489
33490
33491
33492 class ReleaseInfo
33493 {
33494 private $stability;
33495 private $dependencyInfo;
33496
33497
33498
33499
33500
33501 public function __construct($stability, $dependencyInfo)
33502 {
33503 $this->stability = $stability;
33504 $this->dependencyInfo = $dependencyInfo;
33505 }
33506
33507
33508
33509
33510 public function getDependencyInfo()
33511 {
33512 return $this->dependencyInfo;
33513 }
33514
33515
33516
33517
33518 public function getStability()
33519 {
33520 return $this->stability;
33521 }
33522 }
33523 <?php
33524
33525
33526
33527
33528
33529
33530
33531
33532
33533
33534
33535 namespace Composer\Repository;
33536
33537 use Composer\IO\IOInterface;
33538 use Composer\Semver\VersionParser as SemverVersionParser;
33539 use Composer\Package\Version\VersionParser;
33540 use Composer\Repository\Pear\ChannelReader;
33541 use Composer\Package\CompletePackage;
33542 use Composer\Repository\Pear\ChannelInfo;
33543 use Composer\EventDispatcher\EventDispatcher;
33544 use Composer\Package\Link;
33545 use Composer\Semver\Constraint\Constraint;
33546 use Composer\Util\RemoteFilesystem;
33547 use Composer\Config;
33548 use Composer\Factory;
33549
33550
33551
33552
33553
33554
33555
33556
33557
33558
33559 class PearRepository extends ArrayRepository implements ConfigurableRepositoryInterface
33560 {
33561 private $url;
33562 private $io;
33563 private $rfs;
33564 private $versionParser;
33565 private $repoConfig;
33566
33567
33568
33569
33570 private $vendorAlias;
33571
33572 public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, RemoteFilesystem $rfs = null)
33573 {
33574 parent::__construct();
33575 if (!preg_match('{^https?://}', $repoConfig['url'])) {
33576 $repoConfig['url'] = 'http://'.$repoConfig['url'];
33577 }
33578
33579 $urlBits = parse_url($repoConfig['url']);
33580 if (empty($urlBits['scheme']) || empty($urlBits['host'])) {
33581 throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$repoConfig['url']);
33582 }
33583
33584 $this->url = rtrim($repoConfig['url'], '/');
33585 $this->io = $io;
33586 $this->rfs = $rfs ?: Factory::createRemoteFilesystem($this->io, $config);
33587 $this->vendorAlias = isset($repoConfig['vendor-alias']) ? $repoConfig['vendor-alias'] : null;
33588 $this->versionParser = new VersionParser();
33589 $this->repoConfig = $repoConfig;
33590 }
33591
33592 public function getRepoConfig()
33593 {
33594 return $this->repoConfig;
33595 }
33596
33597 protected function initialize()
33598 {
33599 parent::initialize();
33600
33601 $this->io->writeError('Initializing PEAR repository '.$this->url);
33602
33603 $reader = new ChannelReader($this->rfs);
33604 try {
33605 $channelInfo = $reader->read($this->url);
33606 } catch (\Exception $e) {
33607 $this->io->writeError('<warning>PEAR repository from '.$this->url.' could not be loaded. '.$e->getMessage().'</warning>');
33608
33609 return;
33610 }
33611 $packages = $this->buildComposerPackages($channelInfo, $this->versionParser);
33612 foreach ($packages as $package) {
33613 $this->addPackage($package);
33614 }
33615 }
33616
33617
33618
33619
33620
33621
33622
33623
33624 private function buildComposerPackages(ChannelInfo $channelInfo, SemverVersionParser $versionParser)
33625 {
33626 $result = array();
33627 foreach ($channelInfo->getPackages() as $packageDefinition) {
33628 foreach ($packageDefinition->getReleases() as $version => $releaseInfo) {
33629 try {
33630 $normalizedVersion = $versionParser->normalize($version);
33631 } catch (\UnexpectedValueException $e) {
33632 $this->io->writeError('Could not load '.$packageDefinition->getPackageName().' '.$version.': '.$e->getMessage(), true, IOInterface::VERBOSE);
33633 continue;
33634 }
33635
33636 $composerPackageName = $this->buildComposerPackageName($packageDefinition->getChannelName(), $packageDefinition->getPackageName());
33637
33638
33639  
33640  $urlBits = parse_url($this->url);
33641 $scheme = (isset($urlBits['scheme']) && 'https' === $urlBits['scheme'] && extension_loaded('openssl')) ? 'https' : 'http';
33642 $distUrl = "{$scheme}://{$packageDefinition->getChannelName()}/get/{$packageDefinition->getPackageName()}-{$version}.tgz";
33643
33644 $requires = array();
33645 $suggests = array();
33646 $conflicts = array();
33647 $replaces = array();
33648
33649
33650  
33651  if ($channelInfo->getName() == $packageDefinition->getChannelName()) {
33652 $composerPackageAlias = $this->buildComposerPackageName($channelInfo->getAlias(), $packageDefinition->getPackageName());
33653 $aliasConstraint = new Constraint('==', $normalizedVersion);
33654 $replaces[] = new Link($composerPackageName, $composerPackageAlias, $aliasConstraint, 'replaces', (string) $aliasConstraint);
33655 }
33656
33657
33658  if (!empty($this->vendorAlias)
33659 && ($this->vendorAlias != 'pear-'.$channelInfo->getAlias() || $channelInfo->getName() != $packageDefinition->getChannelName())
33660 ) {
33661 $composerPackageAlias = "{$this->vendorAlias}/{$packageDefinition->getPackageName()}";
33662 $aliasConstraint = new Constraint('==', $normalizedVersion);
33663 $replaces[] = new Link($composerPackageName, $composerPackageAlias, $aliasConstraint, 'replaces', (string) $aliasConstraint);
33664 }
33665
33666 foreach ($releaseInfo->getDependencyInfo()->getRequires() as $dependencyConstraint) {
33667 $dependencyPackageName = $this->buildComposerPackageName($dependencyConstraint->getChannelName(), $dependencyConstraint->getPackageName());
33668 $constraint = $versionParser->parseConstraints($dependencyConstraint->getConstraint());
33669 $link = new Link($composerPackageName, $dependencyPackageName, $constraint, $dependencyConstraint->getType(), $dependencyConstraint->getConstraint());
33670 switch ($dependencyConstraint->getType()) {
33671 case 'required':
33672 $requires[] = $link;
33673 break;
33674 case 'conflicts':
33675 $conflicts[] = $link;
33676 break;
33677 case 'replaces':
33678 $replaces[] = $link;
33679 break;
33680 }
33681 }
33682
33683 foreach ($releaseInfo->getDependencyInfo()->getOptionals() as $group => $dependencyConstraints) {
33684 foreach ($dependencyConstraints as $dependencyConstraint) {
33685 $dependencyPackageName = $this->buildComposerPackageName($dependencyConstraint->getChannelName(), $dependencyConstraint->getPackageName());
33686 $suggests[$group.'-'.$dependencyPackageName] = $dependencyConstraint->getConstraint();
33687 }
33688 }
33689
33690 $package = new CompletePackage($composerPackageName, $normalizedVersion, $version);
33691 $package->setType('pear-library');
33692 $package->setDescription($packageDefinition->getDescription());
33693 $package->setLicense(array($packageDefinition->getLicense()));
33694 $package->setDistType('file');
33695 $package->setDistUrl($distUrl);
33696 $package->setAutoload(array('classmap' => array('')));
33697 $package->setIncludePaths(array('/'));
33698 $package->setRequires($requires);
33699 $package->setConflicts($conflicts);
33700 $package->setSuggests($suggests);
33701 $package->setReplaces($replaces);
33702 $result[] = $package;
33703 }
33704 }
33705
33706 return $result;
33707 }
33708
33709 private function buildComposerPackageName($channelName, $packageName)
33710 {
33711 if ('php' === $channelName) {
33712 return "php";
33713 }
33714 if ('ext' === $channelName) {
33715 return "ext-{$packageName}";
33716 }
33717
33718 return "pear-{$channelName}/{$packageName}";
33719 }
33720 }
33721 <?php
33722
33723
33724
33725
33726
33727
33728
33729
33730
33731
33732
33733 namespace Composer\Repository;
33734
33735 use Composer\XdebugHandler;
33736 use Composer\Package\CompletePackage;
33737 use Composer\Package\PackageInterface;
33738 use Composer\Package\Version\VersionParser;
33739 use Composer\Plugin\PluginInterface;
33740 use Composer\Util\Silencer;
33741
33742
33743
33744
33745 class PlatformRepository extends ArrayRepository
33746 {
33747 const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[^/]+)$}i';
33748
33749 private $versionParser;
33750
33751
33752
33753
33754
33755
33756
33757
33758 private $overrides = array();
33759
33760 public function __construct(array $packages = array(), array $overrides = array())
33761 {
33762 foreach ($overrides as $name => $version) {
33763 $this->overrides[strtolower($name)] = array('name' => $name, 'version' => $version);
33764 }
33765 parent::__construct($packages);
33766 }
33767
33768 protected function initialize()
33769 {
33770 parent::initialize();
33771
33772 $this->versionParser = new VersionParser();
33773
33774
33775  
33776  foreach ($this->overrides as $override) {
33777
33778  if (!preg_match(self::PLATFORM_PACKAGE_REGEX, $override['name'])) {
33779 throw new \InvalidArgumentException('Invalid platform package name in config.platform: '.$override['name']);
33780 }
33781
33782 $this->addOverriddenPackage($override);
33783 }
33784
33785 $prettyVersion = PluginInterface::PLUGIN_API_VERSION;
33786 $version = $this->versionParser->normalize($prettyVersion);
33787 $composerPluginApi = new CompletePackage('composer-plugin-api', $version, $prettyVersion);
33788 $composerPluginApi->setDescription('The Composer Plugin API');
33789 $this->addPackage($composerPluginApi);
33790
33791 try {
33792 $prettyVersion = PHP_VERSION;
33793 $version = $this->versionParser->normalize($prettyVersion);
33794 } catch (\UnexpectedValueException $e) {
33795 $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', PHP_VERSION);
33796 $version = $this->versionParser->normalize($prettyVersion);
33797 }
33798
33799 $php = new CompletePackage('php', $version, $prettyVersion);
33800 $php->setDescription('The PHP interpreter');
33801 $this->addPackage($php);
33802
33803 if (PHP_DEBUG) {
33804 $phpdebug = new CompletePackage('php-debug', $version, $prettyVersion);
33805 $phpdebug->setDescription('The PHP interpreter, with debugging symbols');
33806 $this->addPackage($phpdebug);
33807 }
33808
33809 if (defined('PHP_ZTS') && PHP_ZTS) {
33810 $phpzts = new CompletePackage('php-zts', $version, $prettyVersion);
33811 $phpzts->setDescription('The PHP interpreter, with Zend Thread Safety');
33812 $this->addPackage($phpzts);
33813 }
33814
33815 if (PHP_INT_SIZE === 8) {
33816 $php64 = new CompletePackage('php-64bit', $version, $prettyVersion);
33817 $php64->setDescription('The PHP interpreter, 64bit');
33818 $this->addPackage($php64);
33819 }
33820
33821
33822  
33823  if (defined('AF_INET6') || Silencer::call('inet_pton', '::') !== false) {
33824 $phpIpv6 = new CompletePackage('php-ipv6', $version, $prettyVersion);
33825 $phpIpv6->setDescription('The PHP interpreter, with IPv6 support');
33826 $this->addPackage($phpIpv6);
33827 }
33828
33829 $loadedExtensions = get_loaded_extensions();
33830
33831
33832  foreach ($loadedExtensions as $name) {
33833 if (in_array($name, array('standard', 'Core'))) {
33834 continue;
33835 }
33836
33837 $reflExt = new \ReflectionExtension($name);
33838 $prettyVersion = $reflExt->getVersion();
33839 $this->addExtension($name, $prettyVersion);
33840 }
33841
33842
33843  if (!in_array('xdebug', $loadedExtensions, true) && ($prettyVersion = strval(getenv(XdebugHandler::ENV_VERSION)))) {
33844 $this->addExtension('xdebug', $prettyVersion);
33845 }
33846
33847
33848  
33849  
33850  foreach ($loadedExtensions as $name) {
33851 $prettyVersion = null;
33852 $description = 'The '.$name.' PHP library';
33853 switch ($name) {
33854 case 'curl':
33855 $curlVersion = curl_version();
33856 $prettyVersion = $curlVersion['version'];
33857 break;
33858
33859 case 'iconv':
33860 $prettyVersion = ICONV_VERSION;
33861 break;
33862
33863 case 'intl':
33864 $name = 'ICU';
33865 if (defined('INTL_ICU_VERSION')) {
33866 $prettyVersion = INTL_ICU_VERSION;
33867 } else {
33868 $reflector = new \ReflectionExtension('intl');
33869
33870 ob_start();
33871 $reflector->info();
33872 $output = ob_get_clean();
33873
33874 preg_match('/^ICU version => (.*)$/m', $output, $matches);
33875 $prettyVersion = $matches[1];
33876 }
33877
33878 break;
33879
33880 case 'libxml':
33881 $prettyVersion = LIBXML_DOTTED_VERSION;
33882 break;
33883
33884 case 'openssl':
33885 $prettyVersion = preg_replace_callback('{^(?:OpenSSL|LibreSSL)?\s*([0-9.]+)([a-z]*).*}i', function ($match) {
33886 if (empty($match[2])) {
33887 return $match[1];
33888 }
33889
33890
33891  
33892
33893 if (!preg_match('{^z*[a-z]$}', $match[2])) {
33894
33895  return 0;
33896 }
33897
33898 $len = strlen($match[2]);
33899 $patchVersion = ($len - 1) * 26; 
33900  $patchVersion += ord($match[2][$len - 1]) - 96;
33901
33902 return $match[1].'.'.$patchVersion;
33903 }, OPENSSL_VERSION_TEXT);
33904
33905 $description = OPENSSL_VERSION_TEXT;
33906 break;
33907
33908 case 'pcre':
33909 $prettyVersion = preg_replace('{^(\S+).*}', '$1', PCRE_VERSION);
33910 break;
33911
33912 case 'uuid':
33913 $prettyVersion = phpversion('uuid');
33914 break;
33915
33916 case 'xsl':
33917 $prettyVersion = LIBXSLT_DOTTED_VERSION;
33918 break;
33919
33920 default:
33921
33922  continue 2;
33923 }
33924
33925 try {
33926 $version = $this->versionParser->normalize($prettyVersion);
33927 } catch (\UnexpectedValueException $e) {
33928 continue;
33929 }
33930
33931 $lib = new CompletePackage('lib-'.$name, $version, $prettyVersion);
33932 $lib->setDescription($description);
33933 $this->addPackage($lib);
33934 }
33935
33936 if (defined('HHVM_VERSION')) {
33937 try {
33938 $prettyVersion = HHVM_VERSION;
33939 $version = $this->versionParser->normalize($prettyVersion);
33940 } catch (\UnexpectedValueException $e) {
33941 $prettyVersion = preg_replace('#^([^~+-]+).*$#', '$1', HHVM_VERSION);
33942 $version = $this->versionParser->normalize($prettyVersion);
33943 }
33944
33945 $hhvm = new CompletePackage('hhvm', $version, $prettyVersion);
33946 $hhvm->setDescription('The HHVM Runtime (64bit)');
33947 $this->addPackage($hhvm);
33948 }
33949 }
33950
33951
33952
33953
33954 public function addPackage(PackageInterface $package)
33955 {
33956
33957  if (isset($this->overrides[$package->getName()])) {
33958 $overrider = $this->findPackage($package->getName(), '*');
33959 $overrider->setDescription($overrider->getDescription().' (actual: '.$package->getPrettyVersion().')');
33960
33961 return;
33962 }
33963
33964
33965  if (isset($this->overrides['php']) && 0 === strpos($package->getName(), 'php-')) {
33966 $overrider = $this->addOverriddenPackage($this->overrides['php'], $package->getPrettyName());
33967 $overrider->setDescription($overrider->getDescription().' (actual: '.$package->getPrettyVersion().')');
33968
33969 return;
33970 }
33971
33972 parent::addPackage($package);
33973 }
33974
33975 private function addOverriddenPackage(array $override, $name = null)
33976 {
33977 $version = $this->versionParser->normalize($override['version']);
33978 $package = new CompletePackage($name ?: $override['name'], $version, $override['version']);
33979 $package->setDescription('Package overridden via config.platform');
33980 $package->setExtra(array('config.platform' => true));
33981 parent::addPackage($package);
33982
33983 return $package;
33984 }
33985
33986
33987
33988
33989
33990
33991
33992 private function addExtension($name, $prettyVersion)
33993 {
33994 $extraDescription = null;
33995
33996 try {
33997 $version = $this->versionParser->normalize($prettyVersion);
33998 } catch (\UnexpectedValueException $e) {
33999 $extraDescription = ' (actual version: '.$prettyVersion.')';
34000 if (preg_match('{^(\d+\.\d+\.\d+(?:\.\d+)?)}', $prettyVersion, $match)) {
34001 $prettyVersion = $match[1];
34002 } else {
34003 $prettyVersion = '0';
34004 }
34005 $version = $this->versionParser->normalize($prettyVersion);
34006 }
34007
34008 $packageName = $this->buildPackageName($name);
34009 $ext = new CompletePackage($packageName, $version, $prettyVersion);
34010 $ext->setDescription('The '.$name.' PHP extension'.$extraDescription);
34011 $this->addPackage($ext);
34012 }
34013
34014 private function buildPackageName($name)
34015 {
34016 return 'ext-' . str_replace(' ', '-', $name);
34017 }
34018 }
34019 <?php
34020
34021
34022
34023
34024
34025
34026
34027
34028
34029
34030
34031 namespace Composer\Repository;
34032
34033 use Composer\Factory;
34034 use Composer\IO\IOInterface;
34035 use Composer\Config;
34036 use Composer\EventDispatcher\EventDispatcher;
34037 use Composer\Util\RemoteFilesystem;
34038 use Composer\Json\JsonFile;
34039
34040
34041
34042
34043 class RepositoryFactory
34044 {
34045
34046
34047
34048
34049
34050
34051
34052 public static function configFromString(IOInterface $io, Config $config, $repository, $allowFilesystem = false)
34053 {
34054 if (0 === strpos($repository, 'http')) {
34055 $repoConfig = array('type' => 'composer', 'url' => $repository);
34056 } elseif ("json" === pathinfo($repository, PATHINFO_EXTENSION)) {
34057 $json = new JsonFile($repository, Factory::createRemoteFilesystem($io, $config));
34058 $data = $json->read();
34059 if (!empty($data['packages']) || !empty($data['includes']) || !empty($data['provider-includes'])) {
34060 $repoConfig = array('type' => 'composer', 'url' => 'file://' . strtr(realpath($repository), '\\', '/'));
34061 } elseif ($allowFilesystem) {
34062 $repoConfig = array('type' => 'filesystem', 'json' => $json);
34063 } else {
34064 throw new \InvalidArgumentException("Invalid repository URL ($repository) given. This file does not contain a valid composer repository.");
34065 }
34066 } elseif ('{' === substr($repository, 0, 1)) {
34067
34068  $repoConfig = JsonFile::parseJson($repository);
34069 } else {
34070 throw new \InvalidArgumentException("Invalid repository url ($repository) given. Has to be a .json file, an http url or a JSON object.");
34071 }
34072
34073 return $repoConfig;
34074 }
34075
34076
34077
34078
34079
34080
34081
34082
34083 public static function fromString(IOInterface $io, Config $config, $repository, $allowFilesystem = false)
34084 {
34085 $repoConfig = static::configFromString($io, $config, $repository, $allowFilesystem);
34086
34087 return static::createRepo($io, $config, $repoConfig);
34088 }
34089
34090
34091
34092
34093
34094
34095
34096 public static function createRepo(IOInterface $io, Config $config, array $repoConfig)
34097 {
34098 $rm = static::manager($io, $config, null, Factory::createRemoteFilesystem($io, $config));
34099 $repos = static::createRepos($rm, array($repoConfig));
34100
34101 return reset($repos);
34102 }
34103
34104
34105
34106
34107
34108
34109
34110 public static function defaultRepos(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null)
34111 {
34112 if (!$config) {
34113 $config = Factory::createConfig($io);
34114 }
34115 if (!$rm) {
34116 if (!$io) {
34117 throw new \InvalidArgumentException('This function requires either an IOInterface or a RepositoryManager');
34118 }
34119 $rm = static::manager($io, $config, null, Factory::createRemoteFilesystem($io, $config));
34120 }
34121
34122 return static::createRepos($rm, $config->getRepositories());
34123 }
34124
34125
34126
34127
34128
34129
34130
34131
34132 public static function manager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
34133 {
34134 $rm = new RepositoryManager($io, $config, $eventDispatcher, $rfs);
34135 $rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository');
34136 $rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository');
34137 $rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository');
34138 $rm->setRepositoryClass('pear', 'Composer\Repository\PearRepository');
34139 $rm->setRepositoryClass('git', 'Composer\Repository\VcsRepository');
34140 $rm->setRepositoryClass('gitlab', 'Composer\Repository\VcsRepository');
34141 $rm->setRepositoryClass('svn', 'Composer\Repository\VcsRepository');
34142 $rm->setRepositoryClass('fossil', 'Composer\Repository\VcsRepository');
34143 $rm->setRepositoryClass('perforce', 'Composer\Repository\VcsRepository');
34144 $rm->setRepositoryClass('hg', 'Composer\Repository\VcsRepository');
34145 $rm->setRepositoryClass('artifact', 'Composer\Repository\ArtifactRepository');
34146 $rm->setRepositoryClass('path', 'Composer\Repository\PathRepository');
34147
34148 return $rm;
34149 }
34150
34151
34152
34153
34154 private static function createRepos(RepositoryManager $rm, array $repoConfigs)
34155 {
34156 $repos = array();
34157
34158 foreach ($repoConfigs as $index => $repo) {
34159 if (is_string($repo)) {
34160 throw new \UnexpectedValueException('"repositories" should be an array of repository definitions, only a single repository was given');
34161 }
34162 if (!is_array($repo)) {
34163 throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') should be an array, '.gettype($repo).' given');
34164 }
34165 if (!isset($repo['type'])) {
34166 throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') must have a type defined');
34167 }
34168 $name = is_int($index) && isset($repo['url']) ? preg_replace('{^https?://}i', '', $repo['url']) : $index;
34169 while (isset($repos[$name])) {
34170 $name .= '2';
34171 }
34172 if ($repo['type'] === 'filesystem') {
34173 $repos[$name] = new FilesystemRepository($repo['json']);
34174 } else {
34175 $repos[$name] = $rm->createRepository($repo['type'], $repo, $index);
34176 }
34177 }
34178
34179 return $repos;
34180 }
34181 }
34182 <?php
34183
34184
34185
34186
34187
34188
34189
34190
34191
34192
34193
34194 namespace Composer\Repository;
34195
34196 use Composer\Package\PackageInterface;
34197
34198
34199
34200
34201
34202
34203
34204
34205 interface RepositoryInterface extends \Countable
34206 {
34207 const SEARCH_FULLTEXT = 0;
34208 const SEARCH_NAME = 1;
34209
34210
34211
34212
34213
34214
34215
34216
34217 public function hasPackage(PackageInterface $package);
34218
34219
34220
34221
34222
34223
34224
34225
34226
34227 public function findPackage($name, $constraint);
34228
34229
34230
34231
34232
34233
34234
34235
34236
34237 public function findPackages($name, $constraint = null);
34238
34239
34240
34241
34242
34243
34244 public function getPackages();
34245
34246
34247
34248
34249
34250
34251
34252
34253
34254 public function search($query, $mode = 0);
34255 }
34256 <?php
34257
34258
34259
34260
34261
34262
34263
34264
34265
34266
34267
34268 namespace Composer\Repository;
34269
34270 use Composer\IO\IOInterface;
34271 use Composer\Config;
34272 use Composer\EventDispatcher\EventDispatcher;
34273 use Composer\Package\PackageInterface;
34274 use Composer\Util\RemoteFilesystem;
34275
34276
34277
34278
34279
34280
34281
34282
34283 class RepositoryManager
34284 {
34285 private $localRepository;
34286 private $repositories = array();
34287 private $repositoryClasses = array();
34288 private $io;
34289 private $config;
34290 private $eventDispatcher;
34291 private $rfs;
34292
34293 public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null)
34294 {
34295 $this->io = $io;
34296 $this->config = $config;
34297 $this->eventDispatcher = $eventDispatcher;
34298 $this->rfs = $rfs;
34299 }
34300
34301
34302
34303
34304
34305
34306
34307
34308
34309 public function findPackage($name, $constraint)
34310 {
34311 foreach ($this->repositories as $repository) {
34312 if ($package = $repository->findPackage($name, $constraint)) {
34313 return $package;
34314 }
34315 }
34316
34317 return null;
34318 }
34319
34320
34321
34322
34323
34324
34325
34326
34327
34328 public function findPackages($name, $constraint)
34329 {
34330 $packages = array();
34331
34332 foreach ($this->repositories as $repository) {
34333 $packages = array_merge($packages, $repository->findPackages($name, $constraint));
34334 }
34335
34336 return $packages;
34337 }
34338
34339
34340
34341
34342
34343
34344 public function addRepository(RepositoryInterface $repository)
34345 {
34346 $this->repositories[] = $repository;
34347 }
34348
34349
34350
34351
34352
34353
34354
34355
34356 public function prependRepository(RepositoryInterface $repository)
34357 {
34358 array_unshift($this->repositories, $repository);
34359 }
34360
34361
34362
34363
34364
34365
34366
34367
34368
34369
34370 public function createRepository($type, $config, $name = null)
34371 {
34372 if (!isset($this->repositoryClasses[$type])) {
34373 throw new \InvalidArgumentException('Repository type is not registered: '.$type);
34374 }
34375
34376 if (isset($config['packagist']) && false === $config['packagist']) {
34377 $this->io->writeError('<warning>Repository "'.$name.'" ('.json_encode($config).') has a packagist key which should be in its own repository definition</warning>');
34378 }
34379
34380 $class = $this->repositoryClasses[$type];
34381
34382 $reflMethod = new \ReflectionMethod($class, '__construct');
34383 $params = $reflMethod->getParameters();
34384 if (isset($params[4]) && $params[4]->getClass() && $params[4]->getClass()->getName() === 'Composer\Util\RemoteFilesystem') {
34385 return new $class($config, $this->io, $this->config, $this->eventDispatcher, $this->rfs);
34386 }
34387
34388 return new $class($config, $this->io, $this->config, $this->eventDispatcher);
34389 }
34390
34391
34392
34393
34394
34395
34396
34397 public function setRepositoryClass($type, $class)
34398 {
34399 $this->repositoryClasses[$type] = $class;
34400 }
34401
34402
34403
34404
34405
34406
34407 public function getRepositories()
34408 {
34409 return $this->repositories;
34410 }
34411
34412
34413
34414
34415
34416
34417 public function setLocalRepository(WritableRepositoryInterface $repository)
34418 {
34419 $this->localRepository = $repository;
34420 }
34421
34422
34423
34424
34425
34426
34427 public function getLocalRepository()
34428 {
34429 return $this->localRepository;
34430 }
34431 }
34432 <?php
34433
34434
34435
34436
34437
34438
34439
34440
34441
34442
34443
34444 namespace Composer\Repository;
34445
34446
34447
34448
34449
34450
34451 class RepositorySecurityException extends \Exception
34452 {
34453 }
34454 <?php
34455
34456
34457
34458
34459
34460
34461
34462
34463
34464
34465
34466 namespace Composer\Repository\Vcs;
34467
34468 use Composer\Cache;
34469 use Composer\Downloader\TransportException;
34470 use Composer\Json\JsonFile;
34471 use Composer\Util\Bitbucket;
34472
34473 abstract class BitbucketDriver extends VcsDriver
34474 {
34475
34476 protected $cache;
34477 protected $owner;
34478 protected $repository;
34479 protected $hasIssues;
34480 protected $rootIdentifier;
34481 protected $tags;
34482 protected $branches;
34483 protected $infoCache = array();
34484 protected $branchesUrl = '';
34485 protected $tagsUrl = '';
34486 protected $homeUrl = '';
34487 protected $website = '';
34488 protected $cloneHttpsUrl = '';
34489
34490
34491
34492
34493 protected $fallbackDriver;
34494
34495 protected $vcsType;
34496
34497
34498
34499
34500 public function initialize()
34501 {
34502 preg_match('#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)$#', $this->url, $match);
34503 $this->owner = $match[1];
34504 $this->repository = $match[2];
34505 $this->originUrl = 'bitbucket.org';
34506 $this->cache = new Cache(
34507 $this->io,
34508 implode('/', array(
34509 $this->config->get('cache-repo-dir'),
34510 $this->originUrl,
34511 $this->owner,
34512 $this->repository,
34513 ))
34514 );
34515 }
34516
34517
34518
34519
34520 public function getUrl()
34521 {
34522 if ($this->fallbackDriver) {
34523 return $this->fallbackDriver->getUrl();
34524 }
34525
34526 return $this->cloneHttpsUrl;
34527 }
34528
34529
34530
34531
34532
34533
34534
34535 protected function getRepoData()
34536 {
34537 $resource = sprintf(
34538 'https://api.bitbucket.org/2.0/repositories/%s/%s?%s',
34539 $this->owner,
34540 $this->repository,
34541 http_build_query(
34542 array('fields' => '-project,-owner'),
34543 null,
34544 '&'
34545 )
34546 );
34547
34548 $repoData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource, true), $resource);
34549 if ($this->fallbackDriver) {
34550 return false;
34551 }
34552 $this->parseCloneUrls($repoData['links']['clone']);
34553
34554 $this->hasIssues = !empty($repoData['has_issues']);
34555 $this->branchesUrl = $repoData['links']['branches']['href'];
34556 $this->tagsUrl = $repoData['links']['tags']['href'];
34557 $this->homeUrl = $repoData['links']['html']['href'];
34558 $this->website = $repoData['website'];
34559 $this->vcsType = $repoData['scm'];
34560
34561 return true;
34562 }
34563
34564
34565
34566
34567 public function getComposerInformation($identifier)
34568 {
34569 if ($this->fallbackDriver) {
34570 return $this->fallbackDriver->getComposerInformation($identifier);
34571 }
34572
34573 if (!isset($this->infoCache[$identifier])) {
34574 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
34575 return $this->infoCache[$identifier] = JsonFile::parseJson($res);
34576 }
34577
34578 $composer = $this->getBaseComposerInformation($identifier);
34579
34580
34581  if (!isset($composer['support']['source'])) {
34582 $label = array_search(
34583 $identifier,
34584 $this->getTags()
34585 ) ?: array_search(
34586 $identifier,
34587 $this->getBranches()
34588 ) ?: $identifier;
34589
34590 if (array_key_exists($label, $tags = $this->getTags())) {
34591 $hash = $tags[$label];
34592 } elseif (array_key_exists($label, $branches = $this->getBranches())) {
34593 $hash = $branches[$label];
34594 }
34595
34596 if (! isset($hash)) {
34597 $composer['support']['source'] = sprintf(
34598 'https://%s/%s/%s/src',
34599 $this->originUrl,
34600 $this->owner,
34601 $this->repository
34602 );
34603 } else {
34604 $composer['support']['source'] = sprintf(
34605 'https://%s/%s/%s/src/%s/?at=%s',
34606 $this->originUrl,
34607 $this->owner,
34608 $this->repository,
34609 $hash,
34610 $label
34611 );
34612 }
34613 }
34614 if (!isset($composer['support']['issues']) && $this->hasIssues) {
34615 $composer['support']['issues'] = sprintf(
34616 'https://%s/%s/%s/issues',
34617 $this->originUrl,
34618 $this->owner,
34619 $this->repository
34620 );
34621 }
34622 if (!isset($composer['homepage'])) {
34623 $composer['homepage'] = empty($this->website) ? $this->homeUrl : $this->website;
34624 }
34625
34626 $this->infoCache[$identifier] = $composer;
34627
34628 if ($this->shouldCache($identifier)) {
34629 $this->cache->write($identifier, json_encode($composer));
34630 }
34631 }
34632
34633 return $this->infoCache[$identifier];
34634 }
34635
34636
34637
34638
34639 public function getFileContent($file, $identifier)
34640 {
34641 if ($this->fallbackDriver) {
34642 return $this->fallbackDriver->getFileContent($file, $identifier);
34643 }
34644
34645 $resource = sprintf(
34646 'https://api.bitbucket.org/1.0/repositories/%s/%s/raw/%s/%s',
34647 $this->owner,
34648 $this->repository,
34649 $identifier,
34650 $file
34651 );
34652
34653 return $this->getContentsWithOAuthCredentials($resource);
34654 }
34655
34656
34657
34658
34659 public function getChangeDate($identifier)
34660 {
34661 if ($this->fallbackDriver) {
34662 return $this->fallbackDriver->getChangeDate($identifier);
34663 }
34664
34665 $resource = sprintf(
34666 'https://api.bitbucket.org/2.0/repositories/%s/%s/commit/%s?fields=date',
34667 $this->owner,
34668 $this->repository,
34669 $identifier
34670 );
34671 $commit = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
34672
34673 return new \DateTime($commit['date']);
34674 }
34675
34676
34677
34678
34679 public function getSource($identifier)
34680 {
34681 if ($this->fallbackDriver) {
34682 return $this->fallbackDriver->getSource($identifier);
34683 }
34684
34685 return array('type' => $this->vcsType, 'url' => $this->getUrl(), 'reference' => $identifier);
34686 }
34687
34688
34689
34690
34691 public function getDist($identifier)
34692 {
34693 if ($this->fallbackDriver) {
34694 return $this->fallbackDriver->getDist($identifier);
34695 }
34696
34697 $url = sprintf(
34698 'https://bitbucket.org/%s/%s/get/%s.zip',
34699 $this->owner,
34700 $this->repository,
34701 $identifier
34702 );
34703
34704 return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => '');
34705 }
34706
34707
34708
34709
34710 public function getTags()
34711 {
34712 if ($this->fallbackDriver) {
34713 return $this->fallbackDriver->getTags();
34714 }
34715
34716 if (null === $this->tags) {
34717 $this->tags = array();
34718 $resource = sprintf(
34719 '%s?%s',
34720 $this->tagsUrl,
34721 http_build_query(
34722 array(
34723 'pagelen' => 100,
34724 'fields' => 'values.name,values.target.hash,next',
34725 'sort' => '-target.date',
34726 ),
34727 null,
34728 '&'
34729 )
34730 );
34731 $hasNext = true;
34732 while ($hasNext) {
34733 $tagsData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
34734 foreach ($tagsData['values'] as $data) {
34735 $this->tags[$data['name']] = $data['target']['hash'];
34736 }
34737 if (empty($tagsData['next'])) {
34738 $hasNext = false;
34739 } else {
34740 $resource = $tagsData['next'];
34741 }
34742 }
34743 if ($this->vcsType === 'hg') {
34744 unset($this->tags['tip']);
34745 }
34746 }
34747
34748 return $this->tags;
34749 }
34750
34751
34752
34753
34754 public function getBranches()
34755 {
34756 if ($this->fallbackDriver) {
34757 return $this->fallbackDriver->getBranches();
34758 }
34759
34760 if (null === $this->branches) {
34761 $this->branches = array();
34762 $resource = sprintf(
34763 '%s?%s',
34764 $this->branchesUrl,
34765 http_build_query(
34766 array(
34767 'pagelen' => 100,
34768 'fields' => 'values.name,values.target.hash,next',
34769 'sort' => '-target.date',
34770 ),
34771 null,
34772 '&'
34773 )
34774 );
34775 $hasNext = true;
34776 while ($hasNext) {
34777 $branchData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
34778 foreach ($branchData['values'] as $data) {
34779 $this->branches[$data['name']] = $data['target']['hash'];
34780 }
34781 if (empty($branchData['next'])) {
34782 $hasNext = false;
34783 } else {
34784 $resource = $branchData['next'];
34785 }
34786 }
34787 }
34788
34789 return $this->branches;
34790 }
34791
34792
34793
34794
34795
34796
34797
34798
34799
34800 protected function getContentsWithOAuthCredentials($url, $fetchingRepoData = false)
34801 {
34802 try {
34803 return parent::getContents($url);
34804 } catch (TransportException $e) {
34805 $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->remoteFilesystem);
34806
34807 if (403 === $e->getCode() || (401 === $e->getCode() && strpos($e->getMessage(), 'Could not authenticate against') === 0)) {
34808 if (!$this->io->hasAuthentication($this->originUrl)
34809 && $bitbucketUtil->authorizeOAuth($this->originUrl)
34810 ) {
34811 return parent::getContents($url);
34812 }
34813
34814 if (!$this->io->isInteractive() && $fetchingRepoData) {
34815 return $this->attemptCloneFallback();
34816 }
34817 }
34818
34819 throw $e;
34820 }
34821 }
34822
34823
34824
34825
34826
34827
34828 abstract protected function generateSshUrl();
34829
34830 protected function attemptCloneFallback()
34831 {
34832 try {
34833 $this->setupFallbackDriver($this->generateSshUrl());
34834 } catch (\RuntimeException $e) {
34835 $this->fallbackDriver = null;
34836
34837 $this->io->writeError(
34838 '<error>Failed to clone the ' . $this->generateSshUrl() . ' repository, try running in interactive mode'
34839 . ' so that you can enter your Bitbucket OAuth consumer credentials</error>'
34840 );
34841 throw $e;
34842 }
34843 }
34844
34845
34846
34847
34848
34849 abstract protected function setupFallbackDriver($url);
34850
34851
34852
34853
34854
34855 protected function parseCloneUrls(array $cloneLinks)
34856 {
34857 foreach ($cloneLinks as $cloneLink) {
34858 if ($cloneLink['name'] === 'https') {
34859
34860  
34861  $this->cloneHttpsUrl = preg_replace('/https:\/\/([^@]+@)?/', 'https://', $cloneLink['href']);
34862 }
34863 }
34864 }
34865
34866
34867
34868
34869 protected function getMainBranchData()
34870 {
34871 $resource = sprintf(
34872 'https://api.bitbucket.org/1.0/repositories/%s/%s/main-branch',
34873 $this->owner,
34874 $this->repository
34875 );
34876
34877 return JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
34878 }
34879 }
34880 <?php
34881
34882
34883
34884
34885
34886
34887
34888
34889
34890
34891
34892 namespace Composer\Repository\Vcs;
34893
34894 use Composer\Config;
34895 use Composer\Util\ProcessExecutor;
34896 use Composer\Util\Filesystem;
34897 use Composer\IO\IOInterface;
34898
34899
34900
34901
34902 class FossilDriver extends VcsDriver
34903 {
34904 protected $tags;
34905 protected $branches;
34906 protected $rootIdentifier;
34907 protected $repoFile;
34908 protected $checkoutDir;
34909 protected $infoCache = array();
34910
34911
34912
34913
34914 public function initialize()
34915 {
34916 if (Filesystem::isLocalPath($this->url)) {
34917 $this->checkoutDir = $this->url;
34918 } else {
34919 $this->repoFile = $this->config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '.fossil';
34920 $this->checkoutDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '/';
34921
34922 $fs = new Filesystem();
34923 $fs->ensureDirectoryExists($this->checkoutDir);
34924
34925 if (!is_writable(dirname($this->checkoutDir))) {
34926 throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.$this->checkoutDir.'" directory is not writable by the current user.');
34927 }
34928
34929
34930  $this->config->prohibitUrlByConfig($this->url, $this->io);
34931
34932
34933  if (is_file($this->repoFile) && is_dir($this->checkoutDir) && 0 === $this->process->execute('fossil info', $output, $this->checkoutDir)) {
34934 if (0 !== $this->process->execute('fossil pull', $output, $this->checkoutDir)) {
34935 $this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')</error>');
34936 }
34937 } else {
34938
34939  $fs->removeDirectory($this->checkoutDir);
34940 $fs->remove($this->repoFile);
34941
34942 $fs->ensureDirectoryExists($this->checkoutDir);
34943
34944 if (0 !== $this->process->execute(sprintf('fossil clone %s %s', ProcessExecutor::escape($this->url), ProcessExecutor::escape($this->repoFile)), $output)) {
34945 $output = $this->process->getErrorOutput();
34946
34947 if (0 !== $this->process->execute('fossil version', $ignoredOutput)) {
34948 throw new \RuntimeException('Failed to clone '.$this->url.', fossil was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput());
34949 }
34950
34951 throw new \RuntimeException('Failed to clone '.$this->url.' to repository ' . $this->repoFile . "\n\n" .$output);
34952 }
34953
34954 if (0 !== $this->process->execute(sprintf('fossil open %s', ProcessExecutor::escape($this->repoFile)), $output, $this->checkoutDir)) {
34955 $output = $this->process->getErrorOutput();
34956
34957 throw new \RuntimeException('Failed to open repository '.$this->repoFile.' in ' . $this->checkoutDir . "\n\n" .$output);
34958 }
34959 }
34960 }
34961
34962 $this->getTags();
34963 $this->getBranches();
34964 }
34965
34966
34967
34968
34969 public function getRootIdentifier()
34970 {
34971 if (null === $this->rootIdentifier) {
34972 $this->rootIdentifier = 'trunk';
34973 }
34974
34975 return $this->rootIdentifier;
34976 }
34977
34978
34979
34980
34981 public function getUrl()
34982 {
34983 return $this->url;
34984 }
34985
34986
34987
34988
34989 public function getSource($identifier)
34990 {
34991 return array('type' => 'fossil', 'url' => $this->getUrl(), 'reference' => $identifier);
34992 }
34993
34994
34995
34996
34997 public function getDist($identifier)
34998 {
34999 return null;
35000 }
35001
35002
35003
35004
35005 public function getFileContent($file, $identifier)
35006 {
35007 $command = sprintf('fossil cat -r %s %s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
35008 $this->process->execute($command, $content, $this->checkoutDir);
35009
35010 if (!trim($content)) {
35011 return null;
35012 }
35013
35014 return $content;
35015 }
35016
35017
35018
35019
35020 public function getChangeDate($identifier)
35021 {
35022 $this->process->execute(sprintf('fossil finfo composer.json | head -n 2 | tail -n 1 | awk \'{print $1}\''), $output, $this->checkoutDir);
35023
35024 return new \DateTime(trim($output), new \DateTimeZone('UTC'));
35025 }
35026
35027
35028
35029
35030 public function getTags()
35031 {
35032 if (null === $this->tags) {
35033 $tags = array();
35034
35035 $this->process->execute('fossil tag list', $output, $this->checkoutDir);
35036 foreach ($this->process->splitLines($output) as $tag) {
35037 $tags[$tag] = $tag;
35038 }
35039
35040 $this->tags = $tags;
35041 }
35042
35043 return $this->tags;
35044 }
35045
35046
35047
35048
35049 public function getBranches()
35050 {
35051 if (null === $this->branches) {
35052 $branches = array();
35053 $bookmarks = array();
35054
35055 $this->process->execute('fossil branch list', $output, $this->checkoutDir);
35056 foreach ($this->process->splitLines($output) as $branch) {
35057 $branch = trim(preg_replace('/^\*/', '', trim($branch)));
35058 $branches[$branch] = $branch;
35059 }
35060
35061 $this->branches = $branches;
35062 }
35063
35064 return $this->branches;
35065 }
35066
35067
35068
35069
35070 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
35071 {
35072 if (preg_match('#(^(?:https?|ssh)://(?:[^@]@)?(?:chiselapp\.com|fossil\.))#i', $url)) {
35073 return true;
35074 }
35075
35076 if (preg_match('!/fossil/|\.fossil!', $url)) {
35077 return true;
35078 }
35079
35080
35081  if (Filesystem::isLocalPath($url)) {
35082 $url = Filesystem::getPlatformPath($url);
35083 if (!is_dir($url)) {
35084 return false;
35085 }
35086
35087 $process = new ProcessExecutor();
35088
35089  if ($process->execute('fossil info', $output, $url) === 0) {
35090 return true;
35091 }
35092 }
35093
35094 return false;
35095 }
35096 }
35097 <?php
35098
35099
35100
35101
35102
35103
35104
35105
35106
35107
35108
35109 namespace Composer\Repository\Vcs;
35110
35111 use Composer\Config;
35112 use Composer\IO\IOInterface;
35113
35114
35115
35116
35117 class GitBitbucketDriver extends BitbucketDriver
35118 {
35119
35120
35121
35122 public function getRootIdentifier()
35123 {
35124 if ($this->fallbackDriver) {
35125 return $this->fallbackDriver->getRootIdentifier();
35126 }
35127
35128 if (null === $this->rootIdentifier) {
35129 if (! $this->getRepoData()) {
35130 return $this->fallbackDriver->getRootIdentifier();
35131 }
35132
35133 if ($this->vcsType !== 'git') {
35134 throw new \RuntimeException(
35135 $this->url.' does not appear to be a git repository, use '.
35136 $this->cloneHttpsUrl.' if this is a mercurial bitbucket repository'
35137 );
35138 }
35139
35140 $mainBranchData = $this->getMainBranchData();
35141 $this->rootIdentifier = !empty($mainBranchData['name']) ? $mainBranchData['name'] : 'master';
35142 }
35143
35144 return $this->rootIdentifier;
35145 }
35146
35147
35148
35149
35150 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
35151 {
35152 if (!preg_match('#^https?://bitbucket\.org/([^/]+)/(.+?)\.git$#', $url)) {
35153 return false;
35154 }
35155
35156 if (!extension_loaded('openssl')) {
35157 $io->writeError('Skipping Bitbucket git driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
35158
35159 return false;
35160 }
35161
35162 return true;
35163 }
35164
35165
35166
35167
35168 protected function setupFallbackDriver($url)
35169 {
35170 $this->fallbackDriver = new GitDriver(
35171 array('url' => $url),
35172 $this->io,
35173 $this->config,
35174 $this->process,
35175 $this->remoteFilesystem
35176 );
35177 $this->fallbackDriver->initialize();
35178 }
35179
35180
35181
35182
35183 protected function generateSshUrl()
35184 {
35185 return 'git@' . $this->originUrl . ':' . $this->owner.'/'.$this->repository.'.git';
35186 }
35187 }
35188 <?php
35189
35190
35191
35192
35193
35194
35195
35196
35197
35198
35199
35200 namespace Composer\Repository\Vcs;
35201
35202 use Composer\Util\ProcessExecutor;
35203 use Composer\Util\Filesystem;
35204 use Composer\Util\Git as GitUtil;
35205 use Composer\IO\IOInterface;
35206 use Composer\Cache;
35207 use Composer\Config;
35208
35209
35210
35211
35212 class GitDriver extends VcsDriver
35213 {
35214 protected $cache;
35215 protected $tags;
35216 protected $branches;
35217 protected $rootIdentifier;
35218 protected $repoDir;
35219 protected $infoCache = array();
35220
35221
35222
35223
35224 public function initialize()
35225 {
35226 if (Filesystem::isLocalPath($this->url)) {
35227 $this->url = preg_replace('{[\\/]\.git/?$}', '', $this->url);
35228 $this->repoDir = $this->url;
35229 $cacheUrl = realpath($this->url);
35230 } else {
35231 $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
35232
35233 GitUtil::cleanEnv();
35234
35235 $fs = new Filesystem();
35236 $fs->ensureDirectoryExists(dirname($this->repoDir));
35237
35238 if (!is_writable(dirname($this->repoDir))) {
35239 throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.dirname($this->repoDir).'" directory is not writable by the current user.');
35240 }
35241
35242 if (preg_match('{^ssh://[^@]+@[^:]+:[^0-9]+}', $this->url)) {
35243 throw new \InvalidArgumentException('The source URL '.$this->url.' is invalid, ssh URLs should have a port number after ":".'."\n".'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
35244 }
35245
35246 $gitUtil = new GitUtil($this->io, $this->config, $this->process, $fs);
35247 if (!$gitUtil->syncMirror($this->url, $this->repoDir)) {
35248 $this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated</error>');
35249 }
35250
35251 $cacheUrl = $this->url;
35252 }
35253
35254 $this->getTags();
35255 $this->getBranches();
35256
35257 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $cacheUrl));
35258 }
35259
35260
35261
35262
35263 public function getRootIdentifier()
35264 {
35265 if (null === $this->rootIdentifier) {
35266 $this->rootIdentifier = 'master';
35267
35268
35269  $this->process->execute('git branch --no-color', $output, $this->repoDir);
35270 $branches = $this->process->splitLines($output);
35271 if (!in_array('* master', $branches)) {
35272 foreach ($branches as $branch) {
35273 if ($branch && preg_match('{^\* +(\S+)}', $branch, $match)) {
35274 $this->rootIdentifier = $match[1];
35275 break;
35276 }
35277 }
35278 }
35279 }
35280
35281 return $this->rootIdentifier;
35282 }
35283
35284
35285
35286
35287 public function getUrl()
35288 {
35289 return $this->url;
35290 }
35291
35292
35293
35294
35295 public function getSource($identifier)
35296 {
35297 return array('type' => 'git', 'url' => $this->getUrl(), 'reference' => $identifier);
35298 }
35299
35300
35301
35302
35303 public function getDist($identifier)
35304 {
35305 return null;
35306 }
35307
35308
35309
35310
35311 public function getFileContent($file, $identifier)
35312 {
35313 $resource = sprintf('%s:%s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
35314 $this->process->execute(sprintf('git show %s', $resource), $content, $this->repoDir);
35315
35316 if (!trim($content)) {
35317 return null;
35318 }
35319
35320 return $content;
35321 }
35322
35323
35324
35325
35326 public function getChangeDate($identifier)
35327 {
35328 $this->process->execute(sprintf(
35329 'git log -1 --format=%%at %s',
35330 ProcessExecutor::escape($identifier)
35331 ), $output, $this->repoDir);
35332
35333 return new \DateTime('@'.trim($output), new \DateTimeZone('UTC'));
35334 }
35335
35336
35337
35338
35339 public function getTags()
35340 {
35341 if (null === $this->tags) {
35342 $this->tags = array();
35343
35344 $this->process->execute('git show-ref --tags --dereference', $output, $this->repoDir);
35345 foreach ($output = $this->process->splitLines($output) as $tag) {
35346 if ($tag && preg_match('{^([a-f0-9]{40}) refs/tags/(\S+?)(\^\{\})?$}', $tag, $match)) {
35347 $this->tags[$match[2]] = $match[1];
35348 }
35349 }
35350 }
35351
35352 return $this->tags;
35353 }
35354
35355
35356
35357
35358 public function getBranches()
35359 {
35360 if (null === $this->branches) {
35361 $branches = array();
35362
35363 $this->process->execute('git branch --no-color --no-abbrev -v', $output, $this->repoDir);
35364 foreach ($this->process->splitLines($output) as $branch) {
35365 if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
35366 if (preg_match('{^(?:\* )? *(\S+) *([a-f0-9]+)(?: .*)?$}', $branch, $match)) {
35367 $branches[$match[1]] = $match[2];
35368 }
35369 }
35370 }
35371
35372 $this->branches = $branches;
35373 }
35374
35375 return $this->branches;
35376 }
35377
35378
35379
35380
35381 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
35382 {
35383 if (preg_match('#(^git://|\.git/?$|git(?:olite)?@|//git\.|//github.com/)#i', $url)) {
35384 return true;
35385 }
35386
35387
35388  if (Filesystem::isLocalPath($url)) {
35389 $url = Filesystem::getPlatformPath($url);
35390 if (!is_dir($url)) {
35391 return false;
35392 }
35393
35394 $process = new ProcessExecutor($io);
35395
35396  if ($process->execute('git tag', $output, $url) === 0) {
35397 return true;
35398 }
35399 }
35400
35401 if (!$deep) {
35402 return false;
35403 }
35404
35405 $process = new ProcessExecutor($io);
35406 if ($process->execute('git ls-remote --heads ' . ProcessExecutor::escape($url), $output) === 0) {
35407 return true;
35408 }
35409
35410 return false;
35411 }
35412 }
35413 <?php
35414
35415
35416
35417
35418
35419
35420
35421
35422
35423
35424
35425 namespace Composer\Repository\Vcs;
35426
35427 use Composer\Config;
35428 use Composer\Downloader\TransportException;
35429 use Composer\Json\JsonFile;
35430 use Composer\Cache;
35431 use Composer\IO\IOInterface;
35432 use Composer\Util\GitHub;
35433
35434
35435
35436
35437 class GitHubDriver extends VcsDriver
35438 {
35439 protected $cache;
35440 protected $owner;
35441 protected $repository;
35442 protected $tags;
35443 protected $branches;
35444 protected $rootIdentifier;
35445 protected $repoData;
35446 protected $hasIssues;
35447 protected $infoCache = array();
35448 protected $isPrivate = false;
35449
35450
35451
35452
35453
35454
35455 protected $gitDriver;
35456
35457
35458
35459
35460 public function initialize()
35461 {
35462 preg_match('#^(?:(?:https?|git)://([^/]+)/|git@([^:]+):)([^/]+)/(.+?)(?:\.git|/)?$#', $this->url, $match);
35463 $this->owner = $match[3];
35464 $this->repository = $match[4];
35465 $this->originUrl = !empty($match[1]) ? $match[1] : $match[2];
35466 if ($this->originUrl === 'www.github.com') {
35467 $this->originUrl = 'github.com';
35468 }
35469 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->owner.'/'.$this->repository);
35470
35471 if (isset($this->repoConfig['no-api']) && $this->repoConfig['no-api']) {
35472 $this->setupGitDriver($this->url);
35473
35474 return;
35475 }
35476
35477 $this->fetchRootIdentifier();
35478 }
35479
35480 public function getRepositoryUrl()
35481 {
35482 return 'https://'.$this->originUrl.'/'.$this->owner.'/'.$this->repository;
35483 }
35484
35485
35486
35487
35488 public function getRootIdentifier()
35489 {
35490 if ($this->gitDriver) {
35491 return $this->gitDriver->getRootIdentifier();
35492 }
35493
35494 return $this->rootIdentifier;
35495 }
35496
35497
35498
35499
35500 public function getUrl()
35501 {
35502 if ($this->gitDriver) {
35503 return $this->gitDriver->getUrl();
35504 }
35505
35506 return 'https://' . $this->originUrl . '/'.$this->owner.'/'.$this->repository.'.git';
35507 }
35508
35509
35510
35511
35512 protected function getApiUrl()
35513 {
35514 if ('github.com' === $this->originUrl) {
35515 $apiUrl = 'api.github.com';
35516 } else {
35517 $apiUrl = $this->originUrl . '/api/v3';
35518 }
35519
35520 return 'https://' . $apiUrl;
35521 }
35522
35523
35524
35525
35526 public function getSource($identifier)
35527 {
35528 if ($this->gitDriver) {
35529 return $this->gitDriver->getSource($identifier);
35530 }
35531 if ($this->isPrivate) {
35532
35533  
35534  $url = $this->generateSshUrl();
35535 } else {
35536 $url = $this->getUrl();
35537 }
35538
35539 return array('type' => 'git', 'url' => $url, 'reference' => $identifier);
35540 }
35541
35542
35543
35544
35545 public function getDist($identifier)
35546 {
35547 $url = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/zipball/'.$identifier;
35548
35549 return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => '');
35550 }
35551
35552
35553
35554
35555 public function getComposerInformation($identifier)
35556 {
35557 if ($this->gitDriver) {
35558 return $this->gitDriver->getComposerInformation($identifier);
35559 }
35560
35561 if (!isset($this->infoCache[$identifier])) {
35562 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
35563 return $this->infoCache[$identifier] = JsonFile::parseJson($res);
35564 }
35565
35566 $composer = $this->getBaseComposerInformation($identifier);
35567 if ($composer) {
35568
35569
35570  if (!isset($composer['support']['source'])) {
35571 $label = array_search($identifier, $this->getTags()) ?: array_search($identifier, $this->getBranches()) ?: $identifier;
35572 $composer['support']['source'] = sprintf('https://%s/%s/%s/tree/%s', $this->originUrl, $this->owner, $this->repository, $label);
35573 }
35574 if (!isset($composer['support']['issues']) && $this->hasIssues) {
35575 $composer['support']['issues'] = sprintf('https://%s/%s/%s/issues', $this->originUrl, $this->owner, $this->repository);
35576 }
35577 }
35578
35579 if ($this->shouldCache($identifier)) {
35580 $this->cache->write($identifier, json_encode($composer));
35581 }
35582
35583 $this->infoCache[$identifier] = $composer;
35584 }
35585
35586 return $this->infoCache[$identifier];
35587 }
35588
35589
35590
35591
35592 public function getFileContent($file, $identifier)
35593 {
35594 if ($this->gitDriver) {
35595 return $this->gitDriver->getFileContent($file, $identifier);
35596 }
35597
35598 $notFoundRetries = 2;
35599 while ($notFoundRetries) {
35600 try {
35601 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/' . $file . '?ref='.urlencode($identifier);
35602 $resource = JsonFile::parseJson($this->getContents($resource));
35603 if (empty($resource['content']) || $resource['encoding'] !== 'base64' || !($content = base64_decode($resource['content']))) {
35604 throw new \RuntimeException('Could not retrieve ' . $file . ' for '.$identifier);
35605 }
35606
35607 return $content;
35608 } catch (TransportException $e) {
35609 if (404 !== $e->getCode()) {
35610 throw $e;
35611 }
35612
35613
35614  
35615  $notFoundRetries--;
35616
35617 return null;
35618 }
35619 }
35620
35621 return null;
35622 }
35623
35624
35625
35626
35627 public function getChangeDate($identifier)
35628 {
35629 if ($this->gitDriver) {
35630 return $this->gitDriver->getChangeDate($identifier);
35631 }
35632
35633 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier);
35634 $commit = JsonFile::parseJson($this->getContents($resource), $resource);
35635
35636 return new \DateTime($commit['commit']['committer']['date']);
35637 }
35638
35639
35640
35641
35642 public function getTags()
35643 {
35644 if ($this->gitDriver) {
35645 return $this->gitDriver->getTags();
35646 }
35647 if (null === $this->tags) {
35648 $this->tags = array();
35649 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/tags?per_page=100';
35650
35651 do {
35652 $tagsData = JsonFile::parseJson($this->getContents($resource), $resource);
35653 foreach ($tagsData as $tag) {
35654 $this->tags[$tag['name']] = $tag['commit']['sha'];
35655 }
35656
35657 $resource = $this->getNextPage();
35658 } while ($resource);
35659 }
35660
35661 return $this->tags;
35662 }
35663
35664
35665
35666
35667 public function getBranches()
35668 {
35669 if ($this->gitDriver) {
35670 return $this->gitDriver->getBranches();
35671 }
35672 if (null === $this->branches) {
35673 $this->branches = array();
35674 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/git/refs/heads?per_page=100';
35675
35676 $branchBlacklist = array('gh-pages');
35677
35678 do {
35679 $branchData = JsonFile::parseJson($this->getContents($resource), $resource);
35680 foreach ($branchData as $branch) {
35681 $name = substr($branch['ref'], 11);
35682 if (!in_array($name, $branchBlacklist)) {
35683 $this->branches[$name] = $branch['object']['sha'];
35684 }
35685 }
35686
35687 $resource = $this->getNextPage();
35688 } while ($resource);
35689 }
35690
35691 return $this->branches;
35692 }
35693
35694
35695
35696
35697 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
35698 {
35699 if (!preg_match('#^((?:https?|git)://([^/]+)/|git@([^:]+):)([^/]+)/(.+?)(?:\.git|/)?$#', $url, $matches)) {
35700 return false;
35701 }
35702
35703 $originUrl = !empty($matches[2]) ? $matches[2] : $matches[3];
35704 if (!in_array(preg_replace('{^www\.}i', '', $originUrl), $config->get('github-domains'))) {
35705 return false;
35706 }
35707
35708 if (!extension_loaded('openssl')) {
35709 $io->writeError('Skipping GitHub driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
35710
35711 return false;
35712 }
35713
35714 return true;
35715 }
35716
35717
35718
35719
35720
35721
35722 public function getRepoData()
35723 {
35724 $this->fetchRootIdentifier();
35725
35726 return $this->repoData;
35727 }
35728
35729
35730
35731
35732
35733
35734 protected function generateSshUrl()
35735 {
35736 return 'git@' . $this->originUrl . ':'.$this->owner.'/'.$this->repository.'.git';
35737 }
35738
35739
35740
35741
35742 protected function getContents($url, $fetchingRepoData = false)
35743 {
35744 try {
35745 return parent::getContents($url);
35746 } catch (TransportException $e) {
35747 $gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->remoteFilesystem);
35748
35749 switch ($e->getCode()) {
35750 case 401:
35751 case 404:
35752
35753  if (!$fetchingRepoData) {
35754 throw $e;
35755 }
35756
35757 if ($gitHubUtil->authorizeOAuth($this->originUrl)) {
35758 return parent::getContents($url);
35759 }
35760
35761 if (!$this->io->isInteractive()) {
35762 return $this->attemptCloneFallback();
35763 }
35764
35765 $scopesIssued = array();
35766 $scopesNeeded = array();
35767 if ($headers = $e->getHeaders()) {
35768 if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-OAuth-Scopes')) {
35769 $scopesIssued = explode(' ', $scopes);
35770 }
35771 if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) {
35772 $scopesNeeded = explode(' ', $scopes);
35773 }
35774 }
35775 $scopesFailed = array_diff($scopesNeeded, $scopesIssued);
35776 if (!$headers || count($scopesFailed)) {
35777 $gitHubUtil->authorizeOAuthInteractively($this->originUrl, 'Your GitHub credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
35778 }
35779
35780 return parent::getContents($url);
35781
35782 case 403:
35783 if (!$this->io->hasAuthentication($this->originUrl) && $gitHubUtil->authorizeOAuth($this->originUrl)) {
35784 return parent::getContents($url);
35785 }
35786
35787 if (!$this->io->isInteractive() && $fetchingRepoData) {
35788 return $this->attemptCloneFallback();
35789 }
35790
35791 $rateLimited = false;
35792 foreach ($e->getHeaders() as $header) {
35793 if (preg_match('{^X-RateLimit-Remaining: *0$}i', trim($header))) {
35794 $rateLimited = true;
35795 }
35796 }
35797
35798 if (!$this->io->hasAuthentication($this->originUrl)) {
35799 if (!$this->io->isInteractive()) {
35800 $this->io->writeError('<error>GitHub API limit exhausted. Failed to get metadata for the '.$this->url.' repository, try running in interactive mode so that you can enter your GitHub credentials to increase the API limit</error>');
35801 throw $e;
35802 }
35803
35804 $gitHubUtil->authorizeOAuthInteractively($this->originUrl, 'API limit exhausted. Enter your GitHub credentials to get a larger API limit (<info>'.$this->url.'</info>)');
35805
35806 return parent::getContents($url);
35807 }
35808
35809 if ($rateLimited) {
35810 $rateLimit = $this->getRateLimit($e->getHeaders());
35811 $this->io->writeError(sprintf(
35812 '<error>GitHub API limit (%d calls/hr) is exhausted. You are already authorized so you have to wait until %s before doing more requests</error>',
35813 $rateLimit['limit'],
35814 $rateLimit['reset']
35815 ));
35816 }
35817
35818 throw $e;
35819
35820 default:
35821 throw $e;
35822 }
35823 }
35824 }
35825
35826
35827
35828
35829
35830
35831
35832
35833 protected function getRateLimit(array $headers)
35834 {
35835 $rateLimit = array(
35836 'limit' => '?',
35837 'reset' => '?',
35838 );
35839
35840 foreach ($headers as $header) {
35841 $header = trim($header);
35842 if (false === strpos($header, 'X-RateLimit-')) {
35843 continue;
35844 }
35845 list($type, $value) = explode(':', $header, 2);
35846 switch ($type) {
35847 case 'X-RateLimit-Limit':
35848 $rateLimit['limit'] = (int) trim($value);
35849 break;
35850 case 'X-RateLimit-Reset':
35851 $rateLimit['reset'] = date('Y-m-d H:i:s', (int) trim($value));
35852 break;
35853 }
35854 }
35855
35856 return $rateLimit;
35857 }
35858
35859
35860
35861
35862
35863
35864 protected function fetchRootIdentifier()
35865 {
35866 if ($this->repoData) {
35867 return;
35868 }
35869
35870 $repoDataUrl = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository;
35871
35872 $this->repoData = JsonFile::parseJson($this->getContents($repoDataUrl, true), $repoDataUrl);
35873 if (null === $this->repoData && null !== $this->gitDriver) {
35874 return;
35875 }
35876
35877 $this->owner = $this->repoData['owner']['login'];
35878 $this->repository = $this->repoData['name'];
35879
35880 $this->isPrivate = !empty($this->repoData['private']);
35881 if (isset($this->repoData['default_branch'])) {
35882 $this->rootIdentifier = $this->repoData['default_branch'];
35883 } elseif (isset($this->repoData['master_branch'])) {
35884 $this->rootIdentifier = $this->repoData['master_branch'];
35885 } else {
35886 $this->rootIdentifier = 'master';
35887 }
35888 $this->hasIssues = !empty($this->repoData['has_issues']);
35889 }
35890
35891 protected function attemptCloneFallback()
35892 {
35893 $this->isPrivate = true;
35894
35895 try {
35896
35897  
35898  
35899  
35900  $this->setupGitDriver($this->generateSshUrl());
35901
35902 return;
35903 } catch (\RuntimeException $e) {
35904 $this->gitDriver = null;
35905
35906 $this->io->writeError('<error>Failed to clone the '.$this->generateSshUrl().' repository, try running in interactive mode so that you can enter your GitHub credentials</error>');
35907 throw $e;
35908 }
35909 }
35910
35911 protected function setupGitDriver($url)
35912 {
35913 $this->gitDriver = new GitDriver(
35914 array('url' => $url),
35915 $this->io,
35916 $this->config,
35917 $this->process,
35918 $this->remoteFilesystem
35919 );
35920 $this->gitDriver->initialize();
35921 }
35922
35923 protected function getNextPage()
35924 {
35925 $headers = $this->remoteFilesystem->getLastHeaders();
35926 foreach ($headers as $header) {
35927 if (substr($header, 0, 5) === 'Link:') {
35928 $links = explode(',', substr($header, 5));
35929 foreach ($links as $link) {
35930 if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
35931 return $match[1];
35932 }
35933 }
35934 }
35935 }
35936 }
35937 }
35938 <?php
35939
35940
35941
35942
35943
35944
35945
35946
35947
35948
35949
35950 namespace Composer\Repository\Vcs;
35951
35952 use Composer\Config;
35953 use Composer\Cache;
35954 use Composer\IO\IOInterface;
35955 use Composer\Json\JsonFile;
35956 use Composer\Downloader\TransportException;
35957 use Composer\Util\RemoteFilesystem;
35958 use Composer\Util\GitLab;
35959
35960
35961
35962
35963
35964
35965
35966 class GitLabDriver extends VcsDriver
35967 {
35968 private $scheme;
35969 private $owner;
35970 private $repository;
35971
35972
35973
35974
35975 private $project;
35976
35977
35978
35979
35980 private $commits = array();
35981
35982
35983
35984
35985 private $tags;
35986
35987
35988
35989
35990 private $branches;
35991
35992
35993
35994
35995
35996
35997 protected $gitDriver;
35998
35999
36000
36001
36002
36003
36004 private $isPrivate = true;
36005
36006 const URL_REGEX = '#^(?:(?P<scheme>https?)://(?P<domain>.+?)/|git@(?P<domain2>[^:]+):)(?P<owner>[^/]+)/(?P<repo>[^/]+?)(?:\.git|/)?$#';
36007
36008
36009
36010
36011
36012
36013
36014
36015 public function initialize()
36016 {
36017 if (!preg_match(self::URL_REGEX, $this->url, $match)) {
36018 throw new \InvalidArgumentException('The URL provided is invalid. It must be the HTTP URL of a GitLab project.');
36019 }
36020
36021 $this->scheme = !empty($match['scheme']) ? $match['scheme'] : (isset($this->repoConfig['secure-http']) && $this->repoConfig['secure-http'] === false ? 'http' : 'https');
36022 $this->originUrl = !empty($match['domain']) ? $match['domain'] : $match['domain2'];
36023 $this->owner = $match['owner'];
36024 $this->repository = preg_replace('#(\.git)$#', '', $match['repo']);
36025
36026 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->owner.'/'.$this->repository);
36027
36028 $this->fetchProject();
36029 }
36030
36031
36032
36033
36034
36035
36036
36037 public function setRemoteFilesystem(RemoteFilesystem $remoteFilesystem)
36038 {
36039 $this->remoteFilesystem = $remoteFilesystem;
36040 }
36041
36042
36043
36044
36045 public function getFileContent($file, $identifier)
36046 {
36047 if ($this->gitDriver) {
36048 return $this->gitDriver->getFileContent($file, $identifier);
36049 }
36050
36051
36052  if (!preg_match('{[a-f0-9]{40}}i', $identifier)) {
36053 $branches = $this->getBranches();
36054 if (isset($branches[$identifier])) {
36055 $identifier = $branches[$identifier];
36056 }
36057 }
36058
36059 $resource = $this->getApiUrl().'/repository/blobs/'.$identifier.'?filepath=' . $file;
36060
36061 try {
36062 $content = $this->getContents($resource);
36063 } catch (TransportException $e) {
36064 if ($e->getCode() !== 404) {
36065 throw $e;
36066 }
36067
36068 return null;
36069 }
36070
36071 return $content;
36072 }
36073
36074
36075
36076
36077 public function getChangeDate($identifier)
36078 {
36079 if ($this->gitDriver) {
36080 return $this->gitDriver->getChangeDate($identifier);
36081 }
36082
36083 if (isset($this->commits[$identifier])) {
36084 return new \DateTime($this->commits[$identifier]['committed_date']);
36085 }
36086
36087 return new \DateTime();
36088 }
36089
36090
36091
36092
36093 public function getRepositoryUrl()
36094 {
36095 return $this->isPrivate ? $this->project['ssh_url_to_repo'] : $this->project['http_url_to_repo'];
36096 }
36097
36098
36099
36100
36101 public function getUrl()
36102 {
36103 if ($this->gitDriver) {
36104 return $this->gitDriver->getUrl();
36105 }
36106
36107 return $this->project['web_url'];
36108 }
36109
36110
36111
36112
36113 public function getDist($identifier)
36114 {
36115 $url = $this->getApiUrl().'/repository/archive.zip?ref='.$identifier;
36116
36117 return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => '');
36118 }
36119
36120
36121
36122
36123 public function getSource($identifier)
36124 {
36125 if ($this->gitDriver) {
36126 return $this->gitDriver->getSource($identifier);
36127 }
36128
36129 return array('type' => 'git', 'url' => $this->getRepositoryUrl(), 'reference' => $identifier);
36130 }
36131
36132
36133
36134
36135 public function getRootIdentifier()
36136 {
36137 if ($this->gitDriver) {
36138 return $this->gitDriver->getRootIdentifier();
36139 }
36140
36141 return $this->project['default_branch'];
36142 }
36143
36144
36145
36146
36147 public function getBranches()
36148 {
36149 if ($this->gitDriver) {
36150 return $this->gitDriver->getBranches();
36151 }
36152
36153 if (!$this->branches) {
36154 $this->branches = $this->getReferences('branches');
36155 }
36156
36157 return $this->branches;
36158 }
36159
36160
36161
36162
36163 public function getTags()
36164 {
36165 if ($this->gitDriver) {
36166 return $this->gitDriver->getTags();
36167 }
36168
36169 if (!$this->tags) {
36170 $this->tags = $this->getReferences('tags');
36171 }
36172
36173 return $this->tags;
36174 }
36175
36176
36177
36178
36179 public function getApiUrl()
36180 {
36181 return $this->scheme.'://'.$this->originUrl.'/api/v3/projects/'.$this->urlEncodeAll($this->owner).'%2F'.$this->urlEncodeAll($this->repository);
36182 }
36183
36184
36185
36186
36187
36188
36189
36190 private function urlEncodeAll($string)
36191 {
36192 $encoded = '';
36193 for ($i = 0; isset($string[$i]); $i++) {
36194 $character = $string[$i];
36195 if (!ctype_alnum($character) && !in_array($character, array('-', '_'), true)) {
36196 $character = '%' . sprintf('%02X', ord($character));
36197 }
36198 $encoded .= $character;
36199 }
36200
36201 return $encoded;
36202 }
36203
36204
36205
36206
36207
36208
36209 protected function getReferences($type)
36210 {
36211 $resource = $this->getApiUrl().'/repository/'.$type;
36212
36213 $data = JsonFile::parseJson($this->getContents($resource), $resource);
36214
36215 $references = array();
36216
36217 foreach ($data as $datum) {
36218 $references[$datum['name']] = $datum['commit']['id'];
36219
36220
36221  
36222  $this->commits[$datum['commit']['id']] = $datum['commit'];
36223 }
36224
36225 return $references;
36226 }
36227
36228 protected function fetchProject()
36229 {
36230
36231  $resource = $this->getApiUrl();
36232 $this->project = JsonFile::parseJson($this->getContents($resource, true), $resource);
36233 $this->isPrivate = !$this->project['public'];
36234 }
36235
36236 protected function attemptCloneFallback()
36237 {
36238 try {
36239 if ($this->isPrivate === false) {
36240 $url = $this->generatePublicUrl();
36241 } else {
36242 $url = $this->generateSshUrl();
36243 }
36244
36245
36246  
36247  
36248  $this->setupGitDriver($url);
36249
36250 return;
36251 } catch (\RuntimeException $e) {
36252 $this->gitDriver = null;
36253
36254 $this->io->writeError('<error>Failed to clone the '.$url.' repository, try running in interactive mode so that you can enter your credentials</error>');
36255 throw $e;
36256 }
36257 }
36258
36259
36260
36261
36262
36263
36264 protected function generateSshUrl()
36265 {
36266 return 'git@' . $this->originUrl . ':'.$this->owner.'/'.$this->repository.'.git';
36267 }
36268
36269 protected function generatePublicUrl()
36270 {
36271 return 'https://' . $this->originUrl . '/'.$this->owner.'/'.$this->repository.'.git';
36272 }
36273
36274 protected function setupGitDriver($url)
36275 {
36276 $this->gitDriver = new GitDriver(
36277 array('url' => $url),
36278 $this->io,
36279 $this->config,
36280 $this->process,
36281 $this->remoteFilesystem
36282 );
36283 $this->gitDriver->initialize();
36284 }
36285
36286
36287
36288
36289 protected function getContents($url, $fetchingRepoData = false)
36290 {
36291 try {
36292 $res = parent::getContents($url);
36293
36294 if ($fetchingRepoData) {
36295 $json = JsonFile::parseJson($res, $url);
36296
36297
36298  if (!isset($json['default_branch'])) {
36299 if (!empty($json['id'])) {
36300 $this->isPrivate = false;
36301 }
36302
36303 throw new TransportException('GitLab API seems to not be authenticated as it did not return a default_branch', 401);
36304 }
36305 }
36306
36307 return $res;
36308 } catch (TransportException $e) {
36309 $gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->remoteFilesystem);
36310
36311 switch ($e->getCode()) {
36312 case 401:
36313 case 404:
36314
36315  if (!$fetchingRepoData) {
36316 throw $e;
36317 }
36318
36319 if ($gitLabUtil->authorizeOAuth($this->originUrl)) {
36320 return parent::getContents($url);
36321 }
36322
36323 if (!$this->io->isInteractive()) {
36324 return $this->attemptCloneFallback();
36325 }
36326 $this->io->writeError('<warning>Failed to download ' . $this->owner . '/' . $this->repository . ':' . $e->getMessage() . '</warning>');
36327 $gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, 'Your credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
36328
36329 return parent::getContents($url);
36330
36331 case 403:
36332 if (!$this->io->hasAuthentication($this->originUrl) && $gitLabUtil->authorizeOAuth($this->originUrl)) {
36333 return parent::getContents($url);
36334 }
36335
36336 if (!$this->io->isInteractive() && $fetchingRepoData) {
36337 return $this->attemptCloneFallback();
36338 }
36339
36340 throw $e;
36341
36342 default:
36343 throw $e;
36344 }
36345 }
36346 }
36347
36348
36349
36350
36351
36352
36353
36354 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
36355 {
36356 if (!preg_match(self::URL_REGEX, $url, $match)) {
36357 return false;
36358 }
36359
36360 $scheme = !empty($match['scheme']) ? $match['scheme'] : null;
36361 $originUrl = !empty($match['domain']) ? $match['domain'] : $match['domain2'];
36362
36363 if (!in_array($originUrl, (array) $config->get('gitlab-domains'))) {
36364 return false;
36365 }
36366
36367 if ('https' === $scheme && !extension_loaded('openssl')) {
36368 $io->writeError('Skipping GitLab driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
36369
36370 return false;
36371 }
36372
36373 return true;
36374 }
36375 }
36376 <?php
36377
36378
36379
36380
36381
36382
36383
36384
36385
36386
36387
36388 namespace Composer\Repository\Vcs;
36389
36390 use Composer\Config;
36391 use Composer\IO\IOInterface;
36392
36393
36394
36395
36396 class HgBitbucketDriver extends BitbucketDriver
36397 {
36398
36399
36400
36401 public function getRootIdentifier()
36402 {
36403 if ($this->fallbackDriver) {
36404 return $this->fallbackDriver->getRootIdentifier();
36405 }
36406
36407 if (null === $this->rootIdentifier) {
36408 if (! $this->getRepoData()) {
36409 return $this->fallbackDriver->getRootIdentifier();
36410 }
36411
36412 if ($this->vcsType !== 'hg') {
36413 throw new \RuntimeException(
36414 $this->url.' does not appear to be a mercurial repository, use '.
36415 $this->cloneHttpsUrl.' if this is a git bitbucket repository'
36416 );
36417 }
36418
36419 $mainBranchData = $this->getMainBranchData();
36420 $this->rootIdentifier = !empty($mainBranchData['name']) ? $mainBranchData['name'] : 'default';
36421 }
36422
36423 return $this->rootIdentifier;
36424 }
36425
36426
36427
36428
36429 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
36430 {
36431 if (!preg_match('#^https?://bitbucket\.org/([^/]+)/([^/]+)/?$#', $url)) {
36432 return false;
36433 }
36434
36435 if (!extension_loaded('openssl')) {
36436 $io->writeError('Skipping Bitbucket hg driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
36437
36438 return false;
36439 }
36440
36441 return true;
36442 }
36443
36444
36445
36446
36447 protected function setupFallbackDriver($url)
36448 {
36449 $this->fallbackDriver = new HgDriver(
36450 array('url' => $url),
36451 $this->io,
36452 $this->config,
36453 $this->process,
36454 $this->remoteFilesystem
36455 );
36456 $this->fallbackDriver->initialize();
36457 }
36458
36459
36460
36461
36462 protected function generateSshUrl()
36463 {
36464 return 'ssh://hg@' . $this->originUrl . '/' . $this->owner.'/'.$this->repository;
36465 }
36466 }
36467 <?php
36468
36469
36470
36471
36472
36473
36474
36475
36476
36477
36478
36479 namespace Composer\Repository\Vcs;
36480
36481 use Composer\Config;
36482 use Composer\Util\ProcessExecutor;
36483 use Composer\Util\Filesystem;
36484 use Composer\IO\IOInterface;
36485 use Symfony\Component\Process\Process;
36486
36487
36488
36489
36490 class HgDriver extends VcsDriver
36491 {
36492 protected $tags;
36493 protected $branches;
36494 protected $rootIdentifier;
36495 protected $repoDir;
36496 protected $infoCache = array();
36497
36498
36499
36500
36501 public function initialize()
36502 {
36503 if (Filesystem::isLocalPath($this->url)) {
36504 $this->repoDir = $this->url;
36505 } else {
36506 $cacheDir = $this->config->get('cache-vcs-dir');
36507 $this->repoDir = $cacheDir . '/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '/';
36508
36509 $fs = new Filesystem();
36510 $fs->ensureDirectoryExists($cacheDir);
36511
36512 if (!is_writable(dirname($this->repoDir))) {
36513 throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.$cacheDir.'" directory is not writable by the current user.');
36514 }
36515
36516
36517  $this->config->prohibitUrlByConfig($this->url, $this->io);
36518
36519
36520  if (is_dir($this->repoDir) && 0 === $this->process->execute('hg summary', $output, $this->repoDir)) {
36521 if (0 !== $this->process->execute('hg pull', $output, $this->repoDir)) {
36522 $this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')</error>');
36523 }
36524 } else {
36525
36526  $fs->removeDirectory($this->repoDir);
36527
36528 if (0 !== $this->process->execute(sprintf('hg clone --noupdate %s %s', ProcessExecutor::escape($this->url), ProcessExecutor::escape($this->repoDir)), $output, $cacheDir)) {
36529 $output = $this->process->getErrorOutput();
36530
36531 if (0 !== $this->process->execute('hg --version', $ignoredOutput)) {
36532 throw new \RuntimeException('Failed to clone '.$this->url.', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput());
36533 }
36534
36535 throw new \RuntimeException('Failed to clone '.$this->url.', could not read packages from it' . "\n\n" .$output);
36536 }
36537 }
36538 }
36539
36540 $this->getTags();
36541 $this->getBranches();
36542 }
36543
36544
36545
36546
36547 public function getRootIdentifier()
36548 {
36549 if (null === $this->rootIdentifier) {
36550 $this->process->execute(sprintf('hg tip --template "{node}"'), $output, $this->repoDir);
36551 $output = $this->process->splitLines($output);
36552 $this->rootIdentifier = $output[0];
36553 }
36554
36555 return $this->rootIdentifier;
36556 }
36557
36558
36559
36560
36561 public function getUrl()
36562 {
36563 return $this->url;
36564 }
36565
36566
36567
36568
36569 public function getSource($identifier)
36570 {
36571 return array('type' => 'hg', 'url' => $this->getUrl(), 'reference' => $identifier);
36572 }
36573
36574
36575
36576
36577 public function getDist($identifier)
36578 {
36579 return null;
36580 }
36581
36582
36583
36584
36585 public function getFileContent($file, $identifier)
36586 {
36587 $resource = sprintf('hg cat -r %s %s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
36588 $this->process->execute(sprintf('hg cat -r %s', $resource), $content, $this->repoDir);
36589
36590 if (!trim($content)) {
36591 return;
36592 }
36593
36594 return $content;
36595 }
36596
36597
36598
36599
36600 public function getChangeDate($identifier)
36601 {
36602 $this->process->execute(
36603 sprintf(
36604 'hg log --template "{date|rfc3339date}" -r %s',
36605 ProcessExecutor::escape($identifier)
36606 ),
36607 $output,
36608 $this->repoDir
36609 );
36610
36611 return new \DateTime(trim($output), new \DateTimeZone('UTC'));
36612 }
36613
36614
36615
36616
36617 public function getTags()
36618 {
36619 if (null === $this->tags) {
36620 $tags = array();
36621
36622 $this->process->execute('hg tags', $output, $this->repoDir);
36623 foreach ($this->process->splitLines($output) as $tag) {
36624 if ($tag && preg_match('(^([^\s]+)\s+\d+:(.*)$)', $tag, $match)) {
36625 $tags[$match[1]] = $match[2];
36626 }
36627 }
36628 unset($tags['tip']);
36629
36630 $this->tags = $tags;
36631 }
36632
36633 return $this->tags;
36634 }
36635
36636
36637
36638
36639 public function getBranches()
36640 {
36641 if (null === $this->branches) {
36642 $branches = array();
36643 $bookmarks = array();
36644
36645 $this->process->execute('hg branches', $output, $this->repoDir);
36646 foreach ($this->process->splitLines($output) as $branch) {
36647 if ($branch && preg_match('(^([^\s]+)\s+\d+:([a-f0-9]+))', $branch, $match)) {
36648 $branches[$match[1]] = $match[2];
36649 }
36650 }
36651
36652 $this->process->execute('hg bookmarks', $output, $this->repoDir);
36653 foreach ($this->process->splitLines($output) as $branch) {
36654 if ($branch && preg_match('(^(?:[\s*]*)([^\s]+)\s+\d+:(.*)$)', $branch, $match)) {
36655 $bookmarks[$match[1]] = $match[2];
36656 }
36657 }
36658
36659
36660  $this->branches = array_merge($bookmarks, $branches);
36661 }
36662
36663 return $this->branches;
36664 }
36665
36666
36667
36668
36669 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
36670 {
36671 if (preg_match('#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i', $url)) {
36672 return true;
36673 }
36674
36675
36676  if (Filesystem::isLocalPath($url)) {
36677 $url = Filesystem::getPlatformPath($url);
36678 if (!is_dir($url)) {
36679 return false;
36680 }
36681
36682 $process = new ProcessExecutor();
36683
36684  if ($process->execute('hg summary', $output, $url) === 0) {
36685 return true;
36686 }
36687 }
36688
36689 if (!$deep) {
36690 return false;
36691 }
36692
36693 $processExecutor = new ProcessExecutor();
36694 $exit = $processExecutor->execute(sprintf('hg identify %s', ProcessExecutor::escape($url)), $ignored);
36695
36696 return $exit === 0;
36697 }
36698 }
36699 <?php
36700
36701
36702
36703
36704
36705
36706
36707
36708
36709
36710
36711 namespace Composer\Repository\Vcs;
36712
36713 use Composer\Config;
36714 use Composer\IO\IOInterface;
36715 use Composer\Util\ProcessExecutor;
36716 use Composer\Util\Perforce;
36717
36718
36719
36720
36721 class PerforceDriver extends VcsDriver
36722 {
36723 protected $depot;
36724 protected $branch;
36725
36726 protected $perforce;
36727
36728
36729
36730
36731 public function initialize()
36732 {
36733 $this->depot = $this->repoConfig['depot'];
36734 $this->branch = '';
36735 if (!empty($this->repoConfig['branch'])) {
36736 $this->branch = $this->repoConfig['branch'];
36737 }
36738
36739 $this->initPerforce($this->repoConfig);
36740 $this->perforce->p4Login();
36741 $this->perforce->checkStream();
36742
36743 $this->perforce->writeP4ClientSpec();
36744 $this->perforce->connectClient();
36745
36746 return true;
36747 }
36748
36749 private function initPerforce($repoConfig)
36750 {
36751 if (!empty($this->perforce)) {
36752 return;
36753 }
36754
36755 $repoDir = $this->config->get('cache-vcs-dir') . '/' . $this->depot;
36756 $this->perforce = Perforce::create($repoConfig, $this->getUrl(), $repoDir, $this->process, $this->io);
36757 }
36758
36759
36760
36761
36762 public function getFileContent($file, $identifier)
36763 {
36764 return $this->perforce->getFileContent($file, $identifier);
36765 }
36766
36767
36768
36769
36770 public function getChangeDate($identifier)
36771 {
36772 return null;
36773 }
36774
36775
36776
36777
36778 public function getRootIdentifier()
36779 {
36780 return $this->branch;
36781 }
36782
36783
36784
36785
36786 public function getBranches()
36787 {
36788 $branches = $this->perforce->getBranches();
36789
36790 return $branches;
36791 }
36792
36793
36794
36795
36796 public function getTags()
36797 {
36798 $tags = $this->perforce->getTags();
36799
36800 return $tags;
36801 }
36802
36803
36804
36805
36806 public function getDist($identifier)
36807 {
36808 return null;
36809 }
36810
36811
36812
36813
36814 public function getSource($identifier)
36815 {
36816 $source = array(
36817 'type' => 'perforce',
36818 'url' => $this->repoConfig['url'],
36819 'reference' => $identifier,
36820 'p4user' => $this->perforce->getUser(),
36821 );
36822
36823 return $source;
36824 }
36825
36826
36827
36828
36829 public function getUrl()
36830 {
36831 return $this->url;
36832 }
36833
36834
36835
36836
36837 public function hasComposerFile($identifier)
36838 {
36839 $composerInfo = $this->perforce->getComposerInformation('//' . $this->depot . '/' . $identifier);
36840 $composerInfoIdentifier = $identifier;
36841
36842 return !empty($composerInfo);
36843 }
36844
36845
36846
36847
36848 public function getContents($url)
36849 {
36850 return false;
36851 }
36852
36853
36854
36855
36856 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
36857 {
36858 if ($deep || preg_match('#\b(perforce|p4)\b#i', $url)) {
36859 return Perforce::checkServerExists($url, new ProcessExecutor($io));
36860 }
36861
36862 return false;
36863 }
36864
36865
36866
36867
36868 public function cleanup()
36869 {
36870 $this->perforce->cleanupClientSpec();
36871 $this->perforce = null;
36872 }
36873
36874 public function getDepot()
36875 {
36876 return $this->depot;
36877 }
36878
36879 public function getBranch()
36880 {
36881 return $this->branch;
36882 }
36883 }
36884 <?php
36885
36886
36887
36888
36889
36890
36891
36892
36893
36894
36895
36896 namespace Composer\Repository\Vcs;
36897
36898 use Composer\Cache;
36899 use Composer\Config;
36900 use Composer\Json\JsonFile;
36901 use Composer\Util\ProcessExecutor;
36902 use Composer\Util\Filesystem;
36903 use Composer\Util\Svn as SvnUtil;
36904 use Composer\IO\IOInterface;
36905 use Composer\Downloader\TransportException;
36906
36907
36908
36909
36910
36911 class SvnDriver extends VcsDriver
36912 {
36913
36914
36915
36916 protected $cache;
36917 protected $baseUrl;
36918 protected $tags;
36919 protected $branches;
36920 protected $rootIdentifier;
36921 protected $infoCache = array();
36922
36923 protected $trunkPath = 'trunk';
36924 protected $branchesPath = 'branches';
36925 protected $tagsPath = 'tags';
36926 protected $packagePath = '';
36927 protected $cacheCredentials = true;
36928
36929
36930
36931
36932 private $util;
36933
36934
36935
36936
36937 public function initialize()
36938 {
36939 $this->url = $this->baseUrl = rtrim(self::normalizeUrl($this->url), '/');
36940
36941 SvnUtil::cleanEnv();
36942
36943 if (isset($this->repoConfig['trunk-path'])) {
36944 $this->trunkPath = $this->repoConfig['trunk-path'];
36945 }
36946 if (isset($this->repoConfig['branches-path'])) {
36947 $this->branchesPath = $this->repoConfig['branches-path'];
36948 }
36949 if (isset($this->repoConfig['tags-path'])) {
36950 $this->tagsPath = $this->repoConfig['tags-path'];
36951 }
36952 if (array_key_exists('svn-cache-credentials', $this->repoConfig)) {
36953 $this->cacheCredentials = (bool) $this->repoConfig['svn-cache-credentials'];
36954 }
36955 if (isset($this->repoConfig['package-path'])) {
36956 $this->packagePath = '/' . trim($this->repoConfig['package-path'], '/');
36957 }
36958
36959 if (false !== ($pos = strrpos($this->url, '/' . $this->trunkPath))) {
36960 $this->baseUrl = substr($this->url, 0, $pos);
36961 }
36962
36963 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->baseUrl));
36964
36965 $this->getBranches();
36966 $this->getTags();
36967 }
36968
36969
36970
36971
36972 public function getRootIdentifier()
36973 {
36974 return $this->rootIdentifier ?: $this->trunkPath;
36975 }
36976
36977
36978
36979
36980 public function getUrl()
36981 {
36982 return $this->url;
36983 }
36984
36985
36986
36987
36988 public function getSource($identifier)
36989 {
36990 return array('type' => 'svn', 'url' => $this->baseUrl, 'reference' => $identifier);
36991 }
36992
36993
36994
36995
36996 public function getDist($identifier)
36997 {
36998 return null;
36999 }
37000
37001
37002
37003
37004 public function getComposerInformation($identifier)
37005 {
37006 if (!isset($this->infoCache[$identifier])) {
37007 if ($res = $this->cache->read($identifier.'.json')) {
37008 return $this->infoCache[$identifier] = JsonFile::parseJson($res);
37009 }
37010
37011 $composer = $this->getBaseComposerInformation($identifier);
37012
37013 $this->cache->write($identifier.'.json', json_encode($composer));
37014
37015 $this->infoCache[$identifier] = $composer;
37016 }
37017
37018 return $this->infoCache[$identifier];
37019 }
37020
37021
37022
37023
37024
37025 public function getFileContent($file, $identifier)
37026 {
37027 $identifier = '/' . trim($identifier, '/') . '/';
37028
37029 preg_match('{^(.+?)(@\d+)?/$}', $identifier, $match);
37030 if (!empty($match[2])) {
37031 $path = $match[1];
37032 $rev = $match[2];
37033 } else {
37034 $path = $identifier;
37035 $rev = '';
37036 }
37037
37038 try {
37039 $resource = $path.$file;
37040 $output = $this->execute('svn cat', $this->baseUrl . $resource . $rev);
37041 if (!trim($output)) {
37042 return null;
37043 }
37044 } catch (\RuntimeException $e) {
37045 throw new TransportException($e->getMessage());
37046 }
37047
37048 return $output;
37049 }
37050
37051
37052
37053
37054 public function getChangeDate($identifier)
37055 {
37056 $identifier = '/' . trim($identifier, '/') . '/';
37057
37058 preg_match('{^(.+?)(@\d+)?/$}', $identifier, $match);
37059 if (!empty($match[2])) {
37060 $path = $match[1];
37061 $rev = $match[2];
37062 } else {
37063 $path = $identifier;
37064 $rev = '';
37065 }
37066
37067 $output = $this->execute('svn info', $this->baseUrl . $path . $rev);
37068 foreach ($this->process->splitLines($output) as $line) {
37069 if ($line && preg_match('{^Last Changed Date: ([^(]+)}', $line, $match)) {
37070 return new \DateTime($match[1], new \DateTimeZone('UTC'));
37071 }
37072 }
37073
37074 return null;
37075 }
37076
37077
37078
37079
37080 public function getTags()
37081 {
37082 if (null === $this->tags) {
37083 $this->tags = array();
37084
37085 if ($this->tagsPath !== false) {
37086 $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->tagsPath);
37087 if ($output) {
37088 foreach ($this->process->splitLines($output) as $line) {
37089 $line = trim($line);
37090 if ($line && preg_match('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) {
37091 if (isset($match[1]) && isset($match[2]) && $match[2] !== './') {
37092 $this->tags[rtrim($match[2], '/')] = $this->buildIdentifier(
37093 '/' . $this->tagsPath . '/' . $match[2],
37094 $match[1]
37095 );
37096 }
37097 }
37098 }
37099 }
37100 }
37101 }
37102
37103 return $this->tags;
37104 }
37105
37106
37107
37108
37109 public function getBranches()
37110 {
37111 if (null === $this->branches) {
37112 $this->branches = array();
37113
37114 if (false === $this->trunkPath) {
37115 $trunkParent = $this->baseUrl . '/';
37116 } else {
37117 $trunkParent = $this->baseUrl . '/' . $this->trunkPath;
37118 }
37119
37120 $output = $this->execute('svn ls --verbose', $trunkParent);
37121 if ($output) {
37122 foreach ($this->process->splitLines($output) as $line) {
37123 $line = trim($line);
37124 if ($line && preg_match('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) {
37125 if (isset($match[1]) && isset($match[2]) && $match[2] === './') {
37126 $this->branches['trunk'] = $this->buildIdentifier(
37127 '/' . $this->trunkPath,
37128 $match[1]
37129 );
37130 $this->rootIdentifier = $this->branches['trunk'];
37131 break;
37132 }
37133 }
37134 }
37135 }
37136 unset($output);
37137
37138 if ($this->branchesPath !== false) {
37139 $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->branchesPath);
37140 if ($output) {
37141 foreach ($this->process->splitLines(trim($output)) as $line) {
37142 $line = trim($line);
37143 if ($line && preg_match('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) {
37144 if (isset($match[1]) && isset($match[2]) && $match[2] !== './') {
37145 $this->branches[rtrim($match[2], '/')] = $this->buildIdentifier(
37146 '/' . $this->branchesPath . '/' . $match[2],
37147 $match[1]
37148 );
37149 }
37150 }
37151 }
37152 }
37153 }
37154 }
37155
37156 return $this->branches;
37157 }
37158
37159
37160
37161
37162 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
37163 {
37164 $url = self::normalizeUrl($url);
37165 if (preg_match('#(^svn://|^svn\+ssh://|svn\.)#i', $url)) {
37166 return true;
37167 }
37168
37169
37170  if (!$deep && !Filesystem::isLocalPath($url)) {
37171 return false;
37172 }
37173
37174 $processExecutor = new ProcessExecutor();
37175
37176 $exit = $processExecutor->execute(
37177 "svn info --non-interactive {$url}",
37178 $ignoredOutput
37179 );
37180
37181 if ($exit === 0) {
37182
37183  return true;
37184 }
37185
37186
37187  if (false !== stripos($processExecutor->getErrorOutput(), 'authorization failed:')) {
37188
37189  
37190  return true;
37191 }
37192
37193
37194  if (false !== stripos($processExecutor->getErrorOutput(), 'Authentication failed')) {
37195
37196  
37197  return true;
37198 }
37199
37200 return false;
37201 }
37202
37203
37204
37205
37206
37207
37208
37209
37210 protected static function normalizeUrl($url)
37211 {
37212 $fs = new Filesystem();
37213 if ($fs->isAbsolutePath($url)) {
37214 return 'file://' . strtr($url, '\\', '/');
37215 }
37216
37217 return $url;
37218 }
37219
37220
37221
37222
37223
37224
37225
37226
37227
37228
37229 protected function execute($command, $url)
37230 {
37231 if (null === $this->util) {
37232 $this->util = new SvnUtil($this->baseUrl, $this->io, $this->config, $this->process);
37233 $this->util->setCacheCredentials($this->cacheCredentials);
37234 }
37235
37236 try {
37237 return $this->util->execute($command, $url);
37238 } catch (\RuntimeException $e) {
37239 if (0 !== $this->process->execute('svn --version', $ignoredOutput)) {
37240 throw new \RuntimeException('Failed to load '.$this->url.', svn was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput());
37241 }
37242
37243 throw new \RuntimeException(
37244 'Repository '.$this->url.' could not be processed, '.$e->getMessage()
37245 );
37246 }
37247 }
37248
37249
37250
37251
37252
37253
37254
37255
37256
37257 protected function buildIdentifier($baseDir, $revision)
37258 {
37259 return rtrim($baseDir, '/') . $this->packagePath . '/@' . $revision;
37260 }
37261 }
37262 <?php
37263
37264
37265
37266
37267
37268
37269
37270
37271
37272
37273
37274 namespace Composer\Repository\Vcs;
37275
37276 use Composer\Cache;
37277 use Composer\Downloader\TransportException;
37278 use Composer\Config;
37279 use Composer\Factory;
37280 use Composer\IO\IOInterface;
37281 use Composer\Json\JsonFile;
37282 use Composer\Util\ProcessExecutor;
37283 use Composer\Util\RemoteFilesystem;
37284 use Composer\Util\Filesystem;
37285
37286
37287
37288
37289
37290
37291 abstract class VcsDriver implements VcsDriverInterface
37292 {
37293
37294 protected $url;
37295
37296 protected $originUrl;
37297
37298 protected $repoConfig;
37299
37300 protected $io;
37301
37302 protected $config;
37303
37304 protected $process;
37305
37306 protected $remoteFilesystem;
37307
37308 protected $infoCache = array();
37309
37310 protected $cache;
37311
37312
37313
37314
37315
37316
37317
37318
37319
37320
37321 final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
37322 {
37323 if (Filesystem::isLocalPath($repoConfig['url'])) {
37324 $repoConfig['url'] = Filesystem::getPlatformPath($repoConfig['url']);
37325 }
37326
37327 $this->url = $repoConfig['url'];
37328 $this->originUrl = $repoConfig['url'];
37329 $this->repoConfig = $repoConfig;
37330 $this->io = $io;
37331 $this->config = $config;
37332 $this->process = $process ?: new ProcessExecutor($io);
37333 $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
37334 }
37335
37336
37337
37338
37339
37340
37341
37342 protected function shouldCache($identifier)
37343 {
37344 return $this->cache && preg_match('{[a-f0-9]{40}}i', $identifier);
37345 }
37346
37347
37348
37349
37350 public function getComposerInformation($identifier)
37351 {
37352 if (!isset($this->infoCache[$identifier])) {
37353 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
37354 return $this->infoCache[$identifier] = JsonFile::parseJson($res);
37355 }
37356
37357 $composer = $this->getBaseComposerInformation($identifier);
37358
37359 if ($this->shouldCache($identifier)) {
37360 $this->cache->write($identifier, json_encode($composer));
37361 }
37362
37363 $this->infoCache[$identifier] = $composer;
37364 }
37365
37366 return $this->infoCache[$identifier];
37367 }
37368
37369 protected function getBaseComposerInformation($identifier)
37370 {
37371 $composerFileContent = $this->getFileContent('composer.json', $identifier);
37372
37373 if (!$composerFileContent) {
37374 return null;
37375 }
37376
37377 $composer = JsonFile::parseJson($composerFileContent, $identifier . ':composer.json');
37378
37379 if (empty($composer['time']) && $changeDate = $this->getChangeDate($identifier)) {
37380 $composer['time'] = $changeDate->format('Y-m-d H:i:s');
37381 }
37382
37383 return $composer;
37384 }
37385
37386
37387
37388
37389 public function hasComposerFile($identifier)
37390 {
37391 try {
37392 return (bool) $this->getComposerInformation($identifier);
37393 } catch (TransportException $e) {
37394 }
37395
37396 return false;
37397 }
37398
37399
37400
37401
37402
37403
37404
37405
37406 protected function getScheme()
37407 {
37408 if (extension_loaded('openssl')) {
37409 return 'https';
37410 }
37411
37412 return 'http';
37413 }
37414
37415
37416
37417
37418
37419
37420
37421
37422 protected function getContents($url)
37423 {
37424 return $this->remoteFilesystem->getContents($this->originUrl, $url, false);
37425 }
37426
37427
37428
37429
37430 public function cleanup()
37431 {
37432 return;
37433 }
37434 }
37435 <?php
37436
37437
37438
37439
37440
37441
37442
37443
37444
37445
37446
37447 namespace Composer\Repository\Vcs;
37448
37449 use Composer\Config;
37450 use Composer\IO\IOInterface;
37451
37452
37453
37454
37455 interface VcsDriverInterface
37456 {
37457
37458
37459
37460 public function initialize();
37461
37462
37463
37464
37465
37466
37467
37468 public function getComposerInformation($identifier);
37469
37470
37471
37472
37473
37474
37475
37476
37477 public function getFileContent($file, $identifier);
37478
37479
37480
37481
37482
37483
37484
37485 public function getChangeDate($identifier);
37486
37487
37488
37489
37490
37491
37492 public function getRootIdentifier();
37493
37494
37495
37496
37497
37498
37499 public function getBranches();
37500
37501
37502
37503
37504
37505
37506 public function getTags();
37507
37508
37509
37510
37511
37512 public function getDist($identifier);
37513
37514
37515
37516
37517
37518 public function getSource($identifier);
37519
37520
37521
37522
37523
37524
37525 public function getUrl();
37526
37527
37528
37529
37530
37531
37532
37533
37534 public function hasComposerFile($identifier);
37535
37536
37537
37538
37539 public function cleanup();
37540
37541
37542
37543
37544
37545
37546
37547
37548
37549
37550 public static function supports(IOInterface $io, Config $config, $url, $deep = false);
37551 }
37552 <?php
37553
37554
37555
37556
37557
37558
37559
37560
37561
37562
37563
37564 namespace Composer\Repository;
37565
37566 use Composer\Downloader\TransportException;
37567 use Composer\Repository\Vcs\VcsDriverInterface;
37568 use Composer\Package\Version\VersionParser;
37569 use Composer\Package\Loader\ArrayLoader;
37570 use Composer\Package\Loader\ValidatingArrayLoader;
37571 use Composer\Package\Loader\InvalidPackageException;
37572 use Composer\Package\Loader\LoaderInterface;
37573 use Composer\EventDispatcher\EventDispatcher;
37574 use Composer\IO\IOInterface;
37575 use Composer\Config;
37576
37577
37578
37579
37580 class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInterface
37581 {
37582 protected $url;
37583 protected $packageName;
37584 protected $verbose;
37585 protected $io;
37586 protected $config;
37587 protected $versionParser;
37588 protected $type;
37589 protected $loader;
37590 protected $repoConfig;
37591 protected $branchErrorOccurred = false;
37592 private $drivers;
37593
37594 private $driver;
37595
37596 public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, array $drivers = null)
37597 {
37598 parent::__construct();
37599 $this->drivers = $drivers ?: array(
37600 'github' => 'Composer\Repository\Vcs\GitHubDriver',
37601 'gitlab' => 'Composer\Repository\Vcs\GitLabDriver',
37602 'git-bitbucket' => 'Composer\Repository\Vcs\GitBitbucketDriver',
37603 'git' => 'Composer\Repository\Vcs\GitDriver',
37604 'hg-bitbucket' => 'Composer\Repository\Vcs\HgBitbucketDriver',
37605 'hg' => 'Composer\Repository\Vcs\HgDriver',
37606 'perforce' => 'Composer\Repository\Vcs\PerforceDriver',
37607 'fossil' => 'Composer\Repository\Vcs\FossilDriver',
37608
37609  'svn' => 'Composer\Repository\Vcs\SvnDriver',
37610 );
37611
37612 $this->url = $repoConfig['url'];
37613 $this->io = $io;
37614 $this->type = isset($repoConfig['type']) ? $repoConfig['type'] : 'vcs';
37615 $this->verbose = $io->isVeryVerbose();
37616 $this->config = $config;
37617 $this->repoConfig = $repoConfig;
37618 }
37619
37620 public function getRepoConfig()
37621 {
37622 return $this->repoConfig;
37623 }
37624
37625 public function setLoader(LoaderInterface $loader)
37626 {
37627 $this->loader = $loader;
37628 }
37629
37630 public function getDriver()
37631 {
37632 if ($this->driver) {
37633 return $this->driver;
37634 }
37635
37636 if (isset($this->drivers[$this->type])) {
37637 $class = $this->drivers[$this->type];
37638 $this->driver = new $class($this->repoConfig, $this->io, $this->config);
37639 $this->driver->initialize();
37640
37641 return $this->driver;
37642 }
37643
37644 foreach ($this->drivers as $driver) {
37645 if ($driver::supports($this->io, $this->config, $this->url)) {
37646 $this->driver = new $driver($this->repoConfig, $this->io, $this->config);
37647 $this->driver->initialize();
37648
37649 return $this->driver;
37650 }
37651 }
37652
37653 foreach ($this->drivers as $driver) {
37654 if ($driver::supports($this->io, $this->config, $this->url, true)) {
37655 $this->driver = new $driver($this->repoConfig, $this->io, $this->config);
37656 $this->driver->initialize();
37657
37658 return $this->driver;
37659 }
37660 }
37661 }
37662
37663 public function hadInvalidBranches()
37664 {
37665 return $this->branchErrorOccurred;
37666 }
37667
37668 protected function initialize()
37669 {
37670 parent::initialize();
37671
37672 $verbose = $this->verbose;
37673
37674 $driver = $this->getDriver();
37675 if (!$driver) {
37676 throw new \InvalidArgumentException('No driver found to handle VCS repository '.$this->url);
37677 }
37678
37679 $this->versionParser = new VersionParser;
37680 if (!$this->loader) {
37681 $this->loader = new ArrayLoader($this->versionParser);
37682 }
37683
37684 try {
37685 if ($driver->hasComposerFile($driver->getRootIdentifier())) {
37686 $data = $driver->getComposerInformation($driver->getRootIdentifier());
37687 $this->packageName = !empty($data['name']) ? $data['name'] : null;
37688 }
37689 } catch (\Exception $e) {
37690 if ($verbose) {
37691 $this->io->writeError('<error>Skipped parsing '.$driver->getRootIdentifier().', '.$e->getMessage().'</error>');
37692 }
37693 }
37694
37695 foreach ($driver->getTags() as $tag => $identifier) {
37696 $msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $tag . '</comment>)';
37697 if ($verbose) {
37698 $this->io->writeError($msg);
37699 } else {
37700 $this->io->overwriteError($msg, false);
37701 }
37702
37703
37704  $tag = str_replace('release-', '', $tag);
37705
37706 if (!$parsedTag = $this->validateTag($tag)) {
37707 if ($verbose) {
37708 $this->io->writeError('<warning>Skipped tag '.$tag.', invalid tag name</warning>');
37709 }
37710 continue;
37711 }
37712
37713 try {
37714 if (!$data = $driver->getComposerInformation($identifier)) {
37715 if ($verbose) {
37716 $this->io->writeError('<warning>Skipped tag '.$tag.', no composer file</warning>');
37717 }
37718 continue;
37719 }
37720
37721
37722  if (isset($data['version'])) {
37723 $data['version_normalized'] = $this->versionParser->normalize($data['version']);
37724 } else {
37725
37726  $data['version'] = $tag;
37727 $data['version_normalized'] = $parsedTag;
37728 }
37729
37730
37731  $data['version'] = preg_replace('{[.-]?dev$}i', '', $data['version']);
37732 $data['version_normalized'] = preg_replace('{(^dev-|[.-]?dev$)}i', '', $data['version_normalized']);
37733
37734
37735  if ($data['version_normalized'] !== $parsedTag) {
37736 if ($verbose) {
37737 $this->io->writeError('<warning>Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json</warning>');
37738 }
37739 continue;
37740 }
37741
37742 if ($verbose) {
37743 $this->io->writeError('Importing tag '.$tag.' ('.$data['version_normalized'].')');
37744 }
37745
37746 $this->addPackage($this->loader->load($this->preProcess($driver, $data, $identifier)));
37747 } catch (\Exception $e) {
37748 if ($verbose) {
37749 $this->io->writeError('<warning>Skipped tag '.$tag.', '.($e instanceof TransportException ? 'no composer file was found' : $e->getMessage()).'</warning>');
37750 }
37751 continue;
37752 }
37753 }
37754
37755 if (!$verbose) {
37756 $this->io->overwriteError('', false);
37757 }
37758
37759 foreach ($driver->getBranches() as $branch => $identifier) {
37760 $msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $branch . '</comment>)';
37761 if ($verbose) {
37762 $this->io->writeError($msg);
37763 } else {
37764 $this->io->overwriteError($msg, false);
37765 }
37766
37767 if (!$parsedBranch = $this->validateBranch($branch)) {
37768 if ($verbose) {
37769 $this->io->writeError('<warning>Skipped branch '.$branch.', invalid name</warning>');
37770 }
37771 continue;
37772 }
37773
37774 try {
37775 if (!$data = $driver->getComposerInformation($identifier)) {
37776 if ($verbose) {
37777 $this->io->writeError('<warning>Skipped branch '.$branch.', no composer file</warning>');
37778 }
37779 continue;
37780 }
37781
37782
37783  $data['version'] = $branch;
37784 $data['version_normalized'] = $parsedBranch;
37785
37786
37787  if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) {
37788 $data['version'] = 'dev-' . $data['version'];
37789 } else {
37790 $prefix = substr($branch, 0, 1) === 'v' ? 'v' : '';
37791 $data['version'] = $prefix . preg_replace('{(\.9{7})+}', '.x', $parsedBranch);
37792 }
37793
37794 if ($verbose) {
37795 $this->io->writeError('Importing branch '.$branch.' ('.$data['version'].')');
37796 }
37797
37798 $packageData = $this->preProcess($driver, $data, $identifier);
37799 $package = $this->loader->load($packageData);
37800 if ($this->loader instanceof ValidatingArrayLoader && $this->loader->getWarnings()) {
37801 throw new InvalidPackageException($this->loader->getErrors(), $this->loader->getWarnings(), $packageData);
37802 }
37803 $this->addPackage($package);
37804 } catch (TransportException $e) {
37805 if ($verbose) {
37806 $this->io->writeError('<warning>Skipped branch '.$branch.', no composer file was found</warning>');
37807 }
37808 continue;
37809 } catch (\Exception $e) {
37810 if (!$verbose) {
37811 $this->io->writeError('');
37812 }
37813 $this->branchErrorOccurred = true;
37814 $this->io->writeError('<error>Skipped branch '.$branch.', '.$e->getMessage().'</error>');
37815 $this->io->writeError('');
37816 continue;
37817 }
37818 }
37819 $driver->cleanup();
37820
37821 if (!$verbose) {
37822 $this->io->overwriteError('', false);
37823 }
37824
37825 if (!$this->getPackages()) {
37826 throw new InvalidRepositoryException('No valid composer.json was found in any branch or tag of '.$this->url.', could not load a package from it.');
37827 }
37828 }
37829
37830 protected function preProcess(VcsDriverInterface $driver, array $data, $identifier)
37831 {
37832
37833  $data['name'] = $this->packageName ?: $data['name'];
37834
37835 if (!isset($data['dist'])) {
37836 $data['dist'] = $driver->getDist($identifier);
37837 }
37838 if (!isset($data['source'])) {
37839 $data['source'] = $driver->getSource($identifier);
37840 }
37841
37842 return $data;
37843 }
37844
37845 private function validateBranch($branch)
37846 {
37847 try {
37848 return $this->versionParser->normalizeBranch($branch);
37849 } catch (\Exception $e) {
37850 }
37851
37852 return false;
37853 }
37854
37855 private function validateTag($version)
37856 {
37857 try {
37858 return $this->versionParser->normalize($version);
37859 } catch (\Exception $e) {
37860 }
37861
37862 return false;
37863 }
37864 }
37865 <?php
37866
37867
37868
37869
37870
37871
37872
37873
37874
37875
37876
37877 namespace Composer\Repository;
37878
37879 use Composer\Package\AliasPackage;
37880
37881
37882
37883
37884
37885
37886 class WritableArrayRepository extends ArrayRepository implements WritableRepositoryInterface
37887 {
37888
37889
37890
37891 public function write()
37892 {
37893 }
37894
37895
37896
37897
37898 public function reload()
37899 {
37900 }
37901
37902
37903
37904
37905 public function getCanonicalPackages()
37906 {
37907 $packages = $this->getPackages();
37908
37909
37910  $packagesByName = array();
37911 foreach ($packages as $package) {
37912 if (!isset($packagesByName[$package->getName()]) || $packagesByName[$package->getName()] instanceof AliasPackage) {
37913 $packagesByName[$package->getName()] = $package;
37914 }
37915 }
37916
37917 $canonicalPackages = array();
37918
37919
37920  foreach ($packagesByName as $package) {
37921 while ($package instanceof AliasPackage) {
37922 $package = $package->getAliasOf();
37923 }
37924
37925 $canonicalPackages[] = $package;
37926 }
37927
37928 return $canonicalPackages;
37929 }
37930 }
37931 <?php
37932
37933
37934
37935
37936
37937
37938
37939
37940
37941
37942
37943 namespace Composer\Repository;
37944
37945 use Composer\Package\PackageInterface;
37946
37947
37948
37949
37950
37951
37952 interface WritableRepositoryInterface extends RepositoryInterface
37953 {
37954
37955
37956
37957 public function write();
37958
37959
37960
37961
37962
37963
37964 public function addPackage(PackageInterface $package);
37965
37966
37967
37968
37969
37970
37971 public function removePackage(PackageInterface $package);
37972
37973
37974
37975
37976
37977
37978 public function getCanonicalPackages();
37979
37980
37981
37982
37983 public function reload();
37984 }
37985 <?php
37986
37987
37988
37989
37990
37991
37992
37993
37994
37995
37996
37997 namespace Composer\Script;
37998
37999
38000
38001
38002
38003
38004 class CommandEvent extends Event
38005 {
38006 }
38007 <?php
38008
38009
38010
38011
38012
38013
38014
38015
38016
38017
38018
38019 namespace Composer\Script;
38020
38021 use Composer\Composer;
38022 use Composer\IO\IOInterface;
38023 use Composer\EventDispatcher\Event as BaseEvent;
38024
38025
38026
38027
38028
38029
38030
38031 class Event extends BaseEvent
38032 {
38033
38034
38035
38036 private $composer;
38037
38038
38039
38040
38041 private $io;
38042
38043
38044
38045
38046 private $devMode;
38047
38048
38049
38050
38051
38052
38053
38054
38055
38056
38057
38058 public function __construct($name, Composer $composer, IOInterface $io, $devMode = false, array $args = array(), array $flags = array())
38059 {
38060 parent::__construct($name, $args, $flags);
38061 $this->composer = $composer;
38062 $this->io = $io;
38063 $this->devMode = $devMode;
38064 }
38065
38066
38067
38068
38069
38070
38071 public function getComposer()
38072 {
38073 return $this->composer;
38074 }
38075
38076
38077
38078
38079
38080
38081 public function getIO()
38082 {
38083 return $this->io;
38084 }
38085
38086
38087
38088
38089
38090
38091 public function isDevMode()
38092 {
38093 return $this->devMode;
38094 }
38095 }
38096 <?php
38097
38098
38099
38100
38101
38102
38103
38104
38105
38106
38107
38108 namespace Composer\Script;
38109
38110 use Composer\Installer\PackageEvent as BasePackageEvent;
38111
38112
38113
38114
38115
38116
38117 class PackageEvent extends BasePackageEvent
38118 {
38119 }
38120 <?php
38121
38122
38123
38124
38125
38126
38127
38128
38129
38130
38131
38132 namespace Composer\Script;
38133
38134
38135
38136
38137
38138
38139
38140 class ScriptEvents
38141 {
38142
38143
38144
38145
38146
38147
38148
38149 const PRE_INSTALL_CMD = 'pre-install-cmd';
38150
38151
38152
38153
38154
38155
38156
38157
38158 const POST_INSTALL_CMD = 'post-install-cmd';
38159
38160
38161
38162
38163
38164
38165
38166
38167 const PRE_UPDATE_CMD = 'pre-update-cmd';
38168
38169
38170
38171
38172
38173
38174
38175
38176 const POST_UPDATE_CMD = 'post-update-cmd';
38177
38178
38179
38180
38181
38182
38183
38184
38185 const PRE_STATUS_CMD = 'pre-status-cmd';
38186
38187
38188
38189
38190
38191
38192
38193
38194 const POST_STATUS_CMD = 'post-status-cmd';
38195
38196
38197
38198
38199
38200
38201
38202
38203 const PRE_AUTOLOAD_DUMP = 'pre-autoload-dump';
38204
38205
38206
38207
38208
38209
38210
38211
38212 const POST_AUTOLOAD_DUMP = 'post-autoload-dump';
38213
38214
38215
38216
38217
38218
38219
38220
38221 const POST_ROOT_PACKAGE_INSTALL = 'post-root-package-install';
38222
38223
38224
38225
38226
38227
38228
38229
38230
38231 const POST_CREATE_PROJECT_CMD = 'post-create-project-cmd';
38232
38233
38234
38235
38236
38237
38238
38239
38240 const PRE_ARCHIVE_CMD = 'pre-archive-cmd';
38241
38242
38243
38244
38245
38246
38247
38248
38249 const POST_ARCHIVE_CMD = 'post-archive-cmd';
38250
38251
38252
38253
38254
38255
38256
38257
38258
38259
38260
38261 const PRE_PACKAGE_INSTALL = 'pre-package-install';
38262
38263
38264
38265
38266
38267
38268
38269
38270
38271 const POST_PACKAGE_INSTALL = 'post-package-install';
38272
38273
38274
38275
38276
38277
38278
38279
38280
38281 const PRE_PACKAGE_UPDATE = 'pre-package-update';
38282
38283
38284
38285
38286
38287
38288
38289
38290
38291 const POST_PACKAGE_UPDATE = 'post-package-update';
38292
38293
38294
38295
38296
38297
38298
38299
38300
38301 const PRE_PACKAGE_UNINSTALL = 'pre-package-uninstall';
38302
38303
38304
38305
38306
38307
38308
38309
38310
38311 const POST_PACKAGE_UNINSTALL = 'post-package-uninstall';
38312 }
38313 <?php
38314
38315
38316
38317
38318
38319
38320
38321
38322
38323
38324
38325 namespace Composer\SelfUpdate;
38326
38327
38328
38329
38330 class Keys
38331 {
38332 public static function fingerprint($path)
38333 {
38334 $hash = strtoupper(hash('sha256', preg_replace('{\s}', '', file_get_contents($path))));
38335
38336 return implode(' ', array(
38337 substr($hash, 0, 8),
38338 substr($hash, 8, 8),
38339 substr($hash, 16, 8),
38340 substr($hash, 24, 8),
38341 '', 
38342  substr($hash, 32, 8),
38343 substr($hash, 40, 8),
38344 substr($hash, 48, 8),
38345 substr($hash, 56, 8),
38346 ));
38347 }
38348 }
38349 <?php
38350
38351
38352
38353
38354
38355
38356
38357
38358
38359
38360
38361 namespace Composer\SelfUpdate;
38362
38363 use Composer\Util\RemoteFilesystem;
38364 use Composer\Config;
38365 use Composer\Json\JsonFile;
38366
38367
38368
38369
38370 class Versions
38371 {
38372 private $rfs;
38373 private $config;
38374 private $channel;
38375
38376 public function __construct(Config $config, RemoteFilesystem $rfs)
38377 {
38378 $this->rfs = $rfs;
38379 $this->config = $config;
38380 }
38381
38382 public function getChannel()
38383 {
38384 if ($this->channel) {
38385 return $this->channel;
38386 }
38387
38388 $channelFile = $this->config->get('home').'/update-channel';
38389 if (file_exists($channelFile)) {
38390 $channel = trim(file_get_contents($channelFile));
38391 if (in_array($channel, array('stable', 'preview', 'snapshot'), true)) {
38392 return $this->channel = $channel;
38393 }
38394 }
38395
38396 return $this->channel = 'stable';
38397 }
38398
38399 public function setChannel($channel)
38400 {
38401 if (!in_array($channel, array('stable', 'preview', 'snapshot'), true)) {
38402 throw new \InvalidArgumentException('Invalid channel '.$channel.', must be one of: stable, preview, snapshot');
38403 }
38404
38405 $channelFile = $this->config->get('home').'/update-channel';
38406 $this->channel = $channel;
38407 file_put_contents($channelFile, $channel.PHP_EOL);
38408 }
38409
38410 public function getLatest()
38411 {
38412 $protocol = extension_loaded('openssl') ? 'https' : 'http';
38413 $versions = JsonFile::parseJson($this->rfs->getContents('getcomposer.org', $protocol . '://getcomposer.org/versions', false));
38414
38415 foreach ($versions[$this->getChannel()] as $version) {
38416 if ($version['min-php'] <= PHP_VERSION_ID) {
38417 return $version;
38418 }
38419 }
38420
38421 throw new \LogicException('There is no version of Composer available for your PHP version ('.PHP_VERSION.')');
38422 }
38423 }
38424 <?php
38425
38426
38427
38428
38429
38430
38431
38432
38433
38434
38435
38436 namespace Composer\Util;
38437
38438 use Composer\Config;
38439 use Composer\IO\IOInterface;
38440
38441
38442
38443
38444 class AuthHelper
38445 {
38446 protected $io;
38447 protected $config;
38448
38449 public function __construct(IOInterface $io, Config $config)
38450 {
38451 $this->io = $io;
38452 $this->config = $config;
38453 }
38454
38455 public function storeAuth($originUrl, $storeAuth)
38456 {
38457 $store = false;
38458 $configSource = $this->config->getAuthConfigSource();
38459 if ($storeAuth === true) {
38460 $store = $configSource;
38461 } elseif ($storeAuth === 'prompt') {
38462 $answer = $this->io->askAndValidate(
38463 'Do you want to store credentials for '.$originUrl.' in '.$configSource->getName().' ? [Yn] ',
38464 function ($value) {
38465 $input = strtolower(substr(trim($value), 0, 1));
38466 if (in_array($input, array('y','n'))) {
38467 return $input;
38468 }
38469 throw new \RuntimeException('Please answer (y)es or (n)o');
38470 },
38471 null,
38472 'y'
38473 );
38474
38475 if ($answer === 'y') {
38476 $store = $configSource;
38477 }
38478 }
38479 if ($store) {
38480 $store->addConfigSetting(
38481 'http-basic.'.$originUrl,
38482 $this->io->getAuthentication($originUrl)
38483 );
38484 }
38485 }
38486 }
38487 <?php
38488
38489
38490
38491
38492
38493
38494
38495
38496
38497
38498
38499 namespace Composer\Util;
38500
38501 use Composer\Factory;
38502 use Composer\IO\IOInterface;
38503 use Composer\Config;
38504 use Composer\Downloader\TransportException;
38505
38506
38507
38508
38509 class Bitbucket
38510 {
38511 private $io;
38512 private $config;
38513 private $process;
38514 private $remoteFilesystem;
38515 private $token = array();
38516 private $time;
38517
38518 const OAUTH2_ACCESS_TOKEN_URL = 'https://bitbucket.org/site/oauth2/access_token';
38519
38520
38521
38522
38523
38524
38525
38526
38527
38528
38529 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null, $time = null)
38530 {
38531 $this->io = $io;
38532 $this->config = $config;
38533 $this->process = $process ?: new ProcessExecutor;
38534 $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
38535 $this->time = $time;
38536 }
38537
38538
38539
38540
38541 public function getToken()
38542 {
38543 if (!isset($this->token['access_token'])) {
38544 return '';
38545 }
38546
38547 return $this->token['access_token'];
38548 }
38549
38550
38551
38552
38553
38554
38555
38556 public function authorizeOAuth($originUrl)
38557 {
38558 if ($originUrl !== 'bitbucket.org') {
38559 return false;
38560 }
38561
38562
38563  if (0 === $this->process->execute('git config bitbucket.accesstoken', $output)) {
38564 $this->io->setAuthentication($originUrl, 'x-token-auth', trim($output));
38565
38566 return true;
38567 }
38568
38569 return false;
38570 }
38571
38572
38573
38574
38575
38576 private function requestAccessToken($originUrl)
38577 {
38578 try {
38579 $json = $this->remoteFilesystem->getContents($originUrl, self::OAUTH2_ACCESS_TOKEN_URL, false, array(
38580 'retry-auth-failure' => false,
38581 'http' => array(
38582 'method' => 'POST',
38583 'content' => 'grant_type=client_credentials',
38584 ),
38585 ));
38586
38587 $this->token = json_decode($json, true);
38588 } catch (TransportException $e) {
38589 if ($e->getCode() === 400) {
38590 $this->io->writeError('<error>Invalid OAuth consumer provided.</error>');
38591 $this->io->writeError('This can have two reasons:');
38592 $this->io->writeError('1. You are authenticating with a bitbucket username/password combination');
38593 $this->io->writeError('2. You are using an OAuth consumer, but didn\'t configure a (dummy) callback url');
38594
38595 return false;
38596 } elseif (in_array($e->getCode(), array(403, 401))) {
38597 $this->io->writeError('<error>Invalid OAuth consumer provided.</error>');
38598 $this->io->writeError('You can also add it manually later by using "composer config bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>"');
38599
38600 return false;
38601 }
38602
38603 throw $e;
38604 }
38605
38606 return true;
38607 }
38608
38609
38610
38611
38612
38613
38614
38615
38616
38617
38618 public function authorizeOAuthInteractively($originUrl, $message = null)
38619 {
38620 if ($message) {
38621 $this->io->writeError($message);
38622 }
38623
38624 $url = 'https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html';
38625 $this->io->writeError(sprintf('Follow the instructions on %s', $url));
38626 $this->io->writeError(sprintf('to create a consumer. It will be stored in "%s" for future use by Composer.', $this->config->getAuthConfigSource()->getName()));
38627 $this->io->writeError('Ensure you enter a "Callback URL" (http://example.com is fine) or it will not be possible to create an Access Token (this callback url will not be used by composer)');
38628
38629 $consumerKey = trim($this->io->askAndHideAnswer('Consumer Key (hidden): '));
38630
38631 if (!$consumerKey) {
38632 $this->io->writeError('<warning>No consumer key given, aborting.</warning>');
38633 $this->io->writeError('You can also add it manually later by using "composer config bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>"');
38634
38635 return false;
38636 }
38637
38638 $consumerSecret = trim($this->io->askAndHideAnswer('Consumer Secret (hidden): '));
38639
38640 if (!$consumerSecret) {
38641 $this->io->writeError('<warning>No consumer secret given, aborting.</warning>');
38642 $this->io->writeError('You can also add it manually later by using "composer config bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>"');
38643
38644 return false;
38645 }
38646
38647 $this->io->setAuthentication($originUrl, $consumerKey, $consumerSecret);
38648
38649 if (!$this->requestAccessToken($originUrl)) {
38650 return false;
38651 }
38652
38653
38654  $this->storeInAuthConfig($originUrl, $consumerKey, $consumerSecret);
38655
38656
38657  $this->config->getAuthConfigSource()->removeConfigSetting('http-basic.' . $originUrl);
38658
38659 $this->io->writeError('<info>Consumer stored successfully.</info>');
38660
38661 return true;
38662 }
38663
38664
38665
38666
38667
38668
38669
38670
38671
38672 public function requestToken($originUrl, $consumerKey, $consumerSecret)
38673 {
38674 if (!empty($this->token) || $this->getTokenFromConfig($originUrl)) {
38675 return $this->token['access_token'];
38676 }
38677
38678 $this->io->setAuthentication($originUrl, $consumerKey, $consumerSecret);
38679 if (!$this->requestAccessToken($originUrl)) {
38680 return '';
38681 }
38682
38683 $this->storeInAuthConfig($originUrl, $consumerKey, $consumerSecret);
38684
38685 return $this->token['access_token'];
38686 }
38687
38688
38689
38690
38691
38692
38693
38694 private function storeInAuthConfig($originUrl, $consumerKey, $consumerSecret)
38695 {
38696 $this->config->getConfigSource()->removeConfigSetting('bitbucket-oauth.'.$originUrl);
38697
38698 $time = null === $this->time ? time() : $this->time;
38699 $consumer = array(
38700 "consumer-key" => $consumerKey,
38701 "consumer-secret" => $consumerSecret,
38702 "access-token" => $this->token['access_token'],
38703 "access-token-expiration" => $time + $this->token['expires_in'],
38704 );
38705
38706 $this->config->getAuthConfigSource()->addConfigSetting('bitbucket-oauth.'.$originUrl, $consumer);
38707 }
38708
38709
38710
38711
38712
38713 private function getTokenFromConfig($originUrl)
38714 {
38715 $authConfig = $this->config->get('bitbucket-oauth');
38716
38717 if (
38718 !isset($authConfig[$originUrl]['access-token'])
38719 || !isset($authConfig[$originUrl]['access-token-expiration'])
38720 || time() > $authConfig[$originUrl]['access-token-expiration']
38721 ) {
38722 return false;
38723 }
38724
38725 $this->token = array(
38726 'access_token' => $authConfig[$originUrl]['access-token'],
38727 );
38728
38729 return true;
38730 }
38731 }
38732 <?php
38733
38734
38735
38736
38737
38738
38739
38740
38741
38742
38743
38744 namespace Composer\Util;
38745
38746
38747
38748
38749
38750
38751 class ComposerMirror
38752 {
38753 public static function processUrl($mirrorUrl, $packageName, $version, $reference, $type)
38754 {
38755 if ($reference) {
38756 $reference = preg_match('{^([a-f0-9]*|%reference%)$}', $reference) ? $reference : md5($reference);
38757 }
38758 $version = strpos($version, '/') === false ? $version : md5($version);
38759
38760 return str_replace(
38761 array('%package%', '%version%', '%reference%', '%type%'),
38762 array($packageName, $version, $reference, $type),
38763 $mirrorUrl
38764 );
38765 }
38766
38767 public static function processGitUrl($mirrorUrl, $packageName, $url, $type)
38768 {
38769 if (preg_match('#^(?:(?:https?|git)://github\.com/|git@github\.com:)([^/]+)/(.+?)(?:\.git)?$#', $url, $match)) {
38770 $url = 'gh-'.$match[1].'/'.$match[2];
38771 } elseif (preg_match('#^https://bitbucket\.org/([^/]+)/(.+?)(?:\.git)?/?$#', $url, $match)) {
38772 $url = 'bb-'.$match[1].'/'.$match[2];
38773 } else {
38774 $url = preg_replace('{[^a-z0-9_.-]}i', '-', trim($url, '/'));
38775 }
38776
38777 return str_replace(
38778 array('%package%', '%normalizedUrl%', '%type%'),
38779 array($packageName, $url, $type),
38780 $mirrorUrl
38781 );
38782 }
38783
38784 public static function processHgUrl($mirrorUrl, $packageName, $url, $type)
38785 {
38786 return self::processGitUrl($mirrorUrl, $packageName, $url, $type);
38787 }
38788 }
38789 <?php
38790
38791
38792
38793
38794
38795
38796
38797
38798
38799
38800
38801 namespace Composer\Util;
38802
38803 use Composer\Package\Loader\ArrayLoader;
38804 use Composer\Package\Loader\ValidatingArrayLoader;
38805 use Composer\Package\Loader\InvalidPackageException;
38806 use Composer\Json\JsonValidationException;
38807 use Composer\IO\IOInterface;
38808 use Composer\Json\JsonFile;
38809 use Composer\Spdx\SpdxLicenses;
38810
38811
38812
38813
38814
38815
38816
38817 class ConfigValidator
38818 {
38819 private $io;
38820
38821 public function __construct(IOInterface $io)
38822 {
38823 $this->io = $io;
38824 }
38825
38826
38827
38828
38829
38830
38831
38832
38833
38834 public function validate($file, $arrayLoaderValidationFlags = ValidatingArrayLoader::CHECK_ALL)
38835 {
38836 $errors = array();
38837 $publishErrors = array();
38838 $warnings = array();
38839
38840
38841  $laxValid = false;
38842 try {
38843 $json = new JsonFile($file, null, $this->io);
38844 $manifest = $json->read();
38845
38846 $json->validateSchema(JsonFile::LAX_SCHEMA);
38847 $laxValid = true;
38848 $json->validateSchema();
38849 } catch (JsonValidationException $e) {
38850 foreach ($e->getErrors() as $message) {
38851 if ($laxValid) {
38852 $publishErrors[] = $message;
38853 } else {
38854 $errors[] = $message;
38855 }
38856 }
38857 } catch (\Exception $e) {
38858 $errors[] = $e->getMessage();
38859
38860 return array($errors, $publishErrors, $warnings);
38861 }
38862
38863
38864  if (!empty($manifest['license'])) {
38865
38866  if (is_array($manifest['license'])) {
38867 foreach ($manifest['license'] as $key => $license) {
38868 if ('proprietary' === $license) {
38869 unset($manifest['license'][$key]);
38870 }
38871 }
38872 }
38873
38874 $licenseValidator = new SpdxLicenses();
38875 if ('proprietary' !== $manifest['license'] && array() !== $manifest['license'] && !$licenseValidator->validate($manifest['license'])) {
38876 $warnings[] = sprintf(
38877 'License %s is not a valid SPDX license identifier, see https://spdx.org/licenses/ if you use an open license.'
38878 ."\nIf the software is closed-source, you may use \"proprietary\" as license.",
38879 json_encode($manifest['license'])
38880 );
38881 }
38882 } else {
38883 $warnings[] = 'No license specified, it is recommended to do so. For closed-source software you may use "proprietary" as license.';
38884 }
38885
38886 if (isset($manifest['version'])) {
38887 $warnings[] = 'The version field is present, it is recommended to leave it out if the package is published on Packagist.';
38888 }
38889
38890 if (!empty($manifest['name']) && preg_match('{[A-Z]}', $manifest['name'])) {
38891 $suggestName = preg_replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $manifest['name']);
38892 $suggestName = strtolower($suggestName);
38893
38894 $publishErrors[] = sprintf(
38895 'Name "%s" does not match the best practice (e.g. lower-cased/with-dashes). We suggest using "%s" instead. As such you will not be able to submit it to Packagist.',
38896 $manifest['name'],
38897 $suggestName
38898 );
38899 }
38900
38901 if (!empty($manifest['type']) && $manifest['type'] == 'composer-installer') {
38902 $warnings[] = "The package type 'composer-installer' is deprecated. Please distribute your custom installers as plugins from now on. See https://getcomposer.org/doc/articles/plugins.md for plugin documentation.";
38903 }
38904
38905
38906  if (isset($manifest['require']) && isset($manifest['require-dev'])) {
38907 $requireOverrides = array_intersect_key($manifest['require'], $manifest['require-dev']);
38908
38909 if (!empty($requireOverrides)) {
38910 $plural = (count($requireOverrides) > 1) ? 'are' : 'is';
38911 $warnings[] = implode(', ', array_keys($requireOverrides)). " {$plural} required both in require and require-dev, this can lead to unexpected behavior";
38912 }
38913 }
38914
38915
38916  $require = isset($manifest['require']) ? $manifest['require'] : array();
38917 $requireDev = isset($manifest['require-dev']) ? $manifest['require-dev'] : array();
38918 $packages = array_merge($require, $requireDev);
38919 foreach ($packages as $package => $version) {
38920 if (preg_match('/#/', $version) === 1) {
38921 $warnings[] = sprintf(
38922 'The package "%s" is pointing to a commit-ref, this is bad practice and can cause unforeseen issues.',
38923 $package
38924 );
38925 }
38926 }
38927
38928
38929  if (isset($manifest['autoload']['psr-0'][''])) {
38930 $warnings[] = "Defining autoload.psr-0 with an empty namespace prefix is a bad idea for performance";
38931 }
38932 if (isset($manifest['autoload']['psr-4'][''])) {
38933 $warnings[] = "Defining autoload.psr-4 with an empty namespace prefix is a bad idea for performance";
38934 }
38935
38936 try {
38937 $loader = new ValidatingArrayLoader(new ArrayLoader(), true, null, $arrayLoaderValidationFlags);
38938 if (!isset($manifest['version'])) {
38939 $manifest['version'] = '1.0.0';
38940 }
38941 if (!isset($manifest['name'])) {
38942 $manifest['name'] = 'dummy/dummy';
38943 }
38944 $loader->load($manifest);
38945 } catch (InvalidPackageException $e) {
38946 $errors = array_merge($errors, $e->getErrors());
38947 }
38948
38949 $warnings = array_merge($warnings, $loader->getWarnings());
38950
38951 return array($errors, $publishErrors, $warnings);
38952 }
38953 }
38954 <?php
38955
38956
38957
38958
38959
38960
38961
38962
38963
38964
38965
38966 namespace Composer\Util;
38967
38968 use Composer\IO\IOInterface;
38969
38970
38971
38972
38973
38974
38975 class ErrorHandler
38976 {
38977 private static $io;
38978
38979
38980
38981
38982
38983
38984
38985
38986
38987
38988
38989
38990 public static function handle($level, $message, $file, $line)
38991 {
38992
38993  if (!(error_reporting() & $level)) {
38994 return;
38995 }
38996
38997 if (ini_get('xdebug.scream')) {
38998 $message .= "\n\nWarning: You have xdebug.scream enabled, the warning above may be".
38999 "\na legitimately suppressed error that you were not supposed to see.";
39000 }
39001
39002 if ($level !== E_DEPRECATED && $level !== E_USER_DEPRECATED) {
39003 throw new \ErrorException($message, 0, $level, $file, $line);
39004 }
39005
39006 if (self::$io) {
39007 self::$io->writeError('<warning>Deprecation Notice: '.$message.' in '.$file.':'.$line.'</warning>');
39008 if (self::$io->isVerbose()) {
39009 self::$io->writeError('<warning>Stack trace:</warning>');
39010 self::$io->writeError(array_filter(array_map(function ($a) {
39011 if (isset($a['line'], $a['file'])) {
39012 return '<warning> '.$a['file'].':'.$a['line'].'</warning>';
39013 }
39014
39015 return null;
39016 }, array_slice(debug_backtrace(), 2))));
39017 }
39018 }
39019 }
39020
39021
39022
39023
39024
39025
39026 public static function register(IOInterface $io = null)
39027 {
39028 set_error_handler(array(__CLASS__, 'handle'));
39029 error_reporting(E_ALL | E_STRICT);
39030 self::$io = $io;
39031 }
39032 }
39033 <?php
39034
39035
39036
39037
39038
39039
39040
39041
39042
39043
39044
39045 namespace Composer\Util;
39046
39047 use RecursiveDirectoryIterator;
39048 use RecursiveIteratorIterator;
39049 use Symfony\Component\Filesystem\Exception\IOException;
39050 use Symfony\Component\Finder\Finder;
39051
39052
39053
39054
39055
39056 class Filesystem
39057 {
39058 private $processExecutor;
39059
39060 public function __construct(ProcessExecutor $executor = null)
39061 {
39062 $this->processExecutor = $executor ?: new ProcessExecutor();
39063 }
39064
39065 public function remove($file)
39066 {
39067 if (is_dir($file)) {
39068 return $this->removeDirectory($file);
39069 }
39070
39071 if (file_exists($file)) {
39072 return $this->unlink($file);
39073 }
39074
39075 return false;
39076 }
39077
39078
39079
39080
39081
39082
39083
39084 public function isDirEmpty($dir)
39085 {
39086 $finder = Finder::create()
39087 ->ignoreVCS(false)
39088 ->ignoreDotFiles(false)
39089 ->depth(0)
39090 ->in($dir);
39091
39092 return count($finder) === 0;
39093 }
39094
39095 public function emptyDirectory($dir, $ensureDirectoryExists = true)
39096 {
39097 if (file_exists($dir) && is_link($dir)) {
39098 $this->unlink($dir);
39099 }
39100
39101 if ($ensureDirectoryExists) {
39102 $this->ensureDirectoryExists($dir);
39103 }
39104
39105 if (is_dir($dir)) {
39106 $finder = Finder::create()
39107 ->ignoreVCS(false)
39108 ->ignoreDotFiles(false)
39109 ->depth(0)
39110 ->in($dir);
39111
39112 foreach ($finder as $path) {
39113 $this->remove((string) $path);
39114 }
39115 }
39116 }
39117
39118
39119
39120
39121
39122
39123
39124
39125
39126
39127
39128 public function removeDirectory($directory)
39129 {
39130 if ($this->isSymlinkedDirectory($directory)) {
39131 return $this->unlinkSymlinkedDirectory($directory);
39132 }
39133
39134 if ($this->isJunction($directory)) {
39135 return $this->removeJunction($directory);
39136 }
39137
39138 if (!file_exists($directory) || !is_dir($directory)) {
39139 return true;
39140 }
39141
39142 if (preg_match('{^(?:[a-z]:)?[/\\\\]+$}i', $directory)) {
39143 throw new \RuntimeException('Aborting an attempted deletion of '.$directory.', this was probably not intended, if it is a real use case please report it.');
39144 }
39145
39146 if (!function_exists('proc_open')) {
39147 return $this->removeDirectoryPhp($directory);
39148 }
39149
39150 if (Platform::isWindows()) {
39151 $cmd = sprintf('rmdir /S /Q %s', ProcessExecutor::escape(realpath($directory)));
39152 } else {
39153 $cmd = sprintf('rm -rf %s', ProcessExecutor::escape($directory));
39154 }
39155
39156 $result = $this->getProcess()->execute($cmd, $output) === 0;
39157
39158
39159  clearstatcache();
39160
39161 if ($result && !file_exists($directory)) {
39162 return true;
39163 }
39164
39165 return $this->removeDirectoryPhp($directory);
39166 }
39167
39168
39169
39170
39171
39172
39173
39174
39175
39176
39177
39178 public function removeDirectoryPhp($directory)
39179 {
39180 try {
39181 $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
39182 } catch (\UnexpectedValueException $e) {
39183
39184  
39185  clearstatcache();
39186 usleep(100000);
39187 if (!is_dir($directory)) {
39188 return true;
39189 }
39190 $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
39191 }
39192 $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
39193
39194 foreach ($ri as $file) {
39195 if ($file->isDir()) {
39196 $this->rmdir($file->getPathname());
39197 } else {
39198 $this->unlink($file->getPathname());
39199 }
39200 }
39201
39202 return $this->rmdir($directory);
39203 }
39204
39205 public function ensureDirectoryExists($directory)
39206 {
39207 if (!is_dir($directory)) {
39208 if (file_exists($directory)) {
39209 throw new \RuntimeException(
39210 $directory.' exists and is not a directory.'
39211 );
39212 }
39213 if (!@mkdir($directory, 0777, true)) {
39214 throw new \RuntimeException(
39215 $directory.' does not exist and could not be created.'
39216 );
39217 }
39218 }
39219 }
39220
39221
39222
39223
39224
39225
39226
39227
39228 public function unlink($path)
39229 {
39230 if (!@$this->unlinkImplementation($path)) {
39231
39232  if (!Platform::isWindows() || (usleep(350000) && !@$this->unlinkImplementation($path))) {
39233 $error = error_get_last();
39234 $message = 'Could not delete '.$path.': ' . @$error['message'];
39235 if (Platform::isWindows()) {
39236 $message .= "\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed";
39237 }
39238
39239 throw new \RuntimeException($message);
39240 }
39241 }
39242
39243 return true;
39244 }
39245
39246
39247
39248
39249
39250
39251
39252
39253 public function rmdir($path)
39254 {
39255 if (!@rmdir($path)) {
39256
39257  if (!Platform::isWindows() || (usleep(350000) && !@rmdir($path))) {
39258 $error = error_get_last();
39259 $message = 'Could not delete '.$path.': ' . @$error['message'];
39260 if (Platform::isWindows()) {
39261 $message .= "\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed";
39262 }
39263
39264 throw new \RuntimeException($message);
39265 }
39266 }
39267
39268 return true;
39269 }
39270
39271
39272
39273
39274
39275
39276
39277
39278
39279
39280 public function copyThenRemove($source, $target)
39281 {
39282 if (!is_dir($source)) {
39283 copy($source, $target);
39284 $this->unlink($source);
39285
39286 return;
39287 }
39288
39289 $it = new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS);
39290 $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
39291 $this->ensureDirectoryExists($target);
39292
39293 foreach ($ri as $file) {
39294 $targetPath = $target . DIRECTORY_SEPARATOR . $ri->getSubPathName();
39295 if ($file->isDir()) {
39296 $this->ensureDirectoryExists($targetPath);
39297 } else {
39298 copy($file->getPathname(), $targetPath);
39299 }
39300 }
39301
39302 $this->removeDirectoryPhp($source);
39303 }
39304
39305 public function rename($source, $target)
39306 {
39307 if (true === @rename($source, $target)) {
39308 return;
39309 }
39310
39311 if (!function_exists('proc_open')) {
39312 return $this->copyThenRemove($source, $target);
39313 }
39314
39315 if (Platform::isWindows()) {
39316
39317  $command = sprintf('xcopy %s %s /E /I /Q /Y', ProcessExecutor::escape($source), ProcessExecutor::escape($target));
39318 $result = $this->processExecutor->execute($command, $output);
39319
39320
39321  clearstatcache();
39322
39323 if (0 === $result) {
39324 $this->remove($source);
39325
39326 return;
39327 }
39328 } else {
39329
39330  
39331  $command = sprintf('mv %s %s', ProcessExecutor::escape($source), ProcessExecutor::escape($target));
39332 $result = $this->processExecutor->execute($command, $output);
39333
39334
39335  clearstatcache();
39336
39337 if (0 === $result) {
39338 return;
39339 }
39340 }
39341
39342 return $this->copyThenRemove($source, $target);
39343 }
39344
39345
39346
39347
39348
39349
39350
39351
39352
39353
39354 public function findShortestPath($from, $to, $directories = false)
39355 {
39356 if (!$this->isAbsolutePath($from) || !$this->isAbsolutePath($to)) {
39357 throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
39358 }
39359
39360 $from = lcfirst($this->normalizePath($from));
39361 $to = lcfirst($this->normalizePath($to));
39362
39363 if ($directories) {
39364 $from = rtrim($from, '/') . '/dummy_file';
39365 }
39366
39367 if (dirname($from) === dirname($to)) {
39368 return './'.basename($to);
39369 }
39370
39371 $commonPath = $to;
39372 while (strpos($from.'/', $commonPath.'/') !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/?$}i', $commonPath)) {
39373 $commonPath = strtr(dirname($commonPath), '\\', '/');
39374 }
39375
39376 if (0 !== strpos($from, $commonPath) || '/' === $commonPath) {
39377 return $to;
39378 }
39379
39380 $commonPath = rtrim($commonPath, '/') . '/';
39381 $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/');
39382 $commonPathCode = str_repeat('../', $sourcePathDepth);
39383
39384 return ($commonPathCode . substr($to, strlen($commonPath))) ?: './';
39385 }
39386
39387
39388
39389
39390
39391
39392
39393
39394
39395
39396
39397 public function findShortestPathCode($from, $to, $directories = false, $staticCode = false)
39398 {
39399 if (!$this->isAbsolutePath($from) || !$this->isAbsolutePath($to)) {
39400 throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
39401 }
39402
39403 $from = lcfirst($this->normalizePath($from));
39404 $to = lcfirst($this->normalizePath($to));
39405
39406 if ($from === $to) {
39407 return $directories ? '__DIR__' : '__FILE__';
39408 }
39409
39410 $commonPath = $to;
39411 while (strpos($from.'/', $commonPath.'/') !== 0 && '/' !== $commonPath && !preg_match('{^[a-z]:/?$}i', $commonPath) && '.' !== $commonPath) {
39412 $commonPath = strtr(dirname($commonPath), '\\', '/');
39413 }
39414
39415 if (0 !== strpos($from, $commonPath) || '/' === $commonPath || '.' === $commonPath) {
39416 return var_export($to, true);
39417 }
39418
39419 $commonPath = rtrim($commonPath, '/') . '/';
39420 if (strpos($to, $from.'/') === 0) {
39421 return '__DIR__ . '.var_export(substr($to, strlen($from)), true);
39422 }
39423 $sourcePathDepth = substr_count(substr($from, strlen($commonPath)), '/') + $directories;
39424 if ($staticCode) {
39425 $commonPathCode = "__DIR__ . '".str_repeat('/..', $sourcePathDepth)."'";
39426 } else {
39427 $commonPathCode = str_repeat('dirname(', $sourcePathDepth).'__DIR__'.str_repeat(')', $sourcePathDepth);
39428 }
39429 $relTarget = substr($to, strlen($commonPath));
39430
39431 return $commonPathCode . (strlen($relTarget) ? '.' . var_export('/' . $relTarget, true) : '');
39432 }
39433
39434
39435
39436
39437
39438
39439
39440 public function isAbsolutePath($path)
39441 {
39442 return substr($path, 0, 1) === '/' || substr($path, 1, 1) === ':';
39443 }
39444
39445
39446
39447
39448
39449
39450
39451
39452
39453 public function size($path)
39454 {
39455 if (!file_exists($path)) {
39456 throw new \RuntimeException("$path does not exist.");
39457 }
39458 if (is_dir($path)) {
39459 return $this->directorySize($path);
39460 }
39461
39462 return filesize($path);
39463 }
39464
39465
39466
39467
39468
39469
39470
39471
39472 public function normalizePath($path)
39473 {
39474 $parts = array();
39475 $path = strtr($path, '\\', '/');
39476 $prefix = '';
39477 $absolute = false;
39478
39479
39480  if (preg_match('{^( [0-9a-z]{2,}+: (?: // (?: [a-z]: )? )? | [a-z]: )}ix', $path, $match)) {
39481 $prefix = $match[1];
39482 $path = substr($path, strlen($prefix));
39483 }
39484
39485 if (substr($path, 0, 1) === '/') {
39486 $absolute = true;
39487 $path = substr($path, 1);
39488 }
39489
39490 $up = false;
39491 foreach (explode('/', $path) as $chunk) {
39492 if ('..' === $chunk && ($absolute || $up)) {
39493 array_pop($parts);
39494 $up = !(empty($parts) || '..' === end($parts));
39495 } elseif ('.' !== $chunk && '' !== $chunk) {
39496 $parts[] = $chunk;
39497 $up = '..' !== $chunk;
39498 }
39499 }
39500
39501 return $prefix.($absolute ? '/' : '').implode('/', $parts);
39502 }
39503
39504
39505
39506
39507
39508
39509
39510 public static function isLocalPath($path)
39511 {
39512 return (bool) preg_match('{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path);
39513 }
39514
39515 public static function getPlatformPath($path)
39516 {
39517 if (Platform::isWindows()) {
39518 $path = preg_replace('{^(?:file:///([a-z]):?/)}i', 'file://$1:/', $path);
39519 }
39520
39521 return preg_replace('{^file://}i', '', $path);
39522 }
39523
39524 protected function directorySize($directory)
39525 {
39526 $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
39527 $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
39528
39529 $size = 0;
39530 foreach ($ri as $file) {
39531 if ($file->isFile()) {
39532 $size += $file->getSize();
39533 }
39534 }
39535
39536 return $size;
39537 }
39538
39539 protected function getProcess()
39540 {
39541 return new ProcessExecutor;
39542 }
39543
39544
39545
39546
39547
39548
39549
39550
39551
39552
39553 private function unlinkImplementation($path)
39554 {
39555 if (Platform::isWindows() && is_dir($path) && is_link($path)) {
39556 return rmdir($path);
39557 }
39558
39559 return unlink($path);
39560 }
39561
39562
39563
39564
39565
39566
39567
39568
39569 public function relativeSymlink($target, $link)
39570 {
39571 $cwd = getcwd();
39572
39573 $relativePath = $this->findShortestPath($link, $target);
39574 chdir(dirname($link));
39575 $result = @symlink($relativePath, $link);
39576
39577 chdir($cwd);
39578
39579 return (bool) $result;
39580 }
39581
39582
39583
39584
39585
39586
39587
39588
39589 public function isSymlinkedDirectory($directory)
39590 {
39591 if (!is_dir($directory)) {
39592 return false;
39593 }
39594
39595 $resolved = $this->resolveSymlinkedDirectorySymlink($directory);
39596
39597 return is_link($resolved);
39598 }
39599
39600
39601
39602
39603
39604
39605 private function unlinkSymlinkedDirectory($directory)
39606 {
39607 $resolved = $this->resolveSymlinkedDirectorySymlink($directory);
39608
39609 return $this->unlink($resolved);
39610 }
39611
39612
39613
39614
39615
39616
39617
39618
39619 private function resolveSymlinkedDirectorySymlink($pathname)
39620 {
39621 if (!is_dir($pathname)) {
39622 return $pathname;
39623 }
39624
39625 $resolved = rtrim($pathname, '/');
39626
39627 if (!strlen($resolved)) {
39628 return $pathname;
39629 }
39630
39631 return $resolved;
39632 }
39633
39634
39635
39636
39637
39638
39639
39640 public function junction($target, $junction)
39641 {
39642 if (!Platform::isWindows()) {
39643 throw new \LogicException(sprintf('Function %s is not available on non-Windows platform', __CLASS__));
39644 }
39645 if (!is_dir($target)) {
39646 throw new IOException(sprintf('Cannot junction to "%s" as it is not a directory.', $target), 0, null, $target);
39647 }
39648 $cmd = sprintf('mklink /J %s %s',
39649 ProcessExecutor::escape(str_replace('/', DIRECTORY_SEPARATOR, $junction)),
39650 ProcessExecutor::escape(realpath($target)));
39651 if ($this->getProcess()->execute($cmd, $output) !== 0) {
39652 throw new IOException(sprintf('Failed to create junction to "%s" at "%s".', $target, $junction), 0, null, $target);
39653 }
39654 clearstatcache(true, $junction);
39655 }
39656
39657
39658
39659
39660
39661
39662
39663 public function isJunction($junction)
39664 {
39665 if (!Platform::isWindows()) {
39666 return false;
39667 }
39668 if (!is_dir($junction) || is_link($junction)) {
39669 return false;
39670 }
39671
39672
39673
39674
39675
39676
39677
39678
39679
39680
39681
39682 clearstatcache(true, $junction);
39683 $stat = lstat($junction);
39684
39685 return !($stat['mode'] & 0xC000);
39686 }
39687
39688
39689
39690
39691
39692
39693
39694 public function removeJunction($junction)
39695 {
39696 if (!Platform::isWindows()) {
39697 return false;
39698 }
39699 $junction = rtrim(str_replace('/', DIRECTORY_SEPARATOR, $junction), DIRECTORY_SEPARATOR);
39700 if (!$this->isJunction($junction)) {
39701 throw new IOException(sprintf('%s is not a junction and thus cannot be removed as one', $junction));
39702 }
39703 $cmd = sprintf('rmdir /S /Q %s', ProcessExecutor::escape($junction));
39704 clearstatcache(true, $junction);
39705
39706 return ($this->getProcess()->execute($cmd, $output) === 0);
39707 }
39708 }
39709 <?php
39710
39711
39712
39713
39714
39715
39716
39717
39718
39719
39720
39721 namespace Composer\Util;
39722
39723 use Composer\Config;
39724 use Composer\IO\IOInterface;
39725
39726
39727
39728
39729 class Git
39730 {
39731 private static $version;
39732
39733
39734 protected $io;
39735
39736 protected $config;
39737
39738 protected $process;
39739
39740 protected $filesystem;
39741
39742 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process, Filesystem $fs)
39743 {
39744 $this->io = $io;
39745 $this->config = $config;
39746 $this->process = $process;
39747 $this->filesystem = $fs;
39748 }
39749
39750 public function runCommand($commandCallable, $url, $cwd, $initialClone = false)
39751 {
39752
39753  $this->config->prohibitUrlByConfig($url, $this->io);
39754
39755 if ($initialClone) {
39756 $origCwd = $cwd;
39757 $cwd = null;
39758 }
39759
39760 if (preg_match('{^ssh://[^@]+@[^:]+:[^0-9]+}', $url)) {
39761 throw new \InvalidArgumentException('The source URL ' . $url . ' is invalid, ssh URLs should have a port number after ":".' . "\n" . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
39762 }
39763
39764 if (!$initialClone) {
39765
39766  $this->process->execute('git remote -v', $output, $cwd);
39767 if (preg_match('{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)}im', $output, $match)) {
39768 $this->io->setAuthentication($match[3], urldecode($match[1]), urldecode($match[2]));
39769 }
39770 }
39771
39772 $protocols = $this->config->get('github-protocols');
39773 if (!is_array($protocols)) {
39774 throw new \RuntimeException('Config value "github-protocols" must be an array, got ' . gettype($protocols));
39775 }
39776
39777  if (preg_match('{^(?:https?|git)://' . self::getGitHubDomainsRegex($this->config) . '/(.*)}', $url, $match)) {
39778 $messages = array();
39779 foreach ($protocols as $protocol) {
39780 if ('ssh' === $protocol) {
39781 $protoUrl = "git@" . $match[1] . ":" . $match[2];
39782 } else {
39783 $protoUrl = $protocol . "://" . $match[1] . "/" . $match[2];
39784 }
39785
39786 if (0 === $this->process->execute(call_user_func($commandCallable, $protoUrl), $ignoredOutput, $cwd)) {
39787 return;
39788 }
39789 $messages[] = '- ' . $protoUrl . "\n" . preg_replace('#^#m', '  ', $this->process->getErrorOutput());
39790 if ($initialClone) {
39791 $this->filesystem->removeDirectory($origCwd);
39792 }
39793 }
39794
39795
39796  $this->throwException('Failed to clone ' . $url . ' via ' . implode(', ', $protocols) . ' protocols, aborting.' . "\n\n" . implode("\n", $messages), $url);
39797 }
39798
39799
39800  $bypassSshForGitHub = preg_match('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url) && !in_array('ssh', $protocols, true);
39801
39802 $command = call_user_func($commandCallable, $url);
39803
39804 $auth = null;
39805 if ($bypassSshForGitHub || 0 !== $this->process->execute($command, $ignoredOutput, $cwd)) {
39806
39807  if (preg_match('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url, $match)) {
39808 if (!$this->io->hasAuthentication($match[1])) {
39809 $gitHubUtil = new GitHub($this->io, $this->config, $this->process);
39810 $message = 'Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private repos';
39811
39812 if (!$gitHubUtil->authorizeOAuth($match[1]) && $this->io->isInteractive()) {
39813 $gitHubUtil->authorizeOAuthInteractively($match[1], $message);
39814 }
39815 }
39816
39817 if ($this->io->hasAuthentication($match[1])) {
39818 $auth = $this->io->getAuthentication($match[1]);
39819 $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[1] . '/' . $match[2] . '.git';
39820 $command = call_user_func($commandCallable, $authUrl);
39821 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
39822 return;
39823 }
39824 }
39825 } elseif (preg_match('{^https://(bitbucket\.org)/(.*)(\.git)?$}U', $url, $match)) { 
39826  $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process);
39827
39828 if (!$this->io->hasAuthentication($match[1])) {
39829 $message = 'Enter your Bitbucket credentials to access private repos';
39830
39831 if (!$bitbucketUtil->authorizeOAuth($match[1]) && $this->io->isInteractive()) {
39832 $bitbucketUtil->authorizeOAuthInteractively($match[1], $message);
39833 $accessToken = $bitbucketUtil->getToken();
39834 $this->io->setAuthentication($match[1], 'x-token-auth', $accessToken);
39835 }
39836 } else { 
39837  $auth = $this->io->getAuthentication($match[1]);
39838
39839
39840  if ($auth['username'] !== 'x-token-auth') {
39841 $accessToken = $bitbucketUtil->requestToken($match[1], $auth['username'], $auth['password']);
39842 if (! empty($accessToken)) {
39843 $this->io->setAuthentication($match[1], 'x-token-auth', $accessToken);
39844 }
39845 }
39846 }
39847
39848 if ($this->io->hasAuthentication($match[1])) {
39849 $auth = $this->io->getAuthentication($match[1]);
39850 $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[1] . '/' . $match[2] . '.git';
39851
39852 $command = call_user_func($commandCallable, $authUrl);
39853 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
39854 return;
39855 }
39856 } else { 
39857  $sshUrl = 'git@bitbucket.org:' . $match[2] . '.git';
39858 $this->io->writeError('    No bitbucket authentication configured. Falling back to ssh.');
39859 $command = call_user_func($commandCallable, $sshUrl);
39860 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
39861 return;
39862 }
39863 }
39864 } elseif ($this->isAuthenticationFailure($url, $match)) { 
39865  if (strpos($match[2], '@')) {
39866 list($authParts, $match[2]) = explode('@', $match[2], 2);
39867 }
39868
39869 $storeAuth = false;
39870 if ($this->io->hasAuthentication($match[2])) {
39871 $auth = $this->io->getAuthentication($match[2]);
39872 } elseif ($this->io->isInteractive()) {
39873 $defaultUsername = null;
39874 if (isset($authParts) && $authParts) {
39875 if (false !== strpos($authParts, ':')) {
39876 list($defaultUsername, ) = explode(':', $authParts, 2);
39877 } else {
39878 $defaultUsername = $authParts;
39879 }
39880 }
39881
39882 $this->io->writeError('    Authentication required (<info>' . parse_url($url, PHP_URL_HOST) . '</info>):');
39883 $auth = array(
39884 'username' => $this->io->ask('      Username: ', $defaultUsername),
39885 'password' => $this->io->askAndHideAnswer('      Password: '),
39886 );
39887 $storeAuth = $this->config->get('store-auths');
39888 }
39889
39890 if ($auth) {
39891 $authUrl = $match[1] . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[2] . $match[3];
39892
39893 $command = call_user_func($commandCallable, $authUrl);
39894 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
39895 $this->io->setAuthentication($match[2], $auth['username'], $auth['password']);
39896 $authHelper = new AuthHelper($this->io, $this->config);
39897 $authHelper->storeAuth($match[2], $storeAuth);
39898
39899 return;
39900 }
39901 }
39902 }
39903
39904 if ($initialClone) {
39905 $this->filesystem->removeDirectory($origCwd);
39906 }
39907 $this->throwException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput(), $url);
39908 }
39909 }
39910
39911 public function syncMirror($url, $dir)
39912 {
39913
39914  if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
39915 try {
39916 $commandCallable = function ($url) {
39917 return sprintf('git remote set-url origin %s && git remote update --prune origin', ProcessExecutor::escape($url));
39918 };
39919 $this->runCommand($commandCallable, $url, $dir);
39920 } catch (\Exception $e) {
39921 return false;
39922 }
39923
39924 return true;
39925 }
39926
39927
39928  $this->filesystem->removeDirectory($dir);
39929
39930 $commandCallable = function ($url) use ($dir) {
39931 return sprintf('git clone --mirror %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($dir));
39932 };
39933
39934 $this->runCommand($commandCallable, $url, $dir, true);
39935
39936 return true;
39937 }
39938
39939 private function isAuthenticationFailure($url, &$match)
39940 {
39941 if (!preg_match('{(https?://)([^/]+)(.*)$}i', $url, $match)) {
39942 return false;
39943 }
39944
39945 $authFailures = array(
39946 'fatal: Authentication failed',
39947 'remote error: Invalid username or password.',
39948 'error: 401 Unauthorized',
39949 'fatal: unable to access',
39950 );
39951
39952 foreach ($authFailures as $authFailure) {
39953 if (strpos($this->process->getErrorOutput(), $authFailure) !== false) {
39954 return true;
39955 }
39956 }
39957
39958 return false;
39959 }
39960
39961 public static function cleanEnv()
39962 {
39963 if (ini_get('safe_mode') && false === strpos(ini_get('safe_mode_allowed_env_vars'), 'GIT_ASKPASS')) {
39964 throw new \RuntimeException('safe_mode is enabled and safe_mode_allowed_env_vars does not contain GIT_ASKPASS, can not set env var. You can disable safe_mode with "-dsafe_mode=0" when running composer');
39965 }
39966
39967
39968  if (getenv('GIT_ASKPASS') !== 'echo') {
39969 putenv('GIT_ASKPASS=echo');
39970 unset($_SERVER['GIT_ASKPASS']);
39971 }
39972
39973
39974  if (getenv('GIT_DIR')) {
39975 putenv('GIT_DIR');
39976 unset($_SERVER['GIT_DIR']);
39977 }
39978 if (getenv('GIT_WORK_TREE')) {
39979 putenv('GIT_WORK_TREE');
39980 unset($_SERVER['GIT_WORK_TREE']);
39981 }
39982
39983
39984  if (getenv('LANGUAGE') !== 'C') {
39985 putenv('LANGUAGE=C');
39986 }
39987
39988
39989  putenv("DYLD_LIBRARY_PATH");
39990 unset($_SERVER['DYLD_LIBRARY_PATH']);
39991 }
39992
39993 public static function getGitHubDomainsRegex(Config $config)
39994 {
39995 return '(' . implode('|', array_map('preg_quote', $config->get('github-domains'))) . ')';
39996 }
39997
39998 public static function sanitizeUrl($message)
39999 {
40000 return preg_replace_callback('{://(?P<user>[^@]+?):(?P<password>.+?)@}', function ($m) {
40001 if (preg_match('{^[a-f0-9]{12,}$}', $m[1])) {
40002 return '://***:***@';
40003 }
40004
40005 return '://' . $m[1] . ':***@';
40006 }, $message);
40007 }
40008
40009 private function throwException($message, $url)
40010 {
40011
40012  clearstatcache();
40013
40014 if (0 !== $this->process->execute('git --version', $ignoredOutput)) {
40015 throw new \RuntimeException(self::sanitizeUrl('Failed to clone ' . $url . ', git was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput()));
40016 }
40017
40018 throw new \RuntimeException(self::sanitizeUrl($message));
40019 }
40020
40021
40022
40023
40024
40025
40026 public function getVersion()
40027 {
40028 if (isset(self::$version)) {
40029 return self::$version;
40030 }
40031 if (0 !== $this->process->execute('git --version', $output)) {
40032 return;
40033 }
40034 if (preg_match('/^git version (\d+(?:\.\d+)+)/m', $output, $matches)) {
40035 return self::$version = $matches[1];
40036 }
40037 }
40038 }
40039 <?php
40040
40041
40042
40043
40044
40045
40046
40047
40048
40049
40050
40051 namespace Composer\Util;
40052
40053 use Composer\Factory;
40054 use Composer\IO\IOInterface;
40055 use Composer\Config;
40056 use Composer\Downloader\TransportException;
40057
40058
40059
40060
40061 class GitHub
40062 {
40063 protected $io;
40064 protected $config;
40065 protected $process;
40066 protected $remoteFilesystem;
40067
40068
40069
40070
40071
40072
40073
40074
40075
40076 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
40077 {
40078 $this->io = $io;
40079 $this->config = $config;
40080 $this->process = $process ?: new ProcessExecutor;
40081 $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
40082 }
40083
40084
40085
40086
40087
40088
40089
40090 public function authorizeOAuth($originUrl)
40091 {
40092 if (!in_array($originUrl, $this->config->get('github-domains'))) {
40093 return false;
40094 }
40095
40096
40097  if (0 === $this->process->execute('git config github.accesstoken', $output)) {
40098 $this->io->setAuthentication($originUrl, trim($output), 'x-oauth-basic');
40099
40100 return true;
40101 }
40102
40103 return false;
40104 }
40105
40106
40107
40108
40109
40110
40111
40112
40113
40114
40115 public function authorizeOAuthInteractively($originUrl, $message = null)
40116 {
40117 if ($message) {
40118 $this->io->writeError($message);
40119 }
40120
40121 $note = 'Composer';
40122 if ($this->config->get('github-expose-hostname') === true && 0 === $this->process->execute('hostname', $output)) {
40123 $note .= ' on ' . trim($output);
40124 }
40125 $note .= ' ' . date('Y-m-d Hi');
40126
40127 $url = 'https://'.$originUrl.'/settings/tokens/new?scopes=repo&description=' . str_replace('%20', '+', rawurlencode($note));
40128 $this->io->writeError(sprintf('Head to %s', $url));
40129 $this->io->writeError(sprintf('to retrieve a token. It will be stored in "%s" for future use by Composer.', $this->config->getAuthConfigSource()->getName()));
40130
40131 $token = trim($this->io->askAndHideAnswer('Token (hidden): '));
40132
40133 if (!$token) {
40134 $this->io->writeError('<warning>No token given, aborting.</warning>');
40135 $this->io->writeError('You can also add it manually later by using "composer config github-oauth.github.com <token>"');
40136
40137 return false;
40138 }
40139
40140 $this->io->setAuthentication($originUrl, $token, 'x-oauth-basic');
40141
40142 try {
40143 $apiUrl = ('github.com' === $originUrl) ? 'api.github.com/' : $originUrl . '/api/v3/';
40144
40145 $this->remoteFilesystem->getContents($originUrl, 'https://'. $apiUrl, false, array(
40146 'retry-auth-failure' => false,
40147 ));
40148 } catch (TransportException $e) {
40149 if (in_array($e->getCode(), array(403, 401))) {
40150 $this->io->writeError('<error>Invalid token provided.</error>');
40151 $this->io->writeError('You can also add it manually later by using "composer config github-oauth.github.com <token>"');
40152
40153 return false;
40154 }
40155
40156 throw $e;
40157 }
40158
40159
40160  $this->config->getConfigSource()->removeConfigSetting('github-oauth.'.$originUrl);
40161 $this->config->getAuthConfigSource()->addConfigSetting('github-oauth.'.$originUrl, $token);
40162
40163 $this->io->writeError('<info>Token stored successfully.</info>');
40164
40165 return true;
40166 }
40167 }
40168 <?php
40169
40170
40171
40172
40173
40174
40175
40176
40177
40178
40179
40180 namespace Composer\Util;
40181
40182 use Composer\IO\IOInterface;
40183 use Composer\Config;
40184 use Composer\Factory;
40185 use Composer\Downloader\TransportException;
40186 use Composer\Json\JsonFile;
40187
40188
40189
40190
40191 class GitLab
40192 {
40193 protected $io;
40194 protected $config;
40195 protected $process;
40196 protected $remoteFilesystem;
40197
40198
40199
40200
40201
40202
40203
40204
40205
40206 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
40207 {
40208 $this->io = $io;
40209 $this->config = $config;
40210 $this->process = $process ?: new ProcessExecutor();
40211 $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
40212 }
40213
40214
40215
40216
40217
40218
40219
40220
40221 public function authorizeOAuth($originUrl)
40222 {
40223 if (!in_array($originUrl, $this->config->get('gitlab-domains'), true)) {
40224 return false;
40225 }
40226
40227
40228  if (0 === $this->process->execute('git config gitlab.accesstoken', $output)) {
40229 $this->io->setAuthentication($originUrl, trim($output), 'oauth2');
40230
40231 return true;
40232 }
40233
40234
40235  $authTokens = $this->config->get('gitlab-token');
40236
40237 if (isset($authTokens[$originUrl])) {
40238 $this->io->setAuthentication($originUrl, $authTokens[$originUrl], 'private-token');
40239
40240 return true;
40241 }
40242
40243 return false;
40244 }
40245
40246
40247
40248
40249
40250
40251
40252
40253
40254
40255
40256
40257
40258 public function authorizeOAuthInteractively($scheme, $originUrl, $message = null)
40259 {
40260 if ($message) {
40261 $this->io->writeError($message);
40262 }
40263
40264 $this->io->writeError(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName()));
40265 $this->io->writeError('To revoke access to this token you can visit '.$originUrl.'/profile/applications');
40266
40267 $attemptCounter = 0;
40268
40269 while ($attemptCounter++ < 5) {
40270 try {
40271 $response = $this->createToken($scheme, $originUrl);
40272 } catch (TransportException $e) {
40273
40274  
40275  if (in_array($e->getCode(), array(403, 401))) {
40276 if (401 === $e->getCode()) {
40277 $this->io->writeError('Bad credentials.');
40278 } else {
40279 $this->io->writeError('Maximum number of login attempts exceeded. Please try again later.');
40280 }
40281
40282 $this->io->writeError('You can also manually create a personal token at '.$scheme.'://'.$originUrl.'/profile/applications');
40283 $this->io->writeError('Add it using "composer config gitlab-oauth.'.$originUrl.' <token>"');
40284
40285 continue;
40286 }
40287
40288 throw $e;
40289 }
40290
40291 $this->io->setAuthentication($originUrl, $response['access_token'], 'oauth2');
40292
40293
40294  $this->config->getAuthConfigSource()->addConfigSetting('gitlab-oauth.'.$originUrl, $response['access_token']);
40295
40296 return true;
40297 }
40298
40299 throw new \RuntimeException('Invalid GitLab credentials 5 times in a row, aborting.');
40300 }
40301
40302 private function createToken($scheme, $originUrl)
40303 {
40304 $username = $this->io->ask('Username: ');
40305 $password = $this->io->askAndHideAnswer('Password: ');
40306
40307 $headers = array('Content-Type: application/x-www-form-urlencoded');
40308
40309 $apiUrl = $originUrl;
40310 $data = http_build_query(array(
40311 'username' => $username,
40312 'password' => $password,
40313 'grant_type' => 'password',
40314 ), null, '&');
40315 $options = array(
40316 'retry-auth-failure' => false,
40317 'http' => array(
40318 'method' => 'POST',
40319 'header' => $headers,
40320 'content' => $data,
40321 ),
40322 );
40323
40324 $json = $this->remoteFilesystem->getContents($originUrl, $scheme.'://'.$apiUrl.'/oauth/token', false, $options);
40325
40326 $this->io->writeError('Token successfully created');
40327
40328 return JsonFile::parseJson($json);
40329 }
40330 }
40331 <?php
40332
40333
40334
40335
40336
40337
40338
40339
40340
40341
40342
40343 namespace Composer\Util;
40344
40345
40346
40347
40348
40349
40350
40351
40352 class IniHelper
40353 {
40354 const ENV_ORIGINAL = 'COMPOSER_ORIGINAL_INIS';
40355
40356
40357
40358
40359
40360
40361
40362
40363
40364 public static function getAll()
40365 {
40366 if ($env = strval(getenv(self::ENV_ORIGINAL))) {
40367 return explode(PATH_SEPARATOR, $env);
40368 }
40369
40370 $paths = array(strval(php_ini_loaded_file()));
40371
40372 if ($scanned = php_ini_scanned_files()) {
40373 $paths = array_merge($paths, array_map('trim', explode(',', $scanned)));
40374 }
40375
40376 return $paths;
40377 }
40378
40379
40380
40381
40382
40383
40384 public static function getMessage()
40385 {
40386 $paths = self::getAll();
40387
40388 if (empty($paths[0])) {
40389 return 'A php.ini file does not exist. You will have to create one.';
40390 }
40391
40392 return 'The php.ini used by your command-line PHP is: '.$paths[0];
40393 }
40394 }
40395 <?php
40396
40397
40398
40399
40400
40401
40402
40403
40404
40405
40406
40407 namespace Composer\Util;
40408
40409
40410
40411
40412 class NoProxyPattern
40413 {
40414
40415
40416
40417 protected $rules = array();
40418
40419
40420
40421
40422 public function __construct($pattern)
40423 {
40424 $this->rules = preg_split("/[\s,]+/", $pattern);
40425 }
40426
40427
40428
40429
40430
40431
40432
40433
40434 public function test($url)
40435 {
40436 $host = parse_url($url, PHP_URL_HOST);
40437 $port = parse_url($url, PHP_URL_PORT);
40438
40439 if (empty($port)) {
40440 switch (parse_url($url, PHP_URL_SCHEME)) {
40441 case 'http':
40442 $port = 80;
40443 break;
40444 case 'https':
40445 $port = 443;
40446 break;
40447 }
40448 }
40449
40450 foreach ($this->rules as $rule) {
40451 if ($rule == '*') {
40452 return true;
40453 }
40454
40455 $match = false;
40456
40457 list($ruleHost) = explode(':', $rule);
40458 list($base) = explode('/', $ruleHost);
40459
40460 if (filter_var($base, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
40461
40462
40463 if (!isset($ip)) {
40464 $ip = gethostbyname($host);
40465 }
40466
40467 if (strpos($ruleHost, '/') === false) {
40468 $match = $ip === $ruleHost;
40469 } else {
40470
40471  
40472  if ($ip === $host) {
40473 $match = false;
40474 } else {
40475
40476  $match = self::inCIDRBlock($ruleHost, $ip);
40477 }
40478 }
40479 } else {
40480
40481
40482 $haystack = '.' . trim($host, '.') . '.';
40483 $needle = '.'. trim($ruleHost, '.') .'.';
40484 $match = stripos(strrev($haystack), strrev($needle)) === 0;
40485 }
40486
40487
40488  if ($match && strpos($rule, ':') !== false) {
40489 list(, $rulePort) = explode(':', $rule);
40490 if (!empty($rulePort) && $port != $rulePort) {
40491 $match = false;
40492 }
40493 }
40494
40495 if ($match) {
40496 return true;
40497 }
40498 }
40499
40500 return false;
40501 }
40502
40503
40504
40505
40506
40507
40508
40509
40510
40511
40512
40513 private static function inCIDRBlock($cidr, $ip)
40514 {
40515
40516  list($base, $bits) = explode('/', $cidr);
40517
40518
40519  list($a, $b, $c, $d) = explode('.', $base);
40520
40521
40522  $i = ($a << 24) + ($b << 16) + ($c << 8) + $d;
40523 $mask = $bits == 0 ? 0 : (~0 << (32 - $bits));
40524
40525
40526  $low = $i & $mask;
40527
40528
40529  $high = $i | (~$mask & 0xFFFFFFFF);
40530
40531
40532  list($a, $b, $c, $d) = explode('.', $ip);
40533
40534
40535  $check = ($a << 24) + ($b << 16) + ($c << 8) + $d;
40536
40537
40538  
40539  return $check >= $low && $check <= $high;
40540 }
40541 }
40542 <?php
40543
40544
40545
40546
40547
40548
40549
40550
40551
40552
40553
40554 namespace Composer\Util;
40555
40556 use Composer\IO\IOInterface;
40557 use Symfony\Component\Process\Process;
40558
40559
40560
40561
40562 class Perforce
40563 {
40564 protected $path;
40565 protected $p4Depot;
40566 protected $p4Client;
40567 protected $p4User;
40568 protected $p4Password;
40569 protected $p4Port;
40570 protected $p4Stream;
40571 protected $p4ClientSpec;
40572 protected $p4DepotType;
40573 protected $p4Branch;
40574 protected $process;
40575 protected $uniquePerforceClientName;
40576 protected $windowsFlag;
40577 protected $commandResult;
40578
40579 protected $io;
40580
40581 protected $filesystem;
40582
40583 public function __construct($repoConfig, $port, $path, ProcessExecutor $process, $isWindows, IOInterface $io)
40584 {
40585 $this->windowsFlag = $isWindows;
40586 $this->p4Port = $port;
40587 $this->initializePath($path);
40588 $this->process = $process;
40589 $this->initialize($repoConfig);
40590 $this->io = $io;
40591 }
40592
40593 public static function create($repoConfig, $port, $path, ProcessExecutor $process, IOInterface $io)
40594 {
40595 return new Perforce($repoConfig, $port, $path, $process, Platform::isWindows(), $io);
40596 }
40597
40598 public static function checkServerExists($url, ProcessExecutor $processExecutor)
40599 {
40600 $output = null;
40601
40602 return 0 === $processExecutor->execute('p4 -p ' . $url . ' info -s', $output);
40603 }
40604
40605 public function initialize($repoConfig)
40606 {
40607 $this->uniquePerforceClientName = $this->generateUniquePerforceClientName();
40608 if (!$repoConfig) {
40609 return;
40610 }
40611 if (isset($repoConfig['unique_perforce_client_name'])) {
40612 $this->uniquePerforceClientName = $repoConfig['unique_perforce_client_name'];
40613 }
40614
40615 if (isset($repoConfig['depot'])) {
40616 $this->p4Depot = $repoConfig['depot'];
40617 }
40618 if (isset($repoConfig['branch'])) {
40619 $this->p4Branch = $repoConfig['branch'];
40620 }
40621 if (isset($repoConfig['p4user'])) {
40622 $this->p4User = $repoConfig['p4user'];
40623 } else {
40624 $this->p4User = $this->getP4variable('P4USER');
40625 }
40626 if (isset($repoConfig['p4password'])) {
40627 $this->p4Password = $repoConfig['p4password'];
40628 }
40629 }
40630
40631 public function initializeDepotAndBranch($depot, $branch)
40632 {
40633 if (isset($depot)) {
40634 $this->p4Depot = $depot;
40635 }
40636 if (isset($branch)) {
40637 $this->p4Branch = $branch;
40638 }
40639 }
40640
40641 public function generateUniquePerforceClientName()
40642 {
40643 return gethostname() . "_" . time();
40644 }
40645
40646 public function cleanupClientSpec()
40647 {
40648 $client = $this->getClient();
40649 $task = 'client -d ' . $client;
40650 $useP4Client = false;
40651 $command = $this->generateP4Command($task, $useP4Client);
40652 $this->executeCommand($command);
40653 $clientSpec = $this->getP4ClientSpec();
40654 $fileSystem = $this->getFilesystem();
40655 $fileSystem->remove($clientSpec);
40656 }
40657
40658 protected function executeCommand($command)
40659 {
40660 $this->commandResult = "";
40661 $exit_code = $this->process->execute($command, $this->commandResult);
40662
40663 return $exit_code;
40664 }
40665
40666 public function getClient()
40667 {
40668 if (!isset($this->p4Client)) {
40669 $cleanStreamName = str_replace('@', '', str_replace('/', '_', str_replace('//', '', $this->getStream())));
40670 $this->p4Client = 'composer_perforce_' . $this->uniquePerforceClientName . '_' . $cleanStreamName;
40671 }
40672
40673 return $this->p4Client;
40674 }
40675
40676 protected function getPath()
40677 {
40678 return $this->path;
40679 }
40680
40681 public function initializePath($path)
40682 {
40683 $this->path = $path;
40684 $fs = $this->getFilesystem();
40685 $fs->ensureDirectoryExists($path);
40686 }
40687
40688 protected function getPort()
40689 {
40690 return $this->p4Port;
40691 }
40692
40693 public function setStream($stream)
40694 {
40695 $this->p4Stream = $stream;
40696 $index = strrpos($stream, '/');
40697
40698  if ($index > 2) {
40699 $this->p4DepotType = 'stream';
40700 }
40701 }
40702
40703 public function isStream()
40704 {
40705 return (strcmp($this->p4DepotType, 'stream') === 0);
40706 }
40707
40708 public function getStream()
40709 {
40710 if (!isset($this->p4Stream)) {
40711 if ($this->isStream()) {
40712 $this->p4Stream = '//' . $this->p4Depot . '/' . $this->p4Branch;
40713 } else {
40714 $this->p4Stream = '//' . $this->p4Depot;
40715 }
40716 }
40717
40718 return $this->p4Stream;
40719 }
40720
40721 public function getStreamWithoutLabel($stream)
40722 {
40723 $index = strpos($stream, '@');
40724 if ($index === false) {
40725 return $stream;
40726 }
40727
40728 return substr($stream, 0, $index);
40729 }
40730
40731 public function getP4ClientSpec()
40732 {
40733 $p4clientSpec = $this->path . '/' . $this->getClient() . '.p4.spec';
40734
40735 return $p4clientSpec;
40736 }
40737
40738 public function getUser()
40739 {
40740 return $this->p4User;
40741 }
40742
40743 public function setUser($user)
40744 {
40745 $this->p4User = $user;
40746 }
40747
40748 public function queryP4User()
40749 {
40750 $this->getUser();
40751 if (strlen($this->p4User) > 0) {
40752 return;
40753 }
40754 $this->p4User = $this->getP4variable('P4USER');
40755 if (strlen($this->p4User) > 0) {
40756 return;
40757 }
40758 $this->p4User = $this->io->ask('Enter P4 User:');
40759 if ($this->windowsFlag) {
40760 $command = 'p4 set P4USER=' . $this->p4User;
40761 } else {
40762 $command = 'export P4USER=' . $this->p4User;
40763 }
40764 $this->executeCommand($command);
40765 }
40766
40767 protected function getP4variable($name)
40768 {
40769 if ($this->windowsFlag) {
40770 $command = 'p4 set';
40771 $this->executeCommand($command);
40772 $result = trim($this->commandResult);
40773 $resArray = explode(PHP_EOL, $result);
40774 foreach ($resArray as $line) {
40775 $fields = explode('=', $line);
40776 if (strcmp($name, $fields[0]) == 0) {
40777 $index = strpos($fields[1], ' ');
40778 if ($index === false) {
40779 $value = $fields[1];
40780 } else {
40781 $value = substr($fields[1], 0, $index);
40782 }
40783 $value = trim($value);
40784
40785 return $value;
40786 }
40787 }
40788
40789 return null;
40790 } else {
40791 $command = 'echo $' . $name;
40792 $this->executeCommand($command);
40793 $result = trim($this->commandResult);
40794
40795 return $result;
40796 }
40797 }
40798
40799 public function queryP4Password()
40800 {
40801 if (isset($this->p4Password)) {
40802 return $this->p4Password;
40803 }
40804 $password = $this->getP4variable('P4PASSWD');
40805 if (strlen($password) <= 0) {
40806 $password = $this->io->askAndHideAnswer('Enter password for Perforce user ' . $this->getUser() . ': ');
40807 }
40808 $this->p4Password = $password;
40809
40810 return $password;
40811 }
40812
40813 public function generateP4Command($command, $useClient = true)
40814 {
40815 $p4Command = 'p4 ';
40816 $p4Command = $p4Command . '-u ' . $this->getUser() . ' ';
40817 if ($useClient) {
40818 $p4Command = $p4Command . '-c ' . $this->getClient() . ' ';
40819 }
40820 $p4Command = $p4Command . '-p ' . $this->getPort() . ' ';
40821 $p4Command = $p4Command . $command;
40822
40823 return $p4Command;
40824 }
40825
40826 public function isLoggedIn()
40827 {
40828 $command = $this->generateP4Command('login -s', false);
40829 $exitCode = $this->executeCommand($command);
40830 if ($exitCode) {
40831 $errorOutput = $this->process->getErrorOutput();
40832 $index = strpos($errorOutput, $this->getUser());
40833 if ($index === false) {
40834 $index = strpos($errorOutput, 'p4');
40835 if ($index === false) {
40836 return false;
40837 }
40838 throw new \Exception('p4 command not found in path: ' . $errorOutput);
40839 }
40840 throw new \Exception('Invalid user name: ' . $this->getUser());
40841 }
40842
40843 return true;
40844 }
40845
40846 public function connectClient()
40847 {
40848 $p4CreateClientCommand = $this->generateP4Command(
40849 'client -i < ' . str_replace(" ", "\\ ", $this->getP4ClientSpec())
40850 );
40851 $this->executeCommand($p4CreateClientCommand);
40852 }
40853
40854 public function syncCodeBase($sourceReference)
40855 {
40856 $prevDir = getcwd();
40857 chdir($this->path);
40858 $p4SyncCommand = $this->generateP4Command('sync -f ');
40859 if (null !== $sourceReference) {
40860 $p4SyncCommand = $p4SyncCommand . '@' . $sourceReference;
40861 }
40862 $this->executeCommand($p4SyncCommand);
40863 chdir($prevDir);
40864 }
40865
40866 public function writeClientSpecToFile($spec)
40867 {
40868 fwrite($spec, 'Client: ' . $this->getClient() . PHP_EOL . PHP_EOL);
40869 fwrite($spec, 'Update: ' . date('Y/m/d H:i:s') . PHP_EOL . PHP_EOL);
40870 fwrite($spec, 'Access: ' . date('Y/m/d H:i:s') . PHP_EOL);
40871 fwrite($spec, 'Owner:  ' . $this->getUser() . PHP_EOL . PHP_EOL);
40872 fwrite($spec, 'Description:' . PHP_EOL);
40873 fwrite($spec, '  Created by ' . $this->getUser() . ' from composer.' . PHP_EOL . PHP_EOL);
40874 fwrite($spec, 'Root: ' . $this->getPath() . PHP_EOL . PHP_EOL);
40875 fwrite($spec, 'Options:  noallwrite noclobber nocompress unlocked modtime rmdir' . PHP_EOL . PHP_EOL);
40876 fwrite($spec, 'SubmitOptions:  revertunchanged' . PHP_EOL . PHP_EOL);
40877 fwrite($spec, 'LineEnd:  local' . PHP_EOL . PHP_EOL);
40878 if ($this->isStream()) {
40879 fwrite($spec, 'Stream:' . PHP_EOL);
40880 fwrite($spec, '  ' . $this->getStreamWithoutLabel($this->p4Stream) . PHP_EOL);
40881 } else {
40882 fwrite(
40883 $spec,
40884 'View:  ' . $this->getStream() . '/...  //' . $this->getClient() . '/... ' . PHP_EOL
40885 );
40886 }
40887 }
40888
40889 public function writeP4ClientSpec()
40890 {
40891 $clientSpec = $this->getP4ClientSpec();
40892 $spec = fopen($clientSpec, 'w');
40893 try {
40894 $this->writeClientSpecToFile($spec);
40895 } catch (\Exception $e) {
40896 fclose($spec);
40897 throw $e;
40898 }
40899 fclose($spec);
40900 }
40901
40902 protected function read($pipe, $name)
40903 {
40904 if (feof($pipe)) {
40905 return;
40906 }
40907 $line = fgets($pipe);
40908 while ($line !== false) {
40909 $line = fgets($pipe);
40910 }
40911
40912 return;
40913 }
40914
40915 public function windowsLogin($password)
40916 {
40917 $command = $this->generateP4Command(' login -a');
40918 $process = new Process($command, null, null, $password);
40919
40920 return $process->run();
40921 }
40922
40923 public function p4Login()
40924 {
40925 $this->queryP4User();
40926 if (!$this->isLoggedIn()) {
40927 $password = $this->queryP4Password();
40928 if ($this->windowsFlag) {
40929 $this->windowsLogin($password);
40930 } else {
40931 $command = 'echo ' . $password . ' | ' . $this->generateP4Command(' login -a', false);
40932 $exitCode = $this->executeCommand($command);
40933 $result = trim($this->commandResult);
40934 if ($exitCode) {
40935 throw new \Exception("Error logging in:" . $this->process->getErrorOutput());
40936 }
40937 }
40938 }
40939 }
40940
40941 public function getComposerInformation($identifier)
40942 {
40943 $composerFileContent = $this->getFileContent('composer.json', $identifier);
40944
40945 if (!$composerFileContent) {
40946 return;
40947 }
40948
40949 return json_decode($composerFileContent, true);
40950 }
40951
40952 public function getFileContent($file, $identifier)
40953 {
40954 $path = $this->getFilePath($file, $identifier);
40955
40956 $command = $this->generateP4Command(' print ' . $path);
40957 $this->executeCommand($command);
40958 $result = $this->commandResult;
40959
40960 if (!trim($result)) {
40961 return null;
40962 }
40963
40964 return $result;
40965 }
40966
40967 public function getFilePath($file, $identifier)
40968 {
40969 $index = strpos($identifier, '@');
40970 if ($index === false) {
40971 $path = $identifier. '/' . $file;
40972
40973 return $path;
40974 } else {
40975 $path = substr($identifier, 0, $index) . '/' . $file . substr($identifier, $index);
40976 $command = $this->generateP4Command(' files ' . $path, false);
40977 $this->executeCommand($command);
40978 $result = $this->commandResult;
40979 $index2 = strpos($result, 'no such file(s).');
40980 if ($index2 === false) {
40981 $index3 = strpos($result, 'change');
40982 if ($index3 !== false) {
40983 $phrase = trim(substr($result, $index3));
40984 $fields = explode(' ', $phrase);
40985
40986 return substr($identifier, 0, $index) . '/' . $file . '@' . $fields[1];
40987 }
40988 }
40989 }
40990
40991 return null;
40992 }
40993
40994 public function getBranches()
40995 {
40996 $possibleBranches = array();
40997 if (!$this->isStream()) {
40998 $possibleBranches[$this->p4Branch] = $this->getStream();
40999 } else {
41000 $command = $this->generateP4Command('streams //' . $this->p4Depot . '/...');
41001 $this->executeCommand($command);
41002 $result = $this->commandResult;
41003 $resArray = explode(PHP_EOL, $result);
41004 foreach ($resArray as $line) {
41005 $resBits = explode(' ', $line);
41006 if (count($resBits) > 4) {
41007 $branch = preg_replace('/[^A-Za-z0-9 ]/', '', $resBits[4]);
41008 $possibleBranches[$branch] = $resBits[1];
41009 }
41010 }
41011 }
41012 $command = $this->generateP4Command('changes '. $this->getStream() . '/...', false);
41013 $this->executeCommand($command);
41014 $result = $this->commandResult;
41015 $resArray = explode(PHP_EOL, $result);
41016 $lastCommit = $resArray[0];
41017 $lastCommitArr = explode(' ', $lastCommit);
41018 $lastCommitNum = $lastCommitArr[1];
41019
41020 $branches = array('master' => $possibleBranches[$this->p4Branch] . '@'. $lastCommitNum);
41021
41022 return $branches;
41023 }
41024
41025 public function getTags()
41026 {
41027 $command = $this->generateP4Command('labels');
41028 $this->executeCommand($command);
41029 $result = $this->commandResult;
41030 $resArray = explode(PHP_EOL, $result);
41031 $tags = array();
41032 foreach ($resArray as $line) {
41033 $index = strpos($line, 'Label');
41034 if (!($index === false)) {
41035 $fields = explode(' ', $line);
41036 $tags[$fields[1]] = $this->getStream() . '@' . $fields[1];
41037 }
41038 }
41039
41040 return $tags;
41041 }
41042
41043 public function checkStream()
41044 {
41045 $command = $this->generateP4Command('depots', false);
41046 $this->executeCommand($command);
41047 $result = $this->commandResult;
41048 $resArray = explode(PHP_EOL, $result);
41049 foreach ($resArray as $line) {
41050 $index = strpos($line, 'Depot');
41051 if (!($index === false)) {
41052 $fields = explode(' ', $line);
41053 if (strcmp($this->p4Depot, $fields[1]) === 0) {
41054 $this->p4DepotType = $fields[3];
41055
41056 return $this->isStream();
41057 }
41058 }
41059 }
41060
41061 return false;
41062 }
41063
41064
41065
41066
41067
41068 protected function getChangeList($reference)
41069 {
41070 $index = strpos($reference, '@');
41071 if ($index === false) {
41072 return null;
41073 }
41074 $label = substr($reference, $index);
41075 $command = $this->generateP4Command(' changes -m1 ' . $label);
41076 $this->executeCommand($command);
41077 $changes = $this->commandResult;
41078 if (strpos($changes, 'Change') !== 0) {
41079 return null;
41080 }
41081 $fields = explode(' ', $changes);
41082 $changeList = $fields[1];
41083
41084 return $changeList;
41085 }
41086
41087
41088
41089
41090
41091
41092 public function getCommitLogs($fromReference, $toReference)
41093 {
41094 $fromChangeList = $this->getChangeList($fromReference);
41095 if ($fromChangeList === null) {
41096 return null;
41097 }
41098 $toChangeList = $this->getChangeList($toReference);
41099 if ($toChangeList === null) {
41100 return null;
41101 }
41102 $index = strpos($fromReference, '@');
41103 $main = substr($fromReference, 0, $index) . '/...';
41104 $command = $this->generateP4Command('filelog ' . $main . '@' . $fromChangeList. ',' . $toChangeList);
41105 $this->executeCommand($command);
41106 $result = $this->commandResult;
41107
41108 return $result;
41109 }
41110
41111 public function getFilesystem()
41112 {
41113 if (empty($this->filesystem)) {
41114 $this->filesystem = new Filesystem($this->process);
41115 }
41116
41117 return $this->filesystem;
41118 }
41119
41120 public function setFilesystem(Filesystem $fs)
41121 {
41122 $this->filesystem = $fs;
41123 }
41124 }
41125 <?php
41126
41127
41128
41129
41130
41131
41132
41133
41134
41135
41136
41137 namespace Composer\Util;
41138
41139
41140
41141
41142
41143
41144 class Platform
41145 {
41146
41147
41148
41149
41150
41151
41152 public static function expandPath($path)
41153 {
41154 if (preg_match('#^~[\\/]#', $path)) {
41155 return self::getUserDirectory() . substr($path, 1);
41156 }
41157
41158 return preg_replace_callback('#^(\$|(?P<percent>%))(?P<var>\w++)(?(percent)%)(?P<path>.*)#', function ($matches) {
41159
41160  if (Platform::isWindows() && $matches['var'] == 'HOME') {
41161 return (getenv('HOME') ?: getenv('USERPROFILE')) . $matches['path'];
41162 }
41163
41164 return getenv($matches['var']) . $matches['path'];
41165 }, $path);
41166 }
41167
41168
41169
41170
41171
41172 public static function getUserDirectory()
41173 {
41174 if (false !== ($home = getenv('HOME'))) {
41175 return $home;
41176 }
41177
41178 if (self::isWindows() && false !== ($home = getenv('USERPROFILE'))) {
41179 return $home;
41180 }
41181
41182 if (function_exists('posix_getuid') && function_exists('posix_getpwuid')) {
41183 $info = posix_getpwuid(posix_getuid());
41184
41185 return $info['dir'];
41186 }
41187
41188 throw new \RuntimeException('Could not determine user directory');
41189 }
41190
41191
41192
41193
41194 public static function isWindows()
41195 {
41196 return defined('PHP_WINDOWS_VERSION_BUILD');
41197 }
41198
41199
41200
41201
41202
41203 public static function strlen($str)
41204 {
41205 static $useMbString = null;
41206 if (null === $useMbString) {
41207 $useMbString = function_exists('mb_strlen') && ini_get('mbstring.func_overload');
41208 }
41209
41210 if ($useMbString) {
41211 return mb_strlen($str, '8bit');
41212 }
41213
41214 return strlen($str);
41215 }
41216 }
41217 <?php
41218
41219
41220
41221
41222
41223
41224
41225
41226
41227
41228
41229 namespace Composer\Util;
41230
41231 use Symfony\Component\Process\Process;
41232 use Symfony\Component\Process\ProcessUtils;
41233 use Composer\IO\IOInterface;
41234
41235
41236
41237
41238 class ProcessExecutor
41239 {
41240 protected static $timeout = 300;
41241
41242 protected $captureOutput;
41243 protected $errorOutput;
41244 protected $io;
41245
41246 public function __construct(IOInterface $io = null)
41247 {
41248 $this->io = $io;
41249 }
41250
41251
41252
41253
41254
41255
41256
41257
41258
41259
41260 public function execute($command, &$output = null, $cwd = null)
41261 {
41262 if ($this->io && $this->io->isDebug()) {
41263 $safeCommand = preg_replace_callback('{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i', function ($m) {
41264 if (preg_match('{^[a-f0-9]{12,}$}', $m['user'])) {
41265 return '://***:***@';
41266 }
41267
41268 return '://'.$m['user'].':***@';
41269 }, $command);
41270 $this->io->writeError('Executing command ('.($cwd ?: 'CWD').'): '.$safeCommand);
41271 }
41272
41273
41274  
41275  if (null === $cwd && Platform::isWindows() && false !== strpos($command, 'git') && getcwd()) {
41276 $cwd = realpath(getcwd());
41277 }
41278
41279 $this->captureOutput = count(func_get_args()) > 1;
41280 $this->errorOutput = null;
41281 $process = new Process($command, $cwd, null, null, static::getTimeout());
41282
41283 $callback = is_callable($output) ? $output : array($this, 'outputHandler');
41284 $process->run($callback);
41285
41286 if ($this->captureOutput && !is_callable($output)) {
41287 $output = $process->getOutput();
41288 }
41289
41290 $this->errorOutput = $process->getErrorOutput();
41291
41292 return $process->getExitCode();
41293 }
41294
41295 public function splitLines($output)
41296 {
41297 $output = trim($output);
41298
41299 return ((string) $output === '') ? array() : preg_split('{\r?\n}', $output);
41300 }
41301
41302
41303
41304
41305
41306
41307 public function getErrorOutput()
41308 {
41309 return $this->errorOutput;
41310 }
41311
41312 public function outputHandler($type, $buffer)
41313 {
41314 if ($this->captureOutput) {
41315 return;
41316 }
41317
41318 if (null === $this->io) {
41319 echo $buffer;
41320
41321 return;
41322 }
41323
41324 if (Process::ERR === $type) {
41325 $this->io->writeError($buffer, false);
41326 } else {
41327 $this->io->write($buffer, false);
41328 }
41329 }
41330
41331 public static function getTimeout()
41332 {
41333 return static::$timeout;
41334 }
41335
41336 public static function setTimeout($timeout)
41337 {
41338 static::$timeout = $timeout;
41339 }
41340
41341
41342
41343
41344
41345
41346
41347
41348 public static function escape($argument)
41349 {
41350 return ProcessUtils::escapeArgument($argument);
41351 }
41352 }
41353 <?php
41354
41355
41356
41357
41358
41359
41360
41361
41362
41363
41364
41365 namespace Composer\Util;
41366
41367 use Composer\Config;
41368 use Composer\IO\IOInterface;
41369 use Composer\Downloader\TransportException;
41370 use Composer\CaBundle\CaBundle;
41371 use Psr\Log\LoggerInterface;
41372
41373
41374
41375
41376
41377
41378 class RemoteFilesystem
41379 {
41380 private $io;
41381 private $config;
41382 private $scheme;
41383 private $bytesMax;
41384 private $originUrl;
41385 private $fileUrl;
41386 private $fileName;
41387 private $retry;
41388 private $progress;
41389 private $lastProgress;
41390 private $options = array();
41391 private $peerCertificateMap = array();
41392 private $disableTls = false;
41393 private $retryAuthFailure;
41394 private $lastHeaders;
41395 private $storeAuth;
41396 private $degradedMode = false;
41397 private $redirects;
41398 private $maxRedirects = 20;
41399
41400
41401
41402
41403
41404
41405
41406
41407
41408 public function __construct(IOInterface $io, Config $config = null, array $options = array(), $disableTls = false)
41409 {
41410 $this->io = $io;
41411
41412
41413  
41414  if ($disableTls === false) {
41415 $this->options = $this->getTlsDefaults($options);
41416 } else {
41417 $this->disableTls = true;
41418 }
41419
41420
41421  $this->options = array_replace_recursive($this->options, $options);
41422 $this->config = $config;
41423 }
41424
41425
41426
41427
41428
41429
41430
41431
41432
41433
41434
41435
41436 public function copy($originUrl, $fileUrl, $fileName, $progress = true, $options = array())
41437 {
41438 return $this->get($originUrl, $fileUrl, $options, $fileName, $progress);
41439 }
41440
41441
41442
41443
41444
41445
41446
41447
41448
41449
41450
41451 public function getContents($originUrl, $fileUrl, $progress = true, $options = array())
41452 {
41453 return $this->get($originUrl, $fileUrl, $options, null, $progress);
41454 }
41455
41456
41457
41458
41459
41460
41461 public function getOptions()
41462 {
41463 return $this->options;
41464 }
41465
41466
41467
41468
41469
41470
41471 public function setOptions(array $options)
41472 {
41473 $this->options = array_replace_recursive($this->options, $options);
41474 }
41475
41476 public function isTlsDisabled()
41477 {
41478 return $this->disableTls === true;
41479 }
41480
41481
41482
41483
41484
41485
41486 public function getLastHeaders()
41487 {
41488 return $this->lastHeaders;
41489 }
41490
41491
41492
41493
41494
41495
41496 public function findHeaderValue(array $headers, $name)
41497 {
41498 $value = null;
41499 foreach ($headers as $header) {
41500 if (preg_match('{^'.$name.':\s*(.+?)\s*$}i', $header, $match)) {
41501 $value = $match[1];
41502 } elseif (preg_match('{^HTTP/}i', $header)) {
41503
41504  
41505  $value = null;
41506 }
41507 }
41508
41509 return $value;
41510 }
41511
41512
41513
41514
41515
41516 public function findStatusCode(array $headers)
41517 {
41518 $value = null;
41519 foreach ($headers as $header) {
41520 if (preg_match('{^HTTP/\S+ (\d+)}i', $header, $match)) {
41521
41522  
41523  $value = (int) $match[1];
41524 }
41525 }
41526
41527 return $value;
41528 }
41529
41530
41531
41532
41533
41534
41535
41536
41537
41538
41539
41540
41541
41542
41543
41544 protected function get($originUrl, $fileUrl, $additionalOptions = array(), $fileName = null, $progress = true)
41545 {
41546 if (strpos($originUrl, '.github.com') === (strlen($originUrl) - 11)) {
41547 $originUrl = 'github.com';
41548 }
41549
41550 $this->scheme = parse_url($fileUrl, PHP_URL_SCHEME);
41551 $this->bytesMax = 0;
41552 $this->originUrl = $originUrl;
41553 $this->fileUrl = $fileUrl;
41554 $this->fileName = $fileName;
41555 $this->progress = $progress;
41556 $this->lastProgress = null;
41557 $this->retryAuthFailure = true;
41558 $this->lastHeaders = array();
41559 $this->redirects = 1; 
41560
41561
41562  if (preg_match('{^https?://(.+):(.+)@([^/]+)}i', $fileUrl, $match)) {
41563 $this->io->setAuthentication($originUrl, urldecode($match[1]), urldecode($match[2]));
41564 }
41565
41566 $tempAdditionalOptions = $additionalOptions;
41567 if (isset($tempAdditionalOptions['retry-auth-failure'])) {
41568 $this->retryAuthFailure = (bool) $tempAdditionalOptions['retry-auth-failure'];
41569
41570 unset($tempAdditionalOptions['retry-auth-failure']);
41571 }
41572
41573 $isRedirect = false;
41574 if (isset($tempAdditionalOptions['redirects'])) {
41575 $this->redirects = $tempAdditionalOptions['redirects'];
41576 $isRedirect = true;
41577
41578 unset($tempAdditionalOptions['redirects']);
41579 }
41580
41581 $options = $this->getOptionsForUrl($originUrl, $tempAdditionalOptions);
41582 unset($tempAdditionalOptions);
41583 $userlandFollow = isset($options['http']['follow_location']) && !$options['http']['follow_location'];
41584
41585 $origFileUrl = $fileUrl;
41586
41587 if (isset($options['github-token'])) {
41588
41589  if (preg_match('{^https?://([a-z0-9-]+\.)*github\.com/}', $fileUrl)) {
41590 $fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['github-token'];
41591 }
41592 unset($options['github-token']);
41593 }
41594
41595 if (isset($options['gitlab-token'])) {
41596 $fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['gitlab-token'];
41597 unset($options['gitlab-token']);
41598 }
41599
41600 if (isset($options['http'])) {
41601 $options['http']['ignore_errors'] = true;
41602 }
41603
41604 if ($this->degradedMode && substr($fileUrl, 0, 21) === 'http://packagist.org/') {
41605
41606  $fileUrl = 'http://' . gethostbyname('packagist.org') . substr($fileUrl, 20);
41607 $degradedPackagist = true;
41608 }
41609
41610 $ctx = StreamContextFactory::getContext($fileUrl, $options, array('notification' => array($this, 'callbackGet')));
41611
41612 $actualContextOptions = stream_context_get_options($ctx);
41613 $usingProxy = !empty($actualContextOptions['http']['proxy']) ? ' using proxy ' . $actualContextOptions['http']['proxy'] : '';
41614 $this->io->writeError((substr($origFileUrl, 0, 4) === 'http' ? 'Downloading ' : 'Reading ') . $origFileUrl . $usingProxy, true, IOInterface::DEBUG);
41615 unset($origFileUrl, $actualContextOptions);
41616
41617
41618  if ((substr($fileUrl, 0, 23) !== 'http://packagist.org/p/' || (false === strpos($fileUrl, '$') && false === strpos($fileUrl, '%24'))) && empty($degradedPackagist) && $this->config) {
41619 $this->config->prohibitUrlByConfig($fileUrl, $this->io);
41620 }
41621
41622 if ($this->progress && !$isRedirect) {
41623 $this->io->writeError("Downloading (<comment>connecting...</comment>)", false);
41624 }
41625
41626 $errorMessage = '';
41627 $errorCode = 0;
41628 $result = false;
41629 set_error_handler(function ($code, $msg) use (&$errorMessage) {
41630 if ($errorMessage) {
41631 $errorMessage .= "\n";
41632 }
41633 $errorMessage .= preg_replace('{^file_get_contents\(.*?\): }', '', $msg);
41634 });
41635 try {
41636 $result = file_get_contents($fileUrl, false, $ctx);
41637
41638 $contentLength = !empty($http_response_header[0]) ? $this->findHeaderValue($http_response_header, 'content-length') : null;
41639 if ($contentLength && Platform::strlen($result) < $contentLength) {
41640
41641  throw new TransportException('Content-Length mismatch');
41642 }
41643
41644 if (PHP_VERSION_ID < 50600 && !empty($options['ssl']['peer_fingerprint'])) {
41645
41646  $params = stream_context_get_params($ctx);
41647 $expectedPeerFingerprint = $options['ssl']['peer_fingerprint'];
41648 $peerFingerprint = TlsHelper::getCertificateFingerprint($params['options']['ssl']['peer_certificate']);
41649
41650
41651  if ($expectedPeerFingerprint !== $peerFingerprint) {
41652 throw new TransportException('Peer fingerprint did not match');
41653 }
41654 }
41655 } catch (\Exception $e) {
41656 if ($e instanceof TransportException && !empty($http_response_header[0])) {
41657 $e->setHeaders($http_response_header);
41658 $e->setStatusCode($this->findStatusCode($http_response_header));
41659 }
41660 if ($e instanceof TransportException && $result !== false) {
41661 $e->setResponse($result);
41662 }
41663 $result = false;
41664 }
41665 if ($errorMessage && !ini_get('allow_url_fopen')) {
41666 $errorMessage = 'allow_url_fopen must be enabled in php.ini ('.$errorMessage.')';
41667 }
41668 restore_error_handler();
41669 if (isset($e) && !$this->retry) {
41670 if (!$this->degradedMode && false !== strpos($e->getMessage(), 'Operation timed out')) {
41671 $this->degradedMode = true;
41672 $this->io->writeError('');
41673 $this->io->writeError(array(
41674 '<error>'.$e->getMessage().'</error>',
41675 '<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>',
41676 ));
41677
41678 return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
41679 }
41680
41681 throw $e;
41682 }
41683
41684 $statusCode = null;
41685 $contentType = null;
41686 if (!empty($http_response_header[0])) {
41687 $statusCode = $this->findStatusCode($http_response_header);
41688 $contentType = $this->findHeaderValue($http_response_header, 'content-type');
41689 }
41690
41691
41692  if ($originUrl === 'bitbucket.org'
41693 && !$this->isPublicBitBucketDownload($fileUrl)
41694 && substr($fileUrl, -4) === '.zip'
41695 && $contentType && preg_match('{^text/html\b}i', $contentType)
41696 ) {
41697 $result = false;
41698 if ($this->retryAuthFailure) {
41699 $this->promptAuthAndRetry(401);
41700 }
41701 }
41702
41703
41704  $hasFollowedRedirect = false;
41705 if ($userlandFollow && $statusCode >= 300 && $statusCode <= 399 && $statusCode !== 304 && $this->redirects < $this->maxRedirects) {
41706 $hasFollowedRedirect = true;
41707 $result = $this->handleRedirect($http_response_header, $additionalOptions, $result);
41708 }
41709
41710
41711  if ($statusCode && $statusCode >= 400 && $statusCode <= 599) {
41712 if (!$this->retry) {
41713 if ($this->progress && !$this->retry && !$isRedirect) {
41714 $this->io->overwriteError("Downloading (<error>failed</error>)", false);
41715 }
41716
41717 $e = new TransportException('The "'.$this->fileUrl.'" file could not be downloaded ('.$http_response_header[0].')', $statusCode);
41718 $e->setHeaders($http_response_header);
41719 $e->setResponse($result);
41720 $e->setStatusCode($statusCode);
41721 throw $e;
41722 }
41723 $result = false;
41724 }
41725
41726 if ($this->progress && !$this->retry && !$isRedirect) {
41727 $this->io->overwriteError("Downloading (".($result === false ? '<error>failed</error>' : '<comment>100%</comment>').")", false);
41728 }
41729
41730
41731  if ($result && extension_loaded('zlib') && substr($fileUrl, 0, 4) === 'http' && !$hasFollowedRedirect) {
41732 $contentEncoding = $this->findHeaderValue($http_response_header, 'content-encoding');
41733 $decode = $contentEncoding && 'gzip' === strtolower($contentEncoding);
41734
41735 if ($decode) {
41736 try {
41737 if (PHP_VERSION_ID >= 50400) {
41738 $result = zlib_decode($result);
41739 } else {
41740
41741  $result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result));
41742 }
41743
41744 if (!$result) {
41745 throw new TransportException('Failed to decode zlib stream');
41746 }
41747 } catch (\Exception $e) {
41748 if ($this->degradedMode) {
41749 throw $e;
41750 }
41751
41752 $this->degradedMode = true;
41753 $this->io->writeError(array(
41754 '',
41755 '<error>Failed to decode response: '.$e->getMessage().'</error>',
41756 '<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>',
41757 ));
41758
41759 return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
41760 }
41761 }
41762 }
41763
41764
41765  if (false !== $result && null !== $fileName && !$isRedirect) {
41766 if ('' === $result) {
41767 throw new TransportException('"'.$this->fileUrl.'" appears broken, and returned an empty 200 response');
41768 }
41769
41770 $errorMessage = '';
41771 set_error_handler(function ($code, $msg) use (&$errorMessage) {
41772 if ($errorMessage) {
41773 $errorMessage .= "\n";
41774 }
41775 $errorMessage .= preg_replace('{^file_put_contents\(.*?\): }', '', $msg);
41776 });
41777 $result = (bool) file_put_contents($fileName, $result);
41778 restore_error_handler();
41779 if (false === $result) {
41780 throw new TransportException('The "'.$this->fileUrl.'" file could not be written to '.$fileName.': '.$errorMessage);
41781 }
41782 }
41783
41784
41785  if (false === $result && false !== strpos($errorMessage, 'Peer certificate') && PHP_VERSION_ID < 50600) {
41786
41787  
41788  
41789  
41790  
41791  
41792  
41793  
41794  
41795  
41796  
41797  
41798  
41799  
41800  
41801  
41802  if (CaBundle::isOpensslParseSafe()) {
41803 $certDetails = $this->getCertificateCnAndFp($this->fileUrl, $options);
41804
41805 if ($certDetails) {
41806 $this->peerCertificateMap[$this->getUrlAuthority($this->fileUrl)] = $certDetails;
41807
41808 $this->retry = true;
41809 }
41810 } else {
41811 $this->io->writeError('');
41812 $this->io->writeError(sprintf(
41813 '<error>Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.</error>',
41814 PHP_VERSION
41815 ));
41816 }
41817 }
41818
41819 if ($this->retry) {
41820 $this->retry = false;
41821
41822 $result = $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
41823
41824 if ($this->storeAuth && $this->config) {
41825 $authHelper = new AuthHelper($this->io, $this->config);
41826 $authHelper->storeAuth($this->originUrl, $this->storeAuth);
41827 $this->storeAuth = false;
41828 }
41829
41830 return $result;
41831 }
41832
41833 if (false === $result) {
41834 $e = new TransportException('The "'.$this->fileUrl.'" file could not be downloaded: '.$errorMessage, $errorCode);
41835 if (!empty($http_response_header[0])) {
41836 $e->setHeaders($http_response_header);
41837 }
41838
41839 if (!$this->degradedMode && false !== strpos($e->getMessage(), 'Operation timed out')) {
41840 $this->degradedMode = true;
41841 $this->io->writeError('');
41842 $this->io->writeError(array(
41843 '<error>'.$e->getMessage().'</error>',
41844 '<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>',
41845 ));
41846
41847 return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
41848 }
41849
41850 throw $e;
41851 }
41852
41853 if (!empty($http_response_header[0])) {
41854 $this->lastHeaders = $http_response_header;
41855 }
41856
41857 return $result;
41858 }
41859
41860
41861
41862
41863
41864
41865
41866
41867
41868
41869
41870
41871 protected function callbackGet($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax)
41872 {
41873 switch ($notificationCode) {
41874 case STREAM_NOTIFY_FAILURE:
41875 if (400 === $messageCode) {
41876
41877  
41878  throw new TransportException("The '" . $this->fileUrl . "' URL could not be accessed: " . $message, $messageCode);
41879 }
41880
41881  
41882
41883 case STREAM_NOTIFY_AUTH_REQUIRED:
41884 if (401 === $messageCode) {
41885
41886  if (!$this->retryAuthFailure) {
41887 break;
41888 }
41889
41890 $this->promptAuthAndRetry($messageCode);
41891 }
41892 break;
41893
41894 case STREAM_NOTIFY_AUTH_RESULT:
41895 if (403 === $messageCode) {
41896
41897  if (!$this->retryAuthFailure) {
41898 break;
41899 }
41900
41901 $this->promptAuthAndRetry($messageCode, $message);
41902 }
41903 break;
41904
41905 case STREAM_NOTIFY_FILE_SIZE_IS:
41906 $this->bytesMax = $bytesMax;
41907 break;
41908
41909 case STREAM_NOTIFY_PROGRESS:
41910 if ($this->bytesMax > 0 && $this->progress) {
41911 $progression = min(100, round($bytesTransferred / $this->bytesMax * 100));
41912
41913 if ((0 === $progression % 5) && 100 !== $progression && $progression !== $this->lastProgress) {
41914 $this->lastProgress = $progression;
41915 $this->io->overwriteError("Downloading (<comment>$progression%</comment>)", false);
41916 }
41917 }
41918 break;
41919
41920 default:
41921 break;
41922 }
41923 }
41924
41925 protected function promptAuthAndRetry($httpStatus, $reason = null)
41926 {
41927 if ($this->config && in_array($this->originUrl, $this->config->get('github-domains'), true)) {
41928 $message = "\n".'Could not fetch '.$this->fileUrl.', please create a GitHub OAuth token '.($httpStatus === 404 ? 'to access private repos' : 'to go over the API rate limit');
41929 $gitHubUtil = new GitHub($this->io, $this->config, null);
41930 if (!$gitHubUtil->authorizeOAuth($this->originUrl)
41931 && (!$this->io->isInteractive() || !$gitHubUtil->authorizeOAuthInteractively($this->originUrl, $message))
41932 ) {
41933 throw new TransportException('Could not authenticate against '.$this->originUrl, 401);
41934 }
41935 } elseif ($this->config && in_array($this->originUrl, $this->config->get('gitlab-domains'), true)) {
41936 $message = "\n".'Could not fetch '.$this->fileUrl.', enter your ' . $this->originUrl . ' credentials ' .($httpStatus === 401 ? 'to access private repos' : 'to go over the API rate limit');
41937 $gitLabUtil = new GitLab($this->io, $this->config, null);
41938
41939 if ($this->io->hasAuthentication($this->originUrl) && ($auth = $this->io->getAuthentication($this->originUrl)) && $auth['password'] === 'private-token') {
41940 throw new TransportException("Invalid credentials for '" . $this->fileUrl . "', aborting.", $httpStatus);
41941 }
41942
41943 if (!$gitLabUtil->authorizeOAuth($this->originUrl)
41944 && (!$this->io->isInteractive() || !$gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, $message))
41945 ) {
41946 throw new TransportException('Could not authenticate against '.$this->originUrl, 401);
41947 }
41948 } elseif ($this->config && $this->originUrl === 'bitbucket.org') {
41949 $askForOAuthToken = true;
41950 if ($this->io->hasAuthentication($this->originUrl)) {
41951 $auth = $this->io->getAuthentication($this->originUrl);
41952 if ($auth['username'] !== 'x-token-auth') {
41953 $bitbucketUtil = new Bitbucket($this->io, $this->config);
41954 $accessToken = $bitbucketUtil->requestToken($this->originUrl, $auth['username'], $auth['password']);
41955 if (!empty($accessToken)) {
41956 $this->io->setAuthentication($this->originUrl, 'x-token-auth', $accessToken);
41957 $askForOAuthToken = false;
41958 }
41959 } else {
41960 throw new TransportException('Could not authenticate against ' . $this->originUrl, 401);
41961 }
41962 }
41963
41964 if ($askForOAuthToken) {
41965 $message = "\n".'Could not fetch ' . $this->fileUrl . ', please create a bitbucket OAuth token to ' . (($httpStatus === 401 || $httpStatus === 403) ? 'to access private repos' : 'to go over the API rate limit');
41966 $bitBucketUtil = new Bitbucket($this->io, $this->config);
41967 if (! $bitBucketUtil->authorizeOAuth($this->originUrl)
41968 && (! $this->io->isInteractive() || !$bitBucketUtil->authorizeOAuthInteractively($this->originUrl, $message))
41969 ) {
41970 throw new TransportException('Could not authenticate against ' . $this->originUrl, 401);
41971 }
41972 }
41973 } else {
41974
41975  if ($httpStatus === 404) {
41976 return;
41977 }
41978
41979
41980  if (!$this->io->isInteractive()) {
41981 if ($httpStatus === 401) {
41982 $message = "The '" . $this->fileUrl . "' URL required authentication.\nYou must be using the interactive console to authenticate";
41983 }
41984 if ($httpStatus === 403) {
41985 $message = "The '" . $this->fileUrl . "' URL could not be accessed: " . $reason;
41986 }
41987
41988 throw new TransportException($message, $httpStatus);
41989 }
41990
41991  if ($this->io->hasAuthentication($this->originUrl)) {
41992 throw new TransportException("Invalid credentials for '" . $this->fileUrl . "', aborting.", $httpStatus);
41993 }
41994
41995 $this->io->overwriteError('');
41996 $this->io->writeError('    Authentication required (<info>'.parse_url($this->fileUrl, PHP_URL_HOST).'</info>):');
41997 $username = $this->io->ask('      Username: ');
41998 $password = $this->io->askAndHideAnswer('      Password: ');
41999 $this->io->setAuthentication($this->originUrl, $username, $password);
42000 $this->storeAuth = $this->config->get('store-auths');
42001 }
42002
42003 $this->retry = true;
42004 throw new TransportException('RETRY');
42005 }
42006
42007 protected function getOptionsForUrl($originUrl, $additionalOptions)
42008 {
42009 $tlsOptions = array();
42010
42011
42012  if ($this->disableTls === false && PHP_VERSION_ID < 50600 && !stream_is_local($this->fileUrl)) {
42013 $host = parse_url($this->fileUrl, PHP_URL_HOST);
42014
42015 if (PHP_VERSION_ID >= 50304) {
42016
42017  
42018  $userlandFollow = true;
42019 } else {
42020
42021  
42022  
42023  
42024
42025 if ($host === 'github.com' || $host === 'api.github.com') {
42026 $host = '*.github.com';
42027 }
42028 }
42029
42030 $tlsOptions['ssl']['CN_match'] = $host;
42031 $tlsOptions['ssl']['SNI_server_name'] = $host;
42032
42033 $urlAuthority = $this->getUrlAuthority($this->fileUrl);
42034
42035 if (isset($this->peerCertificateMap[$urlAuthority])) {
42036
42037  $certMap = $this->peerCertificateMap[$urlAuthority];
42038
42039 $this->io->writeError('', true, IOInterface::DEBUG);
42040 $this->io->writeError(sprintf(
42041 'Using <info>%s</info> as CN for subjectAltName enabled host <info>%s</info>',
42042 $certMap['cn'],
42043 $urlAuthority
42044 ), true, IOInterface::DEBUG);
42045
42046 $tlsOptions['ssl']['CN_match'] = $certMap['cn'];
42047 $tlsOptions['ssl']['peer_fingerprint'] = $certMap['fp'];
42048 }
42049 }
42050
42051 $headers = array();
42052
42053 if (extension_loaded('zlib')) {
42054 $headers[] = 'Accept-Encoding: gzip';
42055 }
42056
42057 $options = array_replace_recursive($this->options, $tlsOptions, $additionalOptions);
42058 if (!$this->degradedMode) {
42059
42060  
42061  $options['http']['protocol_version'] = 1.1;
42062 $headers[] = 'Connection: close';
42063 }
42064
42065 if (isset($userlandFollow)) {
42066 $options['http']['follow_location'] = 0;
42067 }
42068
42069 if ($this->io->hasAuthentication($originUrl)) {
42070 $auth = $this->io->getAuthentication($originUrl);
42071 if ('github.com' === $originUrl && 'x-oauth-basic' === $auth['password']) {
42072 $options['github-token'] = $auth['username'];
42073 } elseif ($this->config && in_array($originUrl, $this->config->get('gitlab-domains'), true)) {
42074 if ($auth['password'] === 'oauth2') {
42075 $headers[] = 'Authorization: Bearer '.$auth['username'];
42076 } elseif ($auth['password'] === 'private-token') {
42077 $headers[] = 'PRIVATE-TOKEN: '.$auth['username'];
42078 }
42079 } elseif ('bitbucket.org' === $originUrl
42080 && $this->fileUrl !== Bitbucket::OAUTH2_ACCESS_TOKEN_URL && 'x-token-auth' === $auth['username']
42081 ) {
42082 if (!$this->isPublicBitBucketDownload($this->fileUrl)) {
42083 $headers[] = 'Authorization: Bearer ' . $auth['password'];
42084 }
42085 } else {
42086 $authStr = base64_encode($auth['username'] . ':' . $auth['password']);
42087 $headers[] = 'Authorization: Basic '.$authStr;
42088 }
42089 }
42090
42091 if (isset($options['http']['header']) && !is_array($options['http']['header'])) {
42092 $options['http']['header'] = explode("\r\n", trim($options['http']['header'], "\r\n"));
42093 }
42094 foreach ($headers as $header) {
42095 $options['http']['header'][] = $header;
42096 }
42097
42098 return $options;
42099 }
42100
42101 private function handleRedirect(array $http_response_header, array $additionalOptions, $result)
42102 {
42103 if ($locationHeader = $this->findHeaderValue($http_response_header, 'location')) {
42104 if (parse_url($locationHeader, PHP_URL_SCHEME)) {
42105
42106  $targetUrl = $locationHeader;
42107 } elseif (parse_url($locationHeader, PHP_URL_HOST)) {
42108
42109  $targetUrl = $this->scheme.':'.$locationHeader;
42110 } elseif ('/' === $locationHeader[0]) {
42111
42112  $urlHost = parse_url($this->fileUrl, PHP_URL_HOST);
42113
42114
42115  $targetUrl = preg_replace('{^(.+(?://|@)'.preg_quote($urlHost).'(?::\d+)?)(?:[/\?].*)?$}', '\1'.$locationHeader, $this->fileUrl);
42116 } else {
42117
42118  
42119  $targetUrl = preg_replace('{^(.+/)[^/?]*(?:\?.*)?$}', '\1'.$locationHeader, $this->fileUrl);
42120 }
42121 }
42122
42123 if (!empty($targetUrl)) {
42124 $this->redirects++;
42125
42126 $this->io->writeError('', true, IOInterface::DEBUG);
42127 $this->io->writeError(sprintf('Following redirect (%u) %s', $this->redirects, $targetUrl), true, IOInterface::DEBUG);
42128
42129 $additionalOptions['redirects'] = $this->redirects;
42130
42131 return $this->get($this->originUrl, $targetUrl, $additionalOptions, $this->fileName, $this->progress);
42132 }
42133
42134 if (!$this->retry) {
42135 $e = new TransportException('The "'.$this->fileUrl.'" file could not be downloaded, got redirect without Location ('.$http_response_header[0].')');
42136 $e->setHeaders($http_response_header);
42137 $e->setResponse($result);
42138
42139 throw $e;
42140 }
42141
42142 return false;
42143 }
42144
42145
42146
42147
42148
42149
42150 private function getTlsDefaults(array $options)
42151 {
42152 $ciphers = implode(':', array(
42153 'ECDHE-RSA-AES128-GCM-SHA256',
42154 'ECDHE-ECDSA-AES128-GCM-SHA256',
42155 'ECDHE-RSA-AES256-GCM-SHA384',
42156 'ECDHE-ECDSA-AES256-GCM-SHA384',
42157 'DHE-RSA-AES128-GCM-SHA256',
42158 'DHE-DSS-AES128-GCM-SHA256',
42159 'kEDH+AESGCM',
42160 'ECDHE-RSA-AES128-SHA256',
42161 'ECDHE-ECDSA-AES128-SHA256',
42162 'ECDHE-RSA-AES128-SHA',
42163 'ECDHE-ECDSA-AES128-SHA',
42164 'ECDHE-RSA-AES256-SHA384',
42165 'ECDHE-ECDSA-AES256-SHA384',
42166 'ECDHE-RSA-AES256-SHA',
42167 'ECDHE-ECDSA-AES256-SHA',
42168 'DHE-RSA-AES128-SHA256',
42169 'DHE-RSA-AES128-SHA',
42170 'DHE-DSS-AES128-SHA256',
42171 'DHE-RSA-AES256-SHA256',
42172 'DHE-DSS-AES256-SHA',
42173 'DHE-RSA-AES256-SHA',
42174 'AES128-GCM-SHA256',
42175 'AES256-GCM-SHA384',
42176 'AES128-SHA256',
42177 'AES256-SHA256',
42178 'AES128-SHA',
42179 'AES256-SHA',
42180 'AES',
42181 'CAMELLIA',
42182 'DES-CBC3-SHA',
42183 '!aNULL',
42184 '!eNULL',
42185 '!EXPORT',
42186 '!DES',
42187 '!RC4',
42188 '!MD5',
42189 '!PSK',
42190 '!aECDH',
42191 '!EDH-DSS-DES-CBC3-SHA',
42192 '!EDH-RSA-DES-CBC3-SHA',
42193 '!KRB5-DES-CBC3-SHA',
42194 ));
42195
42196
42197
42198
42199
42200
42201
42202 $defaults = array(
42203 'ssl' => array(
42204 'ciphers' => $ciphers,
42205 'verify_peer' => true,
42206 'verify_depth' => 7,
42207 'SNI_enabled' => true,
42208 'capture_peer_cert' => true,
42209 ),
42210 );
42211
42212 if (isset($options['ssl'])) {
42213 $defaults['ssl'] = array_replace_recursive($defaults['ssl'], $options['ssl']);
42214 }
42215
42216 $caBundleLogger = $this->io instanceof LoggerInterface ? $this->io : null;
42217
42218
42219
42220
42221
42222 if (!isset($defaults['ssl']['cafile']) && !isset($defaults['ssl']['capath'])) {
42223 $result = CaBundle::getSystemCaRootBundlePath($caBundleLogger);
42224
42225 if (preg_match('{^phar://}', $result)) {
42226 $hash = hash_file('sha256', $result);
42227 $targetPath = rtrim(sys_get_temp_dir(), '\\/') . '/composer-cacert-' . $hash . '.pem';
42228
42229 if (!file_exists($targetPath) || $hash !== hash_file('sha256', $targetPath)) {
42230 $this->streamCopy($result, $targetPath);
42231 chmod($targetPath, 0666);
42232 }
42233
42234 $defaults['ssl']['cafile'] = $targetPath;
42235 } elseif (is_dir($result)) {
42236 $defaults['ssl']['capath'] = $result;
42237 } else {
42238 $defaults['ssl']['cafile'] = $result;
42239 }
42240 }
42241
42242 if (isset($defaults['ssl']['cafile']) && (!is_readable($defaults['ssl']['cafile']) || !CaBundle::validateCaFile($defaults['ssl']['cafile'], $caBundleLogger))) {
42243 throw new TransportException('The configured cafile was not valid or could not be read.');
42244 }
42245
42246 if (isset($defaults['ssl']['capath']) && (!is_dir($defaults['ssl']['capath']) || !is_readable($defaults['ssl']['capath']))) {
42247 throw new TransportException('The configured capath was not valid or could not be read.');
42248 }
42249
42250
42251
42252
42253 if (PHP_VERSION_ID >= 50413) {
42254 $defaults['ssl']['disable_compression'] = true;
42255 }
42256
42257 return $defaults;
42258 }
42259
42260
42261
42262
42263
42264
42265
42266 private function streamCopy($source, $target)
42267 {
42268 $source = fopen($source, 'r');
42269 $target = fopen($target, 'w+');
42270
42271 stream_copy_to_stream($source, $target);
42272 fclose($source);
42273 fclose($target);
42274
42275 unset($source, $target);
42276 }
42277
42278
42279
42280
42281
42282
42283 private function getCertificateCnAndFp($url, $options)
42284 {
42285 if (PHP_VERSION_ID >= 50600) {
42286 throw new \BadMethodCallException(sprintf(
42287 '%s must not be used on PHP >= 5.6',
42288 __METHOD__
42289 ));
42290 }
42291
42292 $context = StreamContextFactory::getContext($url, $options, array('options' => array(
42293 'ssl' => array(
42294 'capture_peer_cert' => true,
42295 'verify_peer' => false, 
42296  ), ),
42297 ));
42298
42299
42300  
42301  if (false === $handle = @fopen($url, 'rb', false, $context)) {
42302 return;
42303 }
42304
42305
42306  fclose($handle);
42307 $handle = null;
42308
42309 $params = stream_context_get_params($context);
42310
42311 if (!empty($params['options']['ssl']['peer_certificate'])) {
42312 $peerCertificate = $params['options']['ssl']['peer_certificate'];
42313
42314 if (TlsHelper::checkCertificateHost($peerCertificate, parse_url($url, PHP_URL_HOST), $commonName)) {
42315 return array(
42316 'cn' => $commonName,
42317 'fp' => TlsHelper::getCertificateFingerprint($peerCertificate),
42318 );
42319 }
42320 }
42321 }
42322
42323 private function getUrlAuthority($url)
42324 {
42325 $defaultPorts = array(
42326 'ftp' => 21,
42327 'http' => 80,
42328 'https' => 443,
42329 'ssh2.sftp' => 22,
42330 'ssh2.scp' => 22,
42331 );
42332
42333 $scheme = parse_url($url, PHP_URL_SCHEME);
42334
42335 if (!isset($defaultPorts[$scheme])) {
42336 throw new \InvalidArgumentException(sprintf(
42337 'Could not get default port for unknown scheme: %s',
42338 $scheme
42339 ));
42340 }
42341
42342 $defaultPort = $defaultPorts[$scheme];
42343 $port = parse_url($url, PHP_URL_PORT) ?: $defaultPort;
42344
42345 return parse_url($url, PHP_URL_HOST).':'.$port;
42346 }
42347
42348
42349
42350
42351
42352
42353
42354
42355 private function isPublicBitBucketDownload($urlToBitBucketFile)
42356 {
42357 $domain = parse_url($urlToBitBucketFile, PHP_URL_HOST);
42358 if (strpos($domain, 'bitbucket.org') === false) {
42359
42360  
42361  return true;
42362 }
42363
42364 $path = parse_url($urlToBitBucketFile, PHP_URL_PATH);
42365
42366
42367  
42368  $pathParts = explode('/', $path);
42369 if (count($pathParts) >= 4 && $pathParts[3] == 'downloads') {
42370 return true;
42371 }
42372
42373 return false;
42374 }
42375 }
42376 <?php
42377
42378
42379
42380
42381
42382
42383
42384
42385
42386
42387
42388 namespace Composer\Util;
42389
42390
42391
42392
42393
42394
42395 class Silencer
42396 {
42397
42398
42399
42400 private static $stack = array();
42401
42402
42403
42404
42405
42406
42407
42408 public static function suppress($mask = null)
42409 {
42410 if (!isset($mask)) {
42411 $mask = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED | E_USER_DEPRECATED | E_STRICT;
42412 }
42413 $old = error_reporting();
42414 array_push(self::$stack, $old);
42415 error_reporting($old & ~$mask);
42416
42417 return $old;
42418 }
42419
42420
42421
42422
42423 public static function restore()
42424 {
42425 if (!empty(self::$stack)) {
42426 error_reporting(array_pop(self::$stack));
42427 }
42428 }
42429
42430
42431
42432
42433
42434
42435
42436
42437
42438
42439 public static function call($callable )
42440 {
42441 try {
42442 self::suppress();
42443 $result = call_user_func_array($callable, array_slice(func_get_args(), 1));
42444 self::restore();
42445
42446 return $result;
42447 } catch (\Exception $e) {
42448
42449  self::restore();
42450 throw $e;
42451 }
42452 }
42453 }
42454 <?php
42455
42456
42457
42458
42459
42460
42461
42462
42463
42464
42465
42466 namespace Composer\Util;
42467
42468 use Composer\Spdx\SpdxLicenses;
42469
42470 trigger_error('The ' . __NAMESPACE__ . '\SpdxLicense class is deprecated, use Composer\Spdx\SpdxLicenses instead.', E_USER_DEPRECATED);
42471
42472
42473
42474
42475 class SpdxLicense extends SpdxLicenses
42476 {
42477 }
42478 <?php
42479
42480
42481
42482
42483
42484
42485
42486
42487
42488
42489
42490 namespace Composer\Util;
42491
42492 use Composer\Composer;
42493
42494
42495
42496
42497
42498
42499
42500 final class StreamContextFactory
42501 {
42502
42503
42504
42505
42506
42507
42508
42509
42510
42511 public static function getContext($url, array $defaultOptions = array(), array $defaultParams = array())
42512 {
42513 $options = array('http' => array(
42514
42515  'follow_location' => 1,
42516 'max_redirects' => 20,
42517 ));
42518
42519
42520  if (PHP_SAPI === 'cli' && (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy']))) {
42521 $proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
42522 }
42523
42524
42525  if (!empty($_SERVER['CGI_HTTP_PROXY'])) {
42526 $proxy = parse_url($_SERVER['CGI_HTTP_PROXY']);
42527 }
42528
42529
42530  if (preg_match('{^https://}i', $url) && (!empty($_SERVER['HTTPS_PROXY']) || !empty($_SERVER['https_proxy']))) {
42531 $proxy = parse_url(!empty($_SERVER['https_proxy']) ? $_SERVER['https_proxy'] : $_SERVER['HTTPS_PROXY']);
42532 }
42533
42534
42535  if (!empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
42536 $pattern = new NoProxyPattern($_SERVER['no_proxy']);
42537 if ($pattern->test($url)) {
42538 unset($proxy);
42539 }
42540 }
42541
42542 if (!empty($proxy)) {
42543 $proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
42544 $proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
42545
42546 if (isset($proxy['port'])) {
42547 $proxyURL .= ":" . $proxy['port'];
42548 } elseif ('http://' == substr($proxyURL, 0, 7)) {
42549 $proxyURL .= ":80";
42550 } elseif ('https://' == substr($proxyURL, 0, 8)) {
42551 $proxyURL .= ":443";
42552 }
42553
42554
42555  $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
42556
42557 if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
42558 throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
42559 }
42560
42561 $options['http']['proxy'] = $proxyURL;
42562
42563
42564  switch (parse_url($url, PHP_URL_SCHEME)) {
42565 case 'http': 
42566  $reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI');
42567 if ($reqFullUriEnv === false || $reqFullUriEnv === '' || (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv)) {
42568 $options['http']['request_fulluri'] = true;
42569 }
42570 break;
42571 case 'https': 
42572  $reqFullUriEnv = getenv('HTTPS_PROXY_REQUEST_FULLURI');
42573 if ($reqFullUriEnv === false || $reqFullUriEnv === '' || (strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv)) {
42574 $options['http']['request_fulluri'] = true;
42575 }
42576 break;
42577 }
42578
42579
42580  if ('https' === parse_url($url, PHP_URL_SCHEME)) {
42581 $options['ssl']['SNI_enabled'] = true;
42582 if (PHP_VERSION_ID < 50600) {
42583 $options['ssl']['SNI_server_name'] = parse_url($url, PHP_URL_HOST);
42584 }
42585 }
42586
42587
42588  if (isset($proxy['user'])) {
42589 $auth = urldecode($proxy['user']);
42590 if (isset($proxy['pass'])) {
42591 $auth .= ':' . urldecode($proxy['pass']);
42592 }
42593 $auth = base64_encode($auth);
42594
42595
42596  if (isset($defaultOptions['http']['header'])) {
42597 if (is_string($defaultOptions['http']['header'])) {
42598 $defaultOptions['http']['header'] = array($defaultOptions['http']['header']);
42599 }
42600 $defaultOptions['http']['header'][] = "Proxy-Authorization: Basic {$auth}";
42601 } else {
42602 $options['http']['header'] = array("Proxy-Authorization: Basic {$auth}");
42603 }
42604 }
42605 }
42606
42607 $options = array_replace_recursive($options, $defaultOptions);
42608
42609 if (isset($options['http']['header'])) {
42610 $options['http']['header'] = self::fixHttpHeaderField($options['http']['header']);
42611 }
42612
42613 if (defined('HHVM_VERSION')) {
42614 $phpVersion = 'HHVM ' . HHVM_VERSION;
42615 } else {
42616 $phpVersion = 'PHP ' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;
42617 }
42618
42619 if (!isset($options['http']['header']) || false === strpos(strtolower(implode('', $options['http']['header'])), 'user-agent')) {
42620 $options['http']['header'][] = sprintf(
42621 'User-Agent: Composer/%s (%s; %s; %s%s)',
42622 Composer::VERSION === '@package_version@' ? 'source' : Composer::VERSION,
42623 php_uname('s'),
42624 php_uname('r'),
42625 $phpVersion,
42626 getenv('CI') ? '; CI' : ''
42627 );
42628 }
42629
42630 return stream_context_create($options, $defaultParams);
42631 }
42632
42633
42634
42635
42636
42637
42638
42639
42640
42641
42642
42643 private static function fixHttpHeaderField($header)
42644 {
42645 if (!is_array($header)) {
42646 $header = explode("\r\n", $header);
42647 }
42648 uasort($header, function ($el) {
42649 return preg_match('{^content-type}i', $el) ? 1 : -1;
42650 });
42651
42652 return $header;
42653 }
42654 }
42655 <?php
42656
42657
42658
42659
42660
42661
42662
42663
42664
42665
42666
42667 namespace Composer\Util;
42668
42669 use Composer\Config;
42670 use Composer\IO\IOInterface;
42671
42672
42673
42674
42675
42676 class Svn
42677 {
42678 const MAX_QTY_AUTH_TRIES = 5;
42679
42680
42681
42682
42683 protected $credentials;
42684
42685
42686
42687
42688 protected $hasAuth;
42689
42690
42691
42692
42693 protected $io;
42694
42695
42696
42697
42698 protected $url;
42699
42700
42701
42702
42703 protected $cacheCredentials = true;
42704
42705
42706
42707
42708 protected $process;
42709
42710
42711
42712
42713 protected $qtyAuthTries = 0;
42714
42715
42716
42717
42718 protected $config;
42719
42720
42721
42722
42723
42724
42725
42726 public function __construct($url, IOInterface $io, Config $config, ProcessExecutor $process = null)
42727 {
42728 $this->url = $url;
42729 $this->io = $io;
42730 $this->config = $config;
42731 $this->process = $process ?: new ProcessExecutor;
42732 }
42733
42734 public static function cleanEnv()
42735 {
42736
42737  putenv("DYLD_LIBRARY_PATH");
42738 unset($_SERVER['DYLD_LIBRARY_PATH']);
42739 }
42740
42741
42742
42743
42744
42745
42746
42747
42748
42749
42750
42751
42752
42753
42754 public function execute($command, $url, $cwd = null, $path = null, $verbose = false)
42755 {
42756
42757  $this->config->prohibitUrlByConfig($url, $this->io);
42758
42759 $svnCommand = $this->getCommand($command, $url, $path);
42760 $output = null;
42761 $io = $this->io;
42762 $handler = function ($type, $buffer) use (&$output, $io, $verbose) {
42763 if ($type !== 'out') {
42764 return;
42765 }
42766 if ('Redirecting to URL ' === substr($buffer, 0, 19)) {
42767 return;
42768 }
42769 $output .= $buffer;
42770 if ($verbose) {
42771 $io->writeError($buffer, false);
42772 }
42773 };
42774 $status = $this->process->execute($svnCommand, $handler, $cwd);
42775 if (0 === $status) {
42776 return $output;
42777 }
42778
42779 $errorOutput = $this->process->getErrorOutput();
42780 $fullOutput = implode("\n", array($output, $errorOutput));
42781
42782
42783  if (false === stripos($fullOutput, 'Could not authenticate to server:')
42784 && false === stripos($fullOutput, 'authorization failed')
42785 && false === stripos($fullOutput, 'svn: E170001:')
42786 && false === stripos($fullOutput, 'svn: E215004:')) {
42787 throw new \RuntimeException($fullOutput);
42788 }
42789
42790 if (!$this->hasAuth()) {
42791 $this->doAuthDance();
42792 }
42793
42794
42795  if ($this->qtyAuthTries++ < self::MAX_QTY_AUTH_TRIES) {
42796
42797  return $this->execute($command, $url, $cwd, $path, $verbose);
42798 }
42799
42800 throw new \RuntimeException(
42801 'wrong credentials provided ('.$fullOutput.')'
42802 );
42803 }
42804
42805
42806
42807
42808 public function setCacheCredentials($cacheCredentials)
42809 {
42810 $this->cacheCredentials = $cacheCredentials;
42811 }
42812
42813
42814
42815
42816
42817
42818
42819 protected function doAuthDance()
42820 {
42821
42822  if (!$this->io->isInteractive()) {
42823 throw new \RuntimeException(
42824 'can not ask for authentication in non interactive mode'
42825 );
42826 }
42827
42828 $this->io->writeError("The Subversion server ({$this->url}) requested credentials:");
42829
42830 $this->hasAuth = true;
42831 $this->credentials['username'] = $this->io->ask("Username: ");
42832 $this->credentials['password'] = $this->io->askAndHideAnswer("Password: ");
42833
42834 $this->cacheCredentials = $this->io->askConfirmation("Should Subversion cache these credentials? (yes/no) ", true);
42835
42836 return $this;
42837 }
42838
42839
42840
42841
42842
42843
42844
42845
42846
42847
42848 protected function getCommand($cmd, $url, $path = null)
42849 {
42850 $cmd = sprintf('%s %s%s %s',
42851 $cmd,
42852 '--non-interactive ',
42853 $this->getCredentialString(),
42854 ProcessExecutor::escape($url)
42855 );
42856
42857 if ($path) {
42858 $cmd .= ' ' . ProcessExecutor::escape($path);
42859 }
42860
42861 return $cmd;
42862 }
42863
42864
42865
42866
42867
42868
42869
42870
42871 protected function getCredentialString()
42872 {
42873 if (!$this->hasAuth()) {
42874 return '';
42875 }
42876
42877 return sprintf(
42878 ' %s--username %s --password %s ',
42879 $this->getAuthCache(),
42880 ProcessExecutor::escape($this->getUsername()),
42881 ProcessExecutor::escape($this->getPassword())
42882 );
42883 }
42884
42885
42886
42887
42888
42889
42890
42891 protected function getPassword()
42892 {
42893 if ($this->credentials === null) {
42894 throw new \LogicException("No svn auth detected.");
42895 }
42896
42897 return isset($this->credentials['password']) ? $this->credentials['password'] : '';
42898 }
42899
42900
42901
42902
42903
42904
42905
42906 protected function getUsername()
42907 {
42908 if ($this->credentials === null) {
42909 throw new \LogicException("No svn auth detected.");
42910 }
42911
42912 return $this->credentials['username'];
42913 }
42914
42915
42916
42917
42918
42919
42920 protected function hasAuth()
42921 {
42922 if (null !== $this->hasAuth) {
42923 return $this->hasAuth;
42924 }
42925
42926 if (false === $this->createAuthFromConfig()) {
42927 $this->createAuthFromUrl();
42928 }
42929
42930 return $this->hasAuth;
42931 }
42932
42933
42934
42935
42936
42937
42938 protected function getAuthCache()
42939 {
42940 return $this->cacheCredentials ? '' : '--no-auth-cache ';
42941 }
42942
42943
42944
42945
42946
42947
42948 private function createAuthFromConfig()
42949 {
42950 if (!$this->config->has('http-basic')) {
42951 return $this->hasAuth = false;
42952 }
42953
42954 $authConfig = $this->config->get('http-basic');
42955
42956 $host = parse_url($this->url, PHP_URL_HOST);
42957 if (isset($authConfig[$host])) {
42958 $this->credentials['username'] = $authConfig[$host]['username'];
42959 $this->credentials['password'] = $authConfig[$host]['password'];
42960
42961 return $this->hasAuth = true;
42962 }
42963
42964 return $this->hasAuth = false;
42965 }
42966
42967
42968
42969
42970
42971
42972 private function createAuthFromUrl()
42973 {
42974 $uri = parse_url($this->url);
42975 if (empty($uri['user'])) {
42976 return $this->hasAuth = false;
42977 }
42978
42979 $this->credentials['username'] = $uri['user'];
42980 if (!empty($uri['pass'])) {
42981 $this->credentials['password'] = $uri['pass'];
42982 }
42983
42984 return $this->hasAuth = true;
42985 }
42986 }
42987 <?php
42988
42989
42990
42991
42992
42993
42994
42995
42996
42997
42998
42999 namespace Composer\Util;
43000
43001 use Composer\CaBundle\CaBundle;
43002
43003
43004
43005
43006 final class TlsHelper
43007 {
43008 private static $useOpensslParse;
43009
43010
43011
43012
43013
43014
43015
43016
43017
43018
43019 public static function checkCertificateHost($certificate, $hostname, &$cn = null)
43020 {
43021 $names = self::getCertificateNames($certificate);
43022
43023 if (empty($names)) {
43024 return false;
43025 }
43026
43027 $combinedNames = array_merge($names['san'], array($names['cn']));
43028 $hostname = strtolower($hostname);
43029
43030 foreach ($combinedNames as $certName) {
43031 $matcher = self::certNameMatcher($certName);
43032
43033 if ($matcher && $matcher($hostname)) {
43034 $cn = $names['cn'];
43035
43036 return true;
43037 }
43038 }
43039
43040 return false;
43041 }
43042
43043
43044
43045
43046
43047
43048
43049
43050 public static function getCertificateNames($certificate)
43051 {
43052 if (is_array($certificate)) {
43053 $info = $certificate;
43054 } elseif (CaBundle::isOpensslParseSafe()) {
43055 $info = openssl_x509_parse($certificate, false);
43056 }
43057
43058 if (!isset($info['subject']['commonName'])) {
43059 return null;
43060 }
43061
43062 $commonName = strtolower($info['subject']['commonName']);
43063 $subjectAltNames = array();
43064
43065 if (isset($info['extensions']['subjectAltName'])) {
43066 $subjectAltNames = preg_split('{\s*,\s*}', $info['extensions']['subjectAltName']);
43067 $subjectAltNames = array_filter(array_map(function ($name) {
43068 if (0 === strpos($name, 'DNS:')) {
43069 return strtolower(ltrim(substr($name, 4)));
43070 }
43071
43072 return null;
43073 }, $subjectAltNames));
43074 $subjectAltNames = array_values($subjectAltNames);
43075 }
43076
43077 return array(
43078 'cn' => $commonName,
43079 'san' => $subjectAltNames,
43080 );
43081 }
43082
43083
43084
43085
43086
43087
43088
43089
43090
43091
43092
43093
43094
43095
43096
43097
43098
43099
43100
43101
43102
43103
43104
43105
43106
43107
43108
43109
43110
43111
43112
43113
43114
43115
43116
43117
43118
43119
43120
43121
43122 public static function getCertificateFingerprint($certificate)
43123 {
43124 $pubkeydetails = openssl_pkey_get_details(openssl_get_publickey($certificate));
43125 $pubkeypem = $pubkeydetails['key'];
43126
43127  $start = '-----BEGIN PUBLIC KEY-----';
43128 $end = '-----END PUBLIC KEY-----';
43129 $pemtrim = substr($pubkeypem, (strpos($pubkeypem, $start) + strlen($start)), (strlen($pubkeypem) - strpos($pubkeypem, $end)) * (-1));
43130 $der = base64_decode($pemtrim);
43131
43132 return sha1($der);
43133 }
43134
43135
43136
43137
43138
43139
43140
43141
43142
43143 public static function isOpensslParseSafe()
43144 {
43145 return CaBundle::isOpensslParseSafe();
43146 }
43147
43148
43149
43150
43151
43152
43153
43154
43155 private static function certNameMatcher($certName)
43156 {
43157 $wildcards = substr_count($certName, '*');
43158
43159 if (0 === $wildcards) {
43160
43161  return function ($hostname) use ($certName) {
43162 return $hostname === $certName;
43163 };
43164 }
43165
43166 if (1 === $wildcards) {
43167 $components = explode('.', $certName);
43168
43169 if (3 > count($components)) {
43170
43171  return;
43172 }
43173
43174 $firstComponent = $components[0];
43175
43176
43177  if ('*' !== $firstComponent[strlen($firstComponent) - 1]) {
43178 return;
43179 }
43180
43181 $wildcardRegex = preg_quote($certName);
43182 $wildcardRegex = str_replace('\\*', '[a-z0-9-]+', $wildcardRegex);
43183 $wildcardRegex = "{^{$wildcardRegex}$}";
43184
43185 return function ($hostname) use ($wildcardRegex) {
43186 return 1 === preg_match($wildcardRegex, $hostname);
43187 };
43188 }
43189 }
43190 }
43191 <?php
43192
43193
43194
43195
43196
43197
43198
43199
43200
43201
43202
43203 namespace Composer;
43204
43205 use Composer\Util\IniHelper;
43206 use Symfony\Component\Console\Output\OutputInterface;
43207
43208
43209
43210
43211 class XdebugHandler
43212 {
43213 const ENV_ALLOW = 'COMPOSER_ALLOW_XDEBUG';
43214 const ENV_VERSION = 'COMPOSER_XDEBUG_VERSION';
43215 const RESTART_ID = 'internal';
43216
43217 private $output;
43218 private $loaded;
43219 private $envScanDir;
43220 private $version;
43221 private $tmpIni;
43222
43223
43224
43225
43226 public function __construct(OutputInterface $output)
43227 {
43228 $this->output = $output;
43229 $this->loaded = extension_loaded('xdebug');
43230 $this->envScanDir = getenv('PHP_INI_SCAN_DIR');
43231
43232 if ($this->loaded) {
43233 $ext = new \ReflectionExtension('xdebug');
43234 $this->version = strval($ext->getVersion());
43235 }
43236 }
43237
43238
43239
43240
43241
43242
43243
43244
43245
43246
43247
43248
43249
43250
43251 public function check()
43252 {
43253 $args = explode('|', strval(getenv(self::ENV_ALLOW)), 2);
43254
43255 if ($this->needsRestart($args[0])) {
43256 if ($this->prepareRestart()) {
43257 $command = $this->getCommand();
43258 $this->restart($command);
43259 }
43260
43261 return;
43262 }
43263
43264
43265  if (self::RESTART_ID === $args[0]) {
43266 putenv(self::ENV_ALLOW);
43267
43268 if (false !== $this->envScanDir) {
43269
43270  if (isset($args[1])) {
43271 putenv('PHP_INI_SCAN_DIR='.$args[1]);
43272 } else {
43273 putenv('PHP_INI_SCAN_DIR');
43274 }
43275 }
43276
43277
43278  if ($this->loaded) {
43279 putenv(self::ENV_VERSION);
43280 }
43281 }
43282 }
43283
43284
43285
43286
43287
43288
43289 protected function restart($command)
43290 {
43291 passthru($command, $exitCode);
43292
43293 if (!empty($this->tmpIni)) {
43294 @unlink($this->tmpIni);
43295 }
43296
43297 exit($exitCode);
43298 }
43299
43300
43301
43302
43303
43304
43305
43306
43307 private function needsRestart($allow)
43308 {
43309 if (PHP_SAPI !== 'cli' || !defined('PHP_BINARY')) {
43310 return false;
43311 }
43312
43313 return empty($allow) && $this->loaded;
43314 }
43315
43316
43317
43318
43319
43320
43321
43322
43323
43324
43325
43326 private function prepareRestart()
43327 {
43328 $this->tmpIni = '';
43329 $iniPaths = IniHelper::getAll();
43330 $additional = count($iniPaths) > 1;
43331
43332 if (empty($iniPaths[0])) {
43333
43334  array_shift($iniPaths);
43335 }
43336
43337 if ($this->writeTmpIni($iniPaths)) {
43338 return $this->setEnvironment($additional, $iniPaths);
43339 }
43340
43341 return false;
43342 }
43343
43344
43345
43346
43347
43348
43349
43350
43351
43352
43353 private function writeTmpIni(array $iniFiles)
43354 {
43355 if (!$this->tmpIni = tempnam(sys_get_temp_dir(), '')) {
43356 return false;
43357 }
43358
43359 $content = '';
43360 $regex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi';
43361
43362 foreach ($iniFiles as $file) {
43363 $data = preg_replace($regex, ';$1', file_get_contents($file));
43364 $content .= $data.PHP_EOL;
43365 }
43366
43367 $content .= 'memory_limit='.ini_get('memory_limit').PHP_EOL;
43368
43369 if (defined('PHP_WINDOWS_VERSION_BUILD')) {
43370
43371  $content .= 'opcache.enable_cli=0'.PHP_EOL;
43372 }
43373
43374 return @file_put_contents($this->tmpIni, $content);
43375 }
43376
43377
43378
43379
43380
43381
43382 private function getCommand()
43383 {
43384 $phpArgs = array(PHP_BINARY, '-c', $this->tmpIni);
43385 $params = array_merge($phpArgs, $this->getScriptArgs($_SERVER['argv']));
43386
43387 return implode(' ', array_map(array($this, 'escape'), $params));
43388 }
43389
43390
43391
43392
43393
43394
43395
43396
43397
43398 private function setEnvironment($additional, array $iniPaths)
43399 {
43400
43401  if ($additional && !putenv('PHP_INI_SCAN_DIR=')) {
43402 return false;
43403 }
43404
43405
43406  if (!putenv(IniHelper::ENV_ORIGINAL.'='.implode(PATH_SEPARATOR, $iniPaths))) {
43407 return false;
43408 }
43409
43410
43411  if (!putenv(self::ENV_VERSION.'='.$this->version)) {
43412 return false;
43413 }
43414
43415
43416  $args = array(self::RESTART_ID);
43417
43418 if (false !== $this->envScanDir) {
43419
43420  $args[] = $this->envScanDir;
43421 }
43422
43423 return putenv(self::ENV_ALLOW.'='.implode('|', $args));
43424 }
43425
43426
43427
43428
43429
43430
43431
43432
43433
43434
43435
43436 private function getScriptArgs(array $args)
43437 {
43438 if (in_array('--no-ansi', $args) || in_array('--ansi', $args)) {
43439 return $args;
43440 }
43441
43442 if ($this->output->isDecorated()) {
43443 $offset = count($args) > 1 ? 2 : 1;
43444 array_splice($args, $offset, 0, '--ansi');
43445 }
43446
43447 return $args;
43448 }
43449
43450
43451
43452
43453
43454
43455
43456
43457
43458
43459
43460
43461 private function escape($arg, $meta = true)
43462 {
43463 if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
43464 return escapeshellarg($arg);
43465 }
43466
43467 $quote = strpbrk($arg, " \t") !== false || $arg === '';
43468 $arg = preg_replace('/(\\\\*)"/', '$1$1\\"', $arg, -1, $dquotes);
43469
43470 if ($meta) {
43471 $meta = $dquotes || preg_match('/%[^%]+%/', $arg);
43472
43473 if (!$meta && !$quote) {
43474 $quote = strpbrk($arg, '^&|<>()') !== false;
43475 }
43476 }
43477
43478 if ($quote) {
43479 $arg = preg_replace('/(\\\\*)$/', '$1$1', $arg);
43480 $arg = '"'.$arg.'"';
43481 }
43482
43483 if ($meta) {
43484 $arg = preg_replace('/(["^&|<>()%])/', '^$1', $arg);
43485 }
43486
43487 return $arg;
43488 }
43489 }
43490 <?php
43491
43492
43493
43494
43495
43496
43497
43498
43499
43500
43501
43502 function includeIfExists($file)
43503 {
43504 return file_exists($file) ? include $file : false;
43505 }
43506
43507 if ((!$loader = includeIfExists(__DIR__.'/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../../../autoload.php'))) {
43508 echo 'You must set up the project dependencies using `composer install`'.PHP_EOL.
43509 'See https://getcomposer.org/download/ for instructions on installing Composer'.PHP_EOL;
43510 exit(1);
43511 }
43512
43513 return $loader;
43514 <?php
43515
43516 /*
43517  * This file is part of Composer.
43518  *
43519  * (c) Nils Adermann <naderman@naderman.de>
43520  *     Jordi Boggiano <j.boggiano@seld.be>
43521  *
43522  * For the full copyright and license information, please view the LICENSE
43523  * file that was distributed with this source code.
43524  */
43525
43526 namespace Composer\Autoload;
43527
43528 /**
43529  * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
43530  *
43531  *     $loader = new \Composer\Autoload\ClassLoader();
43532  *
43533  *     // register classes with namespaces
43534  *     $loader->add('Symfony\Component', __DIR__.'/component');
43535  *     $loader->add('Symfony',           __DIR__.'/framework');
43536  *
43537  *     // activate the autoloader
43538  *     $loader->register();
43539  *
43540  *     // to enable searching the include path (eg. for PEAR packages)
43541  *     $loader->setUseIncludePath(true);
43542  *
43543  * In this example, if you try to use a class in the Symfony\Component
43544  * namespace or one of its children (Symfony\Component\Console for instance),
43545  * the autoloader will first look for the class under the component/
43546  * directory, and it will then fallback to the framework/ directory if not
43547  * found before giving up.
43548  *
43549  * This class is loosely based on the Symfony UniversalClassLoader.
43550  *
43551  * @author Fabien Potencier <fabien@symfony.com>
43552  * @author Jordi Boggiano <j.boggiano@seld.be>
43553  * @see    http://www.php-fig.org/psr/psr-0/
43554  * @see    http://www.php-fig.org/psr/psr-4/
43555  */
43556 class ClassLoader
43557 {
43558     // PSR-4
43559     private $prefixLengthsPsr4 = array();
43560     private $prefixDirsPsr4 = array();
43561     private $fallbackDirsPsr4 = array();
43562
43563     // PSR-0
43564     private $prefixesPsr0 = array();
43565     private $fallbackDirsPsr0 = array();
43566
43567     private $useIncludePath = false;
43568     private $classMap = array();
43569     private $classMapAuthoritative = false;
43570     private $missingClasses = array();
43571     private $apcuPrefix;
43572
43573     public function getPrefixes()
43574     {
43575         if (!empty($this->prefixesPsr0)) {
43576             return call_user_func_array('array_merge', $this->prefixesPsr0);
43577         }
43578
43579         return array();
43580     }
43581
43582     public function getPrefixesPsr4()
43583     {
43584         return $this->prefixDirsPsr4;
43585     }
43586
43587     public function getFallbackDirs()
43588     {
43589         return $this->fallbackDirsPsr0;
43590     }
43591
43592     public function getFallbackDirsPsr4()
43593     {
43594         return $this->fallbackDirsPsr4;
43595     }
43596
43597     public function getClassMap()
43598     {
43599         return $this->classMap;
43600     }
43601
43602     /**
43603      * @param array $classMap Class to filename map
43604      */
43605     public function addClassMap(array $classMap)
43606     {
43607         if ($this->classMap) {
43608             $this->classMap = array_merge($this->classMap, $classMap);
43609         } else {
43610             $this->classMap = $classMap;
43611         }
43612     }
43613
43614     /**
43615      * Registers a set of PSR-0 directories for a given prefix, either
43616      * appending or prepending to the ones previously set for this prefix.
43617      *
43618      * @param string       $prefix  The prefix
43619      * @param array|string $paths   The PSR-0 root directories
43620      * @param bool         $prepend Whether to prepend the directories
43621      */
43622     public function add($prefix, $paths, $prepend = false)
43623     {
43624         if (!$prefix) {
43625             if ($prepend) {
43626                 $this->fallbackDirsPsr0 = array_merge(
43627                     (array) $paths,
43628                     $this->fallbackDirsPsr0
43629                 );
43630             } else {
43631                 $this->fallbackDirsPsr0 = array_merge(
43632                     $this->fallbackDirsPsr0,
43633                     (array) $paths
43634                 );
43635             }
43636
43637             return;
43638         }
43639
43640         $first = $prefix[0];
43641         if (!isset($this->prefixesPsr0[$first][$prefix])) {
43642             $this->prefixesPsr0[$first][$prefix] = (array) $paths;
43643
43644             return;
43645         }
43646         if ($prepend) {
43647             $this->prefixesPsr0[$first][$prefix] = array_merge(
43648                 (array) $paths,
43649                 $this->prefixesPsr0[$first][$prefix]
43650             );
43651         } else {
43652             $this->prefixesPsr0[$first][$prefix] = array_merge(
43653                 $this->prefixesPsr0[$first][$prefix],
43654                 (array) $paths
43655             );
43656         }
43657     }
43658
43659     /**
43660      * Registers a set of PSR-4 directories for a given namespace, either
43661      * appending or prepending to the ones previously set for this namespace.
43662      *
43663      * @param string       $prefix  The prefix/namespace, with trailing '\\'
43664      * @param array|string $paths   The PSR-4 base directories
43665      * @param bool         $prepend Whether to prepend the directories
43666      *
43667      * @throws \InvalidArgumentException
43668      */
43669     public function addPsr4($prefix, $paths, $prepend = false)
43670     {
43671         if (!$prefix) {
43672             // Register directories for the root namespace.
43673             if ($prepend) {
43674                 $this->fallbackDirsPsr4 = array_merge(
43675                     (array) $paths,
43676                     $this->fallbackDirsPsr4
43677                 );
43678             } else {
43679                 $this->fallbackDirsPsr4 = array_merge(
43680                     $this->fallbackDirsPsr4,
43681                     (array) $paths
43682                 );
43683             }
43684         } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
43685             // Register directories for a new namespace.
43686             $length = strlen($prefix);
43687             if ('\\' !== $prefix[$length - 1]) {
43688                 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
43689             }
43690             $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
43691             $this->prefixDirsPsr4[$prefix] = (array) $paths;
43692         } elseif ($prepend) {
43693             // Prepend directories for an already registered namespace.
43694             $this->prefixDirsPsr4[$prefix] = array_merge(
43695                 (array) $paths,
43696                 $this->prefixDirsPsr4[$prefix]
43697             );
43698         } else {
43699             // Append directories for an already registered namespace.
43700             $this->prefixDirsPsr4[$prefix] = array_merge(
43701                 $this->prefixDirsPsr4[$prefix],
43702                 (array) $paths
43703             );
43704         }
43705     }
43706
43707     /**
43708      * Registers a set of PSR-0 directories for a given prefix,
43709      * replacing any others previously set for this prefix.
43710      *
43711      * @param string       $prefix The prefix
43712      * @param array|string $paths  The PSR-0 base directories
43713      */
43714     public function set($prefix, $paths)
43715     {
43716         if (!$prefix) {
43717             $this->fallbackDirsPsr0 = (array) $paths;
43718         } else {
43719             $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
43720         }
43721     }
43722
43723     /**
43724      * Registers a set of PSR-4 directories for a given namespace,
43725      * replacing any others previously set for this namespace.
43726      *
43727      * @param string       $prefix The prefix/namespace, with trailing '\\'
43728      * @param array|string $paths  The PSR-4 base directories
43729      *
43730      * @throws \InvalidArgumentException
43731      */
43732     public function setPsr4($prefix, $paths)
43733     {
43734         if (!$prefix) {
43735             $this->fallbackDirsPsr4 = (array) $paths;
43736         } else {
43737             $length = strlen($prefix);
43738             if ('\\' !== $prefix[$length - 1]) {
43739                 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
43740             }
43741             $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
43742             $this->prefixDirsPsr4[$prefix] = (array) $paths;
43743         }
43744     }
43745
43746     /**
43747      * Turns on searching the include path for class files.
43748      *
43749      * @param bool $useIncludePath
43750      */
43751     public function setUseIncludePath($useIncludePath)
43752     {
43753         $this->useIncludePath = $useIncludePath;
43754     }
43755
43756     /**
43757      * Can be used to check if the autoloader uses the include path to check
43758      * for classes.
43759      *
43760      * @return bool
43761      */
43762     public function getUseIncludePath()
43763     {
43764         return $this->useIncludePath;
43765     }
43766
43767     /**
43768      * Turns off searching the prefix and fallback directories for classes
43769      * that have not been registered with the class map.
43770      *
43771      * @param bool $classMapAuthoritative
43772      */
43773     public function setClassMapAuthoritative($classMapAuthoritative)
43774     {
43775         $this->classMapAuthoritative = $classMapAuthoritative;
43776     }
43777
43778     /**
43779      * Should class lookup fail if not found in the current class map?
43780      *
43781      * @return bool
43782      */
43783     public function isClassMapAuthoritative()
43784     {
43785         return $this->classMapAuthoritative;
43786     }
43787
43788     /**
43789      * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
43790      *
43791      * @param string|null $apcuPrefix
43792      */
43793     public function setApcuPrefix($apcuPrefix)
43794     {
43795         $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
43796     }
43797
43798     /**
43799      * The APCu prefix in use, or null if APCu caching is not enabled.
43800      *
43801      * @return string|null
43802      */
43803     public function getApcuPrefix()
43804     {
43805         return $this->apcuPrefix;
43806     }
43807
43808     /**
43809      * Registers this instance as an autoloader.
43810      *
43811      * @param bool $prepend Whether to prepend the autoloader or not
43812      */
43813     public function register($prepend = false)
43814     {
43815         spl_autoload_register(array($this, 'loadClass'), true, $prepend);
43816     }
43817
43818     /**
43819      * Unregisters this instance as an autoloader.
43820      */
43821     public function unregister()
43822     {
43823         spl_autoload_unregister(array($this, 'loadClass'));
43824     }
43825
43826     /**
43827      * Loads the given class or interface.
43828      *
43829      * @param  string    $class The name of the class
43830      * @return bool|null True if loaded, null otherwise
43831      */
43832     public function loadClass($class)
43833     {
43834         if ($file = $this->findFile($class)) {
43835             includeFile($file);
43836
43837             return true;
43838         }
43839     }
43840
43841     /**
43842      * Finds the path to the file where the class is defined.
43843      *
43844      * @param string $class The name of the class
43845      *
43846      * @return string|false The path if found, false otherwise
43847      */
43848     public function findFile($class)
43849     {
43850         // class map lookup
43851         if (isset($this->classMap[$class])) {
43852             return $this->classMap[$class];
43853         }
43854         if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
43855             return false;
43856         }
43857         if (null !== $this->apcuPrefix) {
43858             $file = apcu_fetch($this->apcuPrefix.$class, $hit);
43859             if ($hit) {
43860                 return $file;
43861             }
43862         }
43863
43864         $file = $this->findFileWithExtension($class, '.php');
43865
43866         // Search for Hack files if we are running on HHVM
43867         if (false === $file && defined('HHVM_VERSION')) {
43868             $file = $this->findFileWithExtension($class, '.hh');
43869         }
43870
43871         if (null !== $this->apcuPrefix) {
43872             apcu_add($this->apcuPrefix.$class, $file);
43873         }
43874
43875         if (false === $file) {
43876             // Remember that this class does not exist.
43877             $this->missingClasses[$class] = true;
43878         }
43879
43880         return $file;
43881     }
43882
43883     private function findFileWithExtension($class, $ext)
43884     {
43885         // PSR-4 lookup
43886         $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
43887
43888         $first = $class[0];
43889         if (isset($this->prefixLengthsPsr4[$first])) {
43890             $subPath = $class;
43891             while (false !== $lastPos = strrpos($subPath, '\\')) {
43892                 $subPath = substr($subPath, 0, $lastPos);
43893                 $search = $subPath.'\\';
43894                 if (isset($this->prefixDirsPsr4[$search])) {
43895                     foreach ($this->prefixDirsPsr4[$search] as $dir) {
43896                         $length = $this->prefixLengthsPsr4[$first][$search];
43897                         if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
43898                             return $file;
43899                         }
43900                     }
43901                 }
43902             }
43903         }
43904
43905         // PSR-4 fallback dirs
43906         foreach ($this->fallbackDirsPsr4 as $dir) {
43907             if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
43908                 return $file;
43909             }
43910         }
43911
43912         // PSR-0 lookup
43913         if (false !== $pos = strrpos($class, '\\')) {
43914             // namespaced class name
43915             $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
43916                 . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
43917         } else {
43918             // PEAR-like class name
43919             $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
43920         }
43921
43922         if (isset($this->prefixesPsr0[$first])) {
43923             foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
43924                 if (0 === strpos($class, $prefix)) {
43925                     foreach ($dirs as $dir) {
43926                         if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
43927                             return $file;
43928                         }
43929                     }
43930                 }
43931             }
43932         }
43933
43934         // PSR-0 fallback dirs
43935         foreach ($this->fallbackDirsPsr0 as $dir) {
43936             if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
43937                 return $file;
43938             }
43939         }
43940
43941         // PSR-0 include paths.
43942         if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
43943             return $file;
43944         }
43945
43946         return false;
43947     }
43948 }
43949
43950 /**
43951  * Scope isolated include.
43952  *
43953  * Prevents access to $this/self from included files.
43954  */
43955 function includeFile($file)
43956 {
43957     include $file;
43958 }
43959 {
43960     "$schema": "http://json-schema.org/draft-04/schema#",
43961     "description": "A representation of packages metadata.",
43962     "type": "object",
43963     "oneOf": [
43964         { "required": [ "packages" ] },
43965         { "required": [ "providers" ] },
43966         { "required": [ "provider-includes", "providers-url" ] }
43967     ],
43968     "properties": {
43969         "packages": {
43970             "type": ["object", "array"],
43971             "description": "A hashmap of package names in the form of <vendor>/<name>.",
43972             "additionalProperties": { "$ref": "#/definitions/versions" }
43973         },
43974         "providers-url": {
43975             "type": "string",
43976             "description": "Endpoint to retrieve provider data from, e.g. '/p/%package%$%hash%.json'."
43977         },
43978         "provider-includes": {
43979             "type": "object",
43980             "description": "A hashmap of provider listings.",
43981             "additionalProperties": { "$ref": "#/definitions/provider" }
43982         },
43983         "providers": {
43984             "type": "object",
43985             "description": "A hashmap of package names in the form of <vendor>/<name>.",
43986             "additionalProperties": { "$ref": "#/definitions/provider" }
43987         },
43988         "notify-batch": {
43989             "type": "string",
43990             "description": "Endpoint to call after multiple packages have been installed, e.g. '/downloads/'."
43991         },
43992         "search": {
43993             "type": "string",
43994             "description": "Endpoint that provides search capabilities, e.g. '/search.json?q=%query%&type=%type%'."
43995         },
43996         "warning": {
43997             "type": "string",
43998             "description": "A message that will be output by Composer as a warning when this source is consulted."
43999         }
44000     },
44001     "definitions": {
44002         "versions": {
44003             "type": "object",
44004             "description": "A hashmap of versions and their metadata.",
44005             "additionalProperties": { "$ref": "#/definitions/version" }
44006         },
44007         "version": {
44008             "type": "object",
44009             "oneOf": [
44010                 { "$ref": "#/definitions/package" },
44011                 { "$ref": "#/definitions/metapackage" }
44012             ]
44013         },
44014         "package-base": {
44015             "properties": {
44016                 "name": { "type": "string" },
44017                 "type": { "type": "string" },
44018                 "version": { "type": "string" },
44019                 "version_normalized": {
44020                     "type": "string",
44021                     "description": "Normalized version, optional but can save computational time on client side."
44022                 },
44023                 "autoload": { "type": "object" },
44024                 "require": { "type": "object" },
44025                 "replace": { "type": "object" },
44026                 "conflict": { "type": "object" },
44027                 "provide": { "type": "object" },
44028                 "time": { "type": "string" }
44029             },
44030             "additionalProperties": true
44031         },
44032         "package": {
44033             "allOf": [
44034                 { "$ref": "#/definitions/package-base" },
44035                 {
44036                     "properties": {
44037                         "dist": { "type": "object" },
44038                         "source": { "type": "object" }
44039                     }
44040                 },
44041                 { "oneOf": [
44042                     { "required": [ "name", "version", "source" ] },
44043                     { "required": [ "name", "version", "dist" ] }
44044                 ] }
44045             ]
44046         },
44047         "metapackage": {
44048             "allOf": [
44049                 { "$ref": "#/definitions/package-base" },
44050                 {
44051                     "properties": {
44052                         "type": { "type": "string", "enum": [ "metapackage" ] }
44053                     },
44054                     "required": [ "name", "version", "type" ]
44055                 }
44056             ]
44057         },
44058         "provider": {
44059             "type": "object",
44060             "properties": {
44061                 "sha256": {
44062                     "type": "string",
44063                     "description": "Hash value that can be used to validate the resource."
44064                 }
44065             }
44066         }
44067     }
44068 }
44069 {
44070     "$schema": "http://json-schema.org/draft-04/schema#",
44071     "name": "Package",
44072     "type": "object",
44073     "additionalProperties": false,
44074     "required": [ "name", "description" ],
44075     "properties": {
44076         "name": {
44077             "type": "string",
44078             "description": "Package name, including 'vendor-name/' prefix."
44079         },
44080         "type": {
44081             "description": "Package type, either 'library' for common packages, 'composer-plugin' for plugins, 'metapackage' for empty packages, or a custom type ([a-z0-9-]+) defined by whatever project this package applies to.",
44082             "type": "string"
44083         },
44084         "target-dir": {
44085             "description": "DEPRECATED: Forces the package to be installed into the given subdirectory path. This is used for autoloading PSR-0 packages that do not contain their full path. Use forward slashes for cross-platform compatibility.",
44086             "type": "string"
44087         },
44088         "description": {
44089             "type": "string",
44090             "description": "Short package description."
44091         },
44092         "keywords": {
44093             "type": "array",
44094             "items": {
44095                 "type": "string",
44096                 "description": "A tag/keyword that this package relates to."
44097             }
44098         },
44099         "homepage": {
44100             "type": "string",
44101             "description": "Homepage URL for the project.",
44102             "format": "uri"
44103         },
44104         "version": {
44105             "type": "string",
44106             "description": "Package version, see https://getcomposer.org/doc/04-schema.md#version for more info on valid schemes."
44107         },
44108         "time": {
44109             "type": "string",
44110             "description": "Package release date, in 'YYYY-MM-DD', 'YYYY-MM-DD HH:MM:SS' or 'YYYY-MM-DDTHH:MM:SSZ' format."
44111         },
44112         "license": {
44113             "type": ["string", "array"],
44114             "description": "License name. Or an array of license names."
44115         },
44116         "authors": {
44117             "$ref": "#/definitions/authors"
44118         },
44119         "require": {
44120             "type": "object",
44121             "description": "This is a hash of package name (keys) and version constraints (values) that are required to run this package.",
44122             "additionalProperties": {
44123                 "type": "string"
44124             }
44125         },
44126         "replace": {
44127             "type": "object",
44128             "description": "This is a hash of package name (keys) and version constraints (values) that can be replaced by this package.",
44129             "additionalProperties": {
44130                 "type": "string"
44131             }
44132         },
44133         "conflict": {
44134             "type": "object",
44135             "description": "This is a hash of package name (keys) and version constraints (values) that conflict with this package.",
44136             "additionalProperties": {
44137                 "type": "string"
44138             }
44139         },
44140         "provide": {
44141             "type": "object",
44142             "description": "This is a hash of package name (keys) and version constraints (values) that this package provides in addition to this package's name.",
44143             "additionalProperties": {
44144                 "type": "string"
44145             }
44146         },
44147         "require-dev": {
44148             "type": "object",
44149             "description": "This is a hash of package name (keys) and version constraints (values) that this package requires for developing it (testing tools and such).",
44150             "additionalProperties": {
44151                 "type": "string"
44152             }
44153         },
44154         "suggest": {
44155             "type": "object",
44156             "description": "This is a hash of package name (keys) and descriptions (values) that this package suggests work well with it (this will be suggested to the user during installation).",
44157             "additionalProperties": {
44158                 "type": "string"
44159             }
44160         },
44161         "config": {
44162             "type": "object",
44163             "description": "Composer options.",
44164             "properties": {
44165                 "process-timeout": {
44166                     "type": "integer",
44167                     "description": "The timeout in seconds for process executions, defaults to 300 (5mins)."
44168                 },
44169                 "use-include-path": {
44170                     "type": "boolean",
44171                     "description": "If true, the Composer autoloader will also look for classes in the PHP include path."
44172                 },
44173                 "preferred-install": {
44174                     "type": ["string", "object"],
44175                     "description": "The install method Composer will prefer to use, defaults to auto and can be any of source, dist, auto, or a hash of {\"pattern\": \"preference\"}."
44176                 },
44177                 "notify-on-install": {
44178                     "type": "boolean",
44179                     "description": "Composer allows repositories to define a notification URL, so that they get notified whenever a package from that repository is installed. This option allows you to disable that behaviour, defaults to true."
44180                 },
44181                 "github-protocols": {
44182                     "type": "array",
44183                     "description": "A list of protocols to use for github.com clones, in priority order, defaults to [\"git\", \"https\", \"http\"].",
44184                     "items": {
44185                         "type": "string"
44186                     }
44187                 },
44188                 "github-oauth": {
44189                     "type": "object",
44190                     "description": "A hash of domain name => github API oauth tokens, typically {\"github.com\":\"<token>\"}.",
44191                     "additionalProperties": {
44192                         "type": "string"
44193                     }
44194                 },
44195                 "gitlab-oauth": {
44196                     "type": "object",
44197                     "description": "A hash of domain name => gitlab API oauth tokens, typically {\"gitlab.com\":\"<token>\"}.",
44198                     "additionalProperties": {
44199                         "type": "string"
44200                     }
44201                 },
44202                 "gitlab-token": {
44203                     "type": "object",
44204                     "description": "A hash of domain name => gitlab private tokens, typically {\"gitlab.com\":\"<token>\"}.",
44205                     "additionalProperties": true
44206                 },
44207                 "disable-tls": {
44208                     "type": "boolean",
44209                     "description": "Defaults to `false`. If set to true all HTTPS URLs will be tried with HTTP instead and no network level encryption is performed. Enabling this is a security risk and is NOT recommended. The better way is to enable the php_openssl extension in php.ini."
44210                 },
44211                 "secure-http": {
44212                     "type": "boolean",
44213                     "description": "Defaults to `true`. If set to true only HTTPS URLs are allowed to be downloaded via Composer. If you really absolutely need HTTP access to something then you can disable it, but using \"Let's Encrypt\" to get a free SSL certificate is generally a better alternative."
44214                 },
44215                 "cafile": {
44216                     "type": "string",
44217                     "description": "A way to set the path to the openssl CA file. In PHP 5.6+ you should rather set this via openssl.cafile in php.ini, although PHP 5.6+ should be able to detect your system CA file automatically."
44218                 },
44219                 "capath": {
44220                     "type": "string",
44221                     "description": "If cafile is not specified or if the certificate is not found there, the directory pointed to by capath is searched for a suitable certificate. capath must be a correctly hashed certificate directory."
44222                 },
44223                 "http-basic": {
44224                     "type": "object",
44225                     "description": "A hash of domain name => {\"username\": \"...\", \"password\": \"...\"}.",
44226                     "additionalProperties": {
44227                         "type": "object",
44228                         "required": ["username", "password"],
44229                         "properties": {
44230                             "username": {
44231                                 "type": "string",
44232                                 "description": "The username used for HTTP Basic authentication"
44233                             },
44234                             "password": {
44235                                 "type": "string",
44236                                 "description": "The password used for HTTP Basic authentication"
44237                             }
44238                         }
44239                     }
44240                 },
44241                 "store-auths": {
44242                     "type": ["string", "boolean"],
44243                     "description": "What to do after prompting for authentication, one of: true (store), false (do not store) or \"prompt\" (ask every time), defaults to prompt."
44244                 },
44245                 "platform": {
44246                     "type": "object",
44247                     "description": "This is a hash of package name (keys) and version (values) that will be used to mock the platform packages on this machine.",
44248                     "additionalProperties": {
44249                         "type": "string"
44250                     }
44251                 },
44252                 "vendor-dir": {
44253                     "type": "string",
44254                     "description": "The location where all packages are installed, defaults to \"vendor\"."
44255                 },
44256                 "bin-dir": {
44257                     "type": "string",
44258                     "description": "The location where all binaries are linked, defaults to \"vendor/bin\"."
44259                 },
44260                 "data-dir": {
44261                     "type": "string",
44262                     "description": "The location where old phar files are stored, defaults to \"$home\" except on XDG Base Directory compliant unixes."
44263                 },
44264                 "cache-dir": {
44265                     "type": "string",
44266                     "description": "The location where all caches are located, defaults to \"~/.composer/cache\" on *nix and \"%LOCALAPPDATA%\\Composer\" on windows."
44267                 },
44268                 "cache-files-dir": {
44269                     "type": "string",
44270                     "description": "The location where files (zip downloads) are cached, defaults to \"{$cache-dir}/files\"."
44271                 },
44272                 "cache-repo-dir": {
44273                     "type": "string",
44274                     "description": "The location where repo (git/hg repo clones) are cached, defaults to \"{$cache-dir}/repo\"."
44275                 },
44276                 "cache-vcs-dir": {
44277                     "type": "string",
44278                     "description": "The location where vcs infos (git clones, github api calls, etc. when reading vcs repos) are cached, defaults to \"{$cache-dir}/vcs\"."
44279                 },
44280                 "cache-ttl": {
44281                     "type": "integer",
44282                     "description": "The default cache time-to-live, defaults to 15552000 (6 months)."
44283                 },
44284                 "cache-files-ttl": {
44285                     "type": "integer",
44286                     "description": "The cache time-to-live for files, defaults to the value of cache-ttl."
44287                 },
44288                 "cache-files-maxsize": {
44289                     "type": ["string", "integer"],
44290                     "description": "The cache max size for the files cache, defaults to \"300MiB\"."
44291                 },
44292                 "bin-compat": {
44293                     "enum": ["auto", "full"],
44294                     "description": "The compatibility of the binaries, defaults to \"auto\" (automatically guessed) and can be \"full\" (compatible with both Windows and Unix-based systems)."
44295                 },
44296                 "discard-changes": {
44297                     "type": ["string", "boolean"],
44298                     "description": "The default style of handling dirty updates, defaults to false and can be any of true, false or \"stash\"."
44299                 },
44300                 "autoloader-suffix": {
44301                     "type": "string",
44302                     "description": "Optional string to be used as a suffix for the generated Composer autoloader. When null a random one will be generated."
44303                 },
44304                 "optimize-autoloader": {
44305                     "type": "boolean",
44306                     "description": "Always optimize when dumping the autoloader."
44307                 },
44308                 "prepend-autoloader": {
44309                     "type": "boolean",
44310                     "description": "If false, the composer autoloader will not be prepended to existing autoloaders, defaults to true."
44311                 },
44312                 "classmap-authoritative": {
44313                     "type": "boolean",
44314                     "description": "If true, the composer autoloader will not scan the filesystem for classes that are not found in the class map, defaults to false."
44315                 },
44316                 "apcu-autoloader": {
44317                     "type": "boolean",
44318                     "description": "If true, the Composer autoloader will check for APCu and use it to cache found/not-found classes when the extension is enabled, defaults to false."
44319                 },
44320                 "github-domains": {
44321                     "type": "array",
44322                     "description": "A list of domains to use in github mode. This is used for GitHub Enterprise setups, defaults to [\"github.com\"].",
44323                     "items": {
44324                         "type": "string"
44325                     }
44326                 },
44327                 "github-expose-hostname": {
44328                     "type": "boolean",
44329                     "description": "Defaults to true. If set to false, the OAuth tokens created to access the github API will have a date instead of the machine hostname."
44330                 },
44331                 "gitlab-domains": {
44332                     "type": "array",
44333                     "description": "A list of domains to use in gitlab mode. This is used for custom GitLab setups, defaults to [\"gitlab.com\"].",
44334                     "items": {
44335                         "type": "string"
44336                     }
44337                 },
44338                 "archive-format": {
44339                     "type": "string",
44340                     "description": "The default archiving format when not provided on cli, defaults to \"tar\"."
44341                 },
44342                 "archive-dir": {
44343                     "type": "string",
44344                     "description": "The default archive path when not provided on cli, defaults to \".\"."
44345                 }
44346             }
44347         },
44348         "extra": {
44349             "type": ["object", "array"],
44350             "description": "Arbitrary extra data that can be used by plugins, for example, package of type composer-plugin may have a 'class' key defining an installer class name.",
44351             "additionalProperties": true
44352         },
44353         "autoload": {
44354             "$ref": "#/definitions/autoload"
44355         },
44356         "autoload-dev": {
44357             "type": "object",
44358             "description": "Description of additional autoload rules for development purpose (eg. a test suite).",
44359             "properties": {
44360                 "psr-0": {
44361                     "type": "object",
44362                     "description": "This is a hash of namespaces (keys) and the directories they can be found into (values, can be arrays of paths) by the autoloader.",
44363                     "additionalProperties": {
44364                         "type": ["string", "array"],
44365                         "items": {
44366                             "type": "string"
44367                         }
44368                     }
44369                 },
44370                 "psr-4": {
44371                     "type": "object",
44372                     "description": "This is a hash of namespaces (keys) and the PSR-4 directories they can map to (values, can be arrays of paths) by the autoloader.",
44373                     "additionalProperties": {
44374                         "type": ["string", "array"],
44375                         "items": {
44376                             "type": "string"
44377                         }
44378                     }
44379                 },
44380                 "classmap": {
44381                     "type": "array",
44382                     "description": "This is an array of directories that contain classes to be included in the class-map generation process."
44383                 },
44384                 "files": {
44385                     "type": "array",
44386                     "description": "This is an array of files that are always required on every request."
44387                 }
44388             }
44389         },
44390         "archive": {
44391             "type": ["object"],
44392             "description": "Options for creating package archives for distribution.",
44393             "properties": {
44394                 "exclude": {
44395                     "type": "array",
44396                     "description": "A list of patterns for paths to exclude or include if prefixed with an exclamation mark."
44397                 }
44398             }
44399         },
44400         "repositories": {
44401             "type": ["object", "array"],
44402             "description": "A set of additional repositories where packages can be found.",
44403             "additionalProperties": {
44404                 "oneOf": [
44405                     { "$ref": "#/definitions/repository" },
44406                     { "type": "boolean", "enum": [false] }
44407                 ]
44408             },
44409             "items": {
44410                 "oneOf": [
44411                     { "$ref": "#/definitions/repository" },
44412                     {
44413                         "type": "object",
44414                         "additionalProperties": { "type": "boolean", "enum": [false] },
44415                         "minProperties": 1,
44416                         "maxProperties": 1
44417                     }
44418                 ]
44419             }
44420         },
44421         "minimum-stability": {
44422             "type": ["string"],
44423             "description": "The minimum stability the packages must have to be install-able. Possible values are: dev, alpha, beta, RC, stable.",
44424             "pattern": "^dev|alpha|beta|rc|RC|stable$"
44425         },
44426         "prefer-stable": {
44427             "type": ["boolean"],
44428             "description": "If set to true, stable packages will be preferred to dev packages when possible, even if the minimum-stability allows unstable packages."
44429         },
44430         "bin": {
44431             "type": ["array"],
44432             "description": "A set of files that should be treated as binaries and symlinked into bin-dir (from config).",
44433             "items": {
44434                 "type": "string"
44435             }
44436         },
44437         "include-path": {
44438             "type": ["array"],
44439             "description": "DEPRECATED: A list of directories which should get added to PHP's include path. This is only present to support legacy projects, and all new code should preferably use autoloading.",
44440             "items": {
44441                 "type": "string"
44442             }
44443         },
44444         "scripts": {
44445             "type": ["object"],
44446             "description": "Scripts listeners that will be executed before/after some events.",
44447             "properties": {
44448                 "pre-install-cmd": {
44449                     "type": ["array", "string"],
44450                     "description": "Occurs before the install command is executed, contains one or more Class::method callables or shell commands."
44451                 },
44452                 "post-install-cmd": {
44453                     "type": ["array", "string"],
44454                     "description": "Occurs after the install command is executed, contains one or more Class::method callables or shell commands."
44455                 },
44456                 "pre-update-cmd": {
44457                     "type": ["array", "string"],
44458                     "description": "Occurs before the update command is executed, contains one or more Class::method callables or shell commands."
44459                 },
44460                 "post-update-cmd": {
44461                     "type": ["array", "string"],
44462                     "description": "Occurs after the update command is executed, contains one or more Class::method callables or shell commands."
44463                 },
44464                 "pre-status-cmd": {
44465                     "type": ["array", "string"],
44466                     "description": "Occurs before the status command is executed, contains one or more Class::method callables or shell commands."
44467                 },
44468                 "post-status-cmd": {
44469                     "type": ["array", "string"],
44470                     "description": "Occurs after the status command is executed, contains one or more Class::method callables or shell commands."
44471                 },
44472                 "pre-package-install": {
44473                     "type": ["array", "string"],
44474                     "description": "Occurs before a package is installed, contains one or more Class::method callables or shell commands."
44475                 },
44476                 "post-package-install": {
44477                     "type": ["array", "string"],
44478                     "description": "Occurs after a package is installed, contains one or more Class::method callables or shell commands."
44479                 },
44480                 "pre-package-update": {
44481                     "type": ["array", "string"],
44482                     "description": "Occurs before a package is updated, contains one or more Class::method callables or shell commands."
44483                 },
44484                 "post-package-update": {
44485                     "type": ["array", "string"],
44486                     "description": "Occurs after a package is updated, contains one or more Class::method callables or shell commands."
44487                 },
44488                 "pre-package-uninstall": {
44489                     "type": ["array", "string"],
44490                     "description": "Occurs before a package has been uninstalled, contains one or more Class::method callables or shell commands."
44491                 },
44492                 "post-package-uninstall": {
44493                     "type": ["array", "string"],
44494                     "description": "Occurs after a package has been uninstalled, contains one or more Class::method callables or shell commands."
44495                 },
44496                 "pre-autoload-dump": {
44497                     "type": ["array", "string"],
44498                     "description": "Occurs before the autoloader is dumped, contains one or more Class::method callables or shell commands."
44499                 },
44500                 "post-autoload-dump": {
44501                     "type": ["array", "string"],
44502                     "description": "Occurs after the autoloader is dumped, contains one or more Class::method callables or shell commands."
44503                 },
44504                 "post-root-package-install": {
44505                     "type": ["array", "string"],
44506                     "description": "Occurs after the root-package is installed, contains one or more Class::method callables or shell commands."
44507                 },
44508                 "post-create-project-cmd": {
44509                     "type": ["array", "string"],
44510                     "description": "Occurs after the create-project command is executed, contains one or more Class::method callables or shell commands."
44511                 }
44512             }
44513         },
44514         "support": {
44515             "type": "object",
44516             "properties": {
44517                 "email": {
44518                     "type": "string",
44519                     "description": "Email address for support.",
44520                     "format": "email"
44521                 },
44522                 "issues": {
44523                     "type": "string",
44524                     "description": "URL to the issue tracker.",
44525                     "format": "uri"
44526                 },
44527                 "forum": {
44528                     "type": "string",
44529                     "description": "URL to the forum.",
44530                     "format": "uri"
44531                 },
44532                 "wiki": {
44533                     "type": "string",
44534                     "description": "URL to the wiki.",
44535                     "format": "uri"
44536                 },
44537                 "irc": {
44538                     "type": "string",
44539                     "description": "IRC channel for support, as irc://server/channel.",
44540                     "format": "uri"
44541                 },
44542                 "source": {
44543                     "type": "string",
44544                     "description": "URL to browse or download the sources.",
44545                     "format": "uri"
44546                 },
44547                 "docs": {
44548                     "type": "string",
44549                     "description": "URL to the documentation.",
44550                     "format": "uri"
44551                 },
44552                 "rss": {
44553                     "type": "string",
44554                     "description": "URL to the RSS feed.",
44555                     "format": "uri"
44556                 }
44557             }
44558         },
44559         "non-feature-branches": {
44560             "type": ["array"],
44561             "description": "A set of string or regex patterns for non-numeric branch names that will not be handled as feature branches.",
44562             "items": {
44563                 "type": "string"
44564             }
44565         },
44566         "abandoned": {
44567             "type": ["boolean", "string"],
44568             "description": "Indicates whether this package has been abandoned, it can be boolean or a package name/URL pointing to a recommended alternative. Defaults to false."
44569         },
44570         "_comment": {
44571             "type": ["array", "string"],
44572             "description": "A key to store comments in"
44573         }
44574     },
44575     "definitions": {
44576         "authors": {
44577             "type": "array",
44578             "description": "List of authors that contributed to the package. This is typically the main maintainers, not the full list.",
44579             "items": {
44580                 "type": "object",
44581                 "additionalProperties": false,
44582                 "required": [ "name"],
44583                 "properties": {
44584                     "name": {
44585                         "type": "string",
44586                         "description": "Full name of the author."
44587                     },
44588                     "email": {
44589                         "type": "string",
44590                         "description": "Email address of the author.",
44591                         "format": "email"
44592                     },
44593                     "homepage": {
44594                         "type": "string",
44595                         "description": "Homepage URL for the author.",
44596                         "format": "uri"
44597                     },
44598                     "role": {
44599                         "type": "string",
44600                         "description": "Author's role in the project."
44601                     }
44602                 }
44603             }
44604         },
44605         "autoload": {
44606             "type": "object",
44607             "description": "Description of how the package can be autoloaded.",
44608             "properties": {
44609                 "psr-0": {
44610                     "type": "object",
44611                     "description": "This is a hash of namespaces (keys) and the directories they can be found in (values, can be arrays of paths) by the autoloader.",
44612                     "additionalProperties": {
44613                         "type": ["string", "array"],
44614                         "items": {
44615                             "type": "string"
44616                         }
44617                     }
44618                 },
44619                 "psr-4": {
44620                     "type": "object",
44621                     "description": "This is a hash of namespaces (keys) and the PSR-4 directories they can map to (values, can be arrays of paths) by the autoloader.",
44622                     "additionalProperties": {
44623                         "type": ["string", "array"],
44624                         "items": {
44625                             "type": "string"
44626                         }
44627                     }
44628                 },
44629                 "classmap": {
44630                     "type": "array",
44631                     "description": "This is an array of directories that contain classes to be included in the class-map generation process."
44632                 },
44633                 "files": {
44634                     "type": "array",
44635                     "description": "This is an array of files that are always required on every request."
44636                 },
44637                 "exclude-from-classmap": {
44638                     "type": "array",
44639                     "description": "This is an array of patterns to exclude from autoload classmap generation. (e.g. \"exclude-from-classmap\": [\"/test/\", \"/tests/\", \"/Tests/\"]"
44640                 }
44641             }
44642         },
44643         "repository": {
44644             "type": "object",
44645             "oneOf": [
44646                 { "$ref": "#/definitions/composer-repository" },
44647                 { "$ref": "#/definitions/vcs-repository" },
44648                 { "$ref": "#/definitions/path-repository" },
44649                 { "$ref": "#/definitions/artifact-repository" },
44650                 { "$ref": "#/definitions/pear-repository" },
44651                 { "$ref": "#/definitions/package-repository" }
44652             ]
44653         },
44654         "composer-repository": {
44655             "type": "object",
44656             "required": ["type", "url"],
44657             "properties": {
44658                 "type": { "type": "string", "enum": ["composer"] },
44659                 "url": { "type": "string" },
44660                 "options": {
44661                     "type": "object",
44662                     "additionalProperties": true
44663                 },
44664                 "allow_ssl_downgrade": { "type": "boolean" },
44665                 "force-lazy-providers": { "type": "boolean" }
44666             }
44667         },
44668         "vcs-repository": {
44669             "type": "object",
44670             "required": ["type", "url"],
44671             "properties": {
44672                 "type": { "type": "string", "enum": ["vcs", "github", "git", "gitlab", "git-bitbucket", "hg", "hg-bitbucket", "fossil", "perforce", "svn"] },
44673                 "url": { "type": "string" },
44674                 "no-api": { "type": "boolean" },
44675                 "secure-http": { "type": "boolean" },
44676                 "svn-cache-credentials": { "type": "boolean" },
44677                 "trunk-path": { "type": ["string", "boolean"] },
44678                 "branches-path": { "type": ["string", "boolean"] },
44679                 "tags-path": { "type": ["string", "boolean"] },
44680                 "package-path": { "type": "string" },
44681                 "depot": { "type": "string" },
44682                 "branch": { "type": "string" },
44683                 "unique_perforce_client_name": { "type": "string" },
44684                 "p4user": { "type": "string" },
44685                 "p4password": { "type": "string" }
44686             }
44687         },
44688         "path-repository": {
44689             "type": "object",
44690             "required": ["type", "url"],
44691             "properties": {
44692                 "type": { "type": "string", "enum": ["path"] },
44693                 "url": { "type": "string" },
44694                 "options": {
44695                     "type": "object",
44696                     "properties": {
44697                         "symlink": { "type": ["boolean", "null"] }
44698                     },
44699                     "additionalProperties": true
44700                 }
44701             }
44702         },
44703         "artifact-repository": {
44704             "type": "object",
44705             "required": ["type", "url"],
44706             "properties": {
44707                 "type": { "type": "string", "enum": ["artifact"] },
44708                 "url": { "type": "string" }
44709             }
44710         },
44711         "pear-repository": {
44712             "type": "object",
44713             "required": ["type", "url"],
44714             "properties": {
44715                 "type": { "type": "string", "enum": ["pear"] },
44716                 "url": { "type": "string" },
44717                 "vendor-alias": { "type": "string" }
44718             }
44719         },
44720         "package-repository": {
44721             "type": "object",
44722             "required": ["type", "package"],
44723             "properties": {
44724                 "type": { "type": "string", "enum": ["package"] },
44725                 "package": {
44726                     "oneOf": [
44727                         { "$ref": "#/definitions/inline-package" },
44728                         {
44729                             "type": "array",
44730                             "items": {
44731                                 "type": { "$ref": "#/definitions/inline-package" }
44732                             }
44733                         }
44734                     ]
44735                 }
44736             }
44737         },
44738         "inline-package": {
44739             "required": ["name", "version"],
44740             "properties": {
44741                 "name": {
44742                     "type": "string",
44743                     "description": "Package name, including 'vendor-name/' prefix."
44744                 },
44745                 "type": {
44746                     "type": "string"
44747                 },
44748                 "target-dir": {
44749                     "description": "DEPRECATED: Forces the package to be installed into the given subdirectory path. This is used for autoloading PSR-0 packages that do not contain their full path. Use forward slashes for cross-platform compatibility.",
44750                     "type": "string"
44751                 },
44752                 "description": {
44753                     "type": "string"
44754                 },
44755                 "keywords": {
44756                     "type": "array",
44757                     "items": {
44758                         "type": "string"
44759                     }
44760                 },
44761                 "homepage": {
44762                     "type": "string",
44763                     "format": "uri"
44764                 },
44765                 "version": {
44766                     "type": "string"
44767                 },
44768                 "time": {
44769                     "type": "string"
44770                 },
44771                 "license": {
44772                     "type": [
44773                         "string",
44774                         "array"
44775                     ]
44776                 },
44777                 "authors": {
44778                     "$ref": "#/definitions/authors"
44779                 },
44780                 "require": {
44781                     "type": "object",
44782                     "additionalProperties": {
44783                         "type": "string"
44784                     }
44785                 },
44786                 "replace": {
44787                     "type": "object",
44788                     "additionalProperties": {
44789                         "type": "string"
44790                     }
44791                 },
44792                 "conflict": {
44793                     "type": "object",
44794                     "additionalProperties": {
44795                         "type": "string"
44796                     }
44797                 },
44798                 "provide": {
44799                     "type": "object",
44800                     "additionalProperties": {
44801                         "type": "string"
44802                     }
44803                 },
44804                 "require-dev": {
44805                     "type": "object",
44806                     "additionalProperties": {
44807                         "type": "string"
44808                     }
44809                 },
44810                 "suggest": {
44811                     "type": "object",
44812                     "additionalProperties": {
44813                         "type": "string"
44814                     }
44815                 },
44816                 "extra": {
44817                     "type": ["object", "array"],
44818                     "additionalProperties": true
44819                 },
44820                 "autoload": {
44821                     "$ref": "#/definitions/autoload"
44822                 },
44823                 "archive": {
44824                     "type": ["object"],
44825                     "properties": {
44826                         "exclude": {
44827                             "type": "array"
44828                         }
44829                     }
44830                 },
44831                 "bin": {
44832                     "type": ["array"],
44833                     "description": "A set of files that should be treated as binaries and symlinked into bin-dir (from config).",
44834                     "items": {
44835                         "type": "string"
44836                     }
44837                 },
44838                 "include-path": {
44839                     "type": ["array"],
44840                     "description": "DEPRECATED: A list of directories which should get added to PHP's include path. This is only present to support legacy projects, and all new code should preferably use autoloading.",
44841                     "items": {
44842                         "type": "string"
44843                     }
44844                 },
44845                 "source": {
44846                     "type": "object",
44847                     "required": ["type", "url", "reference"],
44848                     "properties": {
44849                         "type": {
44850                             "type": "string"
44851                         },
44852                         "url": {
44853                             "type": "string"
44854                         },
44855                         "reference": {
44856                             "type": "string"
44857                         },
44858                         "mirrors": {
44859                             "type": "array"
44860                         }
44861                     }
44862                 },
44863                 "dist": {
44864                     "type": "object",
44865                     "required": ["type", "url"],
44866                     "properties": {
44867                         "type": {
44868                             "type": "string"
44869                         },
44870                         "url": {
44871                             "type": "string"
44872                         },
44873                         "reference": {
44874                             "type": "string"
44875                         },
44876                         "shasum": {
44877                             "type": "string"
44878                         },
44879                         "mirrors": {
44880                             "type": "array"
44881                         }
44882                     }
44883                 }
44884             },
44885             "additionalProperties": true
44886         }
44887     }
44888 }
44889 {
44890     "389-exception": [
44891         "389 Directory Server\nException"
44892     ],
44893     "Autoconf-exception-2.0": [
44894         "Autoconf exception 2.0"
44895     ],
44896     "Autoconf-exception-3.0": [
44897         "Autoconf exception 3.0"
44898     ],
44899     "Bison-exception-2.2": [
44900         "Bison exception 2.2"
44901     ],
44902     "Classpath-exception-2.0": [
44903         "Classpath exception 2.0"
44904     ],
44905     "CLISP-exception-2.0": [
44906         "CLISP exception 2.0"
44907     ],
44908     "DigiRule-FOSS-exception": [
44909         "DigiRule FOSS License Exception"
44910     ],
44911     "eCos-exception-2.0": [
44912         "eCos exception 2.0"
44913     ],
44914     "Fawkes-Runtime-exception": [
44915         "Fawkes Runtime Exception"
44916     ],
44917     "FLTK-exception": [
44918         "FLTK exception"
44919     ],
44920     "Font-exception-2.0": [
44921         "Font exception 2.0"
44922     ],
44923     "freertos-exception-2.0": [
44924         "FreeRTOS Exception 2.0"
44925     ],
44926     "GCC-exception-2.0": [
44927         "GCC Runtime Library exception 2.0"
44928     ],
44929     "GCC-exception-3.1": [
44930         "GCC Runtime Library exception 3.1"
44931     ],
44932     "gnu-javamail-exception": [
44933         "GNU JavaMail exception"
44934     ],
44935     "i2p-gpl-java-exception": [
44936         "i2p GPL+Java Exception"
44937     ],
44938     "Libtool-exception": [
44939         "Libtool Exception"
44940     ],
44941     "LZMA-exception": [
44942         "LZMA exception"
44943     ],
44944     "mif-exception": [
44945         "Macros and Inline Functions Exception"
44946     ],
44947     "Nokia-Qt-exception-1.1": [
44948         "Nokia Qt LGPL exception 1.1"
44949     ],
44950     "OCCT-exception-1.0": [
44951         "Open CASCADE Exception 1.0"
44952     ],
44953     "openvpn-openssl-exception": [
44954         "OpenVPN OpenSSL Exception"
44955     ],
44956     "Qwt-exception-1.0": [
44957         "Qwt exception 1.0"
44958     ],
44959     "u-boot-exception-2.0": [
44960         "U-Boot exception 2.0"
44961     ],
44962     "WxWindows-exception-3.1": [
44963         "WxWindows Library Exception 3.1"
44964     ]
44965 }{
44966     "0BSD": [
44967         "BSD Zero Clause License",
44968         true
44969     ],
44970     "AAL": [
44971         "Attribution Assurance License",
44972         true
44973     ],
44974     "Abstyles": [
44975         "Abstyles License",
44976         false
44977     ],
44978     "Adobe-2006": [
44979         "Adobe Systems Incorporated Source Code License Agreement",
44980         false
44981     ],
44982     "Adobe-Glyph": [
44983         "Adobe Glyph List License",
44984         false
44985     ],
44986     "ADSL": [
44987         "Amazon Digital Services License",
44988         false
44989     ],
44990     "AFL-1.1": [
44991         "Academic Free License v1.1",
44992         true
44993     ],
44994     "AFL-1.2": [
44995         "Academic Free License v1.2",
44996         true
44997     ],
44998     "AFL-2.0": [
44999         "Academic Free License v2.0",
45000         true
45001     ],
45002     "AFL-2.1": [
45003         "Academic Free License v2.1",
45004         true
45005     ],
45006     "AFL-3.0": [
45007         "Academic Free License v3.0",
45008         true
45009     ],
45010     "Afmparse": [
45011         "Afmparse License",
45012         false
45013     ],
45014     "AGPL-1.0": [
45015         "Affero General Public License v1.0",
45016         false
45017     ],
45018     "AGPL-3.0": [
45019         "GNU Affero General Public License v3.0",
45020         true
45021     ],
45022     "Aladdin": [
45023         "Aladdin Free Public License",
45024         false
45025     ],
45026     "AMDPLPA": [
45027         "AMD's plpa_map.c License",
45028         false
45029     ],
45030     "AML": [
45031         "Apple MIT License",
45032         false
45033     ],
45034     "AMPAS": [
45035         "Academy of Motion Picture Arts and Sciences BSD",
45036         false
45037     ],
45038     "ANTLR-PD": [
45039         "ANTLR Software Rights Notice",
45040         false
45041     ],
45042     "Apache-1.0": [
45043         "Apache License 1.0",
45044         false
45045     ],
45046     "Apache-1.1": [
45047         "Apache License 1.1",
45048         true
45049     ],
45050     "Apache-2.0": [
45051         "Apache License 2.0",
45052         true
45053     ],
45054     "APAFML": [
45055         "Adobe Postscript AFM License",
45056         false
45057     ],
45058     "APL-1.0": [
45059         "Adaptive Public License 1.0",
45060         true
45061     ],
45062     "APSL-1.0": [
45063         "Apple Public Source License 1.0",
45064         true
45065     ],
45066     "APSL-1.1": [
45067         "Apple Public Source License 1.1",
45068         true
45069     ],
45070     "APSL-1.2": [
45071         "Apple Public Source License 1.2",
45072         true
45073     ],
45074     "APSL-2.0": [
45075         "Apple Public Source License 2.0",
45076         true
45077     ],
45078     "Artistic-1.0": [
45079         "Artistic License 1.0",
45080         true
45081     ],
45082     "Artistic-1.0-cl8": [
45083         "Artistic License 1.0 w/clause 8",
45084         true
45085     ],
45086     "Artistic-1.0-Perl": [
45087         "Artistic License 1.0 (Perl)",
45088         true
45089     ],
45090     "Artistic-2.0": [
45091         "Artistic License 2.0",
45092         true
45093     ],
45094     "Bahyph": [
45095         "Bahyph License",
45096         false
45097     ],
45098     "Barr": [
45099         "Barr License",
45100         false
45101     ],
45102     "Beerware": [
45103         "Beerware License",
45104         false
45105     ],
45106     "BitTorrent-1.0": [
45107         "BitTorrent Open Source License v1.0",
45108         false
45109     ],
45110     "BitTorrent-1.1": [
45111         "BitTorrent Open Source License v1.1",
45112         false
45113     ],
45114     "Borceux": [
45115         "Borceux license",
45116         false
45117     ],
45118     "BSD-2-Clause": [
45119         "BSD 2-clause \"Simplified\" License",
45120         true
45121     ],
45122     "BSD-2-Clause-FreeBSD": [
45123         "BSD 2-clause FreeBSD License",
45124         false
45125     ],
45126     "BSD-2-Clause-NetBSD": [
45127         "BSD 2-clause NetBSD License",
45128         false
45129     ],
45130     "BSD-3-Clause": [
45131         "BSD 3-clause \"New\" or \"Revised\" License",
45132         true
45133     ],
45134     "BSD-3-Clause-Attribution": [
45135         "BSD with attribution",
45136         false
45137     ],
45138     "BSD-3-Clause-Clear": [
45139         "BSD 3-clause Clear License",
45140         false
45141     ],
45142     "BSD-3-Clause-LBNL": [
45143         "Lawrence Berkeley National Labs BSD variant license",
45144         false
45145     ],
45146     "BSD-3-Clause-No-Nuclear-License": [
45147         "BSD 3-Clause No Nuclear License",
45148         false
45149     ],
45150     "BSD-3-Clause-No-Nuclear-License-2014": [
45151         "BSD 3-Clause No Nuclear License 2014",
45152         false
45153     ],
45154     "BSD-3-Clause-No-Nuclear-Warranty": [
45155         "BSD 3-Clause No Nuclear Warranty",
45156         false
45157     ],
45158     "BSD-4-Clause": [
45159         "BSD 4-clause \"Original\" or \"Old\" License",
45160         false
45161     ],
45162     "BSD-4-Clause-UC": [
45163         "BSD-4-Clause (University of California-Specific)",
45164         false
45165     ],
45166     "BSD-Protection": [
45167         "BSD Protection License",
45168         false
45169     ],
45170     "BSD-Source-Code": [
45171         "BSD Source Code Attribution",
45172         false
45173     ],
45174     "BSL-1.0": [
45175         "Boost Software License 1.0",
45176         true
45177     ],
45178     "bzip2-1.0.5": [
45179         "bzip2 and libbzip2 License v1.0.5",
45180         false
45181     ],
45182     "bzip2-1.0.6": [
45183         "bzip2 and libbzip2 License v1.0.6",
45184         false
45185     ],
45186     "Caldera": [
45187         "Caldera License",
45188         false
45189     ],
45190     "CATOSL-1.1": [
45191         "Computer Associates Trusted Open Source License 1.1",
45192         true
45193     ],
45194     "CC-BY-1.0": [
45195         "Creative Commons Attribution 1.0",
45196         false
45197     ],
45198     "CC-BY-2.0": [
45199         "Creative Commons Attribution 2.0",
45200         false
45201     ],
45202     "CC-BY-2.5": [
45203         "Creative Commons Attribution 2.5",
45204         false
45205     ],
45206     "CC-BY-3.0": [
45207         "Creative Commons Attribution 3.0",
45208         false
45209     ],
45210     "CC-BY-4.0": [
45211         "Creative Commons Attribution 4.0",
45212         false
45213     ],
45214     "CC-BY-NC-1.0": [
45215         "Creative Commons Attribution Non Commercial 1.0",
45216         false
45217     ],
45218     "CC-BY-NC-2.0": [
45219         "Creative Commons Attribution Non Commercial 2.0",
45220         false
45221     ],
45222     "CC-BY-NC-2.5": [
45223         "Creative Commons Attribution Non Commercial 2.5",
45224         false
45225     ],
45226     "CC-BY-NC-3.0": [
45227         "Creative Commons Attribution Non Commercial 3.0",
45228         false
45229     ],
45230     "CC-BY-NC-4.0": [
45231         "Creative Commons Attribution Non Commercial 4.0",
45232         false
45233     ],
45234     "CC-BY-NC-ND-1.0": [
45235         "Creative Commons Attribution Non Commercial No Derivatives 1.0",
45236         false
45237     ],
45238     "CC-BY-NC-ND-2.0": [
45239         "Creative Commons Attribution Non Commercial No Derivatives 2.0",
45240         false
45241     ],
45242     "CC-BY-NC-ND-2.5": [
45243         "Creative Commons Attribution Non Commercial No Derivatives 2.5",
45244         false
45245     ],
45246     "CC-BY-NC-ND-3.0": [
45247         "Creative Commons Attribution Non Commercial No Derivatives 3.0",
45248         false
45249     ],
45250     "CC-BY-NC-ND-4.0": [
45251         "Creative Commons Attribution Non Commercial No Derivatives 4.0",
45252         false
45253     ],
45254     "CC-BY-NC-SA-1.0": [
45255         "Creative Commons Attribution Non Commercial Share Alike 1.0",
45256         false
45257     ],
45258     "CC-BY-NC-SA-2.0": [
45259         "Creative Commons Attribution Non Commercial Share Alike 2.0",
45260         false
45261     ],
45262     "CC-BY-NC-SA-2.5": [
45263         "Creative Commons Attribution Non Commercial Share Alike 2.5",
45264         false
45265     ],
45266     "CC-BY-NC-SA-3.0": [
45267         "Creative Commons Attribution Non Commercial Share Alike 3.0",
45268         false
45269     ],
45270     "CC-BY-NC-SA-4.0": [
45271         "Creative Commons Attribution Non Commercial Share Alike 4.0",
45272         false
45273     ],
45274     "CC-BY-ND-1.0": [
45275         "Creative Commons Attribution No Derivatives 1.0",
45276         false
45277     ],
45278     "CC-BY-ND-2.0": [
45279         "Creative Commons Attribution No Derivatives 2.0",
45280         false
45281     ],
45282     "CC-BY-ND-2.5": [
45283         "Creative Commons Attribution No Derivatives 2.5",
45284         false
45285     ],
45286     "CC-BY-ND-3.0": [
45287         "Creative Commons Attribution No Derivatives 3.0",
45288         false
45289     ],
45290     "CC-BY-ND-4.0": [
45291         "Creative Commons Attribution No Derivatives 4.0",
45292         false
45293     ],
45294     "CC-BY-SA-1.0": [
45295         "Creative Commons Attribution Share Alike 1.0",
45296         false
45297     ],
45298     "CC-BY-SA-2.0": [
45299         "Creative Commons Attribution Share Alike 2.0",
45300         false
45301     ],
45302     "CC-BY-SA-2.5": [
45303         "Creative Commons Attribution Share Alike 2.5",
45304         false
45305     ],
45306     "CC-BY-SA-3.0": [
45307         "Creative Commons Attribution Share Alike 3.0",
45308         false
45309     ],
45310     "CC-BY-SA-4.0": [
45311         "Creative Commons Attribution Share Alike 4.0",
45312         false
45313     ],
45314     "CC0-1.0": [
45315         "Creative Commons Zero v1.0 Universal",
45316         false
45317     ],
45318     "CDDL-1.0": [
45319         "Common Development and Distribution License 1.0",
45320         true
45321     ],
45322     "CDDL-1.1": [
45323         "Common Development and Distribution License 1.1",
45324         false
45325     ],
45326     "CECILL-1.0": [
45327         "CeCILL Free Software License Agreement v1.0",
45328         false
45329     ],
45330     "CECILL-1.1": [
45331         "CeCILL Free Software License Agreement v1.1",
45332         false
45333     ],
45334     "CECILL-2.0": [
45335         "CeCILL Free Software License Agreement v2.0",
45336         false
45337     ],
45338     "CECILL-2.1": [
45339         "CeCILL Free Software License Agreement v2.1",
45340         true
45341     ],
45342     "CECILL-B": [
45343         "CeCILL-B Free Software License Agreement",
45344         false
45345     ],
45346     "CECILL-C": [
45347         "CeCILL-C Free Software License Agreement",
45348         false
45349     ],
45350     "ClArtistic": [
45351         "Clarified Artistic License",
45352         false
45353     ],
45354     "CNRI-Jython": [
45355         "CNRI Jython License",
45356         false
45357     ],
45358     "CNRI-Python": [
45359         "CNRI Python License",
45360         true
45361     ],
45362     "CNRI-Python-GPL-Compatible": [
45363         "CNRI Python Open Source GPL Compatible License Agreement",
45364         false
45365     ],
45366     "Condor-1.1": [
45367         "Condor Public License v1.1",
45368         false
45369     ],
45370     "CPAL-1.0": [
45371         "Common Public Attribution License 1.0",
45372         true
45373     ],
45374     "CPL-1.0": [
45375         "Common Public License 1.0",
45376         true
45377     ],
45378     "CPOL-1.02": [
45379         "Code Project Open License 1.02",
45380         false
45381     ],
45382     "Crossword": [
45383         "Crossword License",
45384         false
45385     ],
45386     "CrystalStacker": [
45387         "CrystalStacker License",
45388         false
45389     ],
45390     "CUA-OPL-1.0": [
45391         "CUA Office Public License v1.0",
45392         true
45393     ],
45394     "Cube": [
45395         "Cube License",
45396         false
45397     ],
45398     "curl": [
45399         "curl License",
45400         false
45401     ],
45402     "D-FSL-1.0": [
45403         "Deutsche Freie Software Lizenz",
45404         false
45405     ],
45406     "diffmark": [
45407         "diffmark license",
45408         false
45409     ],
45410     "DOC": [
45411         "DOC License",
45412         false
45413     ],
45414     "Dotseqn": [
45415         "Dotseqn License",
45416         false
45417     ],
45418     "DSDP": [
45419         "DSDP License",
45420         false
45421     ],
45422     "dvipdfm": [
45423         "dvipdfm License",
45424         false
45425     ],
45426     "ECL-1.0": [
45427         "Educational Community License v1.0",
45428         true
45429     ],
45430     "ECL-2.0": [
45431         "Educational Community License v2.0",
45432         true
45433     ],
45434     "EFL-1.0": [
45435         "Eiffel Forum License v1.0",
45436         true
45437     ],
45438     "EFL-2.0": [
45439         "Eiffel Forum License v2.0",
45440         true
45441     ],
45442     "eGenix": [
45443         "eGenix.com Public License 1.1.0",
45444         false
45445     ],
45446     "Entessa": [
45447         "Entessa Public License v1.0",
45448         true
45449     ],
45450     "EPL-1.0": [
45451         "Eclipse Public License 1.0",
45452         true
45453     ],
45454     "ErlPL-1.1": [
45455         "Erlang Public License v1.1",
45456         false
45457     ],
45458     "EUDatagrid": [
45459         "EU DataGrid Software License",
45460         true
45461     ],
45462     "EUPL-1.0": [
45463         "European Union Public License 1.0",
45464         false
45465     ],
45466     "EUPL-1.1": [
45467         "European Union Public License 1.1",
45468         true
45469     ],
45470     "Eurosym": [
45471         "Eurosym License",
45472         false
45473     ],
45474     "Fair": [
45475         "Fair License",
45476         true
45477     ],
45478     "Frameworx-1.0": [
45479         "Frameworx Open License 1.0",
45480         true
45481     ],
45482     "FreeImage": [
45483         "FreeImage Public License v1.0",
45484         false
45485     ],
45486     "FSFAP": [
45487         "FSF All Permissive License",
45488         false
45489     ],
45490     "FSFUL": [
45491         "FSF Unlimited License",
45492         false
45493     ],
45494     "FSFULLR": [
45495         "FSF Unlimited License (with License Retention)",
45496         false
45497     ],
45498     "FTL": [
45499         "Freetype Project License",
45500         false
45501     ],
45502     "GFDL-1.1": [
45503         "GNU Free Documentation License v1.1",
45504         false
45505     ],
45506     "GFDL-1.2": [
45507         "GNU Free Documentation License v1.2",
45508         false
45509     ],
45510     "GFDL-1.3": [
45511         "GNU Free Documentation License v1.3",
45512         false
45513     ],
45514     "Giftware": [
45515         "Giftware License",
45516         false
45517     ],
45518     "GL2PS": [
45519         "GL2PS License",
45520         false
45521     ],
45522     "Glide": [
45523         "3dfx Glide License",
45524         false
45525     ],
45526     "Glulxe": [
45527         "Glulxe License",
45528         false
45529     ],
45530     "gnuplot": [
45531         "gnuplot License",
45532         false
45533     ],
45534     "GPL-1.0": [
45535         "GNU General Public License v1.0 only",
45536         false
45537     ],
45538     "GPL-2.0": [
45539         "GNU General Public License v2.0 only",
45540         true
45541     ],
45542     "GPL-3.0": [
45543         "GNU General Public License v3.0 only",
45544         true
45545     ],
45546     "gSOAP-1.3b": [
45547         "gSOAP Public License v1.3b",
45548         false
45549     ],
45550     "HaskellReport": [
45551         "Haskell Language Report License",
45552         false
45553     ],
45554     "HPND": [
45555         "Historic Permission Notice and Disclaimer",
45556         true
45557     ],
45558     "IBM-pibs": [
45559         "IBM PowerPC Initialization and Boot Software",
45560         false
45561     ],
45562     "ICU": [
45563         "ICU License",
45564         false
45565     ],
45566     "IJG": [
45567         "Independent JPEG Group License",
45568         false
45569     ],
45570     "ImageMagick": [
45571         "ImageMagick License",
45572         false
45573     ],
45574     "iMatix": [
45575         "iMatix Standard Function Library Agreement",
45576         false
45577     ],
45578     "Imlib2": [
45579         "Imlib2 License",
45580         false
45581     ],
45582     "Info-ZIP": [
45583         "Info-ZIP License",
45584         false
45585     ],
45586     "Intel": [
45587         "Intel Open Source License",
45588         true
45589     ],
45590     "Intel-ACPI": [
45591         "Intel ACPI Software License Agreement",
45592         false
45593     ],
45594     "Interbase-1.0": [
45595         "Interbase Public License v1.0",
45596         false
45597     ],
45598     "IPA": [
45599         "IPA Font License",
45600         true
45601     ],
45602     "IPL-1.0": [
45603         "IBM Public License v1.0",
45604         true
45605     ],
45606     "ISC": [
45607         "ISC License",
45608         true
45609     ],
45610     "JasPer-2.0": [
45611         "JasPer License",
45612         false
45613     ],
45614     "JSON": [
45615         "JSON License",
45616         false
45617     ],
45618     "LAL-1.2": [
45619         "Licence Art Libre 1.2",
45620         false
45621     ],
45622     "LAL-1.3": [
45623         "Licence Art Libre 1.3",
45624         false
45625     ],
45626     "Latex2e": [
45627         "Latex2e License",
45628         false
45629     ],
45630     "Leptonica": [
45631         "Leptonica License",
45632         false
45633     ],
45634     "LGPL-2.0": [
45635         "GNU Library General Public License v2 only",
45636         true
45637     ],
45638     "LGPL-2.1": [
45639         "GNU Lesser General Public License v2.1 only",
45640         true
45641     ],
45642     "LGPL-3.0": [
45643         "GNU Lesser General Public License v3.0 only",
45644         true
45645     ],
45646     "LGPLLR": [
45647         "Lesser General Public License For Linguistic Resources",
45648         false
45649     ],
45650     "Libpng": [
45651         "libpng License",
45652         false
45653     ],
45654     "libtiff": [
45655         "libtiff License",
45656         false
45657     ],
45658     "LiLiQ-P-1.1": [
45659         "Licence Libre du Qu\u00e9bec \u2013 Permissive version 1.1",
45660         true
45661     ],
45662     "LiLiQ-R-1.1": [
45663         "Licence Libre du Qu\u00e9bec \u2013 R\u00e9ciprocit\u00e9 version 1.1",
45664         true
45665     ],
45666     "LiLiQ-Rplus-1.1": [
45667         "Licence Libre du Qu\u00e9bec \u2013 R\u00e9ciprocit\u00e9 forte version 1.1",
45668         true
45669     ],
45670     "LPL-1.0": [
45671         "Lucent Public License Version 1.0",
45672         true
45673     ],
45674     "LPL-1.02": [
45675         "Lucent Public License v1.02",
45676         true
45677     ],
45678     "LPPL-1.0": [
45679         "LaTeX Project Public License v1.0",
45680         false
45681     ],
45682     "LPPL-1.1": [
45683         "LaTeX Project Public License v1.1",
45684         false
45685     ],
45686     "LPPL-1.2": [
45687         "LaTeX Project Public License v1.2",
45688         false
45689     ],
45690     "LPPL-1.3a": [
45691         "LaTeX Project Public License v1.3a",
45692         false
45693     ],
45694     "LPPL-1.3c": [
45695         "LaTeX Project Public License v1.3c",
45696         true
45697     ],
45698     "MakeIndex": [
45699         "MakeIndex License",
45700         false
45701     ],
45702     "MirOS": [
45703         "MirOS Licence",
45704         true
45705     ],
45706     "MIT": [
45707         "MIT License",
45708         true
45709     ],
45710     "MIT-advertising": [
45711         "Enlightenment License (e16)",
45712         false
45713     ],
45714     "MIT-CMU": [
45715         "CMU License",
45716         false
45717     ],
45718     "MIT-enna": [
45719         "enna License",
45720         false
45721     ],
45722     "MIT-feh": [
45723         "feh License",
45724         false
45725     ],
45726     "MITNFA": [
45727         "MIT +no-false-attribs license",
45728         false
45729     ],
45730     "Motosoto": [
45731         "Motosoto License",
45732         true
45733     ],
45734     "mpich2": [
45735         "mpich2 License",
45736         false
45737     ],
45738     "MPL-1.0": [
45739         "Mozilla Public License 1.0",
45740         true
45741     ],
45742     "MPL-1.1": [
45743         "Mozilla Public License 1.1",
45744         true
45745     ],
45746     "MPL-2.0": [
45747         "Mozilla Public License 2.0",
45748         true
45749     ],
45750     "MPL-2.0-no-copyleft-exception": [
45751         "Mozilla Public License 2.0 (no copyleft exception)",
45752         true
45753     ],
45754     "MS-PL": [
45755         "Microsoft Public License",
45756         true
45757     ],
45758     "MS-RL": [
45759         "Microsoft Reciprocal License",
45760         true
45761     ],
45762     "MTLL": [
45763         "Matrix Template Library License",
45764         false
45765     ],
45766     "Multics": [
45767         "Multics License",
45768         true
45769     ],
45770     "Mup": [
45771         "Mup License",
45772         false
45773     ],
45774     "NASA-1.3": [
45775         "NASA Open Source Agreement 1.3",
45776         true
45777     ],
45778     "Naumen": [
45779         "Naumen Public License",
45780         true
45781     ],
45782     "NBPL-1.0": [
45783         "Net Boolean Public License v1",
45784         false
45785     ],
45786     "NCSA": [
45787         "University of Illinois/NCSA Open Source License",
45788         true
45789     ],
45790     "NetCDF": [
45791         "NetCDF license",
45792         false
45793     ],
45794     "Newsletr": [
45795         "Newsletr License",
45796         false
45797     ],
45798     "NGPL": [
45799         "Nethack General Public License",
45800         true
45801     ],
45802     "NLOD-1.0": [
45803         "Norwegian Licence for Open Government Data",
45804         false
45805     ],
45806     "NLPL": [
45807         "No Limit Public License",
45808         false
45809     ],
45810     "Nokia": [
45811         "Nokia Open Source License",
45812         true
45813     ],
45814     "NOSL": [
45815         "Netizen Open Source License",
45816         false
45817     ],
45818     "Noweb": [
45819         "Noweb License",
45820         false
45821     ],
45822     "NPL-1.0": [
45823         "Netscape Public License v1.0",
45824         false
45825     ],
45826     "NPL-1.1": [
45827         "Netscape Public License v1.1",
45828         false
45829     ],
45830     "NPOSL-3.0": [
45831         "Non-Profit Open Software License 3.0",
45832         true
45833     ],
45834     "NRL": [
45835         "NRL License",
45836         false
45837     ],
45838     "NTP": [
45839         "NTP License",
45840         true
45841     ],
45842     "Nunit": [
45843         "Nunit License",
45844         false
45845     ],
45846     "OCCT-PL": [
45847         "Open CASCADE Technology Public License",
45848         false
45849     ],
45850     "OCLC-2.0": [
45851         "OCLC Research Public License 2.0",
45852         true
45853     ],
45854     "ODbL-1.0": [
45855         "ODC Open Database License v1.0",
45856         false
45857     ],
45858     "OFL-1.0": [
45859         "SIL Open Font License 1.0",
45860         false
45861     ],
45862     "OFL-1.1": [
45863         "SIL Open Font License 1.1",
45864         true
45865     ],
45866     "OGTSL": [
45867         "Open Group Test Suite License",
45868         true
45869     ],
45870     "OLDAP-1.1": [
45871         "Open LDAP Public License v1.1",
45872         false
45873     ],
45874     "OLDAP-1.2": [
45875         "Open LDAP Public License v1.2",
45876         false
45877     ],
45878     "OLDAP-1.3": [
45879         "Open LDAP Public License v1.3",
45880         false
45881     ],
45882     "OLDAP-1.4": [
45883         "Open LDAP Public License v1.4",
45884         false
45885     ],
45886     "OLDAP-2.0": [
45887         "Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B)",
45888         false
45889     ],
45890     "OLDAP-2.0.1": [
45891         "Open LDAP Public License v2.0.1",
45892         false
45893     ],
45894     "OLDAP-2.1": [
45895         "Open LDAP Public License v2.1",
45896         false
45897     ],
45898     "OLDAP-2.2": [
45899         "Open LDAP Public License v2.2",
45900         false
45901     ],
45902     "OLDAP-2.2.1": [
45903         "Open LDAP Public License v2.2.1",
45904         false
45905     ],
45906     "OLDAP-2.2.2": [
45907         "Open LDAP Public License  2.2.2",
45908         false
45909     ],
45910     "OLDAP-2.3": [
45911         "Open LDAP Public License v2.3",
45912         false
45913     ],
45914     "OLDAP-2.4": [
45915         "Open LDAP Public License v2.4",
45916         false
45917     ],
45918     "OLDAP-2.5": [
45919         "Open LDAP Public License v2.5",
45920         false
45921     ],
45922     "OLDAP-2.6": [
45923         "Open LDAP Public License v2.6",
45924         false
45925     ],
45926     "OLDAP-2.7": [
45927         "Open LDAP Public License v2.7",
45928         false
45929     ],
45930     "OLDAP-2.8": [
45931         "Open LDAP Public License v2.8",
45932         false
45933     ],
45934     "OML": [
45935         "Open Market License",
45936         false
45937     ],
45938     "OpenSSL": [
45939         "OpenSSL License",
45940         false
45941     ],
45942     "OPL-1.0": [
45943         "Open Public License v1.0",
45944         false
45945     ],
45946     "OSET-PL-2.1": [
45947         "OSET Public License version 2.1",
45948         true
45949     ],
45950     "OSL-1.0": [
45951         "Open Software License 1.0",
45952         true
45953     ],
45954     "OSL-1.1": [
45955         "Open Software License 1.1",
45956         false
45957     ],
45958     "OSL-2.0": [
45959         "Open Software License 2.0",
45960         true
45961     ],
45962     "OSL-2.1": [
45963         "Open Software License 2.1",
45964         true
45965     ],
45966     "OSL-3.0": [
45967         "Open Software License 3.0",
45968         true
45969     ],
45970     "PDDL-1.0": [
45971         "ODC Public Domain Dedication & License 1.0",
45972         false
45973     ],
45974     "PHP-3.0": [
45975         "PHP License v3.0",
45976         true
45977     ],
45978     "PHP-3.01": [
45979         "PHP License v3.01",
45980         false
45981     ],
45982     "Plexus": [
45983         "Plexus Classworlds License",
45984         false
45985     ],
45986     "PostgreSQL": [
45987         "PostgreSQL License",
45988         true
45989     ],
45990     "psfrag": [
45991         "psfrag License",
45992         false
45993     ],
45994     "psutils": [
45995         "psutils License",
45996         false
45997     ],
45998     "Python-2.0": [
45999         "Python License 2.0",
46000         true
46001     ],
46002     "Qhull": [
46003         "Qhull License",
46004         false
46005     ],
46006     "QPL-1.0": [
46007         "Q Public License 1.0",
46008         true
46009     ],
46010     "Rdisc": [
46011         "Rdisc License",
46012         false
46013     ],
46014     "RHeCos-1.1": [
46015         "Red Hat eCos Public License v1.1",
46016         false
46017     ],
46018     "RPL-1.1": [
46019         "Reciprocal Public License 1.1",
46020         true
46021     ],
46022     "RPL-1.5": [
46023         "Reciprocal Public License 1.5",
46024         true
46025     ],
46026     "RPSL-1.0": [
46027         "RealNetworks Public Source License v1.0",
46028         true
46029     ],
46030     "RSA-MD": [
46031         "RSA Message-Digest License",
46032         false
46033     ],
46034     "RSCPL": [
46035         "Ricoh Source Code Public License",
46036         true
46037     ],
46038     "Ruby": [
46039         "Ruby License",
46040         false
46041     ],
46042     "SAX-PD": [
46043         "Sax Public Domain Notice",
46044         false
46045     ],
46046     "Saxpath": [
46047         "Saxpath License",
46048         false
46049     ],
46050     "SCEA": [
46051         "SCEA Shared Source License",
46052         false
46053     ],
46054     "Sendmail": [
46055         "Sendmail License",
46056         false
46057     ],
46058     "SGI-B-1.0": [
46059         "SGI Free Software License B v1.0",
46060         false
46061     ],
46062     "SGI-B-1.1": [
46063         "SGI Free Software License B v1.1",
46064         false
46065     ],
46066     "SGI-B-2.0": [
46067         "SGI Free Software License B v2.0",
46068         false
46069     ],
46070     "SimPL-2.0": [
46071         "Simple Public License 2.0",
46072         true
46073     ],
46074     "SISSL": [
46075         "Sun Industry Standards Source License v1.1",
46076         true
46077     ],
46078     "SISSL-1.2": [
46079         "Sun Industry Standards Source License v1.2",
46080         false
46081     ],
46082     "Sleepycat": [
46083         "Sleepycat License",
46084         true
46085     ],
46086     "SMLNJ": [
46087         "Standard ML of New Jersey License",
46088         false
46089     ],
46090     "SMPPL": [
46091         "Secure Messaging Protocol Public License",
46092         false
46093     ],
46094     "SNIA": [
46095         "SNIA Public License 1.1",
46096         false
46097     ],
46098     "Spencer-86": [
46099         "Spencer License 86",
46100         false
46101     ],
46102     "Spencer-94": [
46103         "Spencer License 94",
46104         false
46105     ],
46106     "Spencer-99": [
46107         "Spencer License 99",
46108         false
46109     ],
46110     "SPL-1.0": [
46111         "Sun Public License v1.0",
46112         true
46113     ],
46114     "SugarCRM-1.1.3": [
46115         "SugarCRM Public License v1.1.3",
46116         false
46117     ],
46118     "SWL": [
46119         "Scheme Widget Library (SWL) Software License Agreement",
46120         false
46121     ],
46122     "TCL": [
46123         "TCL/TK License",
46124         false
46125     ],
46126     "TMate": [
46127         "TMate Open Source License",
46128         false
46129     ],
46130     "TORQUE-1.1": [
46131         "TORQUE v2.5+ Software License v1.1",
46132         false
46133     ],
46134     "TOSL": [
46135         "Trusster Open Source License",
46136         false
46137     ],
46138     "Unicode-TOU": [
46139         "Unicode Terms of Use",
46140         false
46141     ],
46142     "Unlicense": [
46143         "The Unlicense",
46144         false
46145     ],
46146     "UPL-1.0": [
46147         "Universal Permissive License v1.0",
46148         true
46149     ],
46150     "Vim": [
46151         "Vim License",
46152         false
46153     ],
46154     "VOSTROM": [
46155         "VOSTROM Public License for Open Source",
46156         false
46157     ],
46158     "VSL-1.0": [
46159         "Vovida Software License v1.0",
46160         true
46161     ],
46162     "W3C": [
46163         "W3C Software Notice and License (2002-12-31)",
46164         true
46165     ],
46166     "W3C-19980720": [
46167         "W3C Software Notice and License (1998-07-20)",
46168         false
46169     ],
46170     "Watcom-1.0": [
46171         "Sybase Open Watcom Public License 1.0",
46172         true
46173     ],
46174     "Wsuipa": [
46175         "Wsuipa License",
46176         false
46177     ],
46178     "WTFPL": [
46179         "Do What The F*ck You Want To Public License",
46180         false
46181     ],
46182     "X11": [
46183         "X11 License",
46184         false
46185     ],
46186     "Xerox": [
46187         "Xerox License",
46188         false
46189     ],
46190     "XFree86-1.1": [
46191         "XFree86 License 1.1",
46192         false
46193     ],
46194     "xinetd": [
46195         "xinetd License",
46196         false
46197     ],
46198     "Xnet": [
46199         "X.Net License",
46200         true
46201     ],
46202     "xpp": [
46203         "XPP License",
46204         false
46205     ],
46206     "XSkat": [
46207         "XSkat License",
46208         false
46209     ],
46210     "YPL-1.0": [
46211         "Yahoo! Public License v1.0",
46212         false
46213     ],
46214     "YPL-1.1": [
46215         "Yahoo! Public License v1.1",
46216         false
46217     ],
46218     "Zed": [
46219         "Zed License",
46220         false
46221     ],
46222     "Zend-2.0": [
46223         "Zend License v2.0",
46224         false
46225     ],
46226     "Zimbra-1.3": [
46227         "Zimbra Public License v1.3",
46228         false
46229     ],
46230     "Zimbra-1.4": [
46231         "Zimbra Public License v1.4",
46232         false
46233     ],
46234     "Zlib": [
46235         "zlib License",
46236         true
46237     ],
46238     "zlib-acknowledgement": [
46239         "zlib/libpng License with Acknowledgement",
46240         false
46241     ],
46242     "ZPL-1.1": [
46243         "Zope Public License 1.1",
46244         false
46245     ],
46246     "ZPL-2.0": [
46247         "Zope Public License 2.0",
46248         true
46249     ],
46250     "ZPL-2.1": [
46251         "Zope Public License 2.1",
46252         false
46253     ]
46254 }MZ\90\0\ 3\0\0\0\ 4\0\0\0ÿÿ\0\0¸\0\0\0\0\0\0\0@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0è\0\0\0\ e\1fº\ e\0´ Í!¸\ 1LÍ!This program cannot be run in DOS mode.\r\r
46255 $\0\0\0\0\0\0\0\7fÆ,Í;§B\9e;§B\9e;§B\9e2ß×\9e:§B\9e2ßÁ\9e-§B\9e2ßÆ\9e9§B\9e2ßÑ\9e?§B\9e\1ca9\9e8§B\9e;§C\9e\b§B\9e2ßÈ\9e:§B\9e2ßÖ\9e:§B\9e2ßÓ\9e:§B\9eRich;§B\9e\0\0\0\0\0\0\0\0PE\0\0L\ 1\ 5\0¬MoO\0\0\0\0\0\0\0\0à\0\ 2\ 1\v\ 1      \0\0
46256 \0\0\0\16\0\0\0\0\0\08\13\0\0\0\10\0\0\0 \0\0\0\0@\0\0\10\0\0\0\ 2\0\0\ 5\0\0\0\0\0\0\0\ 5\0\0\0\0\0\0\0\0`\0\0\0\ 4\0\0?\9c\0\0\ 3\0@\81\0\0\10\0\0\10\0\0\0\0\10\0\0\10\0\0\0\0\0\0\10\0\0\0\0\0\0\0\0\0\0\0\90"\0\0P\0\0\0\0@\0\0 \ 6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0P\0\0p\ 1\0\0\0!\0\0\1c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\08!\0\0@\0\0\0\0\0\0\0\0\0\0\0\0 \0\0Ø\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0.text\0\0\0\v     \0\0\0\10\0\0\0
46257 \0\0\0\ 4\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0`.rdata\0\0Π\0\0\0 \0\0\0
46258 \0\0\0\ e\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0\0@.data\0\0\0\90\ 3\0\0\00\0\0\0\ 2\0\0\0\18\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0\0À.rsrc\0\0\0 \ 6\0\0\0@\0\0\0\b\0\0\0\1a\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0\0@.reloc\0\0Ì\ 1\0\0\0P\0\0\0\ 2\0\0\0"\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0\0B\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0j$¸æ\18@\0èx\b\0\0jöÿ\15\b @\0\83\0\8bð\8dEÐPVÿ\15\0 @\0\8b\83àûPVÿ\15\ 4 @\0\8dMÔÿ\15X @\0\83\0\8dEÔPÿ5H @\0ÿ\15L @\0YYÿ5\ @\0\8dEÔPÿ5` @\0ÿ\15D @\0YY\8bÈÿ\15P @\0\83Müÿ\8dMÔÿ\15T @\03ÀèH\b\0\0Ã;\r\00@\0u\ 2óÃé¬\ 2\0\0h\80\15@\0è£\ 4\0\0¡l3@\0Ç\ 4$40@\0ÿ5h3@\0£40@\0h$0@\0h(0@\0h 0@\0ÿ\15  @\0\83Ä\14£00@\0\85À}\bj\bè¹\ 3\0\0YÃj\10h\b"@\0è\1f\ 6\0\0\89]üd¡\18\0\0\0\8bp\ 4\89]ä¿\803@\0SVWÿ\150 @\0;Ãt\19;Æu\b3öF\89uäë\10\ 3\0\0ÿ\154 @\0ëÚ3öF¡|3@\0;Æu
46259 j\1fè\\ 3\0\0Yë;¡|3@\0\85Àu,\895|3@\0hð @\0hä @\0è§\ 5\0\0YY\85Àt\17ÇEüþÿÿÿ¸ÿ\0\0\0éÝ\0\0\0\895<0@\0¡|3@\0;Æu\ehà @\0hØ @\0èl\ 5\0\0YYÇ\ 5|3@\0\ 2\0\0\09]äu\bSWÿ\158 @\09\1d\8c3@\0t\19h\8c3@\0è\83\ 4\0\0Y\85Àt
46260 Sj\ 2Sÿ\15\8c3@\0¡$0@\0\8b\r¼ @\0\89\ 1ÿ5$0@\0ÿ5(0@\0ÿ5 0@\0è\10þÿÿ\83Ä\f£80@\09\1d,0@\0u7Pÿ\15À @\0\8b\8b\b\8b     \89MàPQè\8e\ 3\0\0YYÃ\8b\8bEà£80@\03Û9\1d,0@\0u\aPÿ\15h @\09\1d<0@\0u\ 6ÿ\15\9c @\0ÇEüþÿÿÿ¡80@\0èû\ 4\0\0øMZ\0\0f9\ 5\0\0@\0t\ 43ÀëM¡<\0@\0\8d\80\0\0@\0\818PE\0\0\ f·H\18\81ù\v\ 1\0\0t\e\81ù\v\ 2\0\0\83¸\84\0\0\0\ evÌ3É9\88ø\0\0\0ë\ e\83xt\ ev¼3É9\88è\0\0\0\ f\95Á\8bÁj\ 1£,0@\0ÿ\15p @\0jÿÿ\15l @\0YY£\843@\0£\883@\0ÿ\15Ì @\0\8b\rt3@\0\89\bÿ\15\88 @\0\8b\rp3@\0\89\b¡¨ @\0\8b\0£x3@\0èV\ 2\0\0è¬\ 4\0\0\83=\140@\0\0u\f\17@\0ÿ\15¬ @\0Yèg\ 4\0\0\83=\100@\0ÿu   jÿÿ\15° @\0Y3ÀÃè{\ 4\0\0é\9fýÿÿ\8bÿU\8bì\81ì(\ 3\0\0£H1@\0\89\rD1@\0\89\15@1@\0\89\1d<1@\0\89581@\0\89=41@\0f\8c\15`1@\0f\8c\rT1@\0f\8c\1d01@\0f\8c\ 5,1@\0f\8c%(1@\0f\8c-$1@\0\9c\8f\ 5X1@\0\8bE\0£L1@\0\8bE\ 4£P1@\0\8dE\b£\1@\0\8b\85àüÿÿÇ\ 5\980@\0\ 1\0\ 1\0¡P1@\0£L0@\0Ç\ 5@0@\0   \ 4\0ÀÇ\ 5D0@\0\ 1\0\0\0¡\00@\0\89\85Øüÿÿ¡\ 40@\0\89\85Üüÿÿÿ\15\1c @\0£\900@\0j\ 1è?\ 4\0\0Yj\0ÿ\15  @\0h\1c!@\0ÿ\15$ @\0\83=\900@\0\0u\bj\ 1è\e\ 4\0\0Yh     \ 4\0Àÿ\15( @\0Pÿ\15, @\0ÉÃ\8bÿU\8bì\8bE\b\8b\0\818csmàu*\83x\10\ 3u$\8b@\14\ 5\93\19t\15=!\ 5\93\19t\ e="\ 5\93\19t\a=\0@\99\ 1u\ 5èÐ\ 3\0\03À]Â\ 4\0hH\14@\0ÿ\15  @\03ÀÃÿ%¤ @\0j\14h("@\0èb\ 2\0\0ÿ5\883@\0\8b5\8c @\0ÿÖY\89\83øÿu\fÿu\bÿ\15Ä @\0Yëgj\bè\92\ 3\0\0Y\83\0ÿ5\883@\0ÿÖ\89Eäÿ5\843@\0ÿÖYY\89\8dEàP\8dEäPÿu\b\8b5l @\0ÿÖYPèU\ 3\0\0\89EÜÿuäÿÖ£\883@\0ÿuàÿÖ\83Ä\14£\843@\0ÇEüþÿÿÿè \0\0\0\8bEÜè\18\ 2\0\0Ãj\bè\19\ 3\0\0\8bÿU\8bìÿu\bèNÿÿÿ÷Ø\eÀ÷ØYH]Ã\8bÿV¸ü!@\0¾ü!@\0W\8bø;Æs\ f\8b\a\85Àt\ 2ÿÐ\83Ç\ 4;þrñ_^Ã\8bÿV¸\ 4"@\0¾\ 4"@\0W\8bø;Æs\ f\8b\a\85Àt\ 2ÿÐ\83Ç\ 4;þrñ_^Ãÿ%È @\0ÌÌÌÌ\8bÿU\8bì\8bM\b¸MZ\0\0f9\ 1t\ 43À]Ã\8bA<\ 3Á\818PE\0\0uï3Ò¹\v\ 1\0\0f9H\18\ f\94Â\8bÂ]ÃÌÌÌÌÌÌÌÌÌÌÌ\8bÿU\8bì\8bE\b\8bH<\ 3È\ f·A\14SV\ f·q\ 63ÒW\8dD\b\18\85öv\e\8b}\f\8bH\f;ùr   \8bX\b\ 3Ù;ûr
46261 B\83À(;Örè3À_^[]ÃÌÌÌÌÌÌÌÌÌÌÌÌ\8bÿU\8bìjþhH"@\0he\17@\0\0\0\0\0P\83ì\bSVW¡\00@\01Eø3ÅP\8dEðd£\0\0\0\0\89eèÇEü\0\0\0\0h\0\0@\0è*ÿÿÿ\83Ä\ 4\85ÀtU\8bE\b-\0\0@\0Ph\0\0@\0èPÿÿÿ\83Ä\b\85Àt;\8b@$Áè\1f÷Ð\83à\ 1ÇEüþÿÿÿ\8bMðd\89\r\0\0\0\0Y_^[\8bå]Ã\8b\8b\b\8b\ 13Ò=\ 5\0\0À\ f\94Â\8bÂÃ\8beèÇEüþÿÿÿ3À\8bMðd\89\r\0\0\0\0Y_^[\8bå]ÃÌÿ%¸ @\0ÿ%´ @\0ÌÌhe\17@\0dÿ5\0\0\0\0\8bD$\10\89l$\10\8dl$\10+àSVW¡\00@\01Eü3ÅP\89eèÿuø\8bEüÇEüþÿÿÿ\89\8dEðd£\0\0\0\0Ã\8bMðd\89\r\0\0\0\0Y__^[\8bå]QÃ\8bÿU\8bìÿu\14ÿu\10ÿu\fÿu\bh\87\10@\0h\00@\0èç\0\0\0\83Ä\18\8bÿVh\0\0\ 3\0h\0\0\ 1\03öVèÙ\0\0\0\83Ä\f\85Àt\rVVVVVèÂ\0\0\0\83Ä\14^Ã3ÀÃ\8bÿU\8bì\83ì\10¡\00@\0\83\0\83\0SW¿Næ@»»\0\0ÿÿ;Çt\r\85Ãt     ÷У\ 40@\0ë`V\8dEøPÿ\15< @\0\8buü3uøÿ\15\f @\03ðÿ\15\10 @\03ðÿ\15\14 @\0\8dEðPÿ\15\18 @\0\8bEô3Eð3ð;÷u\a¾Oæ@»ë\v\85óu\a\8bÆÁà\10\vð\895\00@\0÷Ö\895\ 40@\0^_[ÉÃÿ%t @\0ÿ%x @\0ÿ%| @\0ÿ%\80 @\0ÿ%\84 @\0ÿ%\90 @\0ÿ%\94 @\0ÿ%\98 @\0ÿ%Р@\0Pdÿ5\0\0\0\0\8dD$\f+d$\fSVW\89(\8bè¡\00@\03ÅP\89EðÿuüÇEüÿÿÿÿ\8dEôd£\0\0\0\0Ã\8bMôd\89\r\0\0\0\0Y__^[\8bå]QÃ\8bMð3Íè¯÷ÿÿéÝÿÿÿ\8dMÔÿ%T @\0\8bT$\b\8dB\f\8bJÌ3Èè\90÷ÿÿ\8bJü3Èè\86÷ÿÿ¸l"@\0ésÿÿÿ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0¸#\0\0Ê#\0\0Ü#\0\0\88)\0\0r)\0\0b)\0\0H)\0\04)\0\0\16)\0\0ú(\0\0æ(\0\0Ò(\0\0´(\0\0¬(\0\0\96(\0\0\9e)\0\0\0\0\0\0ú#\0\0à$\0\0\1a%\0\0Ê%\0\0\1a&\0\0d&\0\0®&\0\0¤$\0\0\0\0\0\0('\0\0Ä'\0\0Ö'\0\0è'\0\0þ'\0\0\1e(\0\0((\0\06(\0\0¦'\0\0H(\0\0Z(\0\0t(\0\0\86(\0\0\1e'\0\0\ e'\0\0\0'\0\0\96'\0\0\82'\0\0l'\0\0^'\0\0R'\0\0F'\0\0>'\0\0>(\0\00'\0\0¶'\0\0¸)\0\0\0\0\0\0\0\0\0\0\96\10@\0\0\0\0\0\0\0\0\0W\12@\0\8a\14@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0¬MoO\0\0\0\0\ 2\0\0\0l\0\0\0\80!\0\0\80\ f\0\0@0@\0\980@\0bad allocation\0\0\0\0\0\0H\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00@\0ð!@\0\ 2\0\0\0RSDSÑ\8c³\10´\8f\ 1J¨!öÌëLZ\0\ 1\0\0\0c:\users\seld\documents\visual studio 2010\Projects\hiddeninp\Release\hiddeninp.pdb\0\0\0\0\0e\17\0\0æ\18\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0þÿÿÿ\0\0\0\0Ðÿÿÿ\0\0\0\0þÿÿÿ\a\12@\0\e\12@\0\0\0\0\0þÿÿÿ\0\0\0\0Ìÿÿÿ\0\0\0\0þÿÿÿ\0\0\0\0:\15@\0\0\0\0\0þÿÿÿ\0\0\0\0Øÿÿÿ\0\0\0\0þÿÿÿË\16@\0ß\16@\0ÿÿÿÿÝ\18@\0"\ 5\93\19\ 1\0\0\0d"@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 1\0\0\0à"\0\0\0\0\0\0\0\0\0\0ì#\0\0\0 \0\0$#\0\0\0\0\0\0\0\0\0\0ô&\0\0\0\0H#\0\0\0\0\0\0\0\0\0\0\12(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0¸#\0\0Ê#\0\0Ü#\0\0\88)\0\0r)\0\0b)\0\0H)\0\04)\0\0\16)\0\0ú(\0\0æ(\0\0Ò(\0\0´(\0\0¬(\0\0\96(\0\0\9e)\0\0\0\0\0\0ú#\0\0à$\0\0\1a%\0\0Ê%\0\0\1a&\0\0d&\0\0®&\0\0¤$\0\0\0\0\0\0('\0\0Ä'\0\0Ö'\0\0è'\0\0þ'\0\0\1e(\0\0((\0\06(\0\0¦'\0\0H(\0\0Z(\0\0t(\0\0\86(\0\0\1e'\0\0\ e'\0\0\0'\0\0\96'\0\0\82'\0\0l'\0\0^'\0\0R'\0\0F'\0\0>'\0\0>(\0\00'\0\0¶'\0\0¸)\0\0\0\0\0\0\95\ 1GetConsoleMode\0\0·\ 3SetConsoleMode\0\0;\ 2GetStdHandle\0\0KERNEL32.dll\0\0\16\0??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z\0\91\ 6?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A\0\0J\ 6?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A\0Â\0??$getline@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@0@AAV10@AAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z\0\1d\ 3??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z\0\0_\ 2??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ\0\0{\ 1??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ\0\0³\a?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z\0\0MSVCP90.dll\0\15\ 1_amsg_exit\0\0\9f\0__getmainargs\0,\ 1_cexit\0\0|\ 1_exit\0f\0_XcptFilter\0Ì\ 4exit\0\0 \0__initenv\0\ 4\ 2_initterm\0\ 5\ 2_initterm_e\0<\ 1_configthreadlocale\0ã\0__setusermatherr\0\0\v\ 1_adjust_fdiv\0\0Ë\0__p__commode\0\0Ï\0__p__fmode\0\0j\ 1_encode_pointer\0à\0__set_app_type\0\0K\ 1_crt_debugger_hook\0\0C\0?terminate@@YAXXZ\0MSVCR90.dll\0æ\ 3_unlock\0\96\0__dllonexit\0v\ 2_lock\0\1c\ 3_onexit\0`\ 1_decode_pointer\0s\ 1_except_handler4_common\0\v\ 2_invoke_watson\0\0?\ 1_controlfp_s\0\0½\ 2InterlockedExchange\0!\ 4Sleep\0º\ 2InterlockedCompareExchange\0\0-\ 4TerminateProcess\0\0©\ 1GetCurrentProcess\0>\ 4UnhandledExceptionFilter\0\0\15\ 4SetUnhandledExceptionFilter\0Ñ\ 2IsDebuggerPresent\0T\ 3QueryPerformanceCounter\0f\ 2GetTickCount\0\0­\ 1GetCurrentThreadId\0\0ª\ 1GetCurrentProcessId\0O\ 2GetSystemTimeAsFileTime\0s\0__CxxFrameHandler3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Næ@»±\19¿Dÿÿÿÿÿÿÿÿþÿÿÿ\ 1\0\0\0$!@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0\0\0\ 2\0\10\0\0\0 \0\0\80\18\0\0\08\0\0\80\0\0\0\0\0\0\0\0\ 4\0\0\0\0\0\ 1\0\ 1\0\0\0P\0\0\80\0\0\0\0\0\0\0\0\ 4\0\0\0\0\0\ 1\0\ 1\0\0\0h\0\0\80\0\0\0\0\0\0\0\0\ 4\0\0\0\0\0\ 1\0 \ 4\0\0\80\0\0\0\0\0\0\0\0\0\0\0\ 4\0\0\0\0\0\ 1\0 \ 4\0\0\90\0\0\0 @\0\0(\ 3\0\0ä\ 4\0\0\0\0\0\0ÈC\0\0V\ 2\0\0ä\ 4\0\0\0\0\0\0(\ 34\0\0\0V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0\0\0\0\0½\ 4ïþ\0\0\ 1\0\0\0\ 1\0\0\0\0\0\0\0\ 1\0\0\0\0\0\17\0\0\0\0\0\0\0\ 4\0\0\0\ 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\86\ 2\0\0\ 1\0S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0b\ 2\0\0\ 1\00\04\00\09\00\04\0b\00\0\0\0Ê\0Q\0\ 1\0F\0i\0l\0e\0D\0e\0s\0c\0r\0i\0p\0t\0i\0o\0n\0\0\0\0\0R\0e\0a\0d\0s\0 \0f\0r\0o\0m\0 \0s\0t\0d\0i\0n\0 \0w\0i\0t\0h\0o\0u\0t\0 \0l\0e\0a\0k\0i\0n\0g\0 \0i\0n\0f\0o\0 \0t\0o\0 \0t\0h\0e\0 \0t\0e\0r\0m\0i\0n\0a\0l\0 \0a\0n\0d\0 \0o\0u\0t\0p\0u\0t\0s\0 \0b\0a\0c\0k\0 \0t\0o\0 \0s\0t\0d\0o\0u\0t\0\0\0\0\06\0\v\0\ 1\0F\0i\0l\0e\0V\0e\0r\0s\0i\0o\0n\0\0\0\0\01\0,\0 \00\0,\0 \00\0,\0 \00\0\0\0\0\08\0\f\0\ 1\0I\0n\0t\0e\0r\0n\0a\0l\0N\0a\0m\0e\0\0\0h\0i\0d\0d\0e\0n\0i\0n\0p\0u\0t\0\0\0P\0\16\0\ 1\0L\0e\0g\0a\0l\0C\0o\0p\0y\0r\0i\0g\0h\0t\0\0\0J\0o\0r\0d\0i\0 \0B\0o\0g\0g\0i\0a\0n\0o\0 \0-\0 \02\00\01\02\0\0\0H\0\10\0\ 1\0O\0r\0i\0g\0i\0n\0a\0l\0F\0i\0l\0e\0n\0a\0m\0e\0\0\0h\0i\0d\0d\0e\0n\0i\0n\0p\0u\0t\0.\0e\0x\0e\0\0\0:\0\r\0\ 1\0P\0r\0o\0d\0u\0c\0t\0N\0a\0m\0e\0\0\0\0\0H\0i\0d\0d\0e\0n\0 \0I\0n\0p\0u\0t\0\0\0\0\0:\0\v\0\ 1\0P\0r\0o\0d\0u\0c\0t\0V\0e\0r\0s\0i\0o\0n\0\0\01\0,\0 \00\0,\0 \00\0,\0 \00\0\0\0\0\0D\0\0\0\ 1\0V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0\0$\0\ 4\0\0\0T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0\0     \ 4°\ 4<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\r
46262   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">\r
46263     <security>\r
46264       <requestedPrivileges>\r
46265         <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>\r
46266       </requestedPrivileges>\r
46267     </security>\r
46268   </trustInfo>\r
46269   <dependency>\r
46270     <dependentAssembly>\r
46271       <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>\r
46272     </dependentAssembly>\r
46273   </dependency>\r
46274 </assembly>PAPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDING\0\10\0\0@\ 1\0\0\ 30\100!0/080F0L0T0^0d0n0{0\890\970¡0¨0®0³0¸0½0Â0È0Ð0ä0ÿ0\b1#1-1@1J1O1T1v1{1\841\891\961§1­1´1È1Í1Ó1Û1á1ç1ô1ú1\ 32"2*23292A2M2_2j2p2¹2¿2Ç2Î2Ó2Ù2ß2ç2í2ô2û2\v3\133\193%303N3T3Z3`3f3l3s3z3\813\883\8f3\963\9d3¥3­3µ3Á3Ê3Ï3Õ3ß3è3ó3ÿ3\ 44\144\194\1f4%4;4B4\8b4\914\9a4¡4¬4²4Æ4Û4æ4þ4\145!5^5c5\845\895¨5H6M6_6}6\916\976\07\ 67\r7*7w7|7Á7ä7ñ7ý7\ 58\r8\198=8E8P8V8\8b8h8n8t8z8\808\9c8â8\ 29\0\0\0 \0\0$\0\0\0Ü0è0ì0\1c1 1t1x1\1c2 2@2\2`2h2t2\00\0\0\f\0\0\0\180\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<?php
46275
46276
46277
46278
46279
46280
46281
46282
46283
46284
46285 namespace Symfony\Component\Console;
46286
46287 use Symfony\Component\Console\Descriptor\TextDescriptor;
46288 use Symfony\Component\Console\Descriptor\XmlDescriptor;
46289 use Symfony\Component\Console\Exception\ExceptionInterface;
46290 use Symfony\Component\Console\Helper\DebugFormatterHelper;
46291 use Symfony\Component\Console\Helper\ProcessHelper;
46292 use Symfony\Component\Console\Helper\QuestionHelper;
46293 use Symfony\Component\Console\Input\InputInterface;
46294 use Symfony\Component\Console\Input\ArgvInput;
46295 use Symfony\Component\Console\Input\ArrayInput;
46296 use Symfony\Component\Console\Input\InputDefinition;
46297 use Symfony\Component\Console\Input\InputOption;
46298 use Symfony\Component\Console\Input\InputArgument;
46299 use Symfony\Component\Console\Input\InputAwareInterface;
46300 use Symfony\Component\Console\Output\BufferedOutput;
46301 use Symfony\Component\Console\Output\OutputInterface;
46302 use Symfony\Component\Console\Output\ConsoleOutput;
46303 use Symfony\Component\Console\Output\ConsoleOutputInterface;
46304 use Symfony\Component\Console\Command\Command;
46305 use Symfony\Component\Console\Command\HelpCommand;
46306 use Symfony\Component\Console\Command\ListCommand;
46307 use Symfony\Component\Console\Helper\HelperSet;
46308 use Symfony\Component\Console\Helper\FormatterHelper;
46309 use Symfony\Component\Console\Helper\DialogHelper;
46310 use Symfony\Component\Console\Helper\ProgressHelper;
46311 use Symfony\Component\Console\Helper\TableHelper;
46312 use Symfony\Component\Console\Event\ConsoleCommandEvent;
46313 use Symfony\Component\Console\Event\ConsoleExceptionEvent;
46314 use Symfony\Component\Console\Event\ConsoleTerminateEvent;
46315 use Symfony\Component\Console\Exception\CommandNotFoundException;
46316 use Symfony\Component\Console\Exception\LogicException;
46317 use Symfony\Component\Debug\Exception\FatalThrowableError;
46318 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
46319
46320
46321
46322
46323
46324
46325
46326
46327
46328
46329
46330
46331
46332
46333
46334
46335 class Application
46336 {
46337 private $commands = array();
46338 private $wantHelps = false;
46339 private $runningCommand;
46340 private $name;
46341 private $version;
46342 private $catchExceptions = true;
46343 private $autoExit = true;
46344 private $definition;
46345 private $helperSet;
46346 private $dispatcher;
46347 private $terminalDimensions;
46348 private $defaultCommand;
46349
46350
46351
46352
46353
46354
46355
46356 public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
46357 {
46358 $this->name = $name;
46359 $this->version = $version;
46360 $this->defaultCommand = 'list';
46361 $this->helperSet = $this->getDefaultHelperSet();
46362 $this->definition = $this->getDefaultInputDefinition();
46363
46364 foreach ($this->getDefaultCommands() as $command) {
46365 $this->add($command);
46366 }
46367 }
46368
46369 public function setDispatcher(EventDispatcherInterface $dispatcher)
46370 {
46371 $this->dispatcher = $dispatcher;
46372 }
46373
46374
46375
46376
46377
46378
46379
46380
46381
46382 public function run(InputInterface $input = null, OutputInterface $output = null)
46383 {
46384 if (null === $input) {
46385 $input = new ArgvInput();
46386 }
46387
46388 if (null === $output) {
46389 $output = new ConsoleOutput();
46390 }
46391
46392 $this->configureIO($input, $output);
46393
46394 try {
46395 $exitCode = $this->doRun($input, $output);
46396 } catch (\Exception $e) {
46397 if (!$this->catchExceptions) {
46398 throw $e;
46399 }
46400
46401 if ($output instanceof ConsoleOutputInterface) {
46402 $this->renderException($e, $output->getErrorOutput());
46403 } else {
46404 $this->renderException($e, $output);
46405 }
46406
46407 $exitCode = $e->getCode();
46408 if (is_numeric($exitCode)) {
46409 $exitCode = (int) $exitCode;
46410 if (0 === $exitCode) {
46411 $exitCode = 1;
46412 }
46413 } else {
46414 $exitCode = 1;
46415 }
46416 }
46417
46418 if ($this->autoExit) {
46419 if ($exitCode > 255) {
46420 $exitCode = 255;
46421 }
46422
46423 exit($exitCode);
46424 }
46425
46426 return $exitCode;
46427 }
46428
46429
46430
46431
46432
46433
46434
46435
46436
46437 public function doRun(InputInterface $input, OutputInterface $output)
46438 {
46439 if (true === $input->hasParameterOption(array('--version', '-V'))) {
46440 $output->writeln($this->getLongVersion());
46441
46442 return 0;
46443 }
46444
46445 $name = $this->getCommandName($input);
46446 if (true === $input->hasParameterOption(array('--help', '-h'))) {
46447 if (!$name) {
46448 $name = 'help';
46449 $input = new ArrayInput(array('command' => 'help'));
46450 } else {
46451 $this->wantHelps = true;
46452 }
46453 }
46454
46455 if (!$name) {
46456 $name = $this->defaultCommand;
46457 $input = new ArrayInput(array('command' => $this->defaultCommand));
46458 }
46459
46460
46461  $command = $this->find($name);
46462
46463 $this->runningCommand = $command;
46464 $exitCode = $this->doRunCommand($command, $input, $output);
46465 $this->runningCommand = null;
46466
46467 return $exitCode;
46468 }
46469
46470
46471
46472
46473
46474
46475 public function setHelperSet(HelperSet $helperSet)
46476 {
46477 $this->helperSet = $helperSet;
46478 }
46479
46480
46481
46482
46483
46484
46485 public function getHelperSet()
46486 {
46487 return $this->helperSet;
46488 }
46489
46490
46491
46492
46493
46494
46495 public function setDefinition(InputDefinition $definition)
46496 {
46497 $this->definition = $definition;
46498 }
46499
46500
46501
46502
46503
46504
46505 public function getDefinition()
46506 {
46507 return $this->definition;
46508 }
46509
46510
46511
46512
46513
46514
46515 public function getHelp()
46516 {
46517 return $this->getLongVersion();
46518 }
46519
46520
46521
46522
46523
46524
46525 public function setCatchExceptions($boolean)
46526 {
46527 $this->catchExceptions = (bool) $boolean;
46528 }
46529
46530
46531
46532
46533
46534
46535 public function setAutoExit($boolean)
46536 {
46537 $this->autoExit = (bool) $boolean;
46538 }
46539
46540
46541
46542
46543
46544
46545 public function getName()
46546 {
46547 return $this->name;
46548 }
46549
46550
46551
46552
46553
46554
46555 public function setName($name)
46556 {
46557 $this->name = $name;
46558 }
46559
46560
46561
46562
46563
46564
46565 public function getVersion()
46566 {
46567 return $this->version;
46568 }
46569
46570
46571
46572
46573
46574
46575 public function setVersion($version)
46576 {
46577 $this->version = $version;
46578 }
46579
46580
46581
46582
46583
46584
46585 public function getLongVersion()
46586 {
46587 if ('UNKNOWN' !== $this->getName()) {
46588 if ('UNKNOWN' !== $this->getVersion()) {
46589 return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
46590 }
46591
46592 return sprintf('<info>%s</info>', $this->getName());
46593 }
46594
46595 return '<info>Console Tool</info>';
46596 }
46597
46598
46599
46600
46601
46602
46603
46604
46605 public function register($name)
46606 {
46607 return $this->add(new Command($name));
46608 }
46609
46610
46611
46612
46613
46614
46615
46616
46617 public function addCommands(array $commands)
46618 {
46619 foreach ($commands as $command) {
46620 $this->add($command);
46621 }
46622 }
46623
46624
46625
46626
46627
46628
46629
46630
46631
46632
46633
46634 public function add(Command $command)
46635 {
46636 $command->setApplication($this);
46637
46638 if (!$command->isEnabled()) {
46639 $command->setApplication(null);
46640
46641 return;
46642 }
46643
46644 if (null === $command->getDefinition()) {
46645 throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
46646 }
46647
46648 $this->commands[$command->getName()] = $command;
46649
46650 foreach ($command->getAliases() as $alias) {
46651 $this->commands[$alias] = $command;
46652 }
46653
46654 return $command;
46655 }
46656
46657
46658
46659
46660
46661
46662
46663
46664
46665
46666 public function get($name)
46667 {
46668 if (!isset($this->commands[$name])) {
46669 throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
46670 }
46671
46672 $command = $this->commands[$name];
46673
46674 if ($this->wantHelps) {
46675 $this->wantHelps = false;
46676
46677 $helpCommand = $this->get('help');
46678 $helpCommand->setCommand($command);
46679
46680 return $helpCommand;
46681 }
46682
46683 return $command;
46684 }
46685
46686
46687
46688
46689
46690
46691
46692
46693 public function has($name)
46694 {
46695 return isset($this->commands[$name]);
46696 }
46697
46698
46699
46700
46701
46702
46703
46704
46705 public function getNamespaces()
46706 {
46707 $namespaces = array();
46708 foreach ($this->all() as $command) {
46709 $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
46710
46711 foreach ($command->getAliases() as $alias) {
46712 $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
46713 }
46714 }
46715
46716 return array_values(array_unique(array_filter($namespaces)));
46717 }
46718
46719
46720
46721
46722
46723
46724
46725
46726
46727
46728 public function findNamespace($namespace)
46729 {
46730 $allNamespaces = $this->getNamespaces();
46731 $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace);
46732 $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces);
46733
46734 if (empty($namespaces)) {
46735 $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
46736
46737 if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
46738 if (1 == count($alternatives)) {
46739 $message .= "\n\nDid you mean this?\n    ";
46740 } else {
46741 $message .= "\n\nDid you mean one of these?\n    ";
46742 }
46743
46744 $message .= implode("\n    ", $alternatives);
46745 }
46746
46747 throw new CommandNotFoundException($message, $alternatives);
46748 }
46749
46750 $exact = in_array($namespace, $namespaces, true);
46751 if (count($namespaces) > 1 && !$exact) {
46752 throw new CommandNotFoundException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
46753 }
46754
46755 return $exact ? $namespace : reset($namespaces);
46756 }
46757
46758
46759
46760
46761
46762
46763
46764
46765
46766
46767
46768
46769
46770 public function find($name)
46771 {
46772 $allCommands = array_keys($this->commands);
46773 $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
46774 $commands = preg_grep('{^'.$expr.'}', $allCommands);
46775
46776 if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) {
46777 if (false !== $pos = strrpos($name, ':')) {
46778
46779  $this->findNamespace(substr($name, 0, $pos));
46780 }
46781
46782 $message = sprintf('Command "%s" is not defined.', $name);
46783
46784 if ($alternatives = $this->findAlternatives($name, $allCommands)) {
46785 if (1 == count($alternatives)) {
46786 $message .= "\n\nDid you mean this?\n    ";
46787 } else {
46788 $message .= "\n\nDid you mean one of these?\n    ";
46789 }
46790 $message .= implode("\n    ", $alternatives);
46791 }
46792
46793 throw new CommandNotFoundException($message, $alternatives);
46794 }
46795
46796
46797  if (count($commands) > 1) {
46798 $commandList = $this->commands;
46799 $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
46800 $commandName = $commandList[$nameOrAlias]->getName();
46801
46802 return $commandName === $nameOrAlias || !in_array($commandName, $commands);
46803 });
46804 }
46805
46806 $exact = in_array($name, $commands, true);
46807 if (count($commands) > 1 && !$exact) {
46808 $suggestions = $this->getAbbreviationSuggestions(array_values($commands));
46809
46810 throw new CommandNotFoundException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions), array_values($commands));
46811 }
46812
46813 return $this->get($exact ? $name : reset($commands));
46814 }
46815
46816
46817
46818
46819
46820
46821
46822
46823
46824
46825 public function all($namespace = null)
46826 {
46827 if (null === $namespace) {
46828 return $this->commands;
46829 }
46830
46831 $commands = array();
46832 foreach ($this->commands as $name => $command) {
46833 if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
46834 $commands[$name] = $command;
46835 }
46836 }
46837
46838 return $commands;
46839 }
46840
46841
46842
46843
46844
46845
46846
46847
46848 public static function getAbbreviations($names)
46849 {
46850 $abbrevs = array();
46851 foreach ($names as $name) {
46852 for ($len = strlen($name); $len > 0; --$len) {
46853 $abbrev = substr($name, 0, $len);
46854 $abbrevs[$abbrev][] = $name;
46855 }
46856 }
46857
46858 return $abbrevs;
46859 }
46860
46861
46862
46863
46864
46865
46866
46867
46868
46869
46870
46871 public function asText($namespace = null, $raw = false)
46872 {
46873 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
46874
46875 $descriptor = new TextDescriptor();
46876 $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, !$raw);
46877 $descriptor->describe($output, $this, array('namespace' => $namespace, 'raw_output' => true));
46878
46879 return $output->fetch();
46880 }
46881
46882
46883
46884
46885
46886
46887
46888
46889
46890
46891
46892 public function asXml($namespace = null, $asDom = false)
46893 {
46894 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
46895
46896 $descriptor = new XmlDescriptor();
46897
46898 if ($asDom) {
46899 return $descriptor->getApplicationDocument($this, $namespace);
46900 }
46901
46902 $output = new BufferedOutput();
46903 $descriptor->describe($output, $this, array('namespace' => $namespace));
46904
46905 return $output->fetch();
46906 }
46907
46908
46909
46910
46911
46912
46913
46914 public function renderException($e, $output)
46915 {
46916 $output->writeln('', OutputInterface::VERBOSITY_QUIET);
46917
46918 do {
46919 $title = sprintf('  [%s]  ', get_class($e));
46920
46921 $len = $this->stringWidth($title);
46922
46923 $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
46924
46925  if (defined('HHVM_VERSION') && $width > 1 << 31) {
46926 $width = 1 << 31;
46927 }
46928 $formatter = $output->getFormatter();
46929 $lines = array();
46930 foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
46931 foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
46932
46933  $lineLength = $this->stringWidth(preg_replace('/\e\[[^m]*m/', '', $formatter->format($line))) + 4;
46934 $lines[] = array($line, $lineLength);
46935
46936 $len = max($lineLength, $len);
46937 }
46938 }
46939
46940 $messages = array();
46941 $messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
46942 $messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))));
46943 foreach ($lines as $line) {
46944 $messages[] = $formatter->format(sprintf('<error>  %s  %s</error>', $line[0], str_repeat(' ', $len - $line[1])));
46945 }
46946 $messages[] = $emptyLine;
46947 $messages[] = '';
46948
46949 $output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET);
46950
46951 if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
46952 $output->writeln('<comment>Exception trace:</comment>', OutputInterface::VERBOSITY_QUIET);
46953
46954
46955  $trace = $e->getTrace();
46956 array_unshift($trace, array(
46957 'function' => '',
46958 'file' => $e->getFile() !== null ? $e->getFile() : 'n/a',
46959 'line' => $e->getLine() !== null ? $e->getLine() : 'n/a',
46960 'args' => array(),
46961 ));
46962
46963 for ($i = 0, $count = count($trace); $i < $count; ++$i) {
46964 $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
46965 $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
46966 $function = $trace[$i]['function'];
46967 $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
46968 $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
46969
46970 $output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line), OutputInterface::VERBOSITY_QUIET);
46971 }
46972
46973 $output->writeln('', OutputInterface::VERBOSITY_QUIET);
46974 }
46975 } while ($e = $e->getPrevious());
46976
46977 if (null !== $this->runningCommand) {
46978 $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
46979 $output->writeln('', OutputInterface::VERBOSITY_QUIET);
46980 }
46981 }
46982
46983
46984
46985
46986
46987
46988 protected function getTerminalWidth()
46989 {
46990 $dimensions = $this->getTerminalDimensions();
46991
46992 return $dimensions[0];
46993 }
46994
46995
46996
46997
46998
46999
47000 protected function getTerminalHeight()
47001 {
47002 $dimensions = $this->getTerminalDimensions();
47003
47004 return $dimensions[1];
47005 }
47006
47007
47008
47009
47010
47011
47012 public function getTerminalDimensions()
47013 {
47014 if ($this->terminalDimensions) {
47015 return $this->terminalDimensions;
47016 }
47017
47018 if ('\\' === DIRECTORY_SEPARATOR) {
47019
47020  if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
47021 return array((int) $matches[1], (int) $matches[2]);
47022 }
47023
47024  if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) {
47025 return array((int) $matches[1], (int) $matches[2]);
47026 }
47027 }
47028
47029 if ($sttyString = $this->getSttyColumns()) {
47030
47031  if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
47032 return array((int) $matches[2], (int) $matches[1]);
47033 }
47034
47035  if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
47036 return array((int) $matches[2], (int) $matches[1]);
47037 }
47038 }
47039
47040 return array(null, null);
47041 }
47042
47043
47044
47045
47046
47047
47048
47049
47050
47051
47052
47053 public function setTerminalDimensions($width, $height)
47054 {
47055 $this->terminalDimensions = array($width, $height);
47056
47057 return $this;
47058 }
47059
47060
47061
47062
47063
47064
47065
47066 protected function configureIO(InputInterface $input, OutputInterface $output)
47067 {
47068 if (true === $input->hasParameterOption(array('--ansi'))) {
47069 $output->setDecorated(true);
47070 } elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
47071 $output->setDecorated(false);
47072 }
47073
47074 if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
47075 $input->setInteractive(false);
47076 } elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
47077 $inputStream = $this->getHelperSet()->get('question')->getInputStream();
47078 if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
47079 $input->setInteractive(false);
47080 }
47081 }
47082
47083 if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
47084 $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
47085 $input->setInteractive(false);
47086 } else {
47087 if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {
47088 $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
47089 } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) {
47090 $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
47091 } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) {
47092 $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
47093 }
47094 }
47095 }
47096
47097
47098
47099
47100
47101
47102
47103
47104
47105
47106
47107
47108
47109 protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
47110 {
47111 foreach ($command->getHelperSet() as $helper) {
47112 if ($helper instanceof InputAwareInterface) {
47113 $helper->setInput($input);
47114 }
47115 }
47116
47117 if (null === $this->dispatcher) {
47118 try {
47119 return $command->run($input, $output);
47120 } catch (\Exception $e) {
47121 throw $e;
47122 } catch (\Throwable $e) {
47123 throw new FatalThrowableError($e);
47124 }
47125 }
47126
47127
47128  try {
47129 $command->mergeApplicationDefinition();
47130 $input->bind($command->getDefinition());
47131 } catch (ExceptionInterface $e) {
47132
47133  }
47134
47135
47136  
47137  $command->setInputBound(true);
47138
47139 $event = new ConsoleCommandEvent($command, $input, $output);
47140 $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
47141
47142 if ($event->commandShouldRun()) {
47143 try {
47144 $e = null;
47145 $exitCode = $command->run($input, $output);
47146 } catch (\Exception $x) {
47147 $e = $x;
47148 } catch (\Throwable $x) {
47149 $e = new FatalThrowableError($x);
47150 }
47151 if (null !== $e) {
47152 $event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
47153 $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
47154
47155 if ($e !== $event->getException()) {
47156 $x = $e = $event->getException();
47157 }
47158
47159 $event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
47160 $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
47161
47162 throw $x;
47163 }
47164 } else {
47165 $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
47166 }
47167
47168 $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
47169 $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
47170
47171 return $event->getExitCode();
47172 }
47173
47174
47175
47176
47177
47178
47179
47180
47181 protected function getCommandName(InputInterface $input)
47182 {
47183 return $input->getFirstArgument();
47184 }
47185
47186
47187
47188
47189
47190
47191 protected function getDefaultInputDefinition()
47192 {
47193 return new InputDefinition(array(
47194 new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
47195
47196 new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
47197 new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
47198 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'),
47199 new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
47200 new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
47201 new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
47202 new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
47203 ));
47204 }
47205
47206
47207
47208
47209
47210
47211 protected function getDefaultCommands()
47212 {
47213 return array(new HelpCommand(), new ListCommand());
47214 }
47215
47216
47217
47218
47219
47220
47221 protected function getDefaultHelperSet()
47222 {
47223 return new HelperSet(array(
47224 new FormatterHelper(),
47225 new DialogHelper(false),
47226 new ProgressHelper(false),
47227 new TableHelper(false),
47228 new DebugFormatterHelper(),
47229 new ProcessHelper(),
47230 new QuestionHelper(),
47231 ));
47232 }
47233
47234
47235
47236
47237
47238
47239 private function getSttyColumns()
47240 {
47241 if (!function_exists('proc_open')) {
47242 return;
47243 }
47244
47245 $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
47246 $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
47247 if (is_resource($process)) {
47248 $info = stream_get_contents($pipes[1]);
47249 fclose($pipes[1]);
47250 fclose($pipes[2]);
47251 proc_close($process);
47252
47253 return $info;
47254 }
47255 }
47256
47257
47258
47259
47260
47261
47262 private function getConsoleMode()
47263 {
47264 if (!function_exists('proc_open')) {
47265 return;
47266 }
47267
47268 $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
47269 $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
47270 if (is_resource($process)) {
47271 $info = stream_get_contents($pipes[1]);
47272 fclose($pipes[1]);
47273 fclose($pipes[2]);
47274 proc_close($process);
47275
47276 if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
47277 return $matches[2].'x'.$matches[1];
47278 }
47279 }
47280 }
47281
47282
47283
47284
47285
47286
47287
47288
47289 private function getAbbreviationSuggestions($abbrevs)
47290 {
47291 return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
47292 }
47293
47294
47295
47296
47297
47298
47299
47300
47301
47302
47303
47304 public function extractNamespace($name, $limit = null)
47305 {
47306 $parts = explode(':', $name);
47307 array_pop($parts);
47308
47309 return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
47310 }
47311
47312
47313
47314
47315
47316
47317
47318
47319
47320
47321 private function findAlternatives($name, $collection)
47322 {
47323 $threshold = 1e3;
47324 $alternatives = array();
47325
47326 $collectionParts = array();
47327 foreach ($collection as $item) {
47328 $collectionParts[$item] = explode(':', $item);
47329 }
47330
47331 foreach (explode(':', $name) as $i => $subname) {
47332 foreach ($collectionParts as $collectionName => $parts) {
47333 $exists = isset($alternatives[$collectionName]);
47334 if (!isset($parts[$i]) && $exists) {
47335 $alternatives[$collectionName] += $threshold;
47336 continue;
47337 } elseif (!isset($parts[$i])) {
47338 continue;
47339 }
47340
47341 $lev = levenshtein($subname, $parts[$i]);
47342 if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
47343 $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
47344 } elseif ($exists) {
47345 $alternatives[$collectionName] += $threshold;
47346 }
47347 }
47348 }
47349
47350 foreach ($collection as $item) {
47351 $lev = levenshtein($name, $item);
47352 if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
47353 $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
47354 }
47355 }
47356
47357 $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
47358 asort($alternatives);
47359
47360 return array_keys($alternatives);
47361 }
47362
47363
47364
47365
47366
47367
47368 public function setDefaultCommand($commandName)
47369 {
47370 $this->defaultCommand = $commandName;
47371 }
47372
47373 private function stringWidth($string)
47374 {
47375 if (false === $encoding = mb_detect_encoding($string, null, true)) {
47376 return strlen($string);
47377 }
47378
47379 return mb_strwidth($string, $encoding);
47380 }
47381
47382 private function splitStringByWidth($string, $width)
47383 {
47384
47385  
47386  
47387  if (false === $encoding = mb_detect_encoding($string, null, true)) {
47388 return str_split($string, $width);
47389 }
47390
47391 $utf8String = mb_convert_encoding($string, 'utf8', $encoding);
47392 $lines = array();
47393 $line = '';
47394 foreach (preg_split('//u', $utf8String) as $char) {
47395
47396  if (mb_strwidth($line.$char, 'utf8') <= $width) {
47397 $line .= $char;
47398 continue;
47399 }
47400
47401  $lines[] = str_pad($line, $width);
47402 $line = $char;
47403 }
47404 if ('' !== $line) {
47405 $lines[] = count($lines) ? str_pad($line, $width) : $line;
47406 }
47407
47408 mb_convert_variables($encoding, 'utf8', $lines);
47409
47410 return $lines;
47411 }
47412
47413
47414
47415
47416
47417
47418
47419
47420 private function extractAllNamespaces($name)
47421 {
47422
47423  $parts = explode(':', $name, -1);
47424 $namespaces = array();
47425
47426 foreach ($parts as $part) {
47427 if (count($namespaces)) {
47428 $namespaces[] = end($namespaces).':'.$part;
47429 } else {
47430 $namespaces[] = $part;
47431 }
47432 }
47433
47434 return $namespaces;
47435 }
47436 }
47437 <?php
47438
47439
47440
47441
47442
47443
47444
47445
47446
47447
47448 namespace Symfony\Component\Console\Command;
47449
47450 use Symfony\Component\Console\Descriptor\TextDescriptor;
47451 use Symfony\Component\Console\Descriptor\XmlDescriptor;
47452 use Symfony\Component\Console\Exception\ExceptionInterface;
47453 use Symfony\Component\Console\Input\InputDefinition;
47454 use Symfony\Component\Console\Input\InputOption;
47455 use Symfony\Component\Console\Input\InputArgument;
47456 use Symfony\Component\Console\Input\InputInterface;
47457 use Symfony\Component\Console\Output\BufferedOutput;
47458 use Symfony\Component\Console\Output\OutputInterface;
47459 use Symfony\Component\Console\Application;
47460 use Symfony\Component\Console\Helper\HelperSet;
47461 use Symfony\Component\Console\Exception\InvalidArgumentException;
47462 use Symfony\Component\Console\Exception\LogicException;
47463
47464
47465
47466
47467
47468
47469 class Command
47470 {
47471 private $application;
47472 private $name;
47473 private $processTitle;
47474 private $aliases = array();
47475 private $definition;
47476 private $help;
47477 private $description;
47478 private $ignoreValidationErrors = false;
47479 private $applicationDefinitionMerged = false;
47480 private $applicationDefinitionMergedWithArgs = false;
47481 private $inputBound = false;
47482 private $code;
47483 private $synopsis = array();
47484 private $usages = array();
47485 private $helperSet;
47486
47487
47488
47489
47490
47491
47492
47493
47494 public function __construct($name = null)
47495 {
47496 $this->definition = new InputDefinition();
47497
47498 if (null !== $name) {
47499 $this->setName($name);
47500 }
47501
47502 $this->configure();
47503
47504 if (!$this->name) {
47505 throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
47506 }
47507 }
47508
47509
47510
47511
47512
47513
47514 public function ignoreValidationErrors()
47515 {
47516 $this->ignoreValidationErrors = true;
47517 }
47518
47519
47520
47521
47522
47523
47524 public function setApplication(Application $application = null)
47525 {
47526 $this->application = $application;
47527 if ($application) {
47528 $this->setHelperSet($application->getHelperSet());
47529 } else {
47530 $this->helperSet = null;
47531 }
47532 }
47533
47534
47535
47536
47537
47538
47539 public function setHelperSet(HelperSet $helperSet)
47540 {
47541 $this->helperSet = $helperSet;
47542 }
47543
47544
47545
47546
47547
47548
47549 public function getHelperSet()
47550 {
47551 return $this->helperSet;
47552 }
47553
47554
47555
47556
47557
47558
47559 public function getApplication()
47560 {
47561 return $this->application;
47562 }
47563
47564
47565
47566
47567
47568
47569
47570
47571
47572 public function isEnabled()
47573 {
47574 return true;
47575 }
47576
47577
47578
47579
47580 protected function configure()
47581 {
47582 }
47583
47584
47585
47586
47587
47588
47589
47590
47591
47592
47593
47594
47595
47596
47597
47598
47599
47600
47601 protected function execute(InputInterface $input, OutputInterface $output)
47602 {
47603 throw new LogicException('You must override the execute() method in the concrete command class.');
47604 }
47605
47606
47607
47608
47609
47610
47611
47612
47613
47614
47615
47616 protected function interact(InputInterface $input, OutputInterface $output)
47617 {
47618 }
47619
47620
47621
47622
47623
47624
47625
47626
47627
47628
47629 protected function initialize(InputInterface $input, OutputInterface $output)
47630 {
47631 }
47632
47633
47634
47635
47636
47637
47638
47639
47640
47641
47642
47643
47644
47645
47646
47647
47648 public function run(InputInterface $input, OutputInterface $output)
47649 {
47650
47651  $this->getSynopsis(true);
47652 $this->getSynopsis(false);
47653
47654
47655  $this->mergeApplicationDefinition();
47656
47657
47658  if (!$this->inputBound) {
47659 try {
47660 $input->bind($this->definition);
47661 } catch (ExceptionInterface $e) {
47662 if (!$this->ignoreValidationErrors) {
47663 throw $e;
47664 }
47665 }
47666 }
47667
47668 $this->initialize($input, $output);
47669
47670 if (null !== $this->processTitle) {
47671 if (function_exists('cli_set_process_title')) {
47672 if (false === @cli_set_process_title($this->processTitle)) {
47673 if ('Darwin' === PHP_OS) {
47674 $output->writeln('<comment>Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.</comment>');
47675 } else {
47676 $error = error_get_last();
47677 trigger_error($error['message'], E_USER_WARNING);
47678 }
47679 }
47680 } elseif (function_exists('setproctitle')) {
47681 setproctitle($this->processTitle);
47682 } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
47683 $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
47684 }
47685 }
47686
47687 if ($input->isInteractive()) {
47688 $this->interact($input, $output);
47689 }
47690
47691
47692  
47693  
47694  if ($input->hasArgument('command') && null === $input->getArgument('command')) {
47695 $input->setArgument('command', $this->getName());
47696 }
47697
47698 $input->validate();
47699
47700 if ($this->code) {
47701 $statusCode = call_user_func($this->code, $input, $output);
47702 } else {
47703 $statusCode = $this->execute($input, $output);
47704 }
47705
47706 return is_numeric($statusCode) ? (int) $statusCode : 0;
47707 }
47708
47709
47710
47711
47712
47713
47714
47715
47716
47717
47718
47719
47720
47721
47722
47723 public function setCode($code)
47724 {
47725 if (!is_callable($code)) {
47726 throw new InvalidArgumentException('Invalid callable provided to Command::setCode.');
47727 }
47728
47729 if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) {
47730 $r = new \ReflectionFunction($code);
47731 if (null === $r->getClosureThis()) {
47732 if (PHP_VERSION_ID < 70000) {
47733
47734  
47735  
47736  
47737  $code = @\Closure::bind($code, $this);
47738 } else {
47739 $code = \Closure::bind($code, $this);
47740 }
47741 }
47742 }
47743
47744 $this->code = $code;
47745
47746 return $this;
47747 }
47748
47749
47750
47751
47752
47753
47754
47755
47756 public function mergeApplicationDefinition($mergeArgs = true)
47757 {
47758 if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
47759 return;
47760 }
47761
47762 $this->definition->addOptions($this->application->getDefinition()->getOptions());
47763
47764 if ($mergeArgs) {
47765 $currentArguments = $this->definition->getArguments();
47766 $this->definition->setArguments($this->application->getDefinition()->getArguments());
47767 $this->definition->addArguments($currentArguments);
47768 }
47769
47770 $this->applicationDefinitionMerged = true;
47771 if ($mergeArgs) {
47772 $this->applicationDefinitionMergedWithArgs = true;
47773 }
47774 }
47775
47776
47777
47778
47779
47780
47781
47782
47783 public function setDefinition($definition)
47784 {
47785 if ($definition instanceof InputDefinition) {
47786 $this->definition = $definition;
47787 } else {
47788 $this->definition->setDefinition($definition);
47789 }
47790
47791 $this->applicationDefinitionMerged = false;
47792
47793 return $this;
47794 }
47795
47796
47797
47798
47799
47800
47801 public function getDefinition()
47802 {
47803 return $this->definition;
47804 }
47805
47806
47807
47808
47809
47810
47811
47812
47813
47814
47815
47816 public function getNativeDefinition()
47817 {
47818 return $this->getDefinition();
47819 }
47820
47821
47822
47823
47824
47825
47826
47827
47828
47829
47830
47831 public function addArgument($name, $mode = null, $description = '', $default = null)
47832 {
47833 $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
47834
47835 return $this;
47836 }
47837
47838
47839
47840
47841
47842
47843
47844
47845
47846
47847
47848
47849 public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
47850 {
47851 $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
47852
47853 return $this;
47854 }
47855
47856
47857
47858
47859
47860
47861
47862
47863
47864
47865
47866
47867
47868
47869
47870 public function setName($name)
47871 {
47872 $this->validateName($name);
47873
47874 $this->name = $name;
47875
47876 return $this;
47877 }
47878
47879
47880
47881
47882
47883
47884
47885
47886
47887
47888
47889
47890
47891 public function setProcessTitle($title)
47892 {
47893 $this->processTitle = $title;
47894
47895 return $this;
47896 }
47897
47898
47899
47900
47901
47902
47903 public function getName()
47904 {
47905 return $this->name;
47906 }
47907
47908
47909
47910
47911
47912
47913
47914
47915 public function setDescription($description)
47916 {
47917 $this->description = $description;
47918
47919 return $this;
47920 }
47921
47922
47923
47924
47925
47926
47927 public function getDescription()
47928 {
47929 return $this->description;
47930 }
47931
47932
47933
47934
47935
47936
47937
47938
47939 public function setHelp($help)
47940 {
47941 $this->help = $help;
47942
47943 return $this;
47944 }
47945
47946
47947
47948
47949
47950
47951 public function getHelp()
47952 {
47953 return $this->help;
47954 }
47955
47956
47957
47958
47959
47960
47961
47962 public function getProcessedHelp()
47963 {
47964 $name = $this->name;
47965
47966 $placeholders = array(
47967 '%command.name%',
47968 '%command.full_name%',
47969 );
47970 $replacements = array(
47971 $name,
47972 $_SERVER['PHP_SELF'].' '.$name,
47973 );
47974
47975 return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
47976 }
47977
47978
47979
47980
47981
47982
47983
47984
47985
47986
47987 public function setAliases($aliases)
47988 {
47989 if (!is_array($aliases) && !$aliases instanceof \Traversable) {
47990 throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
47991 }
47992
47993 foreach ($aliases as $alias) {
47994 $this->validateName($alias);
47995 }
47996
47997 $this->aliases = $aliases;
47998
47999 return $this;
48000 }
48001
48002
48003
48004
48005
48006
48007 public function getAliases()
48008 {
48009 return $this->aliases;
48010 }
48011
48012
48013
48014
48015
48016
48017
48018
48019 public function getSynopsis($short = false)
48020 {
48021 $key = $short ? 'short' : 'long';
48022
48023 if (!isset($this->synopsis[$key])) {
48024 $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
48025 }
48026
48027 return $this->synopsis[$key];
48028 }
48029
48030
48031
48032
48033
48034
48035
48036
48037 public function addUsage($usage)
48038 {
48039 if (0 !== strpos($usage, $this->name)) {
48040 $usage = sprintf('%s %s', $this->name, $usage);
48041 }
48042
48043 $this->usages[] = $usage;
48044
48045 return $this;
48046 }
48047
48048
48049
48050
48051
48052
48053 public function getUsages()
48054 {
48055 return $this->usages;
48056 }
48057
48058
48059
48060
48061
48062
48063
48064
48065
48066
48067
48068 public function getHelper($name)
48069 {
48070 if (null === $this->helperSet) {
48071 throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
48072 }
48073
48074 return $this->helperSet->get($name);
48075 }
48076
48077
48078
48079
48080
48081
48082
48083
48084 public function asText()
48085 {
48086 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
48087
48088 $descriptor = new TextDescriptor();
48089 $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
48090 $descriptor->describe($output, $this, array('raw_output' => true));
48091
48092 return $output->fetch();
48093 }
48094
48095
48096
48097
48098
48099
48100
48101
48102
48103
48104 public function asXml($asDom = false)
48105 {
48106 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
48107
48108 $descriptor = new XmlDescriptor();
48109
48110 if ($asDom) {
48111 return $descriptor->getCommandDocument($this);
48112 }
48113
48114 $output = new BufferedOutput();
48115 $descriptor->describe($output, $this);
48116
48117 return $output->fetch();
48118 }
48119
48120
48121
48122
48123 public function setInputBound($inputBound)
48124 {
48125 $this->inputBound = $inputBound;
48126 }
48127
48128
48129
48130
48131
48132
48133
48134
48135
48136
48137 private function validateName($name)
48138 {
48139 if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
48140 throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
48141 }
48142 }
48143 }
48144 <?php
48145
48146
48147
48148
48149
48150
48151
48152
48153
48154
48155 namespace Symfony\Component\Console\Command;
48156
48157 use Symfony\Component\Console\Helper\DescriptorHelper;
48158 use Symfony\Component\Console\Input\InputArgument;
48159 use Symfony\Component\Console\Input\InputOption;
48160 use Symfony\Component\Console\Input\InputInterface;
48161 use Symfony\Component\Console\Output\OutputInterface;
48162
48163
48164
48165
48166
48167
48168 class HelpCommand extends Command
48169 {
48170 private $command;
48171
48172
48173
48174
48175 protected function configure()
48176 {
48177 $this->ignoreValidationErrors();
48178
48179 $this
48180 ->setName('help')
48181 ->setDefinition(array(
48182 new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
48183 new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
48184 new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
48185 new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
48186 ))
48187 ->setDescription('Displays help for a command')
48188 ->setHelp(<<<'EOF'
48189 The <info>%command.name%</info> command displays help for a given command:
48190
48191   <info>php %command.full_name% list</info>
48192
48193 You can also output the help in other formats by using the <comment>--format</comment> option:
48194
48195   <info>php %command.full_name% --format=xml list</info>
48196
48197 To display the list of available commands, please use the <info>list</info> command.
48198 EOF
48199 )
48200 ;
48201 }
48202
48203
48204
48205
48206
48207
48208 public function setCommand(Command $command)
48209 {
48210 $this->command = $command;
48211 }
48212
48213
48214
48215
48216 protected function execute(InputInterface $input, OutputInterface $output)
48217 {
48218 if (null === $this->command) {
48219 $this->command = $this->getApplication()->find($input->getArgument('command_name'));
48220 }
48221
48222 if ($input->getOption('xml')) {
48223 @trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED);
48224
48225 $input->setOption('format', 'xml');
48226 }
48227
48228 $helper = new DescriptorHelper();
48229 $helper->describe($output, $this->command, array(
48230 'format' => $input->getOption('format'),
48231 'raw_text' => $input->getOption('raw'),
48232 ));
48233
48234 $this->command = null;
48235 }
48236 }
48237 <?php
48238
48239
48240
48241
48242
48243
48244
48245
48246
48247
48248 namespace Symfony\Component\Console\Command;
48249
48250 use Symfony\Component\Console\Helper\DescriptorHelper;
48251 use Symfony\Component\Console\Input\InputArgument;
48252 use Symfony\Component\Console\Input\InputOption;
48253 use Symfony\Component\Console\Input\InputInterface;
48254 use Symfony\Component\Console\Output\OutputInterface;
48255 use Symfony\Component\Console\Input\InputDefinition;
48256
48257
48258
48259
48260
48261
48262 class ListCommand extends Command
48263 {
48264
48265
48266
48267 protected function configure()
48268 {
48269 $this
48270 ->setName('list')
48271 ->setDefinition($this->createDefinition())
48272 ->setDescription('Lists commands')
48273 ->setHelp(<<<'EOF'
48274 The <info>%command.name%</info> command lists all commands:
48275
48276   <info>php %command.full_name%</info>
48277
48278 You can also display the commands for a specific namespace:
48279
48280   <info>php %command.full_name% test</info>
48281
48282 You can also output the information in other formats by using the <comment>--format</comment> option:
48283
48284   <info>php %command.full_name% --format=xml</info>
48285
48286 It's also possible to get raw list of commands (useful for embedding command runner):
48287
48288   <info>php %command.full_name% --raw</info>
48289 EOF
48290 )
48291 ;
48292 }
48293
48294
48295
48296
48297 public function getNativeDefinition()
48298 {
48299 return $this->createDefinition();
48300 }
48301
48302
48303
48304
48305 protected function execute(InputInterface $input, OutputInterface $output)
48306 {
48307 if ($input->getOption('xml')) {
48308 @trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED);
48309
48310 $input->setOption('format', 'xml');
48311 }
48312
48313 $helper = new DescriptorHelper();
48314 $helper->describe($output, $this->getApplication(), array(
48315 'format' => $input->getOption('format'),
48316 'raw_text' => $input->getOption('raw'),
48317 'namespace' => $input->getArgument('namespace'),
48318 ));
48319 }
48320
48321
48322
48323
48324 private function createDefinition()
48325 {
48326 return new InputDefinition(array(
48327 new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
48328 new InputOption('xml', null, InputOption::VALUE_NONE, 'To output list as XML'),
48329 new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
48330 new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
48331 ));
48332 }
48333 }
48334 <?php
48335
48336
48337
48338
48339
48340
48341
48342
48343
48344
48345 namespace Symfony\Component\Console;
48346
48347
48348
48349
48350
48351
48352 final class ConsoleEvents
48353 {
48354
48355
48356
48357
48358
48359
48360
48361
48362
48363
48364
48365
48366 const COMMAND = 'console.command';
48367
48368
48369
48370
48371
48372
48373
48374
48375
48376
48377
48378
48379 const TERMINATE = 'console.terminate';
48380
48381
48382
48383
48384
48385
48386
48387
48388
48389
48390
48391
48392
48393 const EXCEPTION = 'console.exception';
48394 }
48395 <?php
48396
48397
48398
48399
48400
48401
48402
48403
48404
48405
48406 namespace Symfony\Component\Console\Descriptor;
48407
48408 use Symfony\Component\Console\Application;
48409 use Symfony\Component\Console\Command\Command;
48410 use Symfony\Component\Console\Exception\CommandNotFoundException;
48411
48412
48413
48414
48415
48416
48417 class ApplicationDescription
48418 {
48419 const GLOBAL_NAMESPACE = '_global';
48420
48421
48422
48423
48424 private $application;
48425
48426
48427
48428
48429 private $namespace;
48430
48431
48432
48433
48434 private $namespaces;
48435
48436
48437
48438
48439 private $commands;
48440
48441
48442
48443
48444 private $aliases;
48445
48446
48447
48448
48449
48450
48451
48452 public function __construct(Application $application, $namespace = null)
48453 {
48454 $this->application = $application;
48455 $this->namespace = $namespace;
48456 }
48457
48458
48459
48460
48461 public function getNamespaces()
48462 {
48463 if (null === $this->namespaces) {
48464 $this->inspectApplication();
48465 }
48466
48467 return $this->namespaces;
48468 }
48469
48470
48471
48472
48473 public function getCommands()
48474 {
48475 if (null === $this->commands) {
48476 $this->inspectApplication();
48477 }
48478
48479 return $this->commands;
48480 }
48481
48482
48483
48484
48485
48486
48487
48488
48489 public function getCommand($name)
48490 {
48491 if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
48492 throw new CommandNotFoundException(sprintf('Command %s does not exist.', $name));
48493 }
48494
48495 return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
48496 }
48497
48498 private function inspectApplication()
48499 {
48500 $this->commands = array();
48501 $this->namespaces = array();
48502
48503 $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
48504 foreach ($this->sortCommands($all) as $namespace => $commands) {
48505 $names = array();
48506
48507
48508 foreach ($commands as $name => $command) {
48509 if (!$command->getName()) {
48510 continue;
48511 }
48512
48513 if ($command->getName() === $name) {
48514 $this->commands[$name] = $command;
48515 } else {
48516 $this->aliases[$name] = $command;
48517 }
48518
48519 $names[] = $name;
48520 }
48521
48522 $this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names);
48523 }
48524 }
48525
48526
48527
48528
48529
48530
48531 private function sortCommands(array $commands)
48532 {
48533 $namespacedCommands = array();
48534 $globalCommands = array();
48535 foreach ($commands as $name => $command) {
48536 $key = $this->application->extractNamespace($name, 1);
48537 if (!$key) {
48538 $globalCommands['_global'][$name] = $command;
48539 } else {
48540 $namespacedCommands[$key][$name] = $command;
48541 }
48542 }
48543 ksort($namespacedCommands);
48544 $namespacedCommands = array_merge($globalCommands, $namespacedCommands);
48545
48546 foreach ($namespacedCommands as &$commandsSet) {
48547 ksort($commandsSet);
48548 }
48549
48550  unset($commandsSet);
48551
48552 return $namespacedCommands;
48553 }
48554 }
48555 <?php
48556
48557
48558
48559
48560
48561
48562
48563
48564
48565
48566 namespace Symfony\Component\Console\Descriptor;
48567
48568 use Symfony\Component\Console\Application;
48569 use Symfony\Component\Console\Command\Command;
48570 use Symfony\Component\Console\Input\InputArgument;
48571 use Symfony\Component\Console\Input\InputDefinition;
48572 use Symfony\Component\Console\Input\InputOption;
48573 use Symfony\Component\Console\Output\OutputInterface;
48574 use Symfony\Component\Console\Exception\InvalidArgumentException;
48575
48576
48577
48578
48579
48580
48581 abstract class Descriptor implements DescriptorInterface
48582 {
48583
48584
48585
48586 private $output;
48587
48588
48589
48590
48591 public function describe(OutputInterface $output, $object, array $options = array())
48592 {
48593 $this->output = $output;
48594
48595 switch (true) {
48596 case $object instanceof InputArgument:
48597 $this->describeInputArgument($object, $options);
48598 break;
48599 case $object instanceof InputOption:
48600 $this->describeInputOption($object, $options);
48601 break;
48602 case $object instanceof InputDefinition:
48603 $this->describeInputDefinition($object, $options);
48604 break;
48605 case $object instanceof Command:
48606 $this->describeCommand($object, $options);
48607 break;
48608 case $object instanceof Application:
48609 $this->describeApplication($object, $options);
48610 break;
48611 default:
48612 throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
48613 }
48614 }
48615
48616
48617
48618
48619
48620
48621
48622 protected function write($content, $decorated = false)
48623 {
48624 $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
48625 }
48626
48627
48628
48629
48630
48631
48632
48633
48634
48635 abstract protected function describeInputArgument(InputArgument $argument, array $options = array());
48636
48637
48638
48639
48640
48641
48642
48643
48644
48645 abstract protected function describeInputOption(InputOption $option, array $options = array());
48646
48647
48648
48649
48650
48651
48652
48653
48654
48655 abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());
48656
48657
48658
48659
48660
48661
48662
48663
48664
48665 abstract protected function describeCommand(Command $command, array $options = array());
48666
48667
48668
48669
48670
48671
48672
48673
48674
48675 abstract protected function describeApplication(Application $application, array $options = array());
48676 }
48677 <?php
48678
48679
48680
48681
48682
48683
48684
48685
48686
48687
48688 namespace Symfony\Component\Console\Descriptor;
48689
48690 use Symfony\Component\Console\Output\OutputInterface;
48691
48692
48693
48694
48695
48696
48697 interface DescriptorInterface
48698 {
48699
48700
48701
48702
48703
48704
48705
48706 public function describe(OutputInterface $output, $object, array $options = array());
48707 }
48708 <?php
48709
48710
48711
48712
48713
48714
48715
48716
48717
48718
48719 namespace Symfony\Component\Console\Descriptor;
48720
48721 use Symfony\Component\Console\Application;
48722 use Symfony\Component\Console\Command\Command;
48723 use Symfony\Component\Console\Input\InputArgument;
48724 use Symfony\Component\Console\Input\InputDefinition;
48725 use Symfony\Component\Console\Input\InputOption;
48726
48727
48728
48729
48730
48731
48732
48733
48734 class JsonDescriptor extends Descriptor
48735 {
48736
48737
48738
48739 protected function describeInputArgument(InputArgument $argument, array $options = array())
48740 {
48741 $this->writeData($this->getInputArgumentData($argument), $options);
48742 }
48743
48744
48745
48746
48747 protected function describeInputOption(InputOption $option, array $options = array())
48748 {
48749 $this->writeData($this->getInputOptionData($option), $options);
48750 }
48751
48752
48753
48754
48755 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
48756 {
48757 $this->writeData($this->getInputDefinitionData($definition), $options);
48758 }
48759
48760
48761
48762
48763 protected function describeCommand(Command $command, array $options = array())
48764 {
48765 $this->writeData($this->getCommandData($command), $options);
48766 }
48767
48768
48769
48770
48771 protected function describeApplication(Application $application, array $options = array())
48772 {
48773 $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
48774 $description = new ApplicationDescription($application, $describedNamespace);
48775 $commands = array();
48776
48777 foreach ($description->getCommands() as $command) {
48778 $commands[] = $this->getCommandData($command);
48779 }
48780
48781 $data = $describedNamespace
48782 ? array('commands' => $commands, 'namespace' => $describedNamespace)
48783 : array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces()));
48784
48785 $this->writeData($data, $options);
48786 }
48787
48788
48789
48790
48791
48792
48793
48794
48795
48796 private function writeData(array $data, array $options)
48797 {
48798 $this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0));
48799 }
48800
48801
48802
48803
48804
48805
48806 private function getInputArgumentData(InputArgument $argument)
48807 {
48808 return array(
48809 'name' => $argument->getName(),
48810 'is_required' => $argument->isRequired(),
48811 'is_array' => $argument->isArray(),
48812 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
48813 'default' => $argument->getDefault(),
48814 );
48815 }
48816
48817
48818
48819
48820
48821
48822 private function getInputOptionData(InputOption $option)
48823 {
48824 return array(
48825 'name' => '--'.$option->getName(),
48826 'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
48827 'accept_value' => $option->acceptValue(),
48828 'is_value_required' => $option->isValueRequired(),
48829 'is_multiple' => $option->isArray(),
48830 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
48831 'default' => $option->getDefault(),
48832 );
48833 }
48834
48835
48836
48837
48838
48839
48840 private function getInputDefinitionData(InputDefinition $definition)
48841 {
48842 $inputArguments = array();
48843 foreach ($definition->getArguments() as $name => $argument) {
48844 $inputArguments[$name] = $this->getInputArgumentData($argument);
48845 }
48846
48847 $inputOptions = array();
48848 foreach ($definition->getOptions() as $name => $option) {
48849 $inputOptions[$name] = $this->getInputOptionData($option);
48850 }
48851
48852 return array('arguments' => $inputArguments, 'options' => $inputOptions);
48853 }
48854
48855
48856
48857
48858
48859
48860 private function getCommandData(Command $command)
48861 {
48862 $command->getSynopsis();
48863 $command->mergeApplicationDefinition(false);
48864
48865 return array(
48866 'name' => $command->getName(),
48867 'usage' => array_merge(array($command->getSynopsis()), $command->getUsages(), $command->getAliases()),
48868 'description' => $command->getDescription(),
48869 'help' => $command->getProcessedHelp(),
48870 'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
48871 );
48872 }
48873 }
48874 <?php
48875
48876
48877
48878
48879
48880
48881
48882
48883
48884
48885 namespace Symfony\Component\Console\Descriptor;
48886
48887 use Symfony\Component\Console\Application;
48888 use Symfony\Component\Console\Command\Command;
48889 use Symfony\Component\Console\Helper\Helper;
48890 use Symfony\Component\Console\Input\InputArgument;
48891 use Symfony\Component\Console\Input\InputDefinition;
48892 use Symfony\Component\Console\Input\InputOption;
48893
48894
48895
48896
48897
48898
48899
48900
48901 class MarkdownDescriptor extends Descriptor
48902 {
48903
48904
48905
48906 protected function describeInputArgument(InputArgument $argument, array $options = array())
48907 {
48908 $this->write(
48909 '**'.$argument->getName().':**'."\n\n"
48910 .'* Name: '.($argument->getName() ?: '<none>')."\n"
48911 .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
48912 .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
48913 .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n  ", $argument->getDescription() ?: '<none>')."\n"
48914 .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'
48915 );
48916 }
48917
48918
48919
48920
48921 protected function describeInputOption(InputOption $option, array $options = array())
48922 {
48923 $this->write(
48924 '**'.$option->getName().':**'."\n\n"
48925 .'* Name: `--'.$option->getName().'`'."\n"
48926 .'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '<none>')."\n"
48927 .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
48928 .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
48929 .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
48930 .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n  ", $option->getDescription() ?: '<none>')."\n"
48931 .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'
48932 );
48933 }
48934
48935
48936
48937
48938 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
48939 {
48940 if ($showArguments = count($definition->getArguments()) > 0) {
48941 $this->write('### Arguments:');
48942 foreach ($definition->getArguments() as $argument) {
48943 $this->write("\n\n");
48944 $this->write($this->describeInputArgument($argument));
48945 }
48946 }
48947
48948 if (count($definition->getOptions()) > 0) {
48949 if ($showArguments) {
48950 $this->write("\n\n");
48951 }
48952
48953 $this->write('### Options:');
48954 foreach ($definition->getOptions() as $option) {
48955 $this->write("\n\n");
48956 $this->write($this->describeInputOption($option));
48957 }
48958 }
48959 }
48960
48961
48962
48963
48964 protected function describeCommand(Command $command, array $options = array())
48965 {
48966 $command->getSynopsis();
48967 $command->mergeApplicationDefinition(false);
48968
48969 $this->write(
48970 $command->getName()."\n"
48971 .str_repeat('-', Helper::strlen($command->getName()))."\n\n"
48972 .'* Description: '.($command->getDescription() ?: '<none>')."\n"
48973 .'* Usage:'."\n\n"
48974 .array_reduce(array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
48975 return $carry.'  * `'.$usage.'`'."\n";
48976 })
48977 );
48978
48979 if ($help = $command->getProcessedHelp()) {
48980 $this->write("\n");
48981 $this->write($help);
48982 }
48983
48984 if ($command->getNativeDefinition()) {
48985 $this->write("\n\n");
48986 $this->describeInputDefinition($command->getNativeDefinition());
48987 }
48988 }
48989
48990
48991
48992
48993 protected function describeApplication(Application $application, array $options = array())
48994 {
48995 $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
48996 $description = new ApplicationDescription($application, $describedNamespace);
48997
48998 $this->write($application->getName()."\n".str_repeat('=', Helper::strlen($application->getName())));
48999
49000 foreach ($description->getNamespaces() as $namespace) {
49001 if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
49002 $this->write("\n\n");
49003 $this->write('**'.$namespace['id'].':**');
49004 }
49005
49006 $this->write("\n\n");
49007 $this->write(implode("\n", array_map(function ($commandName) {
49008 return '* '.$commandName;
49009 }, $namespace['commands'])));
49010 }
49011
49012 foreach ($description->getCommands() as $command) {
49013 $this->write("\n\n");
49014 $this->write($this->describeCommand($command));
49015 }
49016 }
49017 }
49018 <?php
49019
49020
49021
49022
49023
49024
49025
49026
49027
49028
49029 namespace Symfony\Component\Console\Descriptor;
49030
49031 use Symfony\Component\Console\Application;
49032 use Symfony\Component\Console\Command\Command;
49033 use Symfony\Component\Console\Formatter\OutputFormatter;
49034 use Symfony\Component\Console\Helper\Helper;
49035 use Symfony\Component\Console\Input\InputArgument;
49036 use Symfony\Component\Console\Input\InputDefinition;
49037 use Symfony\Component\Console\Input\InputOption;
49038
49039
49040
49041
49042
49043
49044
49045
49046 class TextDescriptor extends Descriptor
49047 {
49048
49049
49050
49051 protected function describeInputArgument(InputArgument $argument, array $options = array())
49052 {
49053 if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
49054 $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
49055 } else {
49056 $default = '';
49057 }
49058
49059 $totalWidth = isset($options['total_width']) ? $options['total_width'] : Helper::strlen($argument->getName());
49060 $spacingWidth = $totalWidth - strlen($argument->getName());
49061
49062 $this->writeText(sprintf('  <info>%s</info>  %s%s%s',
49063 $argument->getName(),
49064 str_repeat(' ', $spacingWidth),
49065
49066  preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
49067 $default
49068 ), $options);
49069 }
49070
49071
49072
49073
49074 protected function describeInputOption(InputOption $option, array $options = array())
49075 {
49076 if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
49077 $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
49078 } else {
49079 $default = '';
49080 }
49081
49082 $value = '';
49083 if ($option->acceptValue()) {
49084 $value = '='.strtoupper($option->getName());
49085
49086 if ($option->isValueOptional()) {
49087 $value = '['.$value.']';
49088 }
49089 }
49090
49091 $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions(array($option));
49092 $synopsis = sprintf('%s%s',
49093 $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : '    ',
49094 sprintf('--%s%s', $option->getName(), $value)
49095 );
49096
49097 $spacingWidth = $totalWidth - Helper::strlen($synopsis);
49098
49099 $this->writeText(sprintf('  <info>%s</info>  %s%s%s%s',
49100 $synopsis,
49101 str_repeat(' ', $spacingWidth),
49102
49103  preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()),
49104 $default,
49105 $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
49106 ), $options);
49107 }
49108
49109
49110
49111
49112 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
49113 {
49114 $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
49115 foreach ($definition->getArguments() as $argument) {
49116 $totalWidth = max($totalWidth, Helper::strlen($argument->getName()));
49117 }
49118
49119 if ($definition->getArguments()) {
49120 $this->writeText('<comment>Arguments:</comment>', $options);
49121 $this->writeText("\n");
49122 foreach ($definition->getArguments() as $argument) {
49123 $this->describeInputArgument($argument, array_merge($options, array('total_width' => $totalWidth)));
49124 $this->writeText("\n");
49125 }
49126 }
49127
49128 if ($definition->getArguments() && $definition->getOptions()) {
49129 $this->writeText("\n");
49130 }
49131
49132 if ($definition->getOptions()) {
49133 $laterOptions = array();
49134
49135 $this->writeText('<comment>Options:</comment>', $options);
49136 foreach ($definition->getOptions() as $option) {
49137 if (strlen($option->getShortcut()) > 1) {
49138 $laterOptions[] = $option;
49139 continue;
49140 }
49141 $this->writeText("\n");
49142 $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
49143 }
49144 foreach ($laterOptions as $option) {
49145 $this->writeText("\n");
49146 $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
49147 }
49148 }
49149 }
49150
49151
49152
49153
49154 protected function describeCommand(Command $command, array $options = array())
49155 {
49156 $command->getSynopsis(true);
49157 $command->getSynopsis(false);
49158 $command->mergeApplicationDefinition(false);
49159
49160 $this->writeText('<comment>Usage:</comment>', $options);
49161 foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) {
49162 $this->writeText("\n");
49163 $this->writeText('  '.$usage, $options);
49164 }
49165 $this->writeText("\n");
49166
49167 $definition = $command->getNativeDefinition();
49168 if ($definition->getOptions() || $definition->getArguments()) {
49169 $this->writeText("\n");
49170 $this->describeInputDefinition($definition, $options);
49171 $this->writeText("\n");
49172 }
49173
49174 if ($help = $command->getProcessedHelp()) {
49175 $this->writeText("\n");
49176 $this->writeText('<comment>Help:</comment>', $options);
49177 $this->writeText("\n");
49178 $this->writeText('  '.str_replace("\n", "\n  ", $help), $options);
49179 $this->writeText("\n");
49180 }
49181 }
49182
49183
49184
49185
49186 protected function describeApplication(Application $application, array $options = array())
49187 {
49188 $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
49189 $description = new ApplicationDescription($application, $describedNamespace);
49190
49191 if (isset($options['raw_text']) && $options['raw_text']) {
49192 $width = $this->getColumnWidth($description->getCommands());
49193
49194 foreach ($description->getCommands() as $command) {
49195 $this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
49196 $this->writeText("\n");
49197 }
49198 } else {
49199 if ('' != $help = $application->getHelp()) {
49200 $this->writeText("$help\n\n", $options);
49201 }
49202
49203 $this->writeText("<comment>Usage:</comment>\n", $options);
49204 $this->writeText("  command [options] [arguments]\n\n", $options);
49205
49206 $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options);
49207
49208 $this->writeText("\n");
49209 $this->writeText("\n");
49210
49211 $width = $this->getColumnWidth($description->getCommands());
49212
49213 if ($describedNamespace) {
49214 $this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
49215 } else {
49216 $this->writeText('<comment>Available commands:</comment>', $options);
49217 }
49218
49219
49220  foreach ($description->getNamespaces() as $namespace) {
49221 if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
49222 $this->writeText("\n");
49223 $this->writeText(' <comment>'.$namespace['id'].'</comment>', $options);
49224 }
49225
49226 foreach ($namespace['commands'] as $name) {
49227 $this->writeText("\n");
49228 $spacingWidth = $width - Helper::strlen($name);
49229 $this->writeText(sprintf('  <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
49230 }
49231 }
49232
49233 $this->writeText("\n");
49234 }
49235 }
49236
49237
49238
49239
49240 private function writeText($content, array $options = array())
49241 {
49242 $this->write(
49243 isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
49244 isset($options['raw_output']) ? !$options['raw_output'] : true
49245 );
49246 }
49247
49248
49249
49250
49251
49252
49253
49254
49255 private function formatDefaultValue($default)
49256 {
49257 if (is_string($default)) {
49258 $default = OutputFormatter::escape($default);
49259 } elseif (is_array($default)) {
49260 foreach ($default as $key => $value) {
49261 if (is_string($value)) {
49262 $default[$key] = OutputFormatter::escape($value);
49263 }
49264 }
49265 }
49266
49267 if (PHP_VERSION_ID < 50400) {
49268 return str_replace(array('\/', '\\\\'), array('/', '\\'), json_encode($default));
49269 }
49270
49271 return str_replace('\\\\', '\\', json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
49272 }
49273
49274
49275
49276
49277
49278
49279 private function getColumnWidth(array $commands)
49280 {
49281 $widths = array();
49282
49283 foreach ($commands as $command) {
49284 $widths[] = Helper::strlen($command->getName());
49285 foreach ($command->getAliases() as $alias) {
49286 $widths[] = Helper::strlen($alias);
49287 }
49288 }
49289
49290 return max($widths) + 2;
49291 }
49292
49293
49294
49295
49296
49297
49298 private function calculateTotalWidthForOptions($options)
49299 {
49300 $totalWidth = 0;
49301 foreach ($options as $option) {
49302
49303  $nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + Helper::strlen($option->getName());
49304
49305 if ($option->acceptValue()) {
49306 $valueLength = 1 + Helper::strlen($option->getName()); 
49307  $valueLength += $option->isValueOptional() ? 2 : 0; 
49308
49309 $nameLength += $valueLength;
49310 }
49311 $totalWidth = max($totalWidth, $nameLength);
49312 }
49313
49314 return $totalWidth;
49315 }
49316 }
49317 <?php
49318
49319
49320
49321
49322
49323
49324
49325
49326
49327
49328 namespace Symfony\Component\Console\Descriptor;
49329
49330 use Symfony\Component\Console\Application;
49331 use Symfony\Component\Console\Command\Command;
49332 use Symfony\Component\Console\Input\InputArgument;
49333 use Symfony\Component\Console\Input\InputDefinition;
49334 use Symfony\Component\Console\Input\InputOption;
49335
49336
49337
49338
49339
49340
49341
49342
49343 class XmlDescriptor extends Descriptor
49344 {
49345
49346
49347
49348
49349
49350 public function getInputDefinitionDocument(InputDefinition $definition)
49351 {
49352 $dom = new \DOMDocument('1.0', 'UTF-8');
49353 $dom->appendChild($definitionXML = $dom->createElement('definition'));
49354
49355 $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
49356 foreach ($definition->getArguments() as $argument) {
49357 $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
49358 }
49359
49360 $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
49361 foreach ($definition->getOptions() as $option) {
49362 $this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
49363 }
49364
49365 return $dom;
49366 }
49367
49368
49369
49370
49371
49372
49373 public function getCommandDocument(Command $command)
49374 {
49375 $dom = new \DOMDocument('1.0', 'UTF-8');
49376 $dom->appendChild($commandXML = $dom->createElement('command'));
49377
49378 $command->getSynopsis();
49379 $command->mergeApplicationDefinition(false);
49380
49381 $commandXML->setAttribute('id', $command->getName());
49382 $commandXML->setAttribute('name', $command->getName());
49383
49384 $commandXML->appendChild($usagesXML = $dom->createElement('usages'));
49385
49386 foreach (array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()) as $usage) {
49387 $usagesXML->appendChild($dom->createElement('usage', $usage));
49388 }
49389
49390 $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
49391 $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription())));
49392
49393 $commandXML->appendChild($helpXML = $dom->createElement('help'));
49394 $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp())));
49395
49396 $definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition());
49397 $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
49398
49399 return $dom;
49400 }
49401
49402
49403
49404
49405
49406
49407
49408 public function getApplicationDocument(Application $application, $namespace = null)
49409 {
49410 $dom = new \DOMDocument('1.0', 'UTF-8');
49411 $dom->appendChild($rootXml = $dom->createElement('symfony'));
49412
49413 if ($application->getName() !== 'UNKNOWN') {
49414 $rootXml->setAttribute('name', $application->getName());
49415 if ($application->getVersion() !== 'UNKNOWN') {
49416 $rootXml->setAttribute('version', $application->getVersion());
49417 }
49418 }
49419
49420 $rootXml->appendChild($commandsXML = $dom->createElement('commands'));
49421
49422 $description = new ApplicationDescription($application, $namespace);
49423
49424 if ($namespace) {
49425 $commandsXML->setAttribute('namespace', $namespace);
49426 }
49427
49428 foreach ($description->getCommands() as $command) {
49429 $this->appendDocument($commandsXML, $this->getCommandDocument($command));
49430 }
49431
49432 if (!$namespace) {
49433 $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));
49434
49435 foreach ($description->getNamespaces() as $namespaceDescription) {
49436 $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
49437 $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);
49438
49439 foreach ($namespaceDescription['commands'] as $name) {
49440 $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
49441 $commandXML->appendChild($dom->createTextNode($name));
49442 }
49443 }
49444 }
49445
49446 return $dom;
49447 }
49448
49449
49450
49451
49452 protected function describeInputArgument(InputArgument $argument, array $options = array())
49453 {
49454 $this->writeDocument($this->getInputArgumentDocument($argument));
49455 }
49456
49457
49458
49459
49460 protected function describeInputOption(InputOption $option, array $options = array())
49461 {
49462 $this->writeDocument($this->getInputOptionDocument($option));
49463 }
49464
49465
49466
49467
49468 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
49469 {
49470 $this->writeDocument($this->getInputDefinitionDocument($definition));
49471 }
49472
49473
49474
49475
49476 protected function describeCommand(Command $command, array $options = array())
49477 {
49478 $this->writeDocument($this->getCommandDocument($command));
49479 }
49480
49481
49482
49483
49484 protected function describeApplication(Application $application, array $options = array())
49485 {
49486 $this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null));
49487 }
49488
49489
49490
49491
49492
49493
49494
49495 private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
49496 {
49497 foreach ($importedParent->childNodes as $childNode) {
49498 $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
49499 }
49500 }
49501
49502
49503
49504
49505
49506
49507
49508
49509 private function writeDocument(\DOMDocument $dom)
49510 {
49511 $dom->formatOutput = true;
49512 $this->write($dom->saveXML());
49513 }
49514
49515
49516
49517
49518
49519
49520 private function getInputArgumentDocument(InputArgument $argument)
49521 {
49522 $dom = new \DOMDocument('1.0', 'UTF-8');
49523
49524 $dom->appendChild($objectXML = $dom->createElement('argument'));
49525 $objectXML->setAttribute('name', $argument->getName());
49526 $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
49527 $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
49528 $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
49529 $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
49530
49531 $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
49532 $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
49533 foreach ($defaults as $default) {
49534 $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
49535 $defaultXML->appendChild($dom->createTextNode($default));
49536 }
49537
49538 return $dom;
49539 }
49540
49541
49542
49543
49544
49545
49546 private function getInputOptionDocument(InputOption $option)
49547 {
49548 $dom = new \DOMDocument('1.0', 'UTF-8');
49549
49550 $dom->appendChild($objectXML = $dom->createElement('option'));
49551 $objectXML->setAttribute('name', '--'.$option->getName());
49552 $pos = strpos($option->getShortcut(), '|');
49553 if (false !== $pos) {
49554 $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
49555 $objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut())));
49556 } else {
49557 $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
49558 }
49559 $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
49560 $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
49561 $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
49562 $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
49563 $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
49564
49565 if ($option->acceptValue()) {
49566 $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
49567 $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
49568
49569 if (!empty($defaults)) {
49570 foreach ($defaults as $default) {
49571 $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
49572 $defaultXML->appendChild($dom->createTextNode($default));
49573 }
49574 }
49575 }
49576
49577 return $dom;
49578 }
49579 }
49580 <?php
49581
49582
49583
49584
49585
49586
49587
49588
49589
49590
49591 namespace Symfony\Component\Console\Event;
49592
49593
49594
49595
49596
49597
49598 class ConsoleCommandEvent extends ConsoleEvent
49599 {
49600
49601
49602
49603 const RETURN_CODE_DISABLED = 113;
49604
49605
49606
49607
49608
49609
49610 private $commandShouldRun = true;
49611
49612
49613
49614
49615
49616
49617 public function disableCommand()
49618 {
49619 return $this->commandShouldRun = false;
49620 }
49621
49622
49623
49624
49625
49626
49627 public function enableCommand()
49628 {
49629 return $this->commandShouldRun = true;
49630 }
49631
49632
49633
49634
49635
49636
49637 public function commandShouldRun()
49638 {
49639 return $this->commandShouldRun;
49640 }
49641 }
49642 <?php
49643
49644
49645
49646
49647
49648
49649
49650
49651
49652
49653 namespace Symfony\Component\Console\Event;
49654
49655 use Symfony\Component\Console\Command\Command;
49656 use Symfony\Component\Console\Input\InputInterface;
49657 use Symfony\Component\Console\Output\OutputInterface;
49658 use Symfony\Component\EventDispatcher\Event;
49659
49660
49661
49662
49663
49664
49665 class ConsoleEvent extends Event
49666 {
49667 protected $command;
49668
49669 private $input;
49670 private $output;
49671
49672 public function __construct(Command $command, InputInterface $input, OutputInterface $output)
49673 {
49674 $this->command = $command;
49675 $this->input = $input;
49676 $this->output = $output;
49677 }
49678
49679
49680
49681
49682
49683
49684 public function getCommand()
49685 {
49686 return $this->command;
49687 }
49688
49689
49690
49691
49692
49693
49694 public function getInput()
49695 {
49696 return $this->input;
49697 }
49698
49699
49700
49701
49702
49703
49704 public function getOutput()
49705 {
49706 return $this->output;
49707 }
49708 }
49709 <?php
49710
49711
49712
49713
49714
49715
49716
49717
49718
49719
49720 namespace Symfony\Component\Console\Event;
49721
49722 use Symfony\Component\Console\Command\Command;
49723 use Symfony\Component\Console\Input\InputInterface;
49724 use Symfony\Component\Console\Output\OutputInterface;
49725
49726
49727
49728
49729
49730
49731 class ConsoleExceptionEvent extends ConsoleEvent
49732 {
49733 private $exception;
49734 private $exitCode;
49735
49736 public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
49737 {
49738 parent::__construct($command, $input, $output);
49739
49740 $this->setException($exception);
49741 $this->exitCode = (int) $exitCode;
49742 }
49743
49744
49745
49746
49747
49748
49749 public function getException()
49750 {
49751 return $this->exception;
49752 }
49753
49754
49755
49756
49757
49758
49759
49760
49761 public function setException(\Exception $exception)
49762 {
49763 $this->exception = $exception;
49764 }
49765
49766
49767
49768
49769
49770
49771 public function getExitCode()
49772 {
49773 return $this->exitCode;
49774 }
49775 }
49776 <?php
49777
49778
49779
49780
49781
49782
49783
49784
49785
49786
49787 namespace Symfony\Component\Console\Event;
49788
49789 use Symfony\Component\Console\Command\Command;
49790 use Symfony\Component\Console\Input\InputInterface;
49791 use Symfony\Component\Console\Output\OutputInterface;
49792
49793
49794
49795
49796
49797
49798 class ConsoleTerminateEvent extends ConsoleEvent
49799 {
49800
49801
49802
49803
49804
49805 private $exitCode;
49806
49807 public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode)
49808 {
49809 parent::__construct($command, $input, $output);
49810
49811 $this->setExitCode($exitCode);
49812 }
49813
49814
49815
49816
49817
49818
49819 public function setExitCode($exitCode)
49820 {
49821 $this->exitCode = (int) $exitCode;
49822 }
49823
49824
49825
49826
49827
49828
49829 public function getExitCode()
49830 {
49831 return $this->exitCode;
49832 }
49833 }
49834 <?php
49835
49836
49837
49838
49839
49840
49841
49842
49843
49844
49845 namespace Symfony\Component\Console\Exception;
49846
49847
49848
49849
49850
49851
49852 class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
49853 {
49854 private $alternatives;
49855
49856
49857
49858
49859
49860
49861
49862 public function __construct($message, array $alternatives = array(), $code = 0, \Exception $previous = null)
49863 {
49864 parent::__construct($message, $code, $previous);
49865
49866 $this->alternatives = $alternatives;
49867 }
49868
49869
49870
49871
49872 public function getAlternatives()
49873 {
49874 return $this->alternatives;
49875 }
49876 }
49877 <?php
49878
49879
49880
49881
49882
49883
49884
49885
49886
49887
49888 namespace Symfony\Component\Console\Exception;
49889
49890
49891
49892
49893
49894
49895 interface ExceptionInterface
49896 {
49897 }
49898 <?php
49899
49900
49901
49902
49903
49904
49905
49906
49907
49908
49909 namespace Symfony\Component\Console\Exception;
49910
49911
49912
49913
49914 class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
49915 {
49916 }
49917 <?php
49918
49919
49920
49921
49922
49923
49924
49925
49926
49927
49928 namespace Symfony\Component\Console\Exception;
49929
49930
49931
49932
49933
49934
49935 class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface
49936 {
49937 }
49938 <?php
49939
49940
49941
49942
49943
49944
49945
49946
49947
49948
49949 namespace Symfony\Component\Console\Exception;
49950
49951
49952
49953
49954 class LogicException extends \LogicException implements ExceptionInterface
49955 {
49956 }
49957 <?php
49958
49959
49960
49961
49962
49963
49964
49965
49966
49967
49968 namespace Symfony\Component\Console\Exception;
49969
49970
49971
49972
49973 class RuntimeException extends \RuntimeException implements ExceptionInterface
49974 {
49975 }
49976 <?php
49977
49978
49979
49980
49981
49982
49983
49984
49985
49986
49987 namespace Symfony\Component\Console\Formatter;
49988
49989 use Symfony\Component\Console\Exception\InvalidArgumentException;
49990
49991
49992
49993
49994
49995
49996 class OutputFormatter implements OutputFormatterInterface
49997 {
49998 private $decorated;
49999 private $styles = array();
50000 private $styleStack;
50001
50002
50003
50004
50005
50006
50007
50008
50009 public static function escape($text)
50010 {
50011 $text = preg_replace('/([^\\\\]?)</', '$1\\<', $text);
50012
50013 return self::escapeTrailingBackslash($text);
50014 }
50015
50016
50017
50018
50019
50020
50021
50022
50023
50024
50025 public static function escapeTrailingBackslash($text)
50026 {
50027 if ('\\' === substr($text, -1)) {
50028 $len = strlen($text);
50029 $text = rtrim($text, '\\');
50030 $text .= str_repeat('<<', $len - strlen($text));
50031 }
50032
50033 return $text;
50034 }
50035
50036
50037
50038
50039
50040
50041
50042 public function __construct($decorated = false, array $styles = array())
50043 {
50044 $this->decorated = (bool) $decorated;
50045
50046 $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
50047 $this->setStyle('info', new OutputFormatterStyle('green'));
50048 $this->setStyle('comment', new OutputFormatterStyle('yellow'));
50049 $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
50050
50051 foreach ($styles as $name => $style) {
50052 $this->setStyle($name, $style);
50053 }
50054
50055 $this->styleStack = new OutputFormatterStyleStack();
50056 }
50057
50058
50059
50060
50061
50062
50063 public function setDecorated($decorated)
50064 {
50065 $this->decorated = (bool) $decorated;
50066 }
50067
50068
50069
50070
50071
50072
50073 public function isDecorated()
50074 {
50075 return $this->decorated;
50076 }
50077
50078
50079
50080
50081
50082
50083
50084 public function setStyle($name, OutputFormatterStyleInterface $style)
50085 {
50086 $this->styles[strtolower($name)] = $style;
50087 }
50088
50089
50090
50091
50092
50093
50094
50095
50096 public function hasStyle($name)
50097 {
50098 return isset($this->styles[strtolower($name)]);
50099 }
50100
50101
50102
50103
50104
50105
50106
50107
50108
50109
50110 public function getStyle($name)
50111 {
50112 if (!$this->hasStyle($name)) {
50113 throw new InvalidArgumentException(sprintf('Undefined style: %s', $name));
50114 }
50115
50116 return $this->styles[strtolower($name)];
50117 }
50118
50119
50120
50121
50122
50123
50124
50125
50126 public function format($message)
50127 {
50128 $message = (string) $message;
50129 $offset = 0;
50130 $output = '';
50131 $tagRegex = '[a-z][a-z0-9_=;-]*+';
50132 preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
50133 foreach ($matches[0] as $i => $match) {
50134 $pos = $match[1];
50135 $text = $match[0];
50136
50137 if (0 != $pos && '\\' == $message[$pos - 1]) {
50138 continue;
50139 }
50140
50141
50142  $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
50143 $offset = $pos + strlen($text);
50144
50145
50146  if ($open = '/' != $text[1]) {
50147 $tag = $matches[1][$i][0];
50148 } else {
50149 $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';
50150 }
50151
50152 if (!$open && !$tag) {
50153
50154  $this->styleStack->pop();
50155 } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
50156 $output .= $this->applyCurrentStyle($text);
50157 } elseif ($open) {
50158 $this->styleStack->push($style);
50159 } else {
50160 $this->styleStack->pop($style);
50161 }
50162 }
50163
50164 $output .= $this->applyCurrentStyle(substr($message, $offset));
50165
50166 if (false !== strpos($output, '<<')) {
50167 return strtr($output, array('\\<' => '<', '<<' => '\\'));
50168 }
50169
50170 return str_replace('\\<', '<', $output);
50171 }
50172
50173
50174
50175
50176 public function getStyleStack()
50177 {
50178 return $this->styleStack;
50179 }
50180
50181
50182
50183
50184
50185
50186
50187
50188 private function createStyleFromString($string)
50189 {
50190 if (isset($this->styles[$string])) {
50191 return $this->styles[$string];
50192 }
50193
50194 if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
50195 return false;
50196 }
50197
50198 $style = new OutputFormatterStyle();
50199 foreach ($matches as $match) {
50200 array_shift($match);
50201
50202 if ('fg' == $match[0]) {
50203 $style->setForeground($match[1]);
50204 } elseif ('bg' == $match[0]) {
50205 $style->setBackground($match[1]);
50206 } else {
50207 try {
50208 $style->setOption($match[1]);
50209 } catch (\InvalidArgumentException $e) {
50210 return false;
50211 }
50212 }
50213 }
50214
50215 return $style;
50216 }
50217
50218
50219
50220
50221
50222
50223
50224
50225 private function applyCurrentStyle($text)
50226 {
50227 return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
50228 }
50229 }
50230 <?php
50231
50232
50233
50234
50235
50236
50237
50238
50239
50240
50241 namespace Symfony\Component\Console\Formatter;
50242
50243
50244
50245
50246
50247
50248 interface OutputFormatterInterface
50249 {
50250
50251
50252
50253
50254
50255 public function setDecorated($decorated);
50256
50257
50258
50259
50260
50261
50262 public function isDecorated();
50263
50264
50265
50266
50267
50268
50269
50270 public function setStyle($name, OutputFormatterStyleInterface $style);
50271
50272
50273
50274
50275
50276
50277
50278
50279 public function hasStyle($name);
50280
50281
50282
50283
50284
50285
50286
50287
50288 public function getStyle($name);
50289
50290
50291
50292
50293
50294
50295
50296
50297 public function format($message);
50298 }
50299 <?php
50300
50301
50302
50303
50304
50305
50306
50307
50308
50309
50310 namespace Symfony\Component\Console\Formatter;
50311
50312 use Symfony\Component\Console\Exception\InvalidArgumentException;
50313
50314
50315
50316
50317
50318
50319 class OutputFormatterStyle implements OutputFormatterStyleInterface
50320 {
50321 private static $availableForegroundColors = array(
50322 'black' => array('set' => 30, 'unset' => 39),
50323 'red' => array('set' => 31, 'unset' => 39),
50324 'green' => array('set' => 32, 'unset' => 39),
50325 'yellow' => array('set' => 33, 'unset' => 39),
50326 'blue' => array('set' => 34, 'unset' => 39),
50327 'magenta' => array('set' => 35, 'unset' => 39),
50328 'cyan' => array('set' => 36, 'unset' => 39),
50329 'white' => array('set' => 37, 'unset' => 39),
50330 'default' => array('set' => 39, 'unset' => 39),
50331 );
50332 private static $availableBackgroundColors = array(
50333 'black' => array('set' => 40, 'unset' => 49),
50334 'red' => array('set' => 41, 'unset' => 49),
50335 'green' => array('set' => 42, 'unset' => 49),
50336 'yellow' => array('set' => 43, 'unset' => 49),
50337 'blue' => array('set' => 44, 'unset' => 49),
50338 'magenta' => array('set' => 45, 'unset' => 49),
50339 'cyan' => array('set' => 46, 'unset' => 49),
50340 'white' => array('set' => 47, 'unset' => 49),
50341 'default' => array('set' => 49, 'unset' => 49),
50342 );
50343 private static $availableOptions = array(
50344 'bold' => array('set' => 1, 'unset' => 22),
50345 'underscore' => array('set' => 4, 'unset' => 24),
50346 'blink' => array('set' => 5, 'unset' => 25),
50347 'reverse' => array('set' => 7, 'unset' => 27),
50348 'conceal' => array('set' => 8, 'unset' => 28),
50349 );
50350
50351 private $foreground;
50352 private $background;
50353 private $options = array();
50354
50355
50356
50357
50358
50359
50360
50361
50362 public function __construct($foreground = null, $background = null, array $options = array())
50363 {
50364 if (null !== $foreground) {
50365 $this->setForeground($foreground);
50366 }
50367 if (null !== $background) {
50368 $this->setBackground($background);
50369 }
50370 if (count($options)) {
50371 $this->setOptions($options);
50372 }
50373 }
50374
50375
50376
50377
50378
50379
50380
50381
50382 public function setForeground($color = null)
50383 {
50384 if (null === $color) {
50385 $this->foreground = null;
50386
50387 return;
50388 }
50389
50390 if (!isset(static::$availableForegroundColors[$color])) {
50391 throw new InvalidArgumentException(sprintf(
50392 'Invalid foreground color specified: "%s". Expected one of (%s)',
50393 $color,
50394 implode(', ', array_keys(static::$availableForegroundColors))
50395 ));
50396 }
50397
50398 $this->foreground = static::$availableForegroundColors[$color];
50399 }
50400
50401
50402
50403
50404
50405
50406
50407
50408 public function setBackground($color = null)
50409 {
50410 if (null === $color) {
50411 $this->background = null;
50412
50413 return;
50414 }
50415
50416 if (!isset(static::$availableBackgroundColors[$color])) {
50417 throw new InvalidArgumentException(sprintf(
50418 'Invalid background color specified: "%s". Expected one of (%s)',
50419 $color,
50420 implode(', ', array_keys(static::$availableBackgroundColors))
50421 ));
50422 }
50423
50424 $this->background = static::$availableBackgroundColors[$color];
50425 }
50426
50427
50428
50429
50430
50431
50432
50433
50434 public function setOption($option)
50435 {
50436 if (!isset(static::$availableOptions[$option])) {
50437 throw new InvalidArgumentException(sprintf(
50438 'Invalid option specified: "%s". Expected one of (%s)',
50439 $option,
50440 implode(', ', array_keys(static::$availableOptions))
50441 ));
50442 }
50443
50444 if (!in_array(static::$availableOptions[$option], $this->options)) {
50445 $this->options[] = static::$availableOptions[$option];
50446 }
50447 }
50448
50449
50450
50451
50452
50453
50454
50455
50456 public function unsetOption($option)
50457 {
50458 if (!isset(static::$availableOptions[$option])) {
50459 throw new InvalidArgumentException(sprintf(
50460 'Invalid option specified: "%s". Expected one of (%s)',
50461 $option,
50462 implode(', ', array_keys(static::$availableOptions))
50463 ));
50464 }
50465
50466 $pos = array_search(static::$availableOptions[$option], $this->options);
50467 if (false !== $pos) {
50468 unset($this->options[$pos]);
50469 }
50470 }
50471
50472
50473
50474
50475
50476
50477 public function setOptions(array $options)
50478 {
50479 $this->options = array();
50480
50481 foreach ($options as $option) {
50482 $this->setOption($option);
50483 }
50484 }
50485
50486
50487
50488
50489
50490
50491
50492
50493 public function apply($text)
50494 {
50495 $setCodes = array();
50496 $unsetCodes = array();
50497
50498 if (null !== $this->foreground) {
50499 $setCodes[] = $this->foreground['set'];
50500 $unsetCodes[] = $this->foreground['unset'];
50501 }
50502 if (null !== $this->background) {
50503 $setCodes[] = $this->background['set'];
50504 $unsetCodes[] = $this->background['unset'];
50505 }
50506 if (count($this->options)) {
50507 foreach ($this->options as $option) {
50508 $setCodes[] = $option['set'];
50509 $unsetCodes[] = $option['unset'];
50510 }
50511 }
50512
50513 if (0 === count($setCodes)) {
50514 return $text;
50515 }
50516
50517 return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes));
50518 }
50519 }
50520 <?php
50521
50522
50523
50524
50525
50526
50527
50528
50529
50530
50531 namespace Symfony\Component\Console\Formatter;
50532
50533
50534
50535
50536
50537
50538 interface OutputFormatterStyleInterface
50539 {
50540
50541
50542
50543
50544
50545 public function setForeground($color = null);
50546
50547
50548
50549
50550
50551
50552 public function setBackground($color = null);
50553
50554
50555
50556
50557
50558
50559 public function setOption($option);
50560
50561
50562
50563
50564
50565
50566 public function unsetOption($option);
50567
50568
50569
50570
50571
50572
50573 public function setOptions(array $options);
50574
50575
50576
50577
50578
50579
50580
50581
50582 public function apply($text);
50583 }
50584 <?php
50585
50586
50587
50588
50589
50590
50591
50592
50593
50594
50595 namespace Symfony\Component\Console\Formatter;
50596
50597 use Symfony\Component\Console\Exception\InvalidArgumentException;
50598
50599
50600
50601
50602 class OutputFormatterStyleStack
50603 {
50604
50605
50606
50607 private $styles;
50608
50609
50610
50611
50612 private $emptyStyle;
50613
50614
50615
50616
50617
50618
50619 public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
50620 {
50621 $this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle();
50622 $this->reset();
50623 }
50624
50625
50626
50627
50628 public function reset()
50629 {
50630 $this->styles = array();
50631 }
50632
50633
50634
50635
50636
50637
50638 public function push(OutputFormatterStyleInterface $style)
50639 {
50640 $this->styles[] = $style;
50641 }
50642
50643
50644
50645
50646
50647
50648
50649
50650
50651
50652 public function pop(OutputFormatterStyleInterface $style = null)
50653 {
50654 if (empty($this->styles)) {
50655 return $this->emptyStyle;
50656 }
50657
50658 if (null === $style) {
50659 return array_pop($this->styles);
50660 }
50661
50662 foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
50663 if ($style->apply('') === $stackedStyle->apply('')) {
50664 $this->styles = array_slice($this->styles, 0, $index);
50665
50666 return $stackedStyle;
50667 }
50668 }
50669
50670 throw new InvalidArgumentException('Incorrectly nested style tag found.');
50671 }
50672
50673
50674
50675
50676
50677
50678 public function getCurrent()
50679 {
50680 if (empty($this->styles)) {
50681 return $this->emptyStyle;
50682 }
50683
50684 return $this->styles[count($this->styles) - 1];
50685 }
50686
50687
50688
50689
50690
50691
50692 public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
50693 {
50694 $this->emptyStyle = $emptyStyle;
50695
50696 return $this;
50697 }
50698
50699
50700
50701
50702 public function getEmptyStyle()
50703 {
50704 return $this->emptyStyle;
50705 }
50706 }
50707 <?php
50708
50709
50710
50711
50712
50713
50714
50715
50716
50717
50718 namespace Symfony\Component\Console\Helper;
50719
50720
50721
50722
50723
50724
50725
50726
50727 class DebugFormatterHelper extends Helper
50728 {
50729 private $colors = array('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default');
50730 private $started = array();
50731 private $count = -1;
50732
50733
50734
50735
50736
50737
50738
50739
50740
50741
50742 public function start($id, $message, $prefix = 'RUN')
50743 {
50744 $this->started[$id] = array('border' => ++$this->count % count($this->colors));
50745
50746 return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
50747 }
50748
50749
50750
50751
50752
50753
50754
50755
50756
50757
50758
50759
50760 public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR')
50761 {
50762 $message = '';
50763
50764 if ($error) {
50765 if (isset($this->started[$id]['out'])) {
50766 $message .= "\n";
50767 unset($this->started[$id]['out']);
50768 }
50769 if (!isset($this->started[$id]['err'])) {
50770 $message .= sprintf('%s<bg=red;fg=white> %s </> ', $this->getBorder($id), $errorPrefix);
50771 $this->started[$id]['err'] = true;
50772 }
50773
50774 $message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
50775 } else {
50776 if (isset($this->started[$id]['err'])) {
50777 $message .= "\n";
50778 unset($this->started[$id]['err']);
50779 }
50780 if (!isset($this->started[$id]['out'])) {
50781 $message .= sprintf('%s<bg=green;fg=white> %s </> ', $this->getBorder($id), $prefix);
50782 $this->started[$id]['out'] = true;
50783 }
50784
50785 $message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
50786 }
50787
50788 return $message;
50789 }
50790
50791
50792
50793
50794
50795
50796
50797
50798
50799
50800
50801 public function stop($id, $message, $successful, $prefix = 'RES')
50802 {
50803 $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
50804
50805 if ($successful) {
50806 return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
50807 }
50808
50809 $message = sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
50810
50811 unset($this->started[$id]['out'], $this->started[$id]['err']);
50812
50813 return $message;
50814 }
50815
50816
50817
50818
50819
50820
50821 private function getBorder($id)
50822 {
50823 return sprintf('<bg=%s> </>', $this->colors[$this->started[$id]['border']]);
50824 }
50825
50826
50827
50828
50829 public function getName()
50830 {
50831 return 'debug_formatter';
50832 }
50833 }
50834 <?php
50835
50836
50837
50838
50839
50840
50841
50842
50843
50844
50845 namespace Symfony\Component\Console\Helper;
50846
50847 use Symfony\Component\Console\Descriptor\DescriptorInterface;
50848 use Symfony\Component\Console\Descriptor\JsonDescriptor;
50849 use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
50850 use Symfony\Component\Console\Descriptor\TextDescriptor;
50851 use Symfony\Component\Console\Descriptor\XmlDescriptor;
50852 use Symfony\Component\Console\Output\OutputInterface;
50853 use Symfony\Component\Console\Exception\InvalidArgumentException;
50854
50855
50856
50857
50858
50859
50860 class DescriptorHelper extends Helper
50861 {
50862
50863
50864
50865 private $descriptors = array();
50866
50867
50868
50869
50870 public function __construct()
50871 {
50872 $this
50873 ->register('txt', new TextDescriptor())
50874 ->register('xml', new XmlDescriptor())
50875 ->register('json', new JsonDescriptor())
50876 ->register('md', new MarkdownDescriptor())
50877 ;
50878 }
50879
50880
50881
50882
50883
50884
50885
50886
50887
50888
50889
50890
50891
50892
50893 public function describe(OutputInterface $output, $object, array $options = array())
50894 {
50895 $options = array_merge(array(
50896 'raw_text' => false,
50897 'format' => 'txt',
50898 ), $options);
50899
50900 if (!isset($this->descriptors[$options['format']])) {
50901 throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));
50902 }
50903
50904 $descriptor = $this->descriptors[$options['format']];
50905 $descriptor->describe($output, $object, $options);
50906 }
50907
50908
50909
50910
50911
50912
50913
50914
50915
50916 public function register($format, DescriptorInterface $descriptor)
50917 {
50918 $this->descriptors[$format] = $descriptor;
50919
50920 return $this;
50921 }
50922
50923
50924
50925
50926 public function getName()
50927 {
50928 return 'descriptor';
50929 }
50930 }
50931 <?php
50932
50933
50934
50935
50936
50937
50938
50939
50940
50941
50942 namespace Symfony\Component\Console\Helper;
50943
50944 use Symfony\Component\Console\Exception\InvalidArgumentException;
50945 use Symfony\Component\Console\Exception\RuntimeException;
50946 use Symfony\Component\Console\Output\ConsoleOutputInterface;
50947 use Symfony\Component\Console\Output\OutputInterface;
50948 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
50949
50950
50951
50952
50953
50954
50955
50956
50957
50958 class DialogHelper extends InputAwareHelper
50959 {
50960 private $inputStream;
50961 private static $shell;
50962 private static $stty;
50963
50964 public function __construct($triggerDeprecationError = true)
50965 {
50966 if ($triggerDeprecationError) {
50967 @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
50968 }
50969 }
50970
50971
50972
50973
50974
50975
50976
50977
50978
50979
50980
50981
50982
50983
50984
50985
50986 public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
50987 {
50988 if ($output instanceof ConsoleOutputInterface) {
50989 $output = $output->getErrorOutput();
50990 }
50991
50992 $width = max(array_map('strlen', array_keys($choices)));
50993
50994 $messages = (array) $question;
50995 foreach ($choices as $key => $value) {
50996 $messages[] = sprintf("  [<info>%-{$width}s</info>] %s", $key, $value);
50997 }
50998
50999 $output->writeln($messages);
51000
51001 $result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) {
51002
51003  $selectedChoices = str_replace(' ', '', $picked);
51004
51005 if ($multiselect) {
51006
51007  if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
51008 throw new InvalidArgumentException(sprintf($errorMessage, $picked));
51009 }
51010 $selectedChoices = explode(',', $selectedChoices);
51011 } else {
51012 $selectedChoices = array($picked);
51013 }
51014
51015 $multiselectChoices = array();
51016
51017 foreach ($selectedChoices as $value) {
51018 if (empty($choices[$value])) {
51019 throw new InvalidArgumentException(sprintf($errorMessage, $value));
51020 }
51021 $multiselectChoices[] = $value;
51022 }
51023
51024 if ($multiselect) {
51025 return $multiselectChoices;
51026 }
51027
51028 return $picked;
51029 }, $attempts, $default);
51030
51031 return $result;
51032 }
51033
51034
51035
51036
51037
51038
51039
51040
51041
51042
51043
51044
51045
51046 public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null)
51047 {
51048 if ($this->input && !$this->input->isInteractive()) {
51049 return $default;
51050 }
51051
51052 if ($output instanceof ConsoleOutputInterface) {
51053 $output = $output->getErrorOutput();
51054 }
51055
51056 $output->write($question);
51057
51058 $inputStream = $this->inputStream ?: STDIN;
51059
51060 if (null === $autocomplete || !$this->hasSttyAvailable()) {
51061 $ret = fgets($inputStream, 4096);
51062 if (false === $ret) {
51063 throw new RuntimeException('Aborted');
51064 }
51065 $ret = trim($ret);
51066 } else {
51067 $ret = '';
51068
51069 $i = 0;
51070 $ofs = -1;
51071 $matches = $autocomplete;
51072 $numMatches = count($matches);
51073
51074 $sttyMode = shell_exec('stty -g');
51075
51076
51077  shell_exec('stty -icanon -echo');
51078
51079
51080  $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
51081
51082
51083  while (!feof($inputStream)) {
51084 $c = fread($inputStream, 1);
51085
51086
51087  if ("\177" === $c) {
51088 if (0 === $numMatches && 0 !== $i) {
51089 --$i;
51090
51091  $output->write("\033[1D");
51092 }
51093
51094 if ($i === 0) {
51095 $ofs = -1;
51096 $matches = $autocomplete;
51097 $numMatches = count($matches);
51098 } else {
51099 $numMatches = 0;
51100 }
51101
51102
51103  $ret = substr($ret, 0, $i);
51104 } elseif ("\033" === $c) {
51105
51106  $c .= fread($inputStream, 2);
51107
51108
51109  if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
51110 if ('A' === $c[2] && -1 === $ofs) {
51111 $ofs = 0;
51112 }
51113
51114 if (0 === $numMatches) {
51115 continue;
51116 }
51117
51118 $ofs += ('A' === $c[2]) ? -1 : 1;
51119 $ofs = ($numMatches + $ofs) % $numMatches;
51120 }
51121 } elseif (ord($c) < 32) {
51122 if ("\t" === $c || "\n" === $c) {
51123 if ($numMatches > 0 && -1 !== $ofs) {
51124 $ret = $matches[$ofs];
51125
51126  $output->write(substr($ret, $i));
51127 $i = strlen($ret);
51128 }
51129
51130 if ("\n" === $c) {
51131 $output->write($c);
51132 break;
51133 }
51134
51135 $numMatches = 0;
51136 }
51137
51138 continue;
51139 } else {
51140 $output->write($c);
51141 $ret .= $c;
51142 ++$i;
51143
51144 $numMatches = 0;
51145 $ofs = 0;
51146
51147 foreach ($autocomplete as $value) {
51148
51149  if (0 === strpos($value, $ret) && $i !== strlen($value)) {
51150 $matches[$numMatches++] = $value;
51151 }
51152 }
51153 }
51154
51155
51156  $output->write("\033[K");
51157
51158 if ($numMatches > 0 && -1 !== $ofs) {
51159
51160  $output->write("\0337");
51161
51162  $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
51163
51164  $output->write("\0338");
51165 }
51166 }
51167
51168
51169  shell_exec(sprintf('stty %s', $sttyMode));
51170 }
51171
51172 return strlen($ret) > 0 ? $ret : $default;
51173 }
51174
51175
51176
51177
51178
51179
51180
51181
51182
51183
51184
51185
51186 public function askConfirmation(OutputInterface $output, $question, $default = true)
51187 {
51188 $answer = 'z';
51189 while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
51190 $answer = $this->ask($output, $question);
51191 }
51192
51193 if (false === $default) {
51194 return $answer && 'y' == strtolower($answer[0]);
51195 }
51196
51197 return !$answer || 'y' == strtolower($answer[0]);
51198 }
51199
51200
51201
51202
51203
51204
51205
51206
51207
51208
51209
51210
51211 public function askHiddenResponse(OutputInterface $output, $question, $fallback = true)
51212 {
51213 if ($output instanceof ConsoleOutputInterface) {
51214 $output = $output->getErrorOutput();
51215 }
51216
51217 if ('\\' === DIRECTORY_SEPARATOR) {
51218 $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
51219
51220
51221  if ('phar:' === substr(__FILE__, 0, 5)) {
51222 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
51223 copy($exe, $tmpExe);
51224 $exe = $tmpExe;
51225 }
51226
51227 $output->write($question);
51228 $value = rtrim(shell_exec($exe));
51229 $output->writeln('');
51230
51231 if (isset($tmpExe)) {
51232 unlink($tmpExe);
51233 }
51234
51235 return $value;
51236 }
51237
51238 if ($this->hasSttyAvailable()) {
51239 $output->write($question);
51240
51241 $sttyMode = shell_exec('stty -g');
51242
51243 shell_exec('stty -echo');
51244 $value = fgets($this->inputStream ?: STDIN, 4096);
51245 shell_exec(sprintf('stty %s', $sttyMode));
51246
51247 if (false === $value) {
51248 throw new RuntimeException('Aborted');
51249 }
51250
51251 $value = trim($value);
51252 $output->writeln('');
51253
51254 return $value;
51255 }
51256
51257 if (false !== $shell = $this->getShell()) {
51258 $output->write($question);
51259 $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
51260 $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
51261 $value = rtrim(shell_exec($command));
51262 $output->writeln('');
51263
51264 return $value;
51265 }
51266
51267 if ($fallback) {
51268 return $this->ask($output, $question);
51269 }
51270
51271 throw new RuntimeException('Unable to hide the response');
51272 }
51273
51274
51275
51276
51277
51278
51279
51280
51281
51282
51283
51284
51285
51286
51287
51288
51289
51290
51291
51292 public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null)
51293 {
51294 $that = $this;
51295
51296 $interviewer = function () use ($output, $question, $default, $autocomplete, $that) {
51297 return $that->ask($output, $question, $default, $autocomplete);
51298 };
51299
51300 return $this->validateAttempts($interviewer, $output, $validator, $attempts);
51301 }
51302
51303
51304
51305
51306
51307
51308
51309
51310
51311
51312
51313
51314
51315
51316
51317
51318
51319
51320
51321 public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true)
51322 {
51323 $that = $this;
51324
51325 $interviewer = function () use ($output, $question, $fallback, $that) {
51326 return $that->askHiddenResponse($output, $question, $fallback);
51327 };
51328
51329 return $this->validateAttempts($interviewer, $output, $validator, $attempts);
51330 }
51331
51332
51333
51334
51335
51336
51337
51338
51339 public function setInputStream($stream)
51340 {
51341 $this->inputStream = $stream;
51342 }
51343
51344
51345
51346
51347
51348
51349 public function getInputStream()
51350 {
51351 return $this->inputStream;
51352 }
51353
51354
51355
51356
51357 public function getName()
51358 {
51359 return 'dialog';
51360 }
51361
51362
51363
51364
51365
51366
51367 private function getShell()
51368 {
51369 if (null !== self::$shell) {
51370 return self::$shell;
51371 }
51372
51373 self::$shell = false;
51374
51375 if (file_exists('/usr/bin/env')) {
51376
51377  $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
51378 foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
51379 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
51380 self::$shell = $sh;
51381 break;
51382 }
51383 }
51384 }
51385
51386 return self::$shell;
51387 }
51388
51389 private function hasSttyAvailable()
51390 {
51391 if (null !== self::$stty) {
51392 return self::$stty;
51393 }
51394
51395 exec('stty 2>&1', $output, $exitcode);
51396
51397 return self::$stty = $exitcode === 0;
51398 }
51399
51400
51401
51402
51403
51404
51405
51406
51407
51408
51409
51410
51411
51412 private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts)
51413 {
51414 if ($output instanceof ConsoleOutputInterface) {
51415 $output = $output->getErrorOutput();
51416 }
51417
51418 $e = null;
51419 while (false === $attempts || $attempts--) {
51420 if (null !== $e) {
51421 $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($e->getMessage(), 'error'));
51422 }
51423
51424 try {
51425 return call_user_func($validator, $interviewer());
51426 } catch (\Exception $e) {
51427 }
51428 }
51429
51430 throw $e;
51431 }
51432 }
51433 <?php
51434
51435
51436
51437
51438
51439
51440
51441
51442
51443
51444 namespace Symfony\Component\Console\Helper;
51445
51446 use Symfony\Component\Console\Formatter\OutputFormatter;
51447
51448
51449
51450
51451
51452
51453 class FormatterHelper extends Helper
51454 {
51455
51456
51457
51458
51459
51460
51461
51462
51463
51464 public function formatSection($section, $message, $style = 'info')
51465 {
51466 return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
51467 }
51468
51469
51470
51471
51472
51473
51474
51475
51476
51477
51478 public function formatBlock($messages, $style, $large = false)
51479 {
51480 if (!is_array($messages)) {
51481 $messages = array($messages);
51482 }
51483
51484 $len = 0;
51485 $lines = array();
51486 foreach ($messages as $message) {
51487 $message = OutputFormatter::escape($message);
51488 $lines[] = sprintf($large ? '  %s  ' : ' %s ', $message);
51489 $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
51490 }
51491
51492 $messages = $large ? array(str_repeat(' ', $len)) : array();
51493 for ($i = 0; isset($lines[$i]); ++$i) {
51494 $messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
51495 }
51496 if ($large) {
51497 $messages[] = str_repeat(' ', $len);
51498 }
51499
51500 for ($i = 0; isset($messages[$i]); ++$i) {
51501 $messages[$i] = sprintf('<%s>%s</%s>', $style, $messages[$i], $style);
51502 }
51503
51504 return implode("\n", $messages);
51505 }
51506
51507
51508
51509
51510 public function getName()
51511 {
51512 return 'formatter';
51513 }
51514 }
51515 <?php
51516
51517
51518
51519
51520
51521
51522
51523
51524
51525
51526 namespace Symfony\Component\Console\Helper;
51527
51528 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
51529
51530
51531
51532
51533
51534
51535 abstract class Helper implements HelperInterface
51536 {
51537 protected $helperSet = null;
51538
51539
51540
51541
51542
51543
51544 public function setHelperSet(HelperSet $helperSet = null)
51545 {
51546 $this->helperSet = $helperSet;
51547 }
51548
51549
51550
51551
51552
51553
51554 public function getHelperSet()
51555 {
51556 return $this->helperSet;
51557 }
51558
51559
51560
51561
51562
51563
51564
51565
51566 public static function strlen($string)
51567 {
51568 if (false === $encoding = mb_detect_encoding($string, null, true)) {
51569 return strlen($string);
51570 }
51571
51572 return mb_strwidth($string, $encoding);
51573 }
51574
51575 public static function formatTime($secs)
51576 {
51577 static $timeFormats = array(
51578 array(0, '< 1 sec'),
51579 array(1, '1 sec'),
51580 array(2, 'secs', 1),
51581 array(60, '1 min'),
51582 array(120, 'mins', 60),
51583 array(3600, '1 hr'),
51584 array(7200, 'hrs', 3600),
51585 array(86400, '1 day'),
51586 array(172800, 'days', 86400),
51587 );
51588
51589 foreach ($timeFormats as $index => $format) {
51590 if ($secs >= $format[0]) {
51591 if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
51592 || $index == count($timeFormats) - 1
51593 ) {
51594 if (2 == count($format)) {
51595 return $format[1];
51596 }
51597
51598 return floor($secs / $format[2]).' '.$format[1];
51599 }
51600 }
51601 }
51602 }
51603
51604 public static function formatMemory($memory)
51605 {
51606 if ($memory >= 1024 * 1024 * 1024) {
51607 return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
51608 }
51609
51610 if ($memory >= 1024 * 1024) {
51611 return sprintf('%.1f MiB', $memory / 1024 / 1024);
51612 }
51613
51614 if ($memory >= 1024) {
51615 return sprintf('%d KiB', $memory / 1024);
51616 }
51617
51618 return sprintf('%d B', $memory);
51619 }
51620
51621 public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string)
51622 {
51623 $isDecorated = $formatter->isDecorated();
51624 $formatter->setDecorated(false);
51625
51626  $string = $formatter->format($string);
51627
51628  $string = preg_replace("/\033\[[^m]*m/", '', $string);
51629 $formatter->setDecorated($isDecorated);
51630
51631 return self::strlen($string);
51632 }
51633 }
51634 <?php
51635
51636
51637
51638
51639
51640
51641
51642
51643
51644
51645 namespace Symfony\Component\Console\Helper;
51646
51647
51648
51649
51650
51651
51652 interface HelperInterface
51653 {
51654
51655
51656
51657
51658
51659 public function setHelperSet(HelperSet $helperSet = null);
51660
51661
51662
51663
51664
51665
51666 public function getHelperSet();
51667
51668
51669
51670
51671
51672
51673 public function getName();
51674 }
51675 <?php
51676
51677
51678
51679
51680
51681
51682
51683
51684
51685
51686 namespace Symfony\Component\Console\Helper;
51687
51688 use Symfony\Component\Console\Command\Command;
51689 use Symfony\Component\Console\Exception\InvalidArgumentException;
51690
51691
51692
51693
51694
51695
51696 class HelperSet implements \IteratorAggregate
51697 {
51698
51699
51700
51701 private $helpers = array();
51702 private $command;
51703
51704
51705
51706
51707
51708
51709 public function __construct(array $helpers = array())
51710 {
51711 foreach ($helpers as $alias => $helper) {
51712 $this->set($helper, is_int($alias) ? null : $alias);
51713 }
51714 }
51715
51716
51717
51718
51719
51720
51721
51722 public function set(HelperInterface $helper, $alias = null)
51723 {
51724 $this->helpers[$helper->getName()] = $helper;
51725 if (null !== $alias) {
51726 $this->helpers[$alias] = $helper;
51727 }
51728
51729 $helper->setHelperSet($this);
51730 }
51731
51732
51733
51734
51735
51736
51737
51738
51739 public function has($name)
51740 {
51741 return isset($this->helpers[$name]);
51742 }
51743
51744
51745
51746
51747
51748
51749
51750
51751
51752
51753 public function get($name)
51754 {
51755 if (!$this->has($name)) {
51756 throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
51757 }
51758
51759 if ('dialog' === $name && $this->helpers[$name] instanceof DialogHelper) {
51760 @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
51761 } elseif ('progress' === $name && $this->helpers[$name] instanceof ProgressHelper) {
51762 @trigger_error('"Symfony\Component\Console\Helper\ProgressHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\ProgressBar" instead.', E_USER_DEPRECATED);
51763 } elseif ('table' === $name && $this->helpers[$name] instanceof TableHelper) {
51764 @trigger_error('"Symfony\Component\Console\Helper\TableHelper" is deprecated since version 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\Table" instead.', E_USER_DEPRECATED);
51765 }
51766
51767 return $this->helpers[$name];
51768 }
51769
51770
51771
51772
51773
51774
51775 public function setCommand(Command $command = null)
51776 {
51777 $this->command = $command;
51778 }
51779
51780
51781
51782
51783
51784
51785 public function getCommand()
51786 {
51787 return $this->command;
51788 }
51789
51790
51791
51792
51793 public function getIterator()
51794 {
51795 return new \ArrayIterator($this->helpers);
51796 }
51797 }
51798 <?php
51799
51800
51801
51802
51803
51804
51805
51806
51807
51808
51809 namespace Symfony\Component\Console\Helper;
51810
51811 use Symfony\Component\Console\Input\InputInterface;
51812 use Symfony\Component\Console\Input\InputAwareInterface;
51813
51814
51815
51816
51817
51818
51819 abstract class InputAwareHelper extends Helper implements InputAwareInterface
51820 {
51821 protected $input;
51822
51823
51824
51825
51826 public function setInput(InputInterface $input)
51827 {
51828 $this->input = $input;
51829 }
51830 }
51831 <?php
51832
51833
51834
51835
51836
51837
51838
51839
51840
51841
51842 namespace Symfony\Component\Console\Helper;
51843
51844 use Symfony\Component\Console\Output\ConsoleOutputInterface;
51845 use Symfony\Component\Console\Output\OutputInterface;
51846 use Symfony\Component\Process\Exception\ProcessFailedException;
51847 use Symfony\Component\Process\Process;
51848 use Symfony\Component\Process\ProcessBuilder;
51849
51850
51851
51852
51853
51854
51855 class ProcessHelper extends Helper
51856 {
51857
51858
51859
51860
51861
51862
51863
51864
51865
51866
51867
51868
51869 public function run(OutputInterface $output, $cmd, $error = null, $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE)
51870 {
51871 if ($output instanceof ConsoleOutputInterface) {
51872 $output = $output->getErrorOutput();
51873 }
51874
51875 $formatter = $this->getHelperSet()->get('debug_formatter');
51876
51877 if (is_array($cmd)) {
51878 $process = ProcessBuilder::create($cmd)->getProcess();
51879 } elseif ($cmd instanceof Process) {
51880 $process = $cmd;
51881 } else {
51882 $process = new Process($cmd);
51883 }
51884
51885 if ($verbosity <= $output->getVerbosity()) {
51886 $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine())));
51887 }
51888
51889 if ($output->isDebug()) {
51890 $callback = $this->wrapCallback($output, $process, $callback);
51891 }
51892
51893 $process->run($callback);
51894
51895 if ($verbosity <= $output->getVerbosity()) {
51896 $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());
51897 $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful()));
51898 }
51899
51900 if (!$process->isSuccessful() && null !== $error) {
51901 $output->writeln(sprintf('<error>%s</error>', $this->escapeString($error)));
51902 }
51903
51904 return $process;
51905 }
51906
51907
51908
51909
51910
51911
51912
51913
51914
51915
51916
51917
51918
51919
51920
51921
51922
51923
51924
51925 public function mustRun(OutputInterface $output, $cmd, $error = null, $callback = null)
51926 {
51927 $process = $this->run($output, $cmd, $error, $callback);
51928
51929 if (!$process->isSuccessful()) {
51930 throw new ProcessFailedException($process);
51931 }
51932
51933 return $process;
51934 }
51935
51936
51937
51938
51939
51940
51941
51942
51943
51944
51945 public function wrapCallback(OutputInterface $output, Process $process, $callback = null)
51946 {
51947 if ($output instanceof ConsoleOutputInterface) {
51948 $output = $output->getErrorOutput();
51949 }
51950
51951 $formatter = $this->getHelperSet()->get('debug_formatter');
51952
51953 $that = $this;
51954
51955 return function ($type, $buffer) use ($output, $process, $callback, $formatter, $that) {
51956 $output->write($formatter->progress(spl_object_hash($process), $that->escapeString($buffer), Process::ERR === $type));
51957
51958 if (null !== $callback) {
51959 call_user_func($callback, $type, $buffer);
51960 }
51961 };
51962 }
51963
51964
51965
51966
51967
51968
51969 public function escapeString($str)
51970 {
51971 return str_replace('<', '\\<', $str);
51972 }
51973
51974
51975
51976
51977 public function getName()
51978 {
51979 return 'process';
51980 }
51981 }
51982 <?php
51983
51984
51985
51986
51987
51988
51989
51990
51991
51992
51993 namespace Symfony\Component\Console\Helper;
51994
51995 use Symfony\Component\Console\Output\ConsoleOutputInterface;
51996 use Symfony\Component\Console\Output\OutputInterface;
51997 use Symfony\Component\Console\Exception\LogicException;
51998
51999
52000
52001
52002
52003
52004
52005 class ProgressBar
52006 {
52007
52008  private $barWidth = 28;
52009 private $barChar;
52010 private $emptyBarChar = '-';
52011 private $progressChar = '>';
52012 private $format;
52013 private $internalFormat;
52014 private $redrawFreq = 1;
52015
52016
52017
52018
52019 private $output;
52020 private $step = 0;
52021 private $max;
52022 private $startTime;
52023 private $stepWidth;
52024 private $percent = 0.0;
52025 private $formatLineCount;
52026 private $messages = array();
52027 private $overwrite = true;
52028 private $firstRun = true;
52029
52030 private static $formatters;
52031 private static $formats;
52032
52033
52034
52035
52036
52037
52038
52039 public function __construct(OutputInterface $output, $max = 0)
52040 {
52041 if ($output instanceof ConsoleOutputInterface) {
52042 $output = $output->getErrorOutput();
52043 }
52044
52045 $this->output = $output;
52046 $this->setMaxSteps($max);
52047
52048 if (!$this->output->isDecorated()) {
52049
52050  $this->overwrite = false;
52051
52052
52053  $this->setRedrawFrequency($max / 10);
52054 }
52055
52056 $this->startTime = time();
52057 }
52058
52059
52060
52061
52062
52063
52064
52065
52066
52067 public static function setPlaceholderFormatterDefinition($name, $callable)
52068 {
52069 if (!self::$formatters) {
52070 self::$formatters = self::initPlaceholderFormatters();
52071 }
52072
52073 self::$formatters[$name] = $callable;
52074 }
52075
52076
52077
52078
52079
52080
52081
52082
52083 public static function getPlaceholderFormatterDefinition($name)
52084 {
52085 if (!self::$formatters) {
52086 self::$formatters = self::initPlaceholderFormatters();
52087 }
52088
52089 return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
52090 }
52091
52092
52093
52094
52095
52096
52097
52098
52099
52100 public static function setFormatDefinition($name, $format)
52101 {
52102 if (!self::$formats) {
52103 self::$formats = self::initFormats();
52104 }
52105
52106 self::$formats[$name] = $format;
52107 }
52108
52109
52110
52111
52112
52113
52114
52115
52116 public static function getFormatDefinition($name)
52117 {
52118 if (!self::$formats) {
52119 self::$formats = self::initFormats();
52120 }
52121
52122 return isset(self::$formats[$name]) ? self::$formats[$name] : null;
52123 }
52124
52125
52126
52127
52128
52129
52130
52131
52132
52133
52134
52135 public function setMessage($message, $name = 'message')
52136 {
52137 $this->messages[$name] = $message;
52138 }
52139
52140 public function getMessage($name = 'message')
52141 {
52142 return $this->messages[$name];
52143 }
52144
52145
52146
52147
52148
52149
52150 public function getStartTime()
52151 {
52152 return $this->startTime;
52153 }
52154
52155
52156
52157
52158
52159
52160 public function getMaxSteps()
52161 {
52162 return $this->max;
52163 }
52164
52165
52166
52167
52168
52169
52170
52171
52172 public function getStep()
52173 {
52174 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the getProgress() method instead.', E_USER_DEPRECATED);
52175
52176 return $this->getProgress();
52177 }
52178
52179
52180
52181
52182
52183
52184 public function getProgress()
52185 {
52186 return $this->step;
52187 }
52188
52189
52190
52191
52192
52193
52194
52195
52196 public function getStepWidth()
52197 {
52198 return $this->stepWidth;
52199 }
52200
52201
52202
52203
52204
52205
52206 public function getProgressPercent()
52207 {
52208 return $this->percent;
52209 }
52210
52211
52212
52213
52214
52215
52216 public function setBarWidth($size)
52217 {
52218 $this->barWidth = (int) $size;
52219 }
52220
52221
52222
52223
52224
52225
52226 public function getBarWidth()
52227 {
52228 return $this->barWidth;
52229 }
52230
52231
52232
52233
52234
52235
52236 public function setBarCharacter($char)
52237 {
52238 $this->barChar = $char;
52239 }
52240
52241
52242
52243
52244
52245
52246 public function getBarCharacter()
52247 {
52248 if (null === $this->barChar) {
52249 return $this->max ? '=' : $this->emptyBarChar;
52250 }
52251
52252 return $this->barChar;
52253 }
52254
52255
52256
52257
52258
52259
52260 public function setEmptyBarCharacter($char)
52261 {
52262 $this->emptyBarChar = $char;
52263 }
52264
52265
52266
52267
52268
52269
52270 public function getEmptyBarCharacter()
52271 {
52272 return $this->emptyBarChar;
52273 }
52274
52275
52276
52277
52278
52279
52280 public function setProgressCharacter($char)
52281 {
52282 $this->progressChar = $char;
52283 }
52284
52285
52286
52287
52288
52289
52290 public function getProgressCharacter()
52291 {
52292 return $this->progressChar;
52293 }
52294
52295
52296
52297
52298
52299
52300 public function setFormat($format)
52301 {
52302 $this->format = null;
52303 $this->internalFormat = $format;
52304 }
52305
52306
52307
52308
52309
52310
52311 public function setRedrawFrequency($freq)
52312 {
52313 $this->redrawFreq = max((int) $freq, 1);
52314 }
52315
52316
52317
52318
52319
52320
52321 public function start($max = null)
52322 {
52323 $this->startTime = time();
52324 $this->step = 0;
52325 $this->percent = 0.0;
52326
52327 if (null !== $max) {
52328 $this->setMaxSteps($max);
52329 }
52330
52331 $this->display();
52332 }
52333
52334
52335
52336
52337
52338
52339
52340
52341 public function advance($step = 1)
52342 {
52343 $this->setProgress($this->step + $step);
52344 }
52345
52346
52347
52348
52349
52350
52351
52352
52353
52354
52355 public function setCurrent($step)
52356 {
52357 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setProgress() method instead.', E_USER_DEPRECATED);
52358
52359 $this->setProgress($step);
52360 }
52361
52362
52363
52364
52365
52366
52367 public function setOverwrite($overwrite)
52368 {
52369 $this->overwrite = (bool) $overwrite;
52370 }
52371
52372
52373
52374
52375
52376
52377
52378
52379 public function setProgress($step)
52380 {
52381 $step = (int) $step;
52382 if ($step < $this->step) {
52383 throw new LogicException('You can\'t regress the progress bar.');
52384 }
52385
52386 if ($this->max && $step > $this->max) {
52387 $this->max = $step;
52388 }
52389
52390 $prevPeriod = (int) ($this->step / $this->redrawFreq);
52391 $currPeriod = (int) ($step / $this->redrawFreq);
52392 $this->step = $step;
52393 $this->percent = $this->max ? (float) $this->step / $this->max : 0;
52394 if ($prevPeriod !== $currPeriod || $this->max === $step) {
52395 $this->display();
52396 }
52397 }
52398
52399
52400
52401
52402 public function finish()
52403 {
52404 if (!$this->max) {
52405 $this->max = $this->step;
52406 }
52407
52408 if ($this->step === $this->max && !$this->overwrite) {
52409
52410  return;
52411 }
52412
52413 $this->setProgress($this->max);
52414 }
52415
52416
52417
52418
52419 public function display()
52420 {
52421 if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
52422 return;
52423 }
52424
52425 if (null === $this->format) {
52426 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
52427 }
52428
52429
52430  $self = $this;
52431 $output = $this->output;
52432 $messages = $this->messages;
52433 $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) {
52434 if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
52435 $text = call_user_func($formatter, $self, $output);
52436 } elseif (isset($messages[$matches[1]])) {
52437 $text = $messages[$matches[1]];
52438 } else {
52439 return $matches[0];
52440 }
52441
52442 if (isset($matches[2])) {
52443 $text = sprintf('%'.$matches[2], $text);
52444 }
52445
52446 return $text;
52447 }, $this->format));
52448 }
52449
52450
52451
52452
52453
52454
52455
52456
52457 public function clear()
52458 {
52459 if (!$this->overwrite) {
52460 return;
52461 }
52462
52463 if (null === $this->format) {
52464 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
52465 }
52466
52467 $this->overwrite('');
52468 }
52469
52470
52471
52472
52473
52474
52475 private function setRealFormat($format)
52476 {
52477
52478  if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
52479 $this->format = self::getFormatDefinition($format.'_nomax');
52480 } elseif (null !== self::getFormatDefinition($format)) {
52481 $this->format = self::getFormatDefinition($format);
52482 } else {
52483 $this->format = $format;
52484 }
52485
52486 $this->formatLineCount = substr_count($this->format, "\n");
52487 }
52488
52489
52490
52491
52492
52493
52494 private function setMaxSteps($max)
52495 {
52496 $this->max = max(0, (int) $max);
52497 $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
52498 }
52499
52500
52501
52502
52503
52504
52505 private function overwrite($message)
52506 {
52507 if ($this->overwrite) {
52508 if (!$this->firstRun) {
52509
52510  $this->output->write("\x0D");
52511
52512
52513  $this->output->write("\x1B[2K");
52514
52515
52516  if ($this->formatLineCount > 0) {
52517 $this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
52518 }
52519 }
52520 } elseif ($this->step > 0) {
52521 $this->output->writeln('');
52522 }
52523
52524 $this->firstRun = false;
52525
52526 $this->output->write($message);
52527 }
52528
52529 private function determineBestFormat()
52530 {
52531 switch ($this->output->getVerbosity()) {
52532
52533  case OutputInterface::VERBOSITY_VERBOSE:
52534 return $this->max ? 'verbose' : 'verbose_nomax';
52535 case OutputInterface::VERBOSITY_VERY_VERBOSE:
52536 return $this->max ? 'very_verbose' : 'very_verbose_nomax';
52537 case OutputInterface::VERBOSITY_DEBUG:
52538 return $this->max ? 'debug' : 'debug_nomax';
52539 default:
52540 return $this->max ? 'normal' : 'normal_nomax';
52541 }
52542 }
52543
52544 private static function initPlaceholderFormatters()
52545 {
52546 return array(
52547 'bar' => function (ProgressBar $bar, OutputInterface $output) {
52548 $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
52549 $display = str_repeat($bar->getBarCharacter(), $completeBars);
52550 if ($completeBars < $bar->getBarWidth()) {
52551 $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
52552 $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
52553 }
52554
52555 return $display;
52556 },
52557 'elapsed' => function (ProgressBar $bar) {
52558 return Helper::formatTime(time() - $bar->getStartTime());
52559 },
52560 'remaining' => function (ProgressBar $bar) {
52561 if (!$bar->getMaxSteps()) {
52562 throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
52563 }
52564
52565 if (!$bar->getProgress()) {
52566 $remaining = 0;
52567 } else {
52568 $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
52569 }
52570
52571 return Helper::formatTime($remaining);
52572 },
52573 'estimated' => function (ProgressBar $bar) {
52574 if (!$bar->getMaxSteps()) {
52575 throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
52576 }
52577
52578 if (!$bar->getProgress()) {
52579 $estimated = 0;
52580 } else {
52581 $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
52582 }
52583
52584 return Helper::formatTime($estimated);
52585 },
52586 'memory' => function (ProgressBar $bar) {
52587 return Helper::formatMemory(memory_get_usage(true));
52588 },
52589 'current' => function (ProgressBar $bar) {
52590 return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
52591 },
52592 'max' => function (ProgressBar $bar) {
52593 return $bar->getMaxSteps();
52594 },
52595 'percent' => function (ProgressBar $bar) {
52596 return floor($bar->getProgressPercent() * 100);
52597 },
52598 );
52599 }
52600
52601 private static function initFormats()
52602 {
52603 return array(
52604 'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
52605 'normal_nomax' => ' %current% [%bar%]',
52606
52607 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
52608 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
52609
52610 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
52611 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
52612
52613 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
52614 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
52615 );
52616 }
52617 }
52618 <?php
52619
52620
52621
52622
52623
52624
52625
52626
52627
52628
52629 namespace Symfony\Component\Console\Helper;
52630
52631 use Symfony\Component\Console\Output\NullOutput;
52632 use Symfony\Component\Console\Output\ConsoleOutputInterface;
52633 use Symfony\Component\Console\Output\OutputInterface;
52634 use Symfony\Component\Console\Exception\LogicException;
52635
52636
52637
52638
52639
52640
52641
52642
52643
52644
52645 class ProgressHelper extends Helper
52646 {
52647 const FORMAT_QUIET = ' %percent%%';
52648 const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';
52649 const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';
52650 const FORMAT_QUIET_NOMAX = ' %current%';
52651 const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';
52652 const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';
52653
52654
52655  private $barWidth = 28;
52656 private $barChar = '=';
52657 private $emptyBarChar = '-';
52658 private $progressChar = '>';
52659 private $format = null;
52660 private $redrawFreq = 1;
52661
52662 private $lastMessagesLength;
52663 private $barCharOriginal;
52664
52665
52666
52667
52668 private $output;
52669
52670
52671
52672
52673
52674
52675 private $current;
52676
52677
52678
52679
52680
52681
52682 private $max;
52683
52684
52685
52686
52687
52688
52689 private $startTime;
52690
52691
52692
52693
52694
52695
52696 private $defaultFormatVars = array(
52697 'current',
52698 'max',
52699 'bar',
52700 'percent',
52701 'elapsed',
52702 );
52703
52704
52705
52706
52707
52708
52709 private $formatVars;
52710
52711
52712
52713
52714
52715
52716 private $widths = array(
52717 'current' => 4,
52718 'max' => 4,
52719 'percent' => 3,
52720 'elapsed' => 6,
52721 );
52722
52723
52724
52725
52726
52727
52728 private $timeFormats = array(
52729 array(0, '???'),
52730 array(2, '1 sec'),
52731 array(59, 'secs', 1),
52732 array(60, '1 min'),
52733 array(3600, 'mins', 60),
52734 array(5400, '1 hr'),
52735 array(86400, 'hrs', 3600),
52736 array(129600, '1 day'),
52737 array(604800, 'days', 86400),
52738 );
52739
52740 public function __construct($triggerDeprecationError = true)
52741 {
52742 if ($triggerDeprecationError) {
52743 @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\ProgressBar class instead.', E_USER_DEPRECATED);
52744 }
52745 }
52746
52747
52748
52749
52750
52751
52752 public function setBarWidth($size)
52753 {
52754 $this->barWidth = (int) $size;
52755 }
52756
52757
52758
52759
52760
52761
52762 public function setBarCharacter($char)
52763 {
52764 $this->barChar = $char;
52765 }
52766
52767
52768
52769
52770
52771
52772 public function setEmptyBarCharacter($char)
52773 {
52774 $this->emptyBarChar = $char;
52775 }
52776
52777
52778
52779
52780
52781
52782 public function setProgressCharacter($char)
52783 {
52784 $this->progressChar = $char;
52785 }
52786
52787
52788
52789
52790
52791
52792 public function setFormat($format)
52793 {
52794 $this->format = $format;
52795 }
52796
52797
52798
52799
52800
52801
52802 public function setRedrawFrequency($freq)
52803 {
52804 $this->redrawFreq = (int) $freq;
52805 }
52806
52807
52808
52809
52810
52811
52812
52813 public function start(OutputInterface $output, $max = null)
52814 {
52815 if ($output instanceof ConsoleOutputInterface) {
52816 $output = $output->getErrorOutput();
52817 }
52818
52819 $this->startTime = time();
52820 $this->current = 0;
52821 $this->max = (int) $max;
52822
52823
52824  $this->output = $output->isDecorated() ? $output : new NullOutput();
52825 $this->lastMessagesLength = 0;
52826 $this->barCharOriginal = '';
52827
52828 if (null === $this->format) {
52829 switch ($output->getVerbosity()) {
52830 case OutputInterface::VERBOSITY_QUIET:
52831 $this->format = self::FORMAT_QUIET_NOMAX;
52832 if ($this->max > 0) {
52833 $this->format = self::FORMAT_QUIET;
52834 }
52835 break;
52836 case OutputInterface::VERBOSITY_VERBOSE:
52837 case OutputInterface::VERBOSITY_VERY_VERBOSE:
52838 case OutputInterface::VERBOSITY_DEBUG:
52839 $this->format = self::FORMAT_VERBOSE_NOMAX;
52840 if ($this->max > 0) {
52841 $this->format = self::FORMAT_VERBOSE;
52842 }
52843 break;
52844 default:
52845 $this->format = self::FORMAT_NORMAL_NOMAX;
52846 if ($this->max > 0) {
52847 $this->format = self::FORMAT_NORMAL;
52848 }
52849 break;
52850 }
52851 }
52852
52853 $this->initialize();
52854 }
52855
52856
52857
52858
52859
52860
52861
52862
52863
52864 public function advance($step = 1, $redraw = false)
52865 {
52866 $this->setCurrent($this->current + $step, $redraw);
52867 }
52868
52869
52870
52871
52872
52873
52874
52875
52876
52877 public function setCurrent($current, $redraw = false)
52878 {
52879 if (null === $this->startTime) {
52880 throw new LogicException('You must start the progress bar before calling setCurrent().');
52881 }
52882
52883 $current = (int) $current;
52884
52885 if ($current < $this->current) {
52886 throw new LogicException('You can\'t regress the progress bar');
52887 }
52888
52889 if (0 === $this->current) {
52890 $redraw = true;
52891 }
52892
52893 $prevPeriod = (int) ($this->current / $this->redrawFreq);
52894
52895 $this->current = $current;
52896
52897 $currPeriod = (int) ($this->current / $this->redrawFreq);
52898 if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
52899 $this->display();
52900 }
52901 }
52902
52903
52904
52905
52906
52907
52908
52909
52910 public function display($finish = false)
52911 {
52912 if (null === $this->startTime) {
52913 throw new LogicException('You must start the progress bar before calling display().');
52914 }
52915
52916 $message = $this->format;
52917 foreach ($this->generate($finish) as $name => $value) {
52918 $message = str_replace("%{$name}%", $value, $message);
52919 }
52920 $this->overwrite($this->output, $message);
52921 }
52922
52923
52924
52925
52926
52927
52928
52929
52930 public function clear()
52931 {
52932 $this->overwrite($this->output, '');
52933 }
52934
52935
52936
52937
52938 public function finish()
52939 {
52940 if (null === $this->startTime) {
52941 throw new LogicException('You must start the progress bar before calling finish().');
52942 }
52943
52944 if (null !== $this->startTime) {
52945 if (!$this->max) {
52946 $this->barChar = $this->barCharOriginal;
52947 $this->display(true);
52948 }
52949 $this->startTime = null;
52950 $this->output->writeln('');
52951 $this->output = null;
52952 }
52953 }
52954
52955
52956
52957
52958 private function initialize()
52959 {
52960 $this->formatVars = array();
52961 foreach ($this->defaultFormatVars as $var) {
52962 if (false !== strpos($this->format, "%{$var}%")) {
52963 $this->formatVars[$var] = true;
52964 }
52965 }
52966
52967 if ($this->max > 0) {
52968 $this->widths['max'] = $this->strlen($this->max);
52969 $this->widths['current'] = $this->widths['max'];
52970 } else {
52971 $this->barCharOriginal = $this->barChar;
52972 $this->barChar = $this->emptyBarChar;
52973 }
52974 }
52975
52976
52977
52978
52979
52980
52981
52982
52983 private function generate($finish = false)
52984 {
52985 $vars = array();
52986 $percent = 0;
52987 if ($this->max > 0) {
52988 $percent = (float) $this->current / $this->max;
52989 }
52990
52991 if (isset($this->formatVars['bar'])) {
52992 if ($this->max > 0) {
52993 $completeBars = floor($percent * $this->barWidth);
52994 } else {
52995 if (!$finish) {
52996 $completeBars = floor($this->current % $this->barWidth);
52997 } else {
52998 $completeBars = $this->barWidth;
52999 }
53000 }
53001
53002 $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);
53003 $bar = str_repeat($this->barChar, $completeBars);
53004 if ($completeBars < $this->barWidth) {
53005 $bar .= $this->progressChar;
53006 $bar .= str_repeat($this->emptyBarChar, $emptyBars);
53007 }
53008
53009 $vars['bar'] = $bar;
53010 }
53011
53012 if (isset($this->formatVars['elapsed'])) {
53013 $elapsed = time() - $this->startTime;
53014 $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);
53015 }
53016
53017 if (isset($this->formatVars['current'])) {
53018 $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);
53019 }
53020
53021 if (isset($this->formatVars['max'])) {
53022 $vars['max'] = $this->max;
53023 }
53024
53025 if (isset($this->formatVars['percent'])) {
53026 $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);
53027 }
53028
53029 return $vars;
53030 }
53031
53032
53033
53034
53035
53036
53037
53038
53039 private function humaneTime($secs)
53040 {
53041 $text = '';
53042 foreach ($this->timeFormats as $format) {
53043 if ($secs < $format[0]) {
53044 if (count($format) == 2) {
53045 $text = $format[1];
53046 break;
53047 } else {
53048 $text = ceil($secs / $format[2]).' '.$format[1];
53049 break;
53050 }
53051 }
53052 }
53053
53054 return $text;
53055 }
53056
53057
53058
53059
53060
53061
53062
53063 private function overwrite(OutputInterface $output, $message)
53064 {
53065 $length = $this->strlen($message);
53066
53067
53068  if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {
53069 $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
53070 }
53071
53072
53073  $output->write("\x0D");
53074 $output->write($message);
53075
53076 $this->lastMessagesLength = $this->strlen($message);
53077 }
53078
53079
53080
53081
53082 public function getName()
53083 {
53084 return 'progress';
53085 }
53086 }
53087 <?php
53088
53089
53090
53091
53092
53093
53094
53095
53096
53097
53098 namespace Symfony\Component\Console\Helper;
53099
53100 use Symfony\Component\Console\Exception\InvalidArgumentException;
53101 use Symfony\Component\Console\Exception\LogicException;
53102 use Symfony\Component\Console\Output\OutputInterface;
53103
53104
53105
53106
53107 class ProgressIndicator
53108 {
53109 private $output;
53110 private $startTime;
53111 private $format;
53112 private $message;
53113 private $indicatorValues;
53114 private $indicatorCurrent;
53115 private $indicatorChangeInterval;
53116 private $indicatorUpdateTime;
53117 private $started = false;
53118
53119 private static $formatters;
53120 private static $formats;
53121
53122
53123
53124
53125
53126
53127
53128 public function __construct(OutputInterface $output, $format = null, $indicatorChangeInterval = 100, $indicatorValues = null)
53129 {
53130 $this->output = $output;
53131
53132 if (null === $format) {
53133 $format = $this->determineBestFormat();
53134 }
53135
53136 if (null === $indicatorValues) {
53137 $indicatorValues = array('-', '\\', '|', '/');
53138 }
53139
53140 $indicatorValues = array_values($indicatorValues);
53141
53142 if (2 > count($indicatorValues)) {
53143 throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
53144 }
53145
53146 $this->format = self::getFormatDefinition($format);
53147 $this->indicatorChangeInterval = $indicatorChangeInterval;
53148 $this->indicatorValues = $indicatorValues;
53149 $this->startTime = time();
53150 }
53151
53152
53153
53154
53155
53156
53157 public function setMessage($message)
53158 {
53159 $this->message = $message;
53160
53161 $this->display();
53162 }
53163
53164
53165
53166
53167
53168
53169
53170
53171 public function getMessage()
53172 {
53173 return $this->message;
53174 }
53175
53176
53177
53178
53179
53180
53181
53182
53183 public function getStartTime()
53184 {
53185 return $this->startTime;
53186 }
53187
53188
53189
53190
53191
53192
53193
53194
53195 public function getCurrentValue()
53196 {
53197 return $this->indicatorValues[$this->indicatorCurrent % count($this->indicatorValues)];
53198 }
53199
53200
53201
53202
53203
53204
53205 public function start($message)
53206 {
53207 if ($this->started) {
53208 throw new LogicException('Progress indicator already started.');
53209 }
53210
53211 $this->message = $message;
53212 $this->started = true;
53213 $this->startTime = time();
53214 $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
53215 $this->indicatorCurrent = 0;
53216
53217 $this->display();
53218 }
53219
53220
53221
53222
53223 public function advance()
53224 {
53225 if (!$this->started) {
53226 throw new LogicException('Progress indicator has not yet been started.');
53227 }
53228
53229 if (!$this->output->isDecorated()) {
53230 return;
53231 }
53232
53233 $currentTime = $this->getCurrentTimeInMilliseconds();
53234
53235 if ($currentTime < $this->indicatorUpdateTime) {
53236 return;
53237 }
53238
53239 $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
53240 ++$this->indicatorCurrent;
53241
53242 $this->display();
53243 }
53244
53245
53246
53247
53248
53249
53250 public function finish($message)
53251 {
53252 if (!$this->started) {
53253 throw new LogicException('Progress indicator has not yet been started.');
53254 }
53255
53256 $this->message = $message;
53257 $this->display();
53258 $this->output->writeln('');
53259 $this->started = false;
53260 }
53261
53262
53263
53264
53265
53266
53267
53268
53269 public static function getFormatDefinition($name)
53270 {
53271 if (!self::$formats) {
53272 self::$formats = self::initFormats();
53273 }
53274
53275 return isset(self::$formats[$name]) ? self::$formats[$name] : null;
53276 }
53277
53278
53279
53280
53281
53282
53283
53284
53285
53286 public static function setPlaceholderFormatterDefinition($name, $callable)
53287 {
53288 if (!self::$formatters) {
53289 self::$formatters = self::initPlaceholderFormatters();
53290 }
53291
53292 self::$formatters[$name] = $callable;
53293 }
53294
53295
53296
53297
53298
53299
53300
53301
53302 public static function getPlaceholderFormatterDefinition($name)
53303 {
53304 if (!self::$formatters) {
53305 self::$formatters = self::initPlaceholderFormatters();
53306 }
53307
53308 return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
53309 }
53310
53311 private function display()
53312 {
53313 if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
53314 return;
53315 }
53316
53317 $self = $this;
53318
53319 $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
53320 if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
53321 return call_user_func($formatter, $self);
53322 }
53323
53324 return $matches[0];
53325 }, $this->format));
53326 }
53327
53328 private function determineBestFormat()
53329 {
53330 switch ($this->output->getVerbosity()) {
53331
53332  case OutputInterface::VERBOSITY_VERBOSE:
53333 return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
53334 case OutputInterface::VERBOSITY_VERY_VERBOSE:
53335 case OutputInterface::VERBOSITY_DEBUG:
53336 return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
53337 default:
53338 return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
53339 }
53340 }
53341
53342
53343
53344
53345
53346
53347 private function overwrite($message)
53348 {
53349 if ($this->output->isDecorated()) {
53350 $this->output->write("\x0D\x1B[2K");
53351 $this->output->write($message);
53352 } else {
53353 $this->output->writeln($message);
53354 }
53355 }
53356
53357 private function getCurrentTimeInMilliseconds()
53358 {
53359 return round(microtime(true) * 1000);
53360 }
53361
53362 private static function initPlaceholderFormatters()
53363 {
53364 return array(
53365 'indicator' => function (ProgressIndicator $indicator) {
53366 return $indicator->getCurrentValue();
53367 },
53368 'message' => function (ProgressIndicator $indicator) {
53369 return $indicator->getMessage();
53370 },
53371 'elapsed' => function (ProgressIndicator $indicator) {
53372 return Helper::formatTime(time() - $indicator->getStartTime());
53373 },
53374 'memory' => function () {
53375 return Helper::formatMemory(memory_get_usage(true));
53376 },
53377 );
53378 }
53379
53380 private static function initFormats()
53381 {
53382 return array(
53383 'normal' => ' %indicator% %message%',
53384 'normal_no_ansi' => ' %message%',
53385
53386 'verbose' => ' %indicator% %message% (%elapsed:6s%)',
53387 'verbose_no_ansi' => ' %message% (%elapsed:6s%)',
53388
53389 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
53390 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
53391 );
53392 }
53393 }
53394 <?php
53395
53396
53397
53398
53399
53400
53401
53402
53403
53404
53405 namespace Symfony\Component\Console\Helper;
53406
53407 use Symfony\Component\Console\Exception\InvalidArgumentException;
53408 use Symfony\Component\Console\Exception\RuntimeException;
53409 use Symfony\Component\Console\Input\InputInterface;
53410 use Symfony\Component\Console\Output\ConsoleOutputInterface;
53411 use Symfony\Component\Console\Output\OutputInterface;
53412 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
53413 use Symfony\Component\Console\Question\Question;
53414 use Symfony\Component\Console\Question\ChoiceQuestion;
53415
53416
53417
53418
53419
53420
53421 class QuestionHelper extends Helper
53422 {
53423 private $inputStream;
53424 private static $shell;
53425 private static $stty;
53426
53427
53428
53429
53430
53431
53432
53433
53434
53435
53436
53437
53438 public function ask(InputInterface $input, OutputInterface $output, Question $question)
53439 {
53440 if ($output instanceof ConsoleOutputInterface) {
53441 $output = $output->getErrorOutput();
53442 }
53443
53444 if (!$input->isInteractive()) {
53445 return $question->getDefault();
53446 }
53447
53448 if (!$question->getValidator()) {
53449 return $this->doAsk($output, $question);
53450 }
53451
53452 $that = $this;
53453
53454 $interviewer = function () use ($output, $question, $that) {
53455 return $that->doAsk($output, $question);
53456 };
53457
53458 return $this->validateAttempts($interviewer, $output, $question);
53459 }
53460
53461
53462
53463
53464
53465
53466
53467
53468
53469
53470 public function setInputStream($stream)
53471 {
53472 if (!is_resource($stream)) {
53473 throw new InvalidArgumentException('Input stream must be a valid resource.');
53474 }
53475
53476 $this->inputStream = $stream;
53477 }
53478
53479
53480
53481
53482
53483
53484 public function getInputStream()
53485 {
53486 return $this->inputStream;
53487 }
53488
53489
53490
53491
53492 public function getName()
53493 {
53494 return 'question';
53495 }
53496
53497
53498
53499
53500
53501
53502
53503
53504
53505
53506
53507
53508
53509
53510 public function doAsk(OutputInterface $output, Question $question)
53511 {
53512 $this->writePrompt($output, $question);
53513
53514 $inputStream = $this->inputStream ?: STDIN;
53515 $autocomplete = $question->getAutocompleterValues();
53516
53517 if (null === $autocomplete || !$this->hasSttyAvailable()) {
53518 $ret = false;
53519 if ($question->isHidden()) {
53520 try {
53521 $ret = trim($this->getHiddenResponse($output, $inputStream));
53522 } catch (\RuntimeException $e) {
53523 if (!$question->isHiddenFallback()) {
53524 throw $e;
53525 }
53526 }
53527 }
53528
53529 if (false === $ret) {
53530 $ret = fgets($inputStream, 4096);
53531 if (false === $ret) {
53532 throw new RuntimeException('Aborted');
53533 }
53534 $ret = trim($ret);
53535 }
53536 } else {
53537 $ret = trim($this->autocomplete($output, $question, $inputStream));
53538 }
53539
53540 $ret = strlen($ret) > 0 ? $ret : $question->getDefault();
53541
53542 if ($normalizer = $question->getNormalizer()) {
53543 return $normalizer($ret);
53544 }
53545
53546 return $ret;
53547 }
53548
53549
53550
53551
53552
53553
53554
53555 protected function writePrompt(OutputInterface $output, Question $question)
53556 {
53557 $message = $question->getQuestion();
53558
53559 if ($question instanceof ChoiceQuestion) {
53560 $maxWidth = max(array_map(array($this, 'strlen'), array_keys($question->getChoices())));
53561
53562 $messages = (array) $question->getQuestion();
53563 foreach ($question->getChoices() as $key => $value) {
53564 $width = $maxWidth - $this->strlen($key);
53565 $messages[] = '  [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value;
53566 }
53567
53568 $output->writeln($messages);
53569
53570 $message = $question->getPrompt();
53571 }
53572
53573 $output->write($message);
53574 }
53575
53576
53577
53578
53579
53580
53581
53582 protected function writeError(OutputInterface $output, \Exception $error)
53583 {
53584 if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
53585 $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
53586 } else {
53587 $message = '<error>'.$error->getMessage().'</error>';
53588 }
53589
53590 $output->writeln($message);
53591 }
53592
53593
53594
53595
53596
53597
53598
53599
53600
53601
53602 private function autocomplete(OutputInterface $output, Question $question, $inputStream)
53603 {
53604 $autocomplete = $question->getAutocompleterValues();
53605 $ret = '';
53606
53607 $i = 0;
53608 $ofs = -1;
53609 $matches = $autocomplete;
53610 $numMatches = count($matches);
53611
53612 $sttyMode = shell_exec('stty -g');
53613
53614
53615  shell_exec('stty -icanon -echo');
53616
53617
53618  $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
53619
53620
53621  while (!feof($inputStream)) {
53622 $c = fread($inputStream, 1);
53623
53624
53625  if ("\177" === $c) {
53626 if (0 === $numMatches && 0 !== $i) {
53627 --$i;
53628
53629  $output->write("\033[1D");
53630 }
53631
53632 if ($i === 0) {
53633 $ofs = -1;
53634 $matches = $autocomplete;
53635 $numMatches = count($matches);
53636 } else {
53637 $numMatches = 0;
53638 }
53639
53640
53641  $ret = substr($ret, 0, $i);
53642 } elseif ("\033" === $c) {
53643
53644  $c .= fread($inputStream, 2);
53645
53646
53647  if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
53648 if ('A' === $c[2] && -1 === $ofs) {
53649 $ofs = 0;
53650 }
53651
53652 if (0 === $numMatches) {
53653 continue;
53654 }
53655
53656 $ofs += ('A' === $c[2]) ? -1 : 1;
53657 $ofs = ($numMatches + $ofs) % $numMatches;
53658 }
53659 } elseif (ord($c) < 32) {
53660 if ("\t" === $c || "\n" === $c) {
53661 if ($numMatches > 0 && -1 !== $ofs) {
53662 $ret = $matches[$ofs];
53663
53664  $output->write(substr($ret, $i));
53665 $i = strlen($ret);
53666 }
53667
53668 if ("\n" === $c) {
53669 $output->write($c);
53670 break;
53671 }
53672
53673 $numMatches = 0;
53674 }
53675
53676 continue;
53677 } else {
53678 $output->write($c);
53679 $ret .= $c;
53680 ++$i;
53681
53682 $numMatches = 0;
53683 $ofs = 0;
53684
53685 foreach ($autocomplete as $value) {
53686
53687  if (0 === strpos($value, $ret) && $i !== strlen($value)) {
53688 $matches[$numMatches++] = $value;
53689 }
53690 }
53691 }
53692
53693
53694  $output->write("\033[K");
53695
53696 if ($numMatches > 0 && -1 !== $ofs) {
53697
53698  $output->write("\0337");
53699
53700  $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
53701
53702  $output->write("\0338");
53703 }
53704 }
53705
53706
53707  shell_exec(sprintf('stty %s', $sttyMode));
53708
53709 return $ret;
53710 }
53711
53712
53713
53714
53715
53716
53717
53718
53719
53720
53721
53722 private function getHiddenResponse(OutputInterface $output, $inputStream)
53723 {
53724 if ('\\' === DIRECTORY_SEPARATOR) {
53725 $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
53726
53727
53728  if ('phar:' === substr(__FILE__, 0, 5)) {
53729 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
53730 copy($exe, $tmpExe);
53731 $exe = $tmpExe;
53732 }
53733
53734 $value = rtrim(shell_exec($exe));
53735 $output->writeln('');
53736
53737 if (isset($tmpExe)) {
53738 unlink($tmpExe);
53739 }
53740
53741 return $value;
53742 }
53743
53744 if ($this->hasSttyAvailable()) {
53745 $sttyMode = shell_exec('stty -g');
53746
53747 shell_exec('stty -echo');
53748 $value = fgets($inputStream, 4096);
53749 shell_exec(sprintf('stty %s', $sttyMode));
53750
53751 if (false === $value) {
53752 throw new RuntimeException('Aborted');
53753 }
53754
53755 $value = trim($value);
53756 $output->writeln('');
53757
53758 return $value;
53759 }
53760
53761 if (false !== $shell = $this->getShell()) {
53762 $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
53763 $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
53764 $value = rtrim(shell_exec($command));
53765 $output->writeln('');
53766
53767 return $value;
53768 }
53769
53770 throw new RuntimeException('Unable to hide the response.');
53771 }
53772
53773
53774
53775
53776
53777
53778
53779
53780
53781
53782
53783
53784 private function validateAttempts($interviewer, OutputInterface $output, Question $question)
53785 {
53786 $error = null;
53787 $attempts = $question->getMaxAttempts();
53788 while (null === $attempts || $attempts--) {
53789 if (null !== $error) {
53790 $this->writeError($output, $error);
53791 }
53792
53793 try {
53794 return call_user_func($question->getValidator(), $interviewer());
53795 } catch (RuntimeException $e) {
53796 throw $e;
53797 } catch (\Exception $error) {
53798 }
53799 }
53800
53801 throw $error;
53802 }
53803
53804
53805
53806
53807
53808
53809 private function getShell()
53810 {
53811 if (null !== self::$shell) {
53812 return self::$shell;
53813 }
53814
53815 self::$shell = false;
53816
53817 if (file_exists('/usr/bin/env')) {
53818
53819  $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
53820 foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
53821 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
53822 self::$shell = $sh;
53823 break;
53824 }
53825 }
53826 }
53827
53828 return self::$shell;
53829 }
53830
53831
53832
53833
53834
53835
53836 private function hasSttyAvailable()
53837 {
53838 if (null !== self::$stty) {
53839 return self::$stty;
53840 }
53841
53842 exec('stty 2>&1', $output, $exitcode);
53843
53844 return self::$stty = $exitcode === 0;
53845 }
53846 }
53847 <?php
53848
53849
53850
53851
53852
53853
53854
53855
53856
53857
53858 namespace Symfony\Component\Console\Helper;
53859
53860 use Symfony\Component\Console\Exception\LogicException;
53861 use Symfony\Component\Console\Input\InputInterface;
53862 use Symfony\Component\Console\Output\OutputInterface;
53863 use Symfony\Component\Console\Question\ChoiceQuestion;
53864 use Symfony\Component\Console\Question\ConfirmationQuestion;
53865 use Symfony\Component\Console\Question\Question;
53866 use Symfony\Component\Console\Style\SymfonyStyle;
53867 use Symfony\Component\Console\Formatter\OutputFormatter;
53868
53869
53870
53871
53872
53873
53874 class SymfonyQuestionHelper extends QuestionHelper
53875 {
53876
53877
53878
53879 public function ask(InputInterface $input, OutputInterface $output, Question $question)
53880 {
53881 $validator = $question->getValidator();
53882 $question->setValidator(function ($value) use ($validator) {
53883 if (null !== $validator) {
53884 $value = $validator($value);
53885 } else {
53886
53887  if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) {
53888 throw new LogicException('A value is required.');
53889 }
53890 }
53891
53892 return $value;
53893 });
53894
53895 return parent::ask($input, $output, $question);
53896 }
53897
53898
53899
53900
53901 protected function writePrompt(OutputInterface $output, Question $question)
53902 {
53903 $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
53904 $default = $question->getDefault();
53905
53906 switch (true) {
53907 case null === $default:
53908 $text = sprintf(' <info>%s</info>:', $text);
53909
53910 break;
53911
53912 case $question instanceof ConfirmationQuestion:
53913 $text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no');
53914
53915 break;
53916
53917 case $question instanceof ChoiceQuestion && $question->isMultiselect():
53918 $choices = $question->getChoices();
53919 $default = explode(',', $default);
53920
53921 foreach ($default as $key => $value) {
53922 $default[$key] = $choices[trim($value)];
53923 }
53924
53925 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(implode(', ', $default)));
53926
53927 break;
53928
53929 case $question instanceof ChoiceQuestion:
53930 $choices = $question->getChoices();
53931 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($choices[$default]));
53932
53933 break;
53934
53935 default:
53936 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($default));
53937 }
53938
53939 $output->writeln($text);
53940
53941 if ($question instanceof ChoiceQuestion) {
53942 $width = max(array_map('strlen', array_keys($question->getChoices())));
53943
53944 foreach ($question->getChoices() as $key => $value) {
53945 $output->writeln(sprintf("  [<comment>%-${width}s</comment>] %s", $key, $value));
53946 }
53947 }
53948
53949 $output->write(' > ');
53950 }
53951
53952
53953
53954
53955 protected function writeError(OutputInterface $output, \Exception $error)
53956 {
53957 if ($output instanceof SymfonyStyle) {
53958 $output->newLine();
53959 $output->error($error->getMessage());
53960
53961 return;
53962 }
53963
53964 parent::writeError($output, $error);
53965 }
53966 }
53967 <?php
53968
53969
53970
53971
53972
53973
53974
53975
53976
53977
53978 namespace Symfony\Component\Console\Helper;
53979
53980 use Symfony\Component\Console\Output\OutputInterface;
53981 use Symfony\Component\Console\Exception\InvalidArgumentException;
53982
53983
53984
53985
53986
53987
53988
53989
53990
53991 class Table
53992 {
53993
53994
53995
53996
53997
53998 private $headers = array();
53999
54000
54001
54002
54003
54004
54005 private $rows = array();
54006
54007
54008
54009
54010
54011
54012 private $columnWidths = array();
54013
54014
54015
54016
54017
54018
54019 private $numberOfColumns;
54020
54021
54022
54023
54024 private $output;
54025
54026
54027
54028
54029 private $style;
54030
54031
54032
54033
54034 private $columnStyles = array();
54035
54036 private static $styles;
54037
54038 public function __construct(OutputInterface $output)
54039 {
54040 $this->output = $output;
54041
54042 if (!self::$styles) {
54043 self::$styles = self::initStyles();
54044 }
54045
54046 $this->setStyle('default');
54047 }
54048
54049
54050
54051
54052
54053
54054
54055 public static function setStyleDefinition($name, TableStyle $style)
54056 {
54057 if (!self::$styles) {
54058 self::$styles = self::initStyles();
54059 }
54060
54061 self::$styles[$name] = $style;
54062 }
54063
54064
54065
54066
54067
54068
54069
54070
54071 public static function getStyleDefinition($name)
54072 {
54073 if (!self::$styles) {
54074 self::$styles = self::initStyles();
54075 }
54076
54077 if (isset(self::$styles[$name])) {
54078 return self::$styles[$name];
54079 }
54080
54081 throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
54082 }
54083
54084
54085
54086
54087
54088
54089
54090
54091 public function setStyle($name)
54092 {
54093 $this->style = $this->resolveStyle($name);
54094
54095 return $this;
54096 }
54097
54098
54099
54100
54101
54102
54103 public function getStyle()
54104 {
54105 return $this->style;
54106 }
54107
54108
54109
54110
54111
54112
54113
54114
54115
54116 public function setColumnStyle($columnIndex, $name)
54117 {
54118 $columnIndex = intval($columnIndex);
54119
54120 $this->columnStyles[$columnIndex] = $this->resolveStyle($name);
54121
54122 return $this;
54123 }
54124
54125
54126
54127
54128
54129
54130
54131
54132
54133
54134 public function getColumnStyle($columnIndex)
54135 {
54136 if (isset($this->columnStyles[$columnIndex])) {
54137 return $this->columnStyles[$columnIndex];
54138 }
54139
54140 return $this->getStyle();
54141 }
54142
54143 public function setHeaders(array $headers)
54144 {
54145 $headers = array_values($headers);
54146 if (!empty($headers) && !is_array($headers[0])) {
54147 $headers = array($headers);
54148 }
54149
54150 $this->headers = $headers;
54151
54152 return $this;
54153 }
54154
54155 public function setRows(array $rows)
54156 {
54157 $this->rows = array();
54158
54159 return $this->addRows($rows);
54160 }
54161
54162 public function addRows(array $rows)
54163 {
54164 foreach ($rows as $row) {
54165 $this->addRow($row);
54166 }
54167
54168 return $this;
54169 }
54170
54171 public function addRow($row)
54172 {
54173 if ($row instanceof TableSeparator) {
54174 $this->rows[] = $row;
54175
54176 return $this;
54177 }
54178
54179 if (!is_array($row)) {
54180 throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
54181 }
54182
54183 $this->rows[] = array_values($row);
54184
54185 return $this;
54186 }
54187
54188 public function setRow($column, array $row)
54189 {
54190 $this->rows[$column] = $row;
54191
54192 return $this;
54193 }
54194
54195
54196
54197
54198
54199
54200
54201
54202
54203
54204
54205
54206
54207 public function render()
54208 {
54209 $this->calculateNumberOfColumns();
54210 $rows = $this->buildTableRows($this->rows);
54211 $headers = $this->buildTableRows($this->headers);
54212
54213 $this->calculateColumnsWidth(array_merge($headers, $rows));
54214
54215 $this->renderRowSeparator();
54216 if (!empty($headers)) {
54217 foreach ($headers as $header) {
54218 $this->renderRow($header, $this->style->getCellHeaderFormat());
54219 $this->renderRowSeparator();
54220 }
54221 }
54222 foreach ($rows as $row) {
54223 if ($row instanceof TableSeparator) {
54224 $this->renderRowSeparator();
54225 } else {
54226 $this->renderRow($row, $this->style->getCellRowFormat());
54227 }
54228 }
54229 if (!empty($rows)) {
54230 $this->renderRowSeparator();
54231 }
54232
54233 $this->cleanup();
54234 }
54235
54236
54237
54238
54239
54240
54241 private function renderRowSeparator()
54242 {
54243 if (0 === $count = $this->numberOfColumns) {
54244 return;
54245 }
54246
54247 if (!$this->style->getHorizontalBorderChar() && !$this->style->getCrossingChar()) {
54248 return;
54249 }
54250
54251 $markup = $this->style->getCrossingChar();
54252 for ($column = 0; $column < $count; ++$column) {
54253 $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar();
54254 }
54255
54256 $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
54257 }
54258
54259
54260
54261
54262 private function renderColumnSeparator()
54263 {
54264 return sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar());
54265 }
54266
54267
54268
54269
54270
54271
54272
54273
54274
54275 private function renderRow(array $row, $cellFormat)
54276 {
54277 if (empty($row)) {
54278 return;
54279 }
54280
54281 $rowContent = $this->renderColumnSeparator();
54282 foreach ($this->getRowColumns($row) as $column) {
54283 $rowContent .= $this->renderCell($row, $column, $cellFormat);
54284 $rowContent .= $this->renderColumnSeparator();
54285 }
54286 $this->output->writeln($rowContent);
54287 }
54288
54289
54290
54291
54292
54293
54294
54295
54296 private function renderCell(array $row, $column, $cellFormat)
54297 {
54298 $cell = isset($row[$column]) ? $row[$column] : '';
54299 $width = $this->columnWidths[$column];
54300 if ($cell instanceof TableCell && $cell->getColspan() > 1) {
54301
54302  foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
54303 $width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn];
54304 }
54305 }
54306
54307
54308  if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
54309 $width += strlen($cell) - mb_strwidth($cell, $encoding);
54310 }
54311
54312 $style = $this->getColumnStyle($column);
54313
54314 if ($cell instanceof TableSeparator) {
54315 return sprintf($style->getBorderFormat(), str_repeat($style->getHorizontalBorderChar(), $width));
54316 }
54317
54318 $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
54319 $content = sprintf($style->getCellRowContentFormat(), $cell);
54320
54321 return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType()));
54322 }
54323
54324
54325
54326
54327 private function calculateNumberOfColumns()
54328 {
54329 if (null !== $this->numberOfColumns) {
54330 return;
54331 }
54332
54333 $columns = array(0);
54334 foreach (array_merge($this->headers, $this->rows) as $row) {
54335 if ($row instanceof TableSeparator) {
54336 continue;
54337 }
54338
54339 $columns[] = $this->getNumberOfColumns($row);
54340 }
54341
54342 $this->numberOfColumns = max($columns);
54343 }
54344
54345 private function buildTableRows($rows)
54346 {
54347 $unmergedRows = array();
54348 for ($rowKey = 0; $rowKey < count($rows); ++$rowKey) {
54349 $rows = $this->fillNextRows($rows, $rowKey);
54350
54351
54352  foreach ($rows[$rowKey] as $column => $cell) {
54353 if (!strstr($cell, "\n")) {
54354 continue;
54355 }
54356 $lines = explode("\n", $cell);
54357 foreach ($lines as $lineKey => $line) {
54358 if ($cell instanceof TableCell) {
54359 $line = new TableCell($line, array('colspan' => $cell->getColspan()));
54360 }
54361 if (0 === $lineKey) {
54362 $rows[$rowKey][$column] = $line;
54363 } else {
54364 $unmergedRows[$rowKey][$lineKey][$column] = $line;
54365 }
54366 }
54367 }
54368 }
54369
54370 $tableRows = array();
54371 foreach ($rows as $rowKey => $row) {
54372 $tableRows[] = $this->fillCells($row);
54373 if (isset($unmergedRows[$rowKey])) {
54374 $tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
54375 }
54376 }
54377
54378 return $tableRows;
54379 }
54380
54381
54382
54383
54384
54385
54386
54387
54388
54389 private function fillNextRows($rows, $line)
54390 {
54391 $unmergedRows = array();
54392 foreach ($rows[$line] as $column => $cell) {
54393 if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
54394 $nbLines = $cell->getRowspan() - 1;
54395 $lines = array($cell);
54396 if (strstr($cell, "\n")) {
54397 $lines = explode("\n", $cell);
54398 $nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
54399
54400 $rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan()));
54401 unset($lines[0]);
54402 }
54403
54404
54405  $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, array()), $unmergedRows);
54406 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
54407 $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
54408 $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
54409 if ($nbLines === $unmergedRowKey - $line) {
54410 break;
54411 }
54412 }
54413 }
54414 }
54415
54416 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
54417
54418  if (isset($rows[$unmergedRowKey]) && is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
54419 foreach ($unmergedRow as $cellKey => $cell) {
54420
54421  array_splice($rows[$unmergedRowKey], $cellKey, 0, array($cell));
54422 }
54423 } else {
54424 $row = $this->copyRow($rows, $unmergedRowKey - 1);
54425 foreach ($unmergedRow as $column => $cell) {
54426 if (!empty($cell)) {
54427 $row[$column] = $unmergedRow[$column];
54428 }
54429 }
54430 array_splice($rows, $unmergedRowKey, 0, array($row));
54431 }
54432 }
54433
54434 return $rows;
54435 }
54436
54437
54438
54439
54440
54441
54442
54443
54444 private function fillCells($row)
54445 {
54446 $newRow = array();
54447 foreach ($row as $column => $cell) {
54448 $newRow[] = $cell;
54449 if ($cell instanceof TableCell && $cell->getColspan() > 1) {
54450 foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) {
54451
54452  $newRow[] = '';
54453 }
54454 }
54455 }
54456
54457 return $newRow ?: $row;
54458 }
54459
54460
54461
54462
54463
54464
54465
54466 private function copyRow($rows, $line)
54467 {
54468 $row = $rows[$line];
54469 foreach ($row as $cellKey => $cellValue) {
54470 $row[$cellKey] = '';
54471 if ($cellValue instanceof TableCell) {
54472 $row[$cellKey] = new TableCell('', array('colspan' => $cellValue->getColspan()));
54473 }
54474 }
54475
54476 return $row;
54477 }
54478
54479
54480
54481
54482
54483
54484
54485
54486 private function getNumberOfColumns(array $row)
54487 {
54488 $columns = count($row);
54489 foreach ($row as $column) {
54490 $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0;
54491 }
54492
54493 return $columns;
54494 }
54495
54496
54497
54498
54499
54500
54501
54502
54503 private function getRowColumns($row)
54504 {
54505 $columns = range(0, $this->numberOfColumns - 1);
54506 foreach ($row as $cellKey => $cell) {
54507 if ($cell instanceof TableCell && $cell->getColspan() > 1) {
54508
54509  $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1));
54510 }
54511 }
54512
54513 return $columns;
54514 }
54515
54516
54517
54518
54519
54520
54521 private function calculateColumnsWidth($rows)
54522 {
54523 for ($column = 0; $column < $this->numberOfColumns; ++$column) {
54524 $lengths = array();
54525 foreach ($rows as $row) {
54526 if ($row instanceof TableSeparator) {
54527 continue;
54528 }
54529
54530 foreach ($row as $i => $cell) {
54531 if ($cell instanceof TableCell) {
54532 $textLength = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
54533 if ($textLength > 0) {
54534 $contentColumns = str_split($cell, ceil($textLength / $cell->getColspan()));
54535 foreach ($contentColumns as $position => $content) {
54536 $row[$i + $position] = $content;
54537 }
54538 }
54539 }
54540 }
54541
54542 $lengths[] = $this->getCellWidth($row, $column);
54543 }
54544
54545 $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
54546 }
54547 }
54548
54549
54550
54551
54552
54553
54554 private function getColumnSeparatorWidth()
54555 {
54556 return strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
54557 }
54558
54559
54560
54561
54562
54563
54564
54565
54566
54567 private function getCellWidth(array $row, $column)
54568 {
54569 if (isset($row[$column])) {
54570 $cell = $row[$column];
54571 $cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
54572
54573 return $cellWidth;
54574 }
54575
54576 return 0;
54577 }
54578
54579
54580
54581
54582 private function cleanup()
54583 {
54584 $this->columnWidths = array();
54585 $this->numberOfColumns = null;
54586 }
54587
54588 private static function initStyles()
54589 {
54590 $borderless = new TableStyle();
54591 $borderless
54592 ->setHorizontalBorderChar('=')
54593 ->setVerticalBorderChar(' ')
54594 ->setCrossingChar(' ')
54595 ;
54596
54597 $compact = new TableStyle();
54598 $compact
54599 ->setHorizontalBorderChar('')
54600 ->setVerticalBorderChar(' ')
54601 ->setCrossingChar('')
54602 ->setCellRowContentFormat('%s')
54603 ;
54604
54605 $styleGuide = new TableStyle();
54606 $styleGuide
54607 ->setHorizontalBorderChar('-')
54608 ->setVerticalBorderChar(' ')
54609 ->setCrossingChar(' ')
54610 ->setCellHeaderFormat('%s')
54611 ;
54612
54613 return array(
54614 'default' => new TableStyle(),
54615 'borderless' => $borderless,
54616 'compact' => $compact,
54617 'symfony-style-guide' => $styleGuide,
54618 );
54619 }
54620
54621 private function resolveStyle($name)
54622 {
54623 if ($name instanceof TableStyle) {
54624 return $name;
54625 }
54626
54627 if (isset(self::$styles[$name])) {
54628 return self::$styles[$name];
54629 }
54630
54631 throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
54632 }
54633 }
54634 <?php
54635
54636
54637
54638
54639
54640
54641
54642
54643
54644
54645 namespace Symfony\Component\Console\Helper;
54646
54647 use Symfony\Component\Console\Exception\InvalidArgumentException;
54648
54649
54650
54651
54652 class TableCell
54653 {
54654
54655
54656
54657 private $value;
54658
54659
54660
54661
54662 private $options = array(
54663 'rowspan' => 1,
54664 'colspan' => 1,
54665 );
54666
54667
54668
54669
54670
54671 public function __construct($value = '', array $options = array())
54672 {
54673 if (is_numeric($value) && !is_string($value)) {
54674 $value = (string) $value;
54675 }
54676
54677 $this->value = $value;
54678
54679
54680  if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
54681 throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff)));
54682 }
54683
54684 $this->options = array_merge($this->options, $options);
54685 }
54686
54687
54688
54689
54690
54691
54692 public function __toString()
54693 {
54694 return $this->value;
54695 }
54696
54697
54698
54699
54700
54701
54702 public function getColspan()
54703 {
54704 return (int) $this->options['colspan'];
54705 }
54706
54707
54708
54709
54710
54711
54712 public function getRowspan()
54713 {
54714 return (int) $this->options['rowspan'];
54715 }
54716 }
54717 <?php
54718
54719
54720
54721
54722
54723
54724
54725
54726
54727
54728 namespace Symfony\Component\Console\Helper;
54729
54730 use Symfony\Component\Console\Output\OutputInterface;
54731 use Symfony\Component\Console\Output\NullOutput;
54732 use Symfony\Component\Console\Exception\InvalidArgumentException;
54733
54734
54735
54736
54737
54738
54739
54740
54741
54742
54743 class TableHelper extends Helper
54744 {
54745 const LAYOUT_DEFAULT = 0;
54746 const LAYOUT_BORDERLESS = 1;
54747 const LAYOUT_COMPACT = 2;
54748
54749
54750
54751
54752 private $table;
54753
54754 public function __construct($triggerDeprecationError = true)
54755 {
54756 if ($triggerDeprecationError) {
54757 @trigger_error('The '.__CLASS__.' class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\Table class instead.', E_USER_DEPRECATED);
54758 }
54759
54760 $this->table = new Table(new NullOutput());
54761 }
54762
54763
54764
54765
54766
54767
54768
54769
54770
54771
54772 public function setLayout($layout)
54773 {
54774 switch ($layout) {
54775 case self::LAYOUT_BORDERLESS:
54776 $this->table->setStyle('borderless');
54777 break;
54778
54779 case self::LAYOUT_COMPACT:
54780 $this->table->setStyle('compact');
54781 break;
54782
54783 case self::LAYOUT_DEFAULT:
54784 $this->table->setStyle('default');
54785 break;
54786
54787 default:
54788 throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
54789 }
54790
54791 return $this;
54792 }
54793
54794 public function setHeaders(array $headers)
54795 {
54796 $this->table->setHeaders($headers);
54797
54798 return $this;
54799 }
54800
54801 public function setRows(array $rows)
54802 {
54803 $this->table->setRows($rows);
54804
54805 return $this;
54806 }
54807
54808 public function addRows(array $rows)
54809 {
54810 $this->table->addRows($rows);
54811
54812 return $this;
54813 }
54814
54815 public function addRow(array $row)
54816 {
54817 $this->table->addRow($row);
54818
54819 return $this;
54820 }
54821
54822 public function setRow($column, array $row)
54823 {
54824 $this->table->setRow($column, $row);
54825
54826 return $this;
54827 }
54828
54829
54830
54831
54832
54833
54834
54835
54836 public function setPaddingChar($paddingChar)
54837 {
54838 $this->table->getStyle()->setPaddingChar($paddingChar);
54839
54840 return $this;
54841 }
54842
54843
54844
54845
54846
54847
54848
54849
54850 public function setHorizontalBorderChar($horizontalBorderChar)
54851 {
54852 $this->table->getStyle()->setHorizontalBorderChar($horizontalBorderChar);
54853
54854 return $this;
54855 }
54856
54857
54858
54859
54860
54861
54862
54863
54864 public function setVerticalBorderChar($verticalBorderChar)
54865 {
54866 $this->table->getStyle()->setVerticalBorderChar($verticalBorderChar);
54867
54868 return $this;
54869 }
54870
54871
54872
54873
54874
54875
54876
54877
54878 public function setCrossingChar($crossingChar)
54879 {
54880 $this->table->getStyle()->setCrossingChar($crossingChar);
54881
54882 return $this;
54883 }
54884
54885
54886
54887
54888
54889
54890
54891
54892 public function setCellHeaderFormat($cellHeaderFormat)
54893 {
54894 $this->table->getStyle()->setCellHeaderFormat($cellHeaderFormat);
54895
54896 return $this;
54897 }
54898
54899
54900
54901
54902
54903
54904
54905
54906 public function setCellRowFormat($cellRowFormat)
54907 {
54908 $this->table->getStyle()->setCellHeaderFormat($cellRowFormat);
54909
54910 return $this;
54911 }
54912
54913
54914
54915
54916
54917
54918
54919
54920 public function setCellRowContentFormat($cellRowContentFormat)
54921 {
54922 $this->table->getStyle()->setCellRowContentFormat($cellRowContentFormat);
54923
54924 return $this;
54925 }
54926
54927
54928
54929
54930
54931
54932
54933
54934 public function setBorderFormat($borderFormat)
54935 {
54936 $this->table->getStyle()->setBorderFormat($borderFormat);
54937
54938 return $this;
54939 }
54940
54941
54942
54943
54944
54945
54946
54947
54948 public function setPadType($padType)
54949 {
54950 $this->table->getStyle()->setPadType($padType);
54951
54952 return $this;
54953 }
54954
54955
54956
54957
54958
54959
54960
54961
54962
54963
54964
54965
54966
54967
54968
54969 public function render(OutputInterface $output)
54970 {
54971 $p = new \ReflectionProperty($this->table, 'output');
54972 $p->setAccessible(true);
54973 $p->setValue($this->table, $output);
54974
54975 $this->table->render();
54976 }
54977
54978
54979
54980
54981 public function getName()
54982 {
54983 return 'table';
54984 }
54985 }
54986 <?php
54987
54988
54989
54990
54991
54992
54993
54994
54995
54996
54997 namespace Symfony\Component\Console\Helper;
54998
54999
55000
55001
55002
55003
55004 class TableSeparator extends TableCell
55005 {
55006
55007
55008
55009 public function __construct(array $options = array())
55010 {
55011 parent::__construct('', $options);
55012 }
55013 }
55014 <?php
55015
55016
55017
55018
55019
55020
55021
55022
55023
55024
55025 namespace Symfony\Component\Console\Helper;
55026
55027 use Symfony\Component\Console\Exception\InvalidArgumentException;
55028 use Symfony\Component\Console\Exception\LogicException;
55029
55030
55031
55032
55033
55034
55035
55036 class TableStyle
55037 {
55038 private $paddingChar = ' ';
55039 private $horizontalBorderChar = '-';
55040 private $verticalBorderChar = '|';
55041 private $crossingChar = '+';
55042 private $cellHeaderFormat = '<info>%s</info>';
55043 private $cellRowFormat = '%s';
55044 private $cellRowContentFormat = ' %s ';
55045 private $borderFormat = '%s';
55046 private $padType = STR_PAD_RIGHT;
55047
55048
55049
55050
55051
55052
55053
55054
55055 public function setPaddingChar($paddingChar)
55056 {
55057 if (!$paddingChar) {
55058 throw new LogicException('The padding char must not be empty');
55059 }
55060
55061 $this->paddingChar = $paddingChar;
55062
55063 return $this;
55064 }
55065
55066
55067
55068
55069
55070
55071 public function getPaddingChar()
55072 {
55073 return $this->paddingChar;
55074 }
55075
55076
55077
55078
55079
55080
55081
55082
55083 public function setHorizontalBorderChar($horizontalBorderChar)
55084 {
55085 $this->horizontalBorderChar = $horizontalBorderChar;
55086
55087 return $this;
55088 }
55089
55090
55091
55092
55093
55094
55095 public function getHorizontalBorderChar()
55096 {
55097 return $this->horizontalBorderChar;
55098 }
55099
55100
55101
55102
55103
55104
55105
55106
55107 public function setVerticalBorderChar($verticalBorderChar)
55108 {
55109 $this->verticalBorderChar = $verticalBorderChar;
55110
55111 return $this;
55112 }
55113
55114
55115
55116
55117
55118
55119 public function getVerticalBorderChar()
55120 {
55121 return $this->verticalBorderChar;
55122 }
55123
55124
55125
55126
55127
55128
55129
55130
55131 public function setCrossingChar($crossingChar)
55132 {
55133 $this->crossingChar = $crossingChar;
55134
55135 return $this;
55136 }
55137
55138
55139
55140
55141
55142
55143 public function getCrossingChar()
55144 {
55145 return $this->crossingChar;
55146 }
55147
55148
55149
55150
55151
55152
55153
55154
55155 public function setCellHeaderFormat($cellHeaderFormat)
55156 {
55157 $this->cellHeaderFormat = $cellHeaderFormat;
55158
55159 return $this;
55160 }
55161
55162
55163
55164
55165
55166
55167 public function getCellHeaderFormat()
55168 {
55169 return $this->cellHeaderFormat;
55170 }
55171
55172
55173
55174
55175
55176
55177
55178
55179 public function setCellRowFormat($cellRowFormat)
55180 {
55181 $this->cellRowFormat = $cellRowFormat;
55182
55183 return $this;
55184 }
55185
55186
55187
55188
55189
55190
55191 public function getCellRowFormat()
55192 {
55193 return $this->cellRowFormat;
55194 }
55195
55196
55197
55198
55199
55200
55201
55202
55203 public function setCellRowContentFormat($cellRowContentFormat)
55204 {
55205 $this->cellRowContentFormat = $cellRowContentFormat;
55206
55207 return $this;
55208 }
55209
55210
55211
55212
55213
55214
55215 public function getCellRowContentFormat()
55216 {
55217 return $this->cellRowContentFormat;
55218 }
55219
55220
55221
55222
55223
55224
55225
55226
55227 public function setBorderFormat($borderFormat)
55228 {
55229 $this->borderFormat = $borderFormat;
55230
55231 return $this;
55232 }
55233
55234
55235
55236
55237
55238
55239 public function getBorderFormat()
55240 {
55241 return $this->borderFormat;
55242 }
55243
55244
55245
55246
55247
55248
55249
55250
55251 public function setPadType($padType)
55252 {
55253 if (!in_array($padType, array(STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH), true)) {
55254 throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
55255 }
55256
55257 $this->padType = $padType;
55258
55259 return $this;
55260 }
55261
55262
55263
55264
55265
55266
55267 public function getPadType()
55268 {
55269 return $this->padType;
55270 }
55271 }
55272 <?php
55273
55274
55275
55276
55277
55278
55279
55280
55281
55282
55283 namespace Symfony\Component\Console\Input;
55284
55285 use Symfony\Component\Console\Exception\RuntimeException;
55286
55287
55288
55289
55290
55291
55292
55293
55294
55295
55296
55297
55298
55299
55300
55301
55302
55303
55304
55305
55306
55307
55308
55309
55310
55311
55312 class ArgvInput extends Input
55313 {
55314 private $tokens;
55315 private $parsed;
55316
55317
55318
55319
55320
55321
55322
55323 public function __construct(array $argv = null, InputDefinition $definition = null)
55324 {
55325 if (null === $argv) {
55326 $argv = $_SERVER['argv'];
55327 }
55328
55329
55330  array_shift($argv);
55331
55332 $this->tokens = $argv;
55333
55334 parent::__construct($definition);
55335 }
55336
55337 protected function setTokens(array $tokens)
55338 {
55339 $this->tokens = $tokens;
55340 }
55341
55342
55343
55344
55345 protected function parse()
55346 {
55347 $parseOptions = true;
55348 $this->parsed = $this->tokens;
55349 while (null !== $token = array_shift($this->parsed)) {
55350 if ($parseOptions && '' == $token) {
55351 $this->parseArgument($token);
55352 } elseif ($parseOptions && '--' == $token) {
55353 $parseOptions = false;
55354 } elseif ($parseOptions && 0 === strpos($token, '--')) {
55355 $this->parseLongOption($token);
55356 } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
55357 $this->parseShortOption($token);
55358 } else {
55359 $this->parseArgument($token);
55360 }
55361 }
55362 }
55363
55364
55365
55366
55367
55368
55369 private function parseShortOption($token)
55370 {
55371 $name = substr($token, 1);
55372
55373 if (strlen($name) > 1) {
55374 if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
55375
55376  $this->addShortOption($name[0], substr($name, 1));
55377 } else {
55378 $this->parseShortOptionSet($name);
55379 }
55380 } else {
55381 $this->addShortOption($name, null);
55382 }
55383 }
55384
55385
55386
55387
55388
55389
55390
55391
55392 private function parseShortOptionSet($name)
55393 {
55394 $len = strlen($name);
55395 for ($i = 0; $i < $len; ++$i) {
55396 if (!$this->definition->hasShortcut($name[$i])) {
55397 throw new RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
55398 }
55399
55400 $option = $this->definition->getOptionForShortcut($name[$i]);
55401 if ($option->acceptValue()) {
55402 $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
55403
55404 break;
55405 } else {
55406 $this->addLongOption($option->getName(), null);
55407 }
55408 }
55409 }
55410
55411
55412
55413
55414
55415
55416 private function parseLongOption($token)
55417 {
55418 $name = substr($token, 2);
55419
55420 if (false !== $pos = strpos($name, '=')) {
55421 if (0 === strlen($value = substr($name, $pos + 1))) {
55422 array_unshift($this->parsed, null);
55423 }
55424 $this->addLongOption(substr($name, 0, $pos), $value);
55425 } else {
55426 $this->addLongOption($name, null);
55427 }
55428 }
55429
55430
55431
55432
55433
55434
55435
55436
55437 private function parseArgument($token)
55438 {
55439 $c = count($this->arguments);
55440
55441
55442  if ($this->definition->hasArgument($c)) {
55443 $arg = $this->definition->getArgument($c);
55444 $this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token;
55445
55446
55447  } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
55448 $arg = $this->definition->getArgument($c - 1);
55449 $this->arguments[$arg->getName()][] = $token;
55450
55451
55452  } else {
55453 $all = $this->definition->getArguments();
55454 if (count($all)) {
55455 throw new RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all))));
55456 }
55457
55458 throw new RuntimeException(sprintf('No arguments expected, got "%s".', $token));
55459 }
55460 }
55461
55462
55463
55464
55465
55466
55467
55468
55469
55470 private function addShortOption($shortcut, $value)
55471 {
55472 if (!$this->definition->hasShortcut($shortcut)) {
55473 throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
55474 }
55475
55476 $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
55477 }
55478
55479
55480
55481
55482
55483
55484
55485
55486
55487 private function addLongOption($name, $value)
55488 {
55489 if (!$this->definition->hasOption($name)) {
55490 throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name));
55491 }
55492
55493 $option = $this->definition->getOption($name);
55494
55495
55496  if (!isset($value[0])) {
55497 $value = null;
55498 }
55499
55500 if (null !== $value && !$option->acceptValue()) {
55501 throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
55502 }
55503
55504 if (null === $value && $option->acceptValue() && count($this->parsed)) {
55505
55506  
55507  $next = array_shift($this->parsed);
55508 if (isset($next[0]) && '-' !== $next[0]) {
55509 $value = $next;
55510 } elseif (empty($next)) {
55511 $value = null;
55512 } else {
55513 array_unshift($this->parsed, $next);
55514 }
55515 }
55516
55517 if (null === $value) {
55518 if ($option->isValueRequired()) {
55519 throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
55520 }
55521
55522 if (!$option->isArray()) {
55523 $value = $option->isValueOptional() ? $option->getDefault() : true;
55524 }
55525 }
55526
55527 if ($option->isArray()) {
55528 $this->options[$name][] = $value;
55529 } else {
55530 $this->options[$name] = $value;
55531 }
55532 }
55533
55534
55535
55536
55537 public function getFirstArgument()
55538 {
55539 foreach ($this->tokens as $token) {
55540 if ($token && '-' === $token[0]) {
55541 continue;
55542 }
55543
55544 return $token;
55545 }
55546 }
55547
55548
55549
55550
55551 public function hasParameterOption($values)
55552 {
55553 $values = (array) $values;
55554
55555 foreach ($this->tokens as $token) {
55556 foreach ($values as $value) {
55557 if ($token === $value || 0 === strpos($token, $value.'=')) {
55558 return true;
55559 }
55560 }
55561 }
55562
55563 return false;
55564 }
55565
55566
55567
55568
55569 public function getParameterOption($values, $default = false)
55570 {
55571 $values = (array) $values;
55572 $tokens = $this->tokens;
55573
55574 while (0 < count($tokens)) {
55575 $token = array_shift($tokens);
55576
55577 foreach ($values as $value) {
55578 if ($token === $value || 0 === strpos($token, $value.'=')) {
55579 if (false !== $pos = strpos($token, '=')) {
55580 return substr($token, $pos + 1);
55581 }
55582
55583 return array_shift($tokens);
55584 }
55585 }
55586 }
55587
55588 return $default;
55589 }
55590
55591
55592
55593
55594
55595
55596 public function __toString()
55597 {
55598 $self = $this;
55599 $tokens = array_map(function ($token) use ($self) {
55600 if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
55601 return $match[1].$self->escapeToken($match[2]);
55602 }
55603
55604 if ($token && $token[0] !== '-') {
55605 return $self->escapeToken($token);
55606 }
55607
55608 return $token;
55609 }, $this->tokens);
55610
55611 return implode(' ', $tokens);
55612 }
55613 }
55614 <?php
55615
55616
55617
55618
55619
55620
55621
55622
55623
55624
55625 namespace Symfony\Component\Console\Input;
55626
55627 use Symfony\Component\Console\Exception\InvalidArgumentException;
55628 use Symfony\Component\Console\Exception\InvalidOptionException;
55629
55630
55631
55632
55633
55634
55635
55636
55637
55638
55639 class ArrayInput extends Input
55640 {
55641 private $parameters;
55642
55643
55644
55645
55646
55647
55648
55649 public function __construct(array $parameters, InputDefinition $definition = null)
55650 {
55651 $this->parameters = $parameters;
55652
55653 parent::__construct($definition);
55654 }
55655
55656
55657
55658
55659 public function getFirstArgument()
55660 {
55661 foreach ($this->parameters as $key => $value) {
55662 if ($key && '-' === $key[0]) {
55663 continue;
55664 }
55665
55666 return $value;
55667 }
55668 }
55669
55670
55671
55672
55673 public function hasParameterOption($values)
55674 {
55675 $values = (array) $values;
55676
55677 foreach ($this->parameters as $k => $v) {
55678 if (!is_int($k)) {
55679 $v = $k;
55680 }
55681
55682 if (in_array($v, $values)) {
55683 return true;
55684 }
55685 }
55686
55687 return false;
55688 }
55689
55690
55691
55692
55693 public function getParameterOption($values, $default = false)
55694 {
55695 $values = (array) $values;
55696
55697 foreach ($this->parameters as $k => $v) {
55698 if (is_int($k)) {
55699 if (in_array($v, $values)) {
55700 return true;
55701 }
55702 } elseif (in_array($k, $values)) {
55703 return $v;
55704 }
55705 }
55706
55707 return $default;
55708 }
55709
55710
55711
55712
55713
55714
55715 public function __toString()
55716 {
55717 $params = array();
55718 foreach ($this->parameters as $param => $val) {
55719 if ($param && '-' === $param[0]) {
55720 $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
55721 } else {
55722 $params[] = $this->escapeToken($val);
55723 }
55724 }
55725
55726 return implode(' ', $params);
55727 }
55728
55729
55730
55731
55732 protected function parse()
55733 {
55734 foreach ($this->parameters as $key => $value) {
55735 if (0 === strpos($key, '--')) {
55736 $this->addLongOption(substr($key, 2), $value);
55737 } elseif ('-' === $key[0]) {
55738 $this->addShortOption(substr($key, 1), $value);
55739 } else {
55740 $this->addArgument($key, $value);
55741 }
55742 }
55743 }
55744
55745
55746
55747
55748
55749
55750
55751
55752
55753 private function addShortOption($shortcut, $value)
55754 {
55755 if (!$this->definition->hasShortcut($shortcut)) {
55756 throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut));
55757 }
55758
55759 $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
55760 }
55761
55762
55763
55764
55765
55766
55767
55768
55769
55770
55771 private function addLongOption($name, $value)
55772 {
55773 if (!$this->definition->hasOption($name)) {
55774 throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name));
55775 }
55776
55777 $option = $this->definition->getOption($name);
55778
55779 if (null === $value) {
55780 if ($option->isValueRequired()) {
55781 throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
55782 }
55783
55784 $value = $option->isValueOptional() ? $option->getDefault() : true;
55785 }
55786
55787 $this->options[$name] = $value;
55788 }
55789
55790
55791
55792
55793
55794
55795
55796
55797
55798 private function addArgument($name, $value)
55799 {
55800 if (!$this->definition->hasArgument($name)) {
55801 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
55802 }
55803
55804 $this->arguments[$name] = $value;
55805 }
55806 }
55807 <?php
55808
55809
55810
55811
55812
55813
55814
55815
55816
55817
55818 namespace Symfony\Component\Console\Input;
55819
55820 use Symfony\Component\Console\Exception\InvalidArgumentException;
55821 use Symfony\Component\Console\Exception\RuntimeException;
55822
55823
55824
55825
55826
55827
55828
55829
55830
55831
55832
55833
55834 abstract class Input implements InputInterface
55835 {
55836
55837
55838
55839 protected $definition;
55840 protected $options = array();
55841 protected $arguments = array();
55842 protected $interactive = true;
55843
55844
55845
55846
55847
55848
55849 public function __construct(InputDefinition $definition = null)
55850 {
55851 if (null === $definition) {
55852 $this->definition = new InputDefinition();
55853 } else {
55854 $this->bind($definition);
55855 $this->validate();
55856 }
55857 }
55858
55859
55860
55861
55862 public function bind(InputDefinition $definition)
55863 {
55864 $this->arguments = array();
55865 $this->options = array();
55866 $this->definition = $definition;
55867
55868 $this->parse();
55869 }
55870
55871
55872
55873
55874 abstract protected function parse();
55875
55876
55877
55878
55879 public function validate()
55880 {
55881 $definition = $this->definition;
55882 $givenArguments = $this->arguments;
55883
55884 $missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) {
55885 return !array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
55886 });
55887
55888 if (count($missingArguments) > 0) {
55889 throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
55890 }
55891 }
55892
55893
55894
55895
55896 public function isInteractive()
55897 {
55898 return $this->interactive;
55899 }
55900
55901
55902
55903
55904 public function setInteractive($interactive)
55905 {
55906 $this->interactive = (bool) $interactive;
55907 }
55908
55909
55910
55911
55912 public function getArguments()
55913 {
55914 return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
55915 }
55916
55917
55918
55919
55920 public function getArgument($name)
55921 {
55922 if (!$this->definition->hasArgument($name)) {
55923 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
55924 }
55925
55926 return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault();
55927 }
55928
55929
55930
55931
55932 public function setArgument($name, $value)
55933 {
55934 if (!$this->definition->hasArgument($name)) {
55935 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
55936 }
55937
55938 $this->arguments[$name] = $value;
55939 }
55940
55941
55942
55943
55944 public function hasArgument($name)
55945 {
55946 return $this->definition->hasArgument($name);
55947 }
55948
55949
55950
55951
55952 public function getOptions()
55953 {
55954 return array_merge($this->definition->getOptionDefaults(), $this->options);
55955 }
55956
55957
55958
55959
55960 public function getOption($name)
55961 {
55962 if (!$this->definition->hasOption($name)) {
55963 throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
55964 }
55965
55966 return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
55967 }
55968
55969
55970
55971
55972 public function setOption($name, $value)
55973 {
55974 if (!$this->definition->hasOption($name)) {
55975 throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
55976 }
55977
55978 $this->options[$name] = $value;
55979 }
55980
55981
55982
55983
55984 public function hasOption($name)
55985 {
55986 return $this->definition->hasOption($name);
55987 }
55988
55989
55990
55991
55992
55993
55994
55995
55996 public function escapeToken($token)
55997 {
55998 return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
55999 }
56000 }
56001 <?php
56002
56003
56004
56005
56006
56007
56008
56009
56010
56011
56012 namespace Symfony\Component\Console\Input;
56013
56014 use Symfony\Component\Console\Exception\InvalidArgumentException;
56015 use Symfony\Component\Console\Exception\LogicException;
56016
56017
56018
56019
56020
56021
56022 class InputArgument
56023 {
56024 const REQUIRED = 1;
56025 const OPTIONAL = 2;
56026 const IS_ARRAY = 4;
56027
56028 private $name;
56029 private $mode;
56030 private $default;
56031 private $description;
56032
56033
56034
56035
56036
56037
56038
56039
56040
56041
56042
56043 public function __construct($name, $mode = null, $description = '', $default = null)
56044 {
56045 if (null === $mode) {
56046 $mode = self::OPTIONAL;
56047 } elseif (!is_int($mode) || $mode > 7 || $mode < 1) {
56048 throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
56049 }
56050
56051 $this->name = $name;
56052 $this->mode = $mode;
56053 $this->description = $description;
56054
56055 $this->setDefault($default);
56056 }
56057
56058
56059
56060
56061
56062
56063 public function getName()
56064 {
56065 return $this->name;
56066 }
56067
56068
56069
56070
56071
56072
56073 public function isRequired()
56074 {
56075 return self::REQUIRED === (self::REQUIRED & $this->mode);
56076 }
56077
56078
56079
56080
56081
56082
56083 public function isArray()
56084 {
56085 return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
56086 }
56087
56088
56089
56090
56091
56092
56093
56094
56095 public function setDefault($default = null)
56096 {
56097 if (self::REQUIRED === $this->mode && null !== $default) {
56098 throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
56099 }
56100
56101 if ($this->isArray()) {
56102 if (null === $default) {
56103 $default = array();
56104 } elseif (!is_array($default)) {
56105 throw new LogicException('A default value for an array argument must be an array.');
56106 }
56107 }
56108
56109 $this->default = $default;
56110 }
56111
56112
56113
56114
56115
56116
56117 public function getDefault()
56118 {
56119 return $this->default;
56120 }
56121
56122
56123
56124
56125
56126
56127 public function getDescription()
56128 {
56129 return $this->description;
56130 }
56131 }
56132 <?php
56133
56134
56135
56136
56137
56138
56139
56140
56141
56142
56143 namespace Symfony\Component\Console\Input;
56144
56145
56146
56147
56148
56149
56150
56151 interface InputAwareInterface
56152 {
56153
56154
56155
56156
56157
56158 public function setInput(InputInterface $input);
56159 }
56160 <?php
56161
56162
56163
56164
56165
56166
56167
56168
56169
56170
56171 namespace Symfony\Component\Console\Input;
56172
56173 use Symfony\Component\Console\Descriptor\TextDescriptor;
56174 use Symfony\Component\Console\Descriptor\XmlDescriptor;
56175 use Symfony\Component\Console\Output\BufferedOutput;
56176 use Symfony\Component\Console\Exception\InvalidArgumentException;
56177 use Symfony\Component\Console\Exception\LogicException;
56178
56179
56180
56181
56182
56183
56184
56185
56186
56187
56188
56189
56190
56191 class InputDefinition
56192 {
56193 private $arguments;
56194 private $requiredCount;
56195 private $hasAnArrayArgument = false;
56196 private $hasOptional;
56197 private $options;
56198 private $shortcuts;
56199
56200
56201
56202
56203
56204
56205 public function __construct(array $definition = array())
56206 {
56207 $this->setDefinition($definition);
56208 }
56209
56210
56211
56212
56213
56214
56215 public function setDefinition(array $definition)
56216 {
56217 $arguments = array();
56218 $options = array();
56219 foreach ($definition as $item) {
56220 if ($item instanceof InputOption) {
56221 $options[] = $item;
56222 } else {
56223 $arguments[] = $item;
56224 }
56225 }
56226
56227 $this->setArguments($arguments);
56228 $this->setOptions($options);
56229 }
56230
56231
56232
56233
56234
56235
56236 public function setArguments($arguments = array())
56237 {
56238 $this->arguments = array();
56239 $this->requiredCount = 0;
56240 $this->hasOptional = false;
56241 $this->hasAnArrayArgument = false;
56242 $this->addArguments($arguments);
56243 }
56244
56245
56246
56247
56248
56249
56250 public function addArguments($arguments = array())
56251 {
56252 if (null !== $arguments) {
56253 foreach ($arguments as $argument) {
56254 $this->addArgument($argument);
56255 }
56256 }
56257 }
56258
56259
56260
56261
56262
56263
56264
56265
56266 public function addArgument(InputArgument $argument)
56267 {
56268 if (isset($this->arguments[$argument->getName()])) {
56269 throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
56270 }
56271
56272 if ($this->hasAnArrayArgument) {
56273 throw new LogicException('Cannot add an argument after an array argument.');
56274 }
56275
56276 if ($argument->isRequired() && $this->hasOptional) {
56277 throw new LogicException('Cannot add a required argument after an optional one.');
56278 }
56279
56280 if ($argument->isArray()) {
56281 $this->hasAnArrayArgument = true;
56282 }
56283
56284 if ($argument->isRequired()) {
56285 ++$this->requiredCount;
56286 } else {
56287 $this->hasOptional = true;
56288 }
56289
56290 $this->arguments[$argument->getName()] = $argument;
56291 }
56292
56293
56294
56295
56296
56297
56298
56299
56300
56301
56302 public function getArgument($name)
56303 {
56304 if (!$this->hasArgument($name)) {
56305 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
56306 }
56307
56308 $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
56309
56310 return $arguments[$name];
56311 }
56312
56313
56314
56315
56316
56317
56318
56319
56320 public function hasArgument($name)
56321 {
56322 $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
56323
56324 return isset($arguments[$name]);
56325 }
56326
56327
56328
56329
56330
56331
56332 public function getArguments()
56333 {
56334 return $this->arguments;
56335 }
56336
56337
56338
56339
56340
56341
56342 public function getArgumentCount()
56343 {
56344 return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
56345 }
56346
56347
56348
56349
56350
56351
56352 public function getArgumentRequiredCount()
56353 {
56354 return $this->requiredCount;
56355 }
56356
56357
56358
56359
56360
56361
56362 public function getArgumentDefaults()
56363 {
56364 $values = array();
56365 foreach ($this->arguments as $argument) {
56366 $values[$argument->getName()] = $argument->getDefault();
56367 }
56368
56369 return $values;
56370 }
56371
56372
56373
56374
56375
56376
56377 public function setOptions($options = array())
56378 {
56379 $this->options = array();
56380 $this->shortcuts = array();
56381 $this->addOptions($options);
56382 }
56383
56384
56385
56386
56387
56388
56389 public function addOptions($options = array())
56390 {
56391 foreach ($options as $option) {
56392 $this->addOption($option);
56393 }
56394 }
56395
56396
56397
56398
56399
56400
56401
56402
56403 public function addOption(InputOption $option)
56404 {
56405 if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
56406 throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
56407 }
56408
56409 if ($option->getShortcut()) {
56410 foreach (explode('|', $option->getShortcut()) as $shortcut) {
56411 if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
56412 throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
56413 }
56414 }
56415 }
56416
56417 $this->options[$option->getName()] = $option;
56418 if ($option->getShortcut()) {
56419 foreach (explode('|', $option->getShortcut()) as $shortcut) {
56420 $this->shortcuts[$shortcut] = $option->getName();
56421 }
56422 }
56423 }
56424
56425
56426
56427
56428
56429
56430
56431
56432
56433
56434 public function getOption($name)
56435 {
56436 if (!$this->hasOption($name)) {
56437 throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
56438 }
56439
56440 return $this->options[$name];
56441 }
56442
56443
56444
56445
56446
56447
56448
56449
56450
56451
56452
56453 public function hasOption($name)
56454 {
56455 return isset($this->options[$name]);
56456 }
56457
56458
56459
56460
56461
56462
56463 public function getOptions()
56464 {
56465 return $this->options;
56466 }
56467
56468
56469
56470
56471
56472
56473
56474
56475 public function hasShortcut($name)
56476 {
56477 return isset($this->shortcuts[$name]);
56478 }
56479
56480
56481
56482
56483
56484
56485
56486
56487 public function getOptionForShortcut($shortcut)
56488 {
56489 return $this->getOption($this->shortcutToName($shortcut));
56490 }
56491
56492
56493
56494
56495
56496
56497 public function getOptionDefaults()
56498 {
56499 $values = array();
56500 foreach ($this->options as $option) {
56501 $values[$option->getName()] = $option->getDefault();
56502 }
56503
56504 return $values;
56505 }
56506
56507
56508
56509
56510
56511
56512
56513
56514
56515
56516 private function shortcutToName($shortcut)
56517 {
56518 if (!isset($this->shortcuts[$shortcut])) {
56519 throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
56520 }
56521
56522 return $this->shortcuts[$shortcut];
56523 }
56524
56525
56526
56527
56528
56529
56530
56531
56532 public function getSynopsis($short = false)
56533 {
56534 $elements = array();
56535
56536 if ($short && $this->getOptions()) {
56537 $elements[] = '[options]';
56538 } elseif (!$short) {
56539 foreach ($this->getOptions() as $option) {
56540 $value = '';
56541 if ($option->acceptValue()) {
56542 $value = sprintf(
56543 ' %s%s%s',
56544 $option->isValueOptional() ? '[' : '',
56545 strtoupper($option->getName()),
56546 $option->isValueOptional() ? ']' : ''
56547 );
56548 }
56549
56550 $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
56551 $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);
56552 }
56553 }
56554
56555 if (count($elements) && $this->getArguments()) {
56556 $elements[] = '[--]';
56557 }
56558
56559 foreach ($this->getArguments() as $argument) {
56560 $element = '<'.$argument->getName().'>';
56561 if (!$argument->isRequired()) {
56562 $element = '['.$element.']';
56563 } elseif ($argument->isArray()) {
56564 $element = $element.' ('.$element.')';
56565 }
56566
56567 if ($argument->isArray()) {
56568 $element .= '...';
56569 }
56570
56571 $elements[] = $element;
56572 }
56573
56574 return implode(' ', $elements);
56575 }
56576
56577
56578
56579
56580
56581
56582
56583
56584 public function asText()
56585 {
56586 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
56587
56588 $descriptor = new TextDescriptor();
56589 $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
56590 $descriptor->describe($output, $this, array('raw_output' => true));
56591
56592 return $output->fetch();
56593 }
56594
56595
56596
56597
56598
56599
56600
56601
56602
56603
56604 public function asXml($asDom = false)
56605 {
56606 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
56607
56608 $descriptor = new XmlDescriptor();
56609
56610 if ($asDom) {
56611 return $descriptor->getInputDefinitionDocument($this);
56612 }
56613
56614 $output = new BufferedOutput();
56615 $descriptor->describe($output, $this);
56616
56617 return $output->fetch();
56618 }
56619 }
56620 <?php
56621
56622
56623
56624
56625
56626
56627
56628
56629
56630
56631 namespace Symfony\Component\Console\Input;
56632
56633 use Symfony\Component\Console\Exception\InvalidArgumentException;
56634 use Symfony\Component\Console\Exception\RuntimeException;
56635
56636
56637
56638
56639
56640
56641 interface InputInterface
56642 {
56643
56644
56645
56646
56647
56648 public function getFirstArgument();
56649
56650
56651
56652
56653
56654
56655
56656
56657
56658
56659
56660 public function hasParameterOption($values);
56661
56662
56663
56664
56665
56666
56667
56668
56669
56670
56671
56672
56673 public function getParameterOption($values, $default = false);
56674
56675
56676
56677
56678
56679
56680 public function bind(InputDefinition $definition);
56681
56682
56683
56684
56685
56686
56687 public function validate();
56688
56689
56690
56691
56692
56693
56694 public function getArguments();
56695
56696
56697
56698
56699
56700
56701
56702
56703
56704
56705 public function getArgument($name);
56706
56707
56708
56709
56710
56711
56712
56713
56714
56715 public function setArgument($name, $value);
56716
56717
56718
56719
56720
56721
56722
56723
56724 public function hasArgument($name);
56725
56726
56727
56728
56729
56730
56731 public function getOptions();
56732
56733
56734
56735
56736
56737
56738
56739
56740
56741
56742 public function getOption($name);
56743
56744
56745
56746
56747
56748
56749
56750
56751
56752 public function setOption($name, $value);
56753
56754
56755
56756
56757
56758
56759
56760
56761 public function hasOption($name);
56762
56763
56764
56765
56766
56767
56768 public function isInteractive();
56769
56770
56771
56772
56773
56774
56775 public function setInteractive($interactive);
56776 }
56777 <?php
56778
56779
56780
56781
56782
56783
56784
56785
56786
56787
56788 namespace Symfony\Component\Console\Input;
56789
56790 use Symfony\Component\Console\Exception\InvalidArgumentException;
56791 use Symfony\Component\Console\Exception\LogicException;
56792
56793
56794
56795
56796
56797
56798 class InputOption
56799 {
56800 const VALUE_NONE = 1;
56801 const VALUE_REQUIRED = 2;
56802 const VALUE_OPTIONAL = 4;
56803 const VALUE_IS_ARRAY = 8;
56804
56805 private $name;
56806 private $shortcut;
56807 private $mode;
56808 private $default;
56809 private $description;
56810
56811
56812
56813
56814
56815
56816
56817
56818
56819
56820
56821
56822 public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
56823 {
56824 if (0 === strpos($name, '--')) {
56825 $name = substr($name, 2);
56826 }
56827
56828 if (empty($name)) {
56829 throw new InvalidArgumentException('An option name cannot be empty.');
56830 }
56831
56832 if (empty($shortcut)) {
56833 $shortcut = null;
56834 }
56835
56836 if (null !== $shortcut) {
56837 if (is_array($shortcut)) {
56838 $shortcut = implode('|', $shortcut);
56839 }
56840 $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
56841 $shortcuts = array_filter($shortcuts);
56842 $shortcut = implode('|', $shortcuts);
56843
56844 if (empty($shortcut)) {
56845 throw new InvalidArgumentException('An option shortcut cannot be empty.');
56846 }
56847 }
56848
56849 if (null === $mode) {
56850 $mode = self::VALUE_NONE;
56851 } elseif (!is_int($mode) || $mode > 15 || $mode < 1) {
56852 throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
56853 }
56854
56855 $this->name = $name;
56856 $this->shortcut = $shortcut;
56857 $this->mode = $mode;
56858 $this->description = $description;
56859
56860 if ($this->isArray() && !$this->acceptValue()) {
56861 throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
56862 }
56863
56864 $this->setDefault($default);
56865 }
56866
56867
56868
56869
56870
56871
56872 public function getShortcut()
56873 {
56874 return $this->shortcut;
56875 }
56876
56877
56878
56879
56880
56881
56882 public function getName()
56883 {
56884 return $this->name;
56885 }
56886
56887
56888
56889
56890
56891
56892 public function acceptValue()
56893 {
56894 return $this->isValueRequired() || $this->isValueOptional();
56895 }
56896
56897
56898
56899
56900
56901
56902 public function isValueRequired()
56903 {
56904 return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
56905 }
56906
56907
56908
56909
56910
56911
56912 public function isValueOptional()
56913 {
56914 return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
56915 }
56916
56917
56918
56919
56920
56921
56922 public function isArray()
56923 {
56924 return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
56925 }
56926
56927
56928
56929
56930
56931
56932
56933
56934 public function setDefault($default = null)
56935 {
56936 if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
56937 throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
56938 }
56939
56940 if ($this->isArray()) {
56941 if (null === $default) {
56942 $default = array();
56943 } elseif (!is_array($default)) {
56944 throw new LogicException('A default value for an array option must be an array.');
56945 }
56946 }
56947
56948 $this->default = $this->acceptValue() ? $default : false;
56949 }
56950
56951
56952
56953
56954
56955
56956 public function getDefault()
56957 {
56958 return $this->default;
56959 }
56960
56961
56962
56963
56964
56965
56966 public function getDescription()
56967 {
56968 return $this->description;
56969 }
56970
56971
56972
56973
56974
56975
56976
56977
56978 public function equals(InputOption $option)
56979 {
56980 return $option->getName() === $this->getName()
56981 && $option->getShortcut() === $this->getShortcut()
56982 && $option->getDefault() === $this->getDefault()
56983 && $option->isArray() === $this->isArray()
56984 && $option->isValueRequired() === $this->isValueRequired()
56985 && $option->isValueOptional() === $this->isValueOptional()
56986 ;
56987 }
56988 }
56989 <?php
56990
56991
56992
56993
56994
56995
56996
56997
56998
56999
57000 namespace Symfony\Component\Console\Input;
57001
57002 use Symfony\Component\Console\Exception\InvalidArgumentException;
57003
57004
57005
57006
57007
57008
57009
57010
57011
57012
57013 class StringInput extends ArgvInput
57014 {
57015 const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
57016 const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
57017
57018
57019
57020
57021
57022
57023
57024
57025
57026 public function __construct($input, InputDefinition $definition = null)
57027 {
57028 if ($definition) {
57029 @trigger_error('The $definition argument of the '.__METHOD__.' method is deprecated and will be removed in 3.0. Set this parameter with the bind() method instead.', E_USER_DEPRECATED);
57030 }
57031
57032 parent::__construct(array(), null);
57033
57034 $this->setTokens($this->tokenize($input));
57035
57036 if (null !== $definition) {
57037 $this->bind($definition);
57038 }
57039 }
57040
57041
57042
57043
57044
57045
57046
57047
57048
57049
57050 private function tokenize($input)
57051 {
57052 $tokens = array();
57053 $length = strlen($input);
57054 $cursor = 0;
57055 while ($cursor < $length) {
57056 if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
57057 } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
57058 $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
57059 } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
57060 $tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
57061 } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
57062 $tokens[] = stripcslashes($match[1]);
57063 } else {
57064
57065  throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
57066 }
57067
57068 $cursor += strlen($match[0]);
57069 }
57070
57071 return $tokens;
57072 }
57073 }
57074 Copyright (c) 2004-2017 Fabien Potencier
57075
57076 Permission is hereby granted, free of charge, to any person obtaining a copy
57077 of this software and associated documentation files (the "Software"), to deal
57078 in the Software without restriction, including without limitation the rights
57079 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57080 copies of the Software, and to permit persons to whom the Software is furnished
57081 to do so, subject to the following conditions:
57082
57083 The above copyright notice and this permission notice shall be included in all
57084 copies or substantial portions of the Software.
57085
57086 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57087 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57088 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57089 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57090 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57091 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57092 THE SOFTWARE.
57093 <?php
57094
57095
57096
57097
57098
57099
57100
57101
57102
57103
57104 namespace Symfony\Component\Console\Logger;
57105
57106 use Psr\Log\AbstractLogger;
57107 use Psr\Log\InvalidArgumentException;
57108 use Psr\Log\LogLevel;
57109 use Symfony\Component\Console\Output\OutputInterface;
57110 use Symfony\Component\Console\Output\ConsoleOutputInterface;
57111
57112
57113
57114
57115
57116
57117
57118
57119 class ConsoleLogger extends AbstractLogger
57120 {
57121 const INFO = 'info';
57122 const ERROR = 'error';
57123
57124
57125
57126
57127 private $output;
57128
57129
57130
57131 private $verbosityLevelMap = array(
57132 LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
57133 LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
57134 LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
57135 LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
57136 LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
57137 LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
57138 LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
57139 LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
57140 );
57141
57142
57143
57144 private $formatLevelMap = array(
57145 LogLevel::EMERGENCY => self::ERROR,
57146 LogLevel::ALERT => self::ERROR,
57147 LogLevel::CRITICAL => self::ERROR,
57148 LogLevel::ERROR => self::ERROR,
57149 LogLevel::WARNING => self::INFO,
57150 LogLevel::NOTICE => self::INFO,
57151 LogLevel::INFO => self::INFO,
57152 LogLevel::DEBUG => self::INFO,
57153 );
57154
57155
57156
57157
57158
57159
57160 public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array())
57161 {
57162 $this->output = $output;
57163 $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
57164 $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
57165 }
57166
57167
57168
57169
57170 public function log($level, $message, array $context = array())
57171 {
57172 if (!isset($this->verbosityLevelMap[$level])) {
57173 throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
57174 }
57175
57176
57177  if ($this->formatLevelMap[$level] === self::ERROR && $this->output instanceof ConsoleOutputInterface) {
57178 $output = $this->output->getErrorOutput();
57179 } else {
57180 $output = $this->output;
57181 }
57182
57183 if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
57184 $output->writeln(sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)));
57185 }
57186 }
57187
57188
57189
57190
57191
57192
57193
57194
57195
57196
57197
57198 private function interpolate($message, array $context)
57199 {
57200
57201  $replace = array();
57202 foreach ($context as $key => $val) {
57203 if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
57204 $replace[sprintf('{%s}', $key)] = $val;
57205 }
57206 }
57207
57208
57209  return strtr($message, $replace);
57210 }
57211 }
57212 <?php
57213
57214
57215
57216
57217
57218
57219
57220
57221
57222
57223 namespace Symfony\Component\Console\Output;
57224
57225
57226
57227
57228 class BufferedOutput extends Output
57229 {
57230
57231
57232
57233 private $buffer = '';
57234
57235
57236
57237
57238
57239
57240 public function fetch()
57241 {
57242 $content = $this->buffer;
57243 $this->buffer = '';
57244
57245 return $content;
57246 }
57247
57248
57249
57250
57251 protected function doWrite($message, $newline)
57252 {
57253 $this->buffer .= $message;
57254
57255 if ($newline) {
57256 $this->buffer .= "\n";
57257 }
57258 }
57259 }
57260 <?php
57261
57262
57263
57264
57265
57266
57267
57268
57269
57270
57271 namespace Symfony\Component\Console\Output;
57272
57273 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
57274
57275
57276
57277
57278
57279
57280
57281
57282
57283
57284
57285
57286
57287
57288 class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
57289 {
57290
57291
57292
57293 private $stderr;
57294
57295
57296
57297
57298
57299
57300
57301
57302 public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
57303 {
57304 parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
57305
57306 $actualDecorated = $this->isDecorated();
57307 $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
57308
57309 if (null === $decorated) {
57310 $this->setDecorated($actualDecorated && $this->stderr->isDecorated());
57311 }
57312 }
57313
57314
57315
57316
57317 public function setDecorated($decorated)
57318 {
57319 parent::setDecorated($decorated);
57320 $this->stderr->setDecorated($decorated);
57321 }
57322
57323
57324
57325
57326 public function setFormatter(OutputFormatterInterface $formatter)
57327 {
57328 parent::setFormatter($formatter);
57329 $this->stderr->setFormatter($formatter);
57330 }
57331
57332
57333
57334
57335 public function setVerbosity($level)
57336 {
57337 parent::setVerbosity($level);
57338 $this->stderr->setVerbosity($level);
57339 }
57340
57341
57342
57343
57344 public function getErrorOutput()
57345 {
57346 return $this->stderr;
57347 }
57348
57349
57350
57351
57352 public function setErrorOutput(OutputInterface $error)
57353 {
57354 $this->stderr = $error;
57355 }
57356
57357
57358
57359
57360
57361
57362
57363 protected function hasStdoutSupport()
57364 {
57365 return false === $this->isRunningOS400();
57366 }
57367
57368
57369
57370
57371
57372
57373
57374 protected function hasStderrSupport()
57375 {
57376 return false === $this->isRunningOS400();
57377 }
57378
57379
57380
57381
57382
57383
57384
57385 private function isRunningOS400()
57386 {
57387 $checks = array(
57388 function_exists('php_uname') ? php_uname('s') : '',
57389 getenv('OSTYPE'),
57390 PHP_OS,
57391 );
57392
57393 return false !== stripos(implode(';', $checks), 'OS400');
57394 }
57395
57396
57397
57398
57399 private function openOutputStream()
57400 {
57401 $outputStream = $this->hasStdoutSupport() ? 'php://stdout' : 'php://output';
57402
57403 return @fopen($outputStream, 'w') ?: fopen('php://output', 'w');
57404 }
57405
57406
57407
57408
57409 private function openErrorStream()
57410 {
57411 $errorStream = $this->hasStderrSupport() ? 'php://stderr' : 'php://output';
57412
57413 return fopen($errorStream, 'w');
57414 }
57415 }
57416 <?php
57417
57418
57419
57420
57421
57422
57423
57424
57425
57426
57427 namespace Symfony\Component\Console\Output;
57428
57429
57430
57431
57432
57433
57434
57435 interface ConsoleOutputInterface extends OutputInterface
57436 {
57437
57438
57439
57440
57441
57442 public function getErrorOutput();
57443
57444
57445
57446
57447
57448
57449 public function setErrorOutput(OutputInterface $error);
57450 }
57451 <?php
57452
57453
57454
57455
57456
57457
57458
57459
57460
57461
57462 namespace Symfony\Component\Console\Output;
57463
57464 use Symfony\Component\Console\Formatter\OutputFormatter;
57465 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
57466
57467
57468
57469
57470
57471
57472
57473
57474
57475 class NullOutput implements OutputInterface
57476 {
57477
57478
57479
57480 public function setFormatter(OutputFormatterInterface $formatter)
57481 {
57482
57483  }
57484
57485
57486
57487
57488 public function getFormatter()
57489 {
57490
57491  return new OutputFormatter();
57492 }
57493
57494
57495
57496
57497 public function setDecorated($decorated)
57498 {
57499
57500  }
57501
57502
57503
57504
57505 public function isDecorated()
57506 {
57507 return false;
57508 }
57509
57510
57511
57512
57513 public function setVerbosity($level)
57514 {
57515
57516  }
57517
57518
57519
57520
57521 public function getVerbosity()
57522 {
57523 return self::VERBOSITY_QUIET;
57524 }
57525
57526
57527
57528
57529 public function isQuiet()
57530 {
57531 return true;
57532 }
57533
57534
57535
57536
57537 public function isVerbose()
57538 {
57539 return false;
57540 }
57541
57542
57543
57544
57545 public function isVeryVerbose()
57546 {
57547 return false;
57548 }
57549
57550
57551
57552
57553 public function isDebug()
57554 {
57555 return false;
57556 }
57557
57558
57559
57560
57561 public function writeln($messages, $options = self::OUTPUT_NORMAL)
57562 {
57563
57564  }
57565
57566
57567
57568
57569 public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
57570 {
57571
57572  }
57573 }
57574 <?php
57575
57576
57577
57578
57579
57580
57581
57582
57583
57584
57585 namespace Symfony\Component\Console\Output;
57586
57587 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
57588 use Symfony\Component\Console\Formatter\OutputFormatter;
57589
57590
57591
57592
57593
57594
57595
57596
57597
57598
57599
57600
57601
57602
57603 abstract class Output implements OutputInterface
57604 {
57605 private $verbosity;
57606 private $formatter;
57607
57608
57609
57610
57611
57612
57613
57614
57615 public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null)
57616 {
57617 $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
57618 $this->formatter = $formatter ?: new OutputFormatter();
57619 $this->formatter->setDecorated($decorated);
57620 }
57621
57622
57623
57624
57625 public function setFormatter(OutputFormatterInterface $formatter)
57626 {
57627 $this->formatter = $formatter;
57628 }
57629
57630
57631
57632
57633 public function getFormatter()
57634 {
57635 return $this->formatter;
57636 }
57637
57638
57639
57640
57641 public function setDecorated($decorated)
57642 {
57643 $this->formatter->setDecorated($decorated);
57644 }
57645
57646
57647
57648
57649 public function isDecorated()
57650 {
57651 return $this->formatter->isDecorated();
57652 }
57653
57654
57655
57656
57657 public function setVerbosity($level)
57658 {
57659 $this->verbosity = (int) $level;
57660 }
57661
57662
57663
57664
57665 public function getVerbosity()
57666 {
57667 return $this->verbosity;
57668 }
57669
57670
57671
57672
57673 public function isQuiet()
57674 {
57675 return self::VERBOSITY_QUIET === $this->verbosity;
57676 }
57677
57678
57679
57680
57681 public function isVerbose()
57682 {
57683 return self::VERBOSITY_VERBOSE <= $this->verbosity;
57684 }
57685
57686
57687
57688
57689 public function isVeryVerbose()
57690 {
57691 return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
57692 }
57693
57694
57695
57696
57697 public function isDebug()
57698 {
57699 return self::VERBOSITY_DEBUG <= $this->verbosity;
57700 }
57701
57702
57703
57704
57705 public function writeln($messages, $options = self::OUTPUT_NORMAL)
57706 {
57707 $this->write($messages, true, $options);
57708 }
57709
57710
57711
57712
57713 public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
57714 {
57715 $messages = (array) $messages;
57716
57717 $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
57718 $type = $types & $options ?: self::OUTPUT_NORMAL;
57719
57720 $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
57721 $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;
57722
57723 if ($verbosity > $this->getVerbosity()) {
57724 return;
57725 }
57726
57727 foreach ($messages as $message) {
57728 switch ($type) {
57729 case OutputInterface::OUTPUT_NORMAL:
57730 $message = $this->formatter->format($message);
57731 break;
57732 case OutputInterface::OUTPUT_RAW:
57733 break;
57734 case OutputInterface::OUTPUT_PLAIN:
57735 $message = strip_tags($this->formatter->format($message));
57736 break;
57737 }
57738
57739 $this->doWrite($message, $newline);
57740 }
57741 }
57742
57743
57744
57745
57746
57747
57748
57749 abstract protected function doWrite($message, $newline);
57750 }
57751 <?php
57752
57753
57754
57755
57756
57757
57758
57759
57760
57761
57762 namespace Symfony\Component\Console\Output;
57763
57764 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
57765
57766
57767
57768
57769
57770
57771 interface OutputInterface
57772 {
57773 const VERBOSITY_QUIET = 16;
57774 const VERBOSITY_NORMAL = 32;
57775 const VERBOSITY_VERBOSE = 64;
57776 const VERBOSITY_VERY_VERBOSE = 128;
57777 const VERBOSITY_DEBUG = 256;
57778
57779 const OUTPUT_NORMAL = 1;
57780 const OUTPUT_RAW = 2;
57781 const OUTPUT_PLAIN = 4;
57782
57783
57784
57785
57786
57787
57788
57789
57790 public function write($messages, $newline = false, $options = 0);
57791
57792
57793
57794
57795
57796
57797
57798 public function writeln($messages, $options = 0);
57799
57800
57801
57802
57803
57804
57805 public function setVerbosity($level);
57806
57807
57808
57809
57810
57811
57812 public function getVerbosity();
57813
57814
57815
57816
57817
57818
57819 public function setDecorated($decorated);
57820
57821
57822
57823
57824
57825
57826 public function isDecorated();
57827
57828
57829
57830
57831
57832
57833 public function setFormatter(OutputFormatterInterface $formatter);
57834
57835
57836
57837
57838
57839
57840 public function getFormatter();
57841 }
57842 <?php
57843
57844
57845
57846
57847
57848
57849
57850
57851
57852
57853 namespace Symfony\Component\Console\Output;
57854
57855 use Symfony\Component\Console\Exception\InvalidArgumentException;
57856 use Symfony\Component\Console\Exception\RuntimeException;
57857 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
57858
57859
57860
57861
57862
57863
57864
57865
57866
57867
57868
57869
57870
57871
57872 class StreamOutput extends Output
57873 {
57874 private $stream;
57875
57876
57877
57878
57879
57880
57881
57882
57883
57884
57885
57886 public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
57887 {
57888 if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
57889 throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
57890 }
57891
57892 $this->stream = $stream;
57893
57894 if (null === $decorated) {
57895 $decorated = $this->hasColorSupport();
57896 }
57897
57898 parent::__construct($verbosity, $decorated, $formatter);
57899 }
57900
57901
57902
57903
57904
57905
57906 public function getStream()
57907 {
57908 return $this->stream;
57909 }
57910
57911
57912
57913
57914 protected function doWrite($message, $newline)
57915 {
57916 if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {
57917
57918  throw new RuntimeException('Unable to write output.');
57919 }
57920
57921 fflush($this->stream);
57922 }
57923
57924
57925
57926
57927
57928
57929
57930
57931
57932
57933
57934 protected function hasColorSupport()
57935 {
57936 if (DIRECTORY_SEPARATOR === '\\') {
57937 return
57938 '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD
57939 || false !== getenv('ANSICON')
57940 || 'ON' === getenv('ConEmuANSI')
57941 || 'xterm' === getenv('TERM');
57942 }
57943
57944 return function_exists('posix_isatty') && @posix_isatty($this->stream);
57945 }
57946 }
57947 <?php
57948
57949
57950
57951
57952
57953
57954
57955
57956
57957
57958 namespace Symfony\Component\Console\Question;
57959
57960 use Symfony\Component\Console\Exception\InvalidArgumentException;
57961
57962
57963
57964
57965
57966
57967 class ChoiceQuestion extends Question
57968 {
57969 private $choices;
57970 private $multiselect = false;
57971 private $prompt = ' > ';
57972 private $errorMessage = 'Value "%s" is invalid';
57973
57974
57975
57976
57977
57978
57979
57980
57981 public function __construct($question, array $choices, $default = null)
57982 {
57983 parent::__construct($question, $default);
57984
57985 $this->choices = $choices;
57986 $this->setValidator($this->getDefaultValidator());
57987 $this->setAutocompleterValues($choices);
57988 }
57989
57990
57991
57992
57993
57994
57995 public function getChoices()
57996 {
57997 return $this->choices;
57998 }
57999
58000
58001
58002
58003
58004
58005
58006
58007
58008
58009 public function setMultiselect($multiselect)
58010 {
58011 $this->multiselect = $multiselect;
58012 $this->setValidator($this->getDefaultValidator());
58013
58014 return $this;
58015 }
58016
58017
58018
58019
58020
58021
58022 public function isMultiselect()
58023 {
58024 return $this->multiselect;
58025 }
58026
58027
58028
58029
58030
58031
58032 public function getPrompt()
58033 {
58034 return $this->prompt;
58035 }
58036
58037
58038
58039
58040
58041
58042
58043
58044 public function setPrompt($prompt)
58045 {
58046 $this->prompt = $prompt;
58047
58048 return $this;
58049 }
58050
58051
58052
58053
58054
58055
58056
58057
58058
58059
58060 public function setErrorMessage($errorMessage)
58061 {
58062 $this->errorMessage = $errorMessage;
58063 $this->setValidator($this->getDefaultValidator());
58064
58065 return $this;
58066 }
58067
58068
58069
58070
58071
58072
58073 private function getDefaultValidator()
58074 {
58075 $choices = $this->choices;
58076 $errorMessage = $this->errorMessage;
58077 $multiselect = $this->multiselect;
58078 $isAssoc = $this->isAssoc($choices);
58079
58080 return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
58081
58082  $selectedChoices = str_replace(' ', '', $selected);
58083
58084 if ($multiselect) {
58085
58086  if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
58087 throw new InvalidArgumentException(sprintf($errorMessage, $selected));
58088 }
58089 $selectedChoices = explode(',', $selectedChoices);
58090 } else {
58091 $selectedChoices = array($selected);
58092 }
58093
58094 $multiselectChoices = array();
58095 foreach ($selectedChoices as $value) {
58096 $results = array();
58097 foreach ($choices as $key => $choice) {
58098 if ($choice === $value) {
58099 $results[] = $key;
58100 }
58101 }
58102
58103 if (count($results) > 1) {
58104 throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
58105 }
58106
58107 $result = array_search($value, $choices);
58108
58109 if (!$isAssoc) {
58110 if (false !== $result) {
58111 $result = $choices[$result];
58112 } elseif (isset($choices[$value])) {
58113 $result = $choices[$value];
58114 }
58115 } elseif (false === $result && isset($choices[$value])) {
58116 $result = $value;
58117 }
58118
58119 if (false === $result) {
58120 throw new InvalidArgumentException(sprintf($errorMessage, $value));
58121 }
58122
58123 $multiselectChoices[] = (string) $result;
58124 }
58125
58126 if ($multiselect) {
58127 return $multiselectChoices;
58128 }
58129
58130 return current($multiselectChoices);
58131 };
58132 }
58133 }
58134 <?php
58135
58136
58137
58138
58139
58140
58141
58142
58143
58144
58145 namespace Symfony\Component\Console\Question;
58146
58147
58148
58149
58150
58151
58152 class ConfirmationQuestion extends Question
58153 {
58154 private $trueAnswerRegex;
58155
58156
58157
58158
58159
58160
58161
58162
58163 public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i')
58164 {
58165 parent::__construct($question, (bool) $default);
58166
58167 $this->trueAnswerRegex = $trueAnswerRegex;
58168 $this->setNormalizer($this->getDefaultNormalizer());
58169 }
58170
58171
58172
58173
58174
58175
58176 private function getDefaultNormalizer()
58177 {
58178 $default = $this->getDefault();
58179 $regex = $this->trueAnswerRegex;
58180
58181 return function ($answer) use ($default, $regex) {
58182 if (is_bool($answer)) {
58183 return $answer;
58184 }
58185
58186 $answerIsTrue = (bool) preg_match($regex, $answer);
58187 if (false === $default) {
58188 return $answer && $answerIsTrue;
58189 }
58190
58191 return !$answer || $answerIsTrue;
58192 };
58193 }
58194 }
58195 <?php
58196
58197
58198
58199
58200
58201
58202
58203
58204
58205
58206 namespace Symfony\Component\Console\Question;
58207
58208 use Symfony\Component\Console\Exception\InvalidArgumentException;
58209 use Symfony\Component\Console\Exception\LogicException;
58210
58211
58212
58213
58214
58215
58216 class Question
58217 {
58218 private $question;
58219 private $attempts;
58220 private $hidden = false;
58221 private $hiddenFallback = true;
58222 private $autocompleterValues;
58223 private $validator;
58224 private $default;
58225 private $normalizer;
58226
58227
58228
58229
58230
58231
58232
58233 public function __construct($question, $default = null)
58234 {
58235 $this->question = $question;
58236 $this->default = $default;
58237 }
58238
58239
58240
58241
58242
58243
58244 public function getQuestion()
58245 {
58246 return $this->question;
58247 }
58248
58249
58250
58251
58252
58253
58254 public function getDefault()
58255 {
58256 return $this->default;
58257 }
58258
58259
58260
58261
58262
58263
58264 public function isHidden()
58265 {
58266 return $this->hidden;
58267 }
58268
58269
58270
58271
58272
58273
58274
58275
58276
58277
58278 public function setHidden($hidden)
58279 {
58280 if ($this->autocompleterValues) {
58281 throw new LogicException('A hidden question cannot use the autocompleter.');
58282 }
58283
58284 $this->hidden = (bool) $hidden;
58285
58286 return $this;
58287 }
58288
58289
58290
58291
58292
58293
58294 public function isHiddenFallback()
58295 {
58296 return $this->hiddenFallback;
58297 }
58298
58299
58300
58301
58302
58303
58304
58305
58306 public function setHiddenFallback($fallback)
58307 {
58308 $this->hiddenFallback = (bool) $fallback;
58309
58310 return $this;
58311 }
58312
58313
58314
58315
58316
58317
58318 public function getAutocompleterValues()
58319 {
58320 return $this->autocompleterValues;
58321 }
58322
58323
58324
58325
58326
58327
58328
58329
58330
58331
58332
58333 public function setAutocompleterValues($values)
58334 {
58335 if (is_array($values)) {
58336 $values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
58337 }
58338
58339 if (null !== $values && !is_array($values)) {
58340 if (!$values instanceof \Traversable || !$values instanceof \Countable) {
58341 throw new InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');
58342 }
58343 }
58344
58345 if ($this->hidden) {
58346 throw new LogicException('A hidden question cannot use the autocompleter.');
58347 }
58348
58349 $this->autocompleterValues = $values;
58350
58351 return $this;
58352 }
58353
58354
58355
58356
58357
58358
58359
58360
58361 public function setValidator($validator)
58362 {
58363 $this->validator = $validator;
58364
58365 return $this;
58366 }
58367
58368
58369
58370
58371
58372
58373 public function getValidator()
58374 {
58375 return $this->validator;
58376 }
58377
58378
58379
58380
58381
58382
58383
58384
58385
58386
58387
58388
58389 public function setMaxAttempts($attempts)
58390 {
58391 if (null !== $attempts && $attempts < 1) {
58392 throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
58393 }
58394
58395 $this->attempts = $attempts;
58396
58397 return $this;
58398 }
58399
58400
58401
58402
58403
58404
58405
58406
58407 public function getMaxAttempts()
58408 {
58409 return $this->attempts;
58410 }
58411
58412
58413
58414
58415
58416
58417
58418
58419
58420
58421 public function setNormalizer($normalizer)
58422 {
58423 $this->normalizer = $normalizer;
58424
58425 return $this;
58426 }
58427
58428
58429
58430
58431
58432
58433
58434
58435 public function getNormalizer()
58436 {
58437 return $this->normalizer;
58438 }
58439
58440 protected function isAssoc($array)
58441 {
58442 return (bool) count(array_filter(array_keys($array), 'is_string'));
58443 }
58444 }
58445 <?php
58446
58447
58448
58449
58450
58451
58452
58453
58454
58455
58456 namespace Symfony\Component\Console;
58457
58458 use Symfony\Component\Console\Exception\RuntimeException;
58459 use Symfony\Component\Console\Input\StringInput;
58460 use Symfony\Component\Console\Output\ConsoleOutput;
58461 use Symfony\Component\Process\ProcessBuilder;
58462 use Symfony\Component\Process\PhpExecutableFinder;
58463
58464
58465
58466
58467
58468
58469
58470
58471
58472
58473
58474
58475 class Shell
58476 {
58477 private $application;
58478 private $history;
58479 private $output;
58480 private $hasReadline;
58481 private $processIsolation = false;
58482
58483
58484
58485
58486
58487
58488
58489
58490
58491 public function __construct(Application $application)
58492 {
58493 @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
58494
58495 $this->hasReadline = function_exists('readline');
58496 $this->application = $application;
58497 $this->history = getenv('HOME').'/.history_'.$application->getName();
58498 $this->output = new ConsoleOutput();
58499 }
58500
58501
58502
58503
58504 public function run()
58505 {
58506 $this->application->setAutoExit(false);
58507 $this->application->setCatchExceptions(true);
58508
58509 if ($this->hasReadline) {
58510 readline_read_history($this->history);
58511 readline_completion_function(array($this, 'autocompleter'));
58512 }
58513
58514 $this->output->writeln($this->getHeader());
58515 $php = null;
58516 if ($this->processIsolation) {
58517 $finder = new PhpExecutableFinder();
58518 $php = $finder->find();
58519 $this->output->writeln(<<<'EOF'
58520 <info>Running with process isolation, you should consider this:</info>
58521   * each command is executed as separate process,
58522   * commands don't support interactivity, all params must be passed explicitly,
58523   * commands output is not colorized.
58524
58525 EOF
58526 );
58527 }
58528
58529 while (true) {
58530 $command = $this->readline();
58531
58532 if (false === $command) {
58533 $this->output->writeln("\n");
58534
58535 break;
58536 }
58537
58538 if ($this->hasReadline) {
58539 readline_add_history($command);
58540 readline_write_history($this->history);
58541 }
58542
58543 if ($this->processIsolation) {
58544 $pb = new ProcessBuilder();
58545
58546 $process = $pb
58547 ->add($php)
58548 ->add($_SERVER['argv'][0])
58549 ->add($command)
58550 ->inheritEnvironmentVariables(true)
58551 ->getProcess()
58552 ;
58553
58554 $output = $this->output;
58555 $process->run(function ($type, $data) use ($output) {
58556 $output->writeln($data);
58557 });
58558
58559 $ret = $process->getExitCode();
58560 } else {
58561 $ret = $this->application->run(new StringInput($command), $this->output);
58562 }
58563
58564 if (0 !== $ret) {
58565 $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
58566 }
58567 }
58568 }
58569
58570
58571
58572
58573
58574
58575 protected function getHeader()
58576 {
58577 return <<<EOF
58578
58579 Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).
58580
58581 At the prompt, type <comment>help</comment> for some help,
58582 or <comment>list</comment> to get a list of available commands.
58583
58584 To exit the shell, type <comment>^D</comment>.
58585
58586 EOF;
58587 }
58588
58589
58590
58591
58592
58593
58594 protected function getPrompt()
58595 {
58596
58597  return $this->output->getFormatter()->format($this->application->getName().' > ');
58598 }
58599
58600 protected function getOutput()
58601 {
58602 return $this->output;
58603 }
58604
58605 protected function getApplication()
58606 {
58607 return $this->application;
58608 }
58609
58610
58611
58612
58613
58614
58615
58616
58617 private function autocompleter($text)
58618 {
58619 $info = readline_info();
58620 $text = substr($info['line_buffer'], 0, $info['end']);
58621
58622 if ($info['point'] !== $info['end']) {
58623 return true;
58624 }
58625
58626
58627  if (false === strpos($text, ' ') || !$text) {
58628 return array_keys($this->application->all());
58629 }
58630
58631
58632  try {
58633 $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
58634 } catch (\Exception $e) {
58635 return true;
58636 }
58637
58638 $list = array('--help');
58639 foreach ($command->getDefinition()->getOptions() as $option) {
58640 $list[] = '--'.$option->getName();
58641 }
58642
58643 return $list;
58644 }
58645
58646
58647
58648
58649
58650
58651 private function readline()
58652 {
58653 if ($this->hasReadline) {
58654 $line = readline($this->getPrompt());
58655 } else {
58656 $this->output->write($this->getPrompt());
58657 $line = fgets(STDIN, 1024);
58658 $line = (false === $line || '' === $line) ? false : rtrim($line);
58659 }
58660
58661 return $line;
58662 }
58663
58664 public function getProcessIsolation()
58665 {
58666 return $this->processIsolation;
58667 }
58668
58669 public function setProcessIsolation($processIsolation)
58670 {
58671 $this->processIsolation = (bool) $processIsolation;
58672
58673 if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
58674 throw new RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
58675 }
58676 }
58677 }
58678 <?php
58679
58680
58681
58682
58683
58684
58685
58686
58687
58688
58689 namespace Symfony\Component\Console\Style;
58690
58691 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
58692 use Symfony\Component\Console\Helper\ProgressBar;
58693 use Symfony\Component\Console\Output\OutputInterface;
58694
58695
58696
58697
58698
58699
58700 abstract class OutputStyle implements OutputInterface, StyleInterface
58701 {
58702 private $output;
58703
58704
58705
58706
58707 public function __construct(OutputInterface $output)
58708 {
58709 $this->output = $output;
58710 }
58711
58712
58713
58714
58715 public function newLine($count = 1)
58716 {
58717 $this->output->write(str_repeat(PHP_EOL, $count));
58718 }
58719
58720
58721
58722
58723
58724
58725 public function createProgressBar($max = 0)
58726 {
58727 return new ProgressBar($this->output, $max);
58728 }
58729
58730
58731
58732
58733 public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
58734 {
58735 $this->output->write($messages, $newline, $type);
58736 }
58737
58738
58739
58740
58741 public function writeln($messages, $type = self::OUTPUT_NORMAL)
58742 {
58743 $this->output->writeln($messages, $type);
58744 }
58745
58746
58747
58748
58749 public function setVerbosity($level)
58750 {
58751 $this->output->setVerbosity($level);
58752 }
58753
58754
58755
58756
58757 public function getVerbosity()
58758 {
58759 return $this->output->getVerbosity();
58760 }
58761
58762
58763
58764
58765 public function setDecorated($decorated)
58766 {
58767 $this->output->setDecorated($decorated);
58768 }
58769
58770
58771
58772
58773 public function isDecorated()
58774 {
58775 return $this->output->isDecorated();
58776 }
58777
58778
58779
58780
58781 public function setFormatter(OutputFormatterInterface $formatter)
58782 {
58783 $this->output->setFormatter($formatter);
58784 }
58785
58786
58787
58788
58789 public function getFormatter()
58790 {
58791 return $this->output->getFormatter();
58792 }
58793 }
58794 <?php
58795
58796
58797
58798
58799
58800
58801
58802
58803
58804
58805 namespace Symfony\Component\Console\Style;
58806
58807
58808
58809
58810
58811
58812 interface StyleInterface
58813 {
58814
58815
58816
58817
58818
58819 public function title($message);
58820
58821
58822
58823
58824
58825
58826 public function section($message);
58827
58828
58829
58830
58831
58832
58833 public function listing(array $elements);
58834
58835
58836
58837
58838
58839
58840 public function text($message);
58841
58842
58843
58844
58845
58846
58847 public function success($message);
58848
58849
58850
58851
58852
58853
58854 public function error($message);
58855
58856
58857
58858
58859
58860
58861 public function warning($message);
58862
58863
58864
58865
58866
58867
58868 public function note($message);
58869
58870
58871
58872
58873
58874
58875 public function caution($message);
58876
58877
58878
58879
58880
58881
58882
58883 public function table(array $headers, array $rows);
58884
58885
58886
58887
58888
58889
58890
58891
58892
58893
58894 public function ask($question, $default = null, $validator = null);
58895
58896
58897
58898
58899
58900
58901
58902
58903
58904 public function askHidden($question, $validator = null);
58905
58906
58907
58908
58909
58910
58911
58912
58913
58914 public function confirm($question, $default = true);
58915
58916
58917
58918
58919
58920
58921
58922
58923
58924
58925 public function choice($question, array $choices, $default = null);
58926
58927
58928
58929
58930
58931
58932 public function newLine($count = 1);
58933
58934
58935
58936
58937
58938
58939 public function progressStart($max = 0);
58940
58941
58942
58943
58944
58945
58946 public function progressAdvance($step = 1);
58947
58948
58949
58950
58951 public function progressFinish();
58952 }
58953 <?php
58954
58955
58956
58957
58958
58959
58960
58961
58962
58963
58964 namespace Symfony\Component\Console\Style;
58965
58966 use Symfony\Component\Console\Application;
58967 use Symfony\Component\Console\Exception\RuntimeException;
58968 use Symfony\Component\Console\Formatter\OutputFormatter;
58969 use Symfony\Component\Console\Helper\Helper;
58970 use Symfony\Component\Console\Helper\ProgressBar;
58971 use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
58972 use Symfony\Component\Console\Helper\Table;
58973 use Symfony\Component\Console\Input\InputInterface;
58974 use Symfony\Component\Console\Output\BufferedOutput;
58975 use Symfony\Component\Console\Output\OutputInterface;
58976 use Symfony\Component\Console\Question\ChoiceQuestion;
58977 use Symfony\Component\Console\Question\ConfirmationQuestion;
58978 use Symfony\Component\Console\Question\Question;
58979
58980
58981
58982
58983
58984
58985 class SymfonyStyle extends OutputStyle
58986 {
58987 const MAX_LINE_LENGTH = 120;
58988
58989 private $input;
58990 private $questionHelper;
58991 private $progressBar;
58992 private $lineLength;
58993 private $bufferedOutput;
58994
58995
58996
58997
58998
58999 public function __construct(InputInterface $input, OutputInterface $output)
59000 {
59001 $this->input = $input;
59002 $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
59003
59004  $this->lineLength = min($this->getTerminalWidth() - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
59005
59006 parent::__construct($output);
59007 }
59008
59009
59010
59011
59012
59013
59014
59015
59016
59017
59018 public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
59019 {
59020 $messages = is_array($messages) ? array_values($messages) : array($messages);
59021
59022 $this->autoPrependBlock();
59023 $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, true));
59024 $this->newLine();
59025 }
59026
59027
59028
59029
59030 public function title($message)
59031 {
59032 $this->autoPrependBlock();
59033 $this->writeln(array(
59034 sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
59035 sprintf('<comment>%s</>', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
59036 ));
59037 $this->newLine();
59038 }
59039
59040
59041
59042
59043 public function section($message)
59044 {
59045 $this->autoPrependBlock();
59046 $this->writeln(array(
59047 sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
59048 sprintf('<comment>%s</>', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
59049 ));
59050 $this->newLine();
59051 }
59052
59053
59054
59055
59056 public function listing(array $elements)
59057 {
59058 $this->autoPrependText();
59059 $elements = array_map(function ($element) {
59060 return sprintf(' * %s', $element);
59061 }, $elements);
59062
59063 $this->writeln($elements);
59064 $this->newLine();
59065 }
59066
59067
59068
59069
59070 public function text($message)
59071 {
59072 $this->autoPrependText();
59073
59074 $messages = is_array($message) ? array_values($message) : array($message);
59075 foreach ($messages as $message) {
59076 $this->writeln(sprintf(' %s', $message));
59077 }
59078 }
59079
59080
59081
59082
59083
59084
59085 public function comment($message)
59086 {
59087 $messages = is_array($message) ? array_values($message) : array($message);
59088
59089 $this->autoPrependBlock();
59090 $this->writeln($this->createBlock($messages, null, null, '<fg=default;bg=default> // </>'));
59091 $this->newLine();
59092 }
59093
59094
59095
59096
59097 public function success($message)
59098 {
59099 $this->block($message, 'OK', 'fg=black;bg=green', ' ', true);
59100 }
59101
59102
59103
59104
59105 public function error($message)
59106 {
59107 $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
59108 }
59109
59110
59111
59112
59113 public function warning($message)
59114 {
59115 $this->block($message, 'WARNING', 'fg=white;bg=red', ' ', true);
59116 }
59117
59118
59119
59120
59121 public function note($message)
59122 {
59123 $this->block($message, 'NOTE', 'fg=yellow', ' ! ');
59124 }
59125
59126
59127
59128
59129 public function caution($message)
59130 {
59131 $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
59132 }
59133
59134
59135
59136
59137 public function table(array $headers, array $rows)
59138 {
59139 $style = clone Table::getStyleDefinition('symfony-style-guide');
59140 $style->setCellHeaderFormat('<info>%s</info>');
59141
59142 $table = new Table($this);
59143 $table->setHeaders($headers);
59144 $table->setRows($rows);
59145 $table->setStyle($style);
59146
59147 $table->render();
59148 $this->newLine();
59149 }
59150
59151
59152
59153
59154 public function ask($question, $default = null, $validator = null)
59155 {
59156 $question = new Question($question, $default);
59157 $question->setValidator($validator);
59158
59159 return $this->askQuestion($question);
59160 }
59161
59162
59163
59164
59165 public function askHidden($question, $validator = null)
59166 {
59167 $question = new Question($question);
59168
59169 $question->setHidden(true);
59170 $question->setValidator($validator);
59171
59172 return $this->askQuestion($question);
59173 }
59174
59175
59176
59177
59178 public function confirm($question, $default = true)
59179 {
59180 return $this->askQuestion(new ConfirmationQuestion($question, $default));
59181 }
59182
59183
59184
59185
59186 public function choice($question, array $choices, $default = null)
59187 {
59188 if (null !== $default) {
59189 $values = array_flip($choices);
59190 $default = $values[$default];
59191 }
59192
59193 return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
59194 }
59195
59196
59197
59198
59199 public function progressStart($max = 0)
59200 {
59201 $this->progressBar = $this->createProgressBar($max);
59202 $this->progressBar->start();
59203 }
59204
59205
59206
59207
59208 public function progressAdvance($step = 1)
59209 {
59210 $this->getProgressBar()->advance($step);
59211 }
59212
59213
59214
59215
59216 public function progressFinish()
59217 {
59218 $this->getProgressBar()->finish();
59219 $this->newLine(2);
59220 $this->progressBar = null;
59221 }
59222
59223
59224
59225
59226 public function createProgressBar($max = 0)
59227 {
59228 $progressBar = parent::createProgressBar($max);
59229
59230 if ('\\' !== DIRECTORY_SEPARATOR) {
59231 $progressBar->setEmptyBarCharacter('░'); 
59232  $progressBar->setProgressCharacter('');
59233 $progressBar->setBarCharacter('▓'); 
59234  }
59235
59236 return $progressBar;
59237 }
59238
59239
59240
59241
59242
59243
59244 public function askQuestion(Question $question)
59245 {
59246 if ($this->input->isInteractive()) {
59247 $this->autoPrependBlock();
59248 }
59249
59250 if (!$this->questionHelper) {
59251 $this->questionHelper = new SymfonyQuestionHelper();
59252 }
59253
59254 $answer = $this->questionHelper->ask($this->input, $this, $question);
59255
59256 if ($this->input->isInteractive()) {
59257 $this->newLine();
59258 $this->bufferedOutput->write("\n");
59259 }
59260
59261 return $answer;
59262 }
59263
59264
59265
59266
59267 public function writeln($messages, $type = self::OUTPUT_NORMAL)
59268 {
59269 parent::writeln($messages, $type);
59270 $this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
59271 }
59272
59273
59274
59275
59276 public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
59277 {
59278 parent::write($messages, $newline, $type);
59279 $this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
59280 }
59281
59282
59283
59284
59285 public function newLine($count = 1)
59286 {
59287 parent::newLine($count);
59288 $this->bufferedOutput->write(str_repeat("\n", $count));
59289 }
59290
59291
59292
59293
59294 private function getProgressBar()
59295 {
59296 if (!$this->progressBar) {
59297 throw new RuntimeException('The ProgressBar is not started.');
59298 }
59299
59300 return $this->progressBar;
59301 }
59302
59303 private function getTerminalWidth()
59304 {
59305 $application = new Application();
59306 $dimensions = $application->getTerminalDimensions();
59307
59308 return $dimensions[0] ?: self::MAX_LINE_LENGTH;
59309 }
59310
59311 private function autoPrependBlock()
59312 {
59313 $chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
59314
59315 if (!isset($chars[0])) {
59316 return $this->newLine(); 
59317  }
59318
59319  $this->newLine(2 - substr_count($chars, "\n"));
59320 }
59321
59322 private function autoPrependText()
59323 {
59324 $fetched = $this->bufferedOutput->fetch();
59325
59326  if ("\n" !== substr($fetched, -1)) {
59327 $this->newLine();
59328 }
59329 }
59330
59331 private function reduceBuffer($messages)
59332 {
59333
59334  
59335  return array_map(function ($value) {
59336 return substr($value, -4);
59337 }, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
59338 }
59339
59340 private function createBlock($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = false)
59341 {
59342 $indentLength = 0;
59343 $prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix);
59344 $lines = array();
59345
59346 if (null !== $type) {
59347 $type = sprintf('[%s] ', $type);
59348 $indentLength = strlen($type);
59349 $lineIndentation = str_repeat(' ', $indentLength);
59350 }
59351
59352
59353  foreach ($messages as $key => $message) {
59354 if ($escape) {
59355 $message = OutputFormatter::escape($message);
59356 }
59357
59358 $lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, PHP_EOL, true)));
59359
59360 if (count($messages) > 1 && $key < count($messages) - 1) {
59361 $lines[] = '';
59362 }
59363 }
59364
59365 $firstLineIndex = 0;
59366 if ($padding && $this->isDecorated()) {
59367 $firstLineIndex = 1;
59368 array_unshift($lines, '');
59369 $lines[] = '';
59370 }
59371
59372 foreach ($lines as $i => &$line) {
59373 if (null !== $type) {
59374 $line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
59375 }
59376
59377 $line = $prefix.$line;
59378 $line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
59379
59380 if ($style) {
59381 $line = sprintf('<%s>%s</>', $style, $line);
59382 }
59383 }
59384
59385 return $lines;
59386 }
59387 }
59388 <?php
59389
59390
59391
59392
59393
59394
59395
59396
59397
59398
59399 namespace Symfony\Component\Console\Tester;
59400
59401 use Symfony\Component\Console\Application;
59402 use Symfony\Component\Console\Input\ArrayInput;
59403 use Symfony\Component\Console\Input\InputInterface;
59404 use Symfony\Component\Console\Output\OutputInterface;
59405 use Symfony\Component\Console\Output\StreamOutput;
59406
59407
59408
59409
59410
59411
59412
59413
59414
59415
59416
59417 class ApplicationTester
59418 {
59419 private $application;
59420 private $input;
59421 private $output;
59422 private $statusCode;
59423
59424
59425
59426
59427
59428
59429 public function __construct(Application $application)
59430 {
59431 $this->application = $application;
59432 }
59433
59434
59435
59436
59437
59438
59439
59440
59441
59442
59443
59444
59445
59446
59447
59448 public function run(array $input, $options = array())
59449 {
59450 $this->input = new ArrayInput($input);
59451 if (isset($options['interactive'])) {
59452 $this->input->setInteractive($options['interactive']);
59453 }
59454
59455 $this->output = new StreamOutput(fopen('php://memory', 'w', false));
59456 if (isset($options['decorated'])) {
59457 $this->output->setDecorated($options['decorated']);
59458 }
59459 if (isset($options['verbosity'])) {
59460 $this->output->setVerbosity($options['verbosity']);
59461 }
59462
59463 return $this->statusCode = $this->application->run($this->input, $this->output);
59464 }
59465
59466
59467
59468
59469
59470
59471
59472
59473 public function getDisplay($normalize = false)
59474 {
59475 rewind($this->output->getStream());
59476
59477 $display = stream_get_contents($this->output->getStream());
59478
59479 if ($normalize) {
59480 $display = str_replace(PHP_EOL, "\n", $display);
59481 }
59482
59483 return $display;
59484 }
59485
59486
59487
59488
59489
59490
59491 public function getInput()
59492 {
59493 return $this->input;
59494 }
59495
59496
59497
59498
59499
59500
59501 public function getOutput()
59502 {
59503 return $this->output;
59504 }
59505
59506
59507
59508
59509
59510
59511 public function getStatusCode()
59512 {
59513 return $this->statusCode;
59514 }
59515 }
59516 <?php
59517
59518
59519
59520
59521
59522
59523
59524
59525
59526
59527 namespace Symfony\Component\Console\Tester;
59528
59529 use Symfony\Component\Console\Command\Command;
59530 use Symfony\Component\Console\Input\ArrayInput;
59531 use Symfony\Component\Console\Output\StreamOutput;
59532 use Symfony\Component\Console\Input\InputInterface;
59533 use Symfony\Component\Console\Output\OutputInterface;
59534
59535
59536
59537
59538
59539
59540 class CommandTester
59541 {
59542 private $command;
59543 private $input;
59544 private $output;
59545 private $statusCode;
59546
59547
59548
59549
59550
59551
59552 public function __construct(Command $command)
59553 {
59554 $this->command = $command;
59555 }
59556
59557
59558
59559
59560
59561
59562
59563
59564
59565
59566
59567
59568
59569
59570
59571 public function execute(array $input, array $options = array())
59572 {
59573
59574  
59575  if (!isset($input['command'])
59576 && (null !== $application = $this->command->getApplication())
59577 && $application->getDefinition()->hasArgument('command')
59578 ) {
59579 $input = array_merge(array('command' => $this->command->getName()), $input);
59580 }
59581
59582 $this->input = new ArrayInput($input);
59583 if (isset($options['interactive'])) {
59584 $this->input->setInteractive($options['interactive']);
59585 }
59586
59587 $this->output = new StreamOutput(fopen('php://memory', 'w', false));
59588 if (isset($options['decorated'])) {
59589 $this->output->setDecorated($options['decorated']);
59590 }
59591 if (isset($options['verbosity'])) {
59592 $this->output->setVerbosity($options['verbosity']);
59593 }
59594
59595 return $this->statusCode = $this->command->run($this->input, $this->output);
59596 }
59597
59598
59599
59600
59601
59602
59603
59604
59605 public function getDisplay($normalize = false)
59606 {
59607 rewind($this->output->getStream());
59608
59609 $display = stream_get_contents($this->output->getStream());
59610
59611 if ($normalize) {
59612 $display = str_replace(PHP_EOL, "\n", $display);
59613 }
59614
59615 return $display;
59616 }
59617
59618
59619
59620
59621
59622
59623 public function getInput()
59624 {
59625 return $this->input;
59626 }
59627
59628
59629
59630
59631
59632
59633 public function getOutput()
59634 {
59635 return $this->output;
59636 }
59637
59638
59639
59640
59641
59642
59643 public function getStatusCode()
59644 {
59645 return $this->statusCode;
59646 }
59647 }
59648 <?php
59649
59650
59651
59652
59653
59654
59655
59656
59657
59658
59659 namespace Symfony\Component\Debug;
59660
59661 use Psr\Log\AbstractLogger;
59662
59663
59664
59665
59666
59667
59668 class BufferingLogger extends AbstractLogger
59669 {
59670 private $logs = array();
59671
59672 public function log($level, $message, array $context = array())
59673 {
59674 $this->logs[] = array($level, $message, $context);
59675 }
59676
59677 public function cleanLogs()
59678 {
59679 $logs = $this->logs;
59680 $this->logs = array();
59681
59682 return $logs;
59683 }
59684 }
59685 <?php
59686
59687
59688
59689
59690
59691
59692
59693
59694
59695
59696 namespace Symfony\Component\Debug;
59697
59698
59699
59700
59701
59702
59703 class Debug
59704 {
59705 private static $enabled = false;
59706
59707
59708
59709
59710
59711
59712
59713
59714
59715
59716
59717
59718 public static function enable($errorReportingLevel = null, $displayErrors = true)
59719 {
59720 if (static::$enabled) {
59721 return;
59722 }
59723
59724 static::$enabled = true;
59725
59726 if (null !== $errorReportingLevel) {
59727 error_reporting($errorReportingLevel);
59728 } else {
59729 error_reporting(-1);
59730 }
59731
59732 if ('cli' !== PHP_SAPI) {
59733 ini_set('display_errors', 0);
59734 ExceptionHandler::register();
59735 } elseif ($displayErrors && (!ini_get('log_errors') || ini_get('error_log'))) {
59736
59737  ini_set('display_errors', 1);
59738 }
59739 if ($displayErrors) {
59740 ErrorHandler::register(new ErrorHandler(new BufferingLogger()));
59741 } else {
59742 ErrorHandler::register()->throwAt(0, true);
59743 }
59744
59745 DebugClassLoader::enable();
59746 }
59747 }
59748 <?php
59749
59750
59751
59752
59753
59754
59755
59756
59757
59758
59759 namespace Symfony\Component\Debug;
59760
59761
59762
59763
59764
59765
59766
59767
59768
59769
59770
59771
59772 class DebugClassLoader
59773 {
59774 private $classLoader;
59775 private $isFinder;
59776 private $wasFinder;
59777 private static $caseCheck;
59778 private static $deprecated = array();
59779 private static $php7Reserved = array('int', 'float', 'bool', 'string', 'true', 'false', 'null');
59780 private static $darwinCache = array('/' => array('/', array()));
59781
59782
59783
59784
59785
59786
59787 public function __construct($classLoader)
59788 {
59789 $this->wasFinder = is_object($classLoader) && method_exists($classLoader, 'findFile');
59790
59791 if ($this->wasFinder) {
59792 @trigger_error('The '.__METHOD__.' method will no longer support receiving an object into its $classLoader argument in 3.0.', E_USER_DEPRECATED);
59793 $this->classLoader = array($classLoader, 'loadClass');
59794 $this->isFinder = true;
59795 } else {
59796 $this->classLoader = $classLoader;
59797 $this->isFinder = is_array($classLoader) && method_exists($classLoader[0], 'findFile');
59798 }
59799
59800 if (!isset(self::$caseCheck)) {
59801 $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), DIRECTORY_SEPARATOR);
59802 $i = strrpos($file, DIRECTORY_SEPARATOR);
59803 $dir = substr($file, 0, 1 + $i);
59804 $file = substr($file, 1 + $i);
59805 $test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);
59806 $test = realpath($dir.$test);
59807
59808 if (false === $test || false === $i) {
59809
59810  self::$caseCheck = 0;
59811 } elseif (substr($test, -strlen($file)) === $file) {
59812
59813  self::$caseCheck = 1;
59814 } elseif (false !== stripos(PHP_OS, 'darwin')) {
59815
59816  self::$caseCheck = 2;
59817 } else {
59818
59819  self::$caseCheck = 0;
59820 }
59821 }
59822 }
59823
59824
59825
59826
59827
59828
59829 public function getClassLoader()
59830 {
59831 return $this->wasFinder ? $this->classLoader[0] : $this->classLoader;
59832 }
59833
59834
59835
59836
59837 public static function enable()
59838 {
59839
59840  class_exists('Symfony\Component\Debug\ErrorHandler');
59841 class_exists('Psr\Log\LogLevel');
59842
59843 if (!is_array($functions = spl_autoload_functions())) {
59844 return;
59845 }
59846
59847 foreach ($functions as $function) {
59848 spl_autoload_unregister($function);
59849 }
59850
59851 foreach ($functions as $function) {
59852 if (!is_array($function) || !$function[0] instanceof self) {
59853 $function = array(new static($function), 'loadClass');
59854 }
59855
59856 spl_autoload_register($function);
59857 }
59858 }
59859
59860
59861
59862
59863 public static function disable()
59864 {
59865 if (!is_array($functions = spl_autoload_functions())) {
59866 return;
59867 }
59868
59869 foreach ($functions as $function) {
59870 spl_autoload_unregister($function);
59871 }
59872
59873 foreach ($functions as $function) {
59874 if (is_array($function) && $function[0] instanceof self) {
59875 $function = $function[0]->getClassLoader();
59876 }
59877
59878 spl_autoload_register($function);
59879 }
59880 }
59881
59882
59883
59884
59885
59886
59887
59888
59889
59890
59891 public function findFile($class)
59892 {
59893 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
59894
59895 if ($this->wasFinder) {
59896 return $this->classLoader[0]->findFile($class);
59897 }
59898 }
59899
59900
59901
59902
59903
59904
59905
59906
59907
59908
59909 public function loadClass($class)
59910 {
59911 ErrorHandler::stackErrors();
59912
59913 try {
59914 if ($this->isFinder) {
59915 if ($file = $this->classLoader[0]->findFile($class)) {
59916 require_once $file;
59917 }
59918 } else {
59919 call_user_func($this->classLoader, $class);
59920 $file = false;
59921 }
59922 } catch (\Exception $e) {
59923 ErrorHandler::unstackErrors();
59924
59925 throw $e;
59926 } catch (\Throwable $e) {
59927 ErrorHandler::unstackErrors();
59928
59929 throw $e;
59930 }
59931
59932 ErrorHandler::unstackErrors();
59933
59934 $exists = class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false));
59935
59936 if ('\\' === $class[0]) {
59937 $class = substr($class, 1);
59938 }
59939
59940 if ($exists) {
59941 $refl = new \ReflectionClass($class);
59942 $name = $refl->getName();
59943
59944 if ($name !== $class && 0 === strcasecmp($name, $class)) {
59945 throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: %s vs %s', $class, $name));
59946 }
59947
59948 if (in_array(strtolower($refl->getShortName()), self::$php7Reserved)) {
59949 @trigger_error(sprintf('%s uses a reserved class name (%s) that will break on PHP 7 and higher', $name, $refl->getShortName()), E_USER_DEPRECATED);
59950 } elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
59951 self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
59952 } else {
59953 if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) {
59954 $len = 0;
59955 $ns = '';
59956 } else {
59957 switch ($ns = substr($name, 0, $len)) {
59958 case 'Symfony\Bridge\\':
59959 case 'Symfony\Bundle\\':
59960 case 'Symfony\Component\\':
59961 $ns = 'Symfony\\';
59962 $len = strlen($ns);
59963 break;
59964 }
59965 }
59966 $parent = get_parent_class($class);
59967
59968 if (!$parent || strncmp($ns, $parent, $len)) {
59969 if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) {
59970 @trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED);
59971 }
59972
59973 $parentInterfaces = array();
59974 $deprecatedInterfaces = array();
59975 if ($parent) {
59976 foreach (class_implements($parent) as $interface) {
59977 $parentInterfaces[$interface] = 1;
59978 }
59979 }
59980
59981 foreach ($refl->getInterfaceNames() as $interface) {
59982 if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len)) {
59983 $deprecatedInterfaces[] = $interface;
59984 }
59985 foreach (class_implements($interface) as $interface) {
59986 $parentInterfaces[$interface] = 1;
59987 }
59988 }
59989
59990 foreach ($deprecatedInterfaces as $interface) {
59991 if (!isset($parentInterfaces[$interface])) {
59992 @trigger_error(sprintf('The %s %s %s that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED);
59993 }
59994 }
59995 }
59996 }
59997 }
59998
59999 if ($file) {
60000 if (!$exists) {
60001 if (false !== strpos($class, '/')) {
60002 throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
60003 }
60004
60005 throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
60006 }
60007 if (self::$caseCheck) {
60008 $real = explode('\\', $class.strrchr($file, '.'));
60009 $tail = explode(DIRECTORY_SEPARATOR, str_replace('/', DIRECTORY_SEPARATOR, $file));
60010
60011 $i = count($tail) - 1;
60012 $j = count($real) - 1;
60013
60014 while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
60015 --$i;
60016 --$j;
60017 }
60018
60019 array_splice($tail, 0, $i + 1);
60020 }
60021 if (self::$caseCheck && $tail) {
60022 $tail = DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $tail);
60023 $tailLen = strlen($tail);
60024 $real = $refl->getFileName();
60025
60026 if (2 === self::$caseCheck) {
60027
60028
60029 $i = 1 + strrpos($real, '/');
60030 $file = substr($real, $i);
60031 $real = substr($real, 0, $i);
60032
60033 if (isset(self::$darwinCache[$real])) {
60034 $kDir = $real;
60035 } else {
60036 $kDir = strtolower($real);
60037
60038 if (isset(self::$darwinCache[$kDir])) {
60039 $real = self::$darwinCache[$kDir][0];
60040 } else {
60041 $dir = getcwd();
60042 chdir($real);
60043 $real = getcwd().'/';
60044 chdir($dir);
60045
60046 $dir = $real;
60047 $k = $kDir;
60048 $i = strlen($dir) - 1;
60049 while (!isset(self::$darwinCache[$k])) {
60050 self::$darwinCache[$k] = array($dir, array());
60051 self::$darwinCache[$dir] = &self::$darwinCache[$k];
60052
60053 while ('/' !== $dir[--$i]) {
60054 }
60055 $k = substr($k, 0, ++$i);
60056 $dir = substr($dir, 0, $i--);
60057 }
60058 }
60059 }
60060
60061 $dirFiles = self::$darwinCache[$kDir][1];
60062
60063 if (isset($dirFiles[$file])) {
60064 $kFile = $file;
60065 } else {
60066 $kFile = strtolower($file);
60067
60068 if (!isset($dirFiles[$kFile])) {
60069 foreach (scandir($real, 2) as $f) {
60070 if ('.' !== $f[0]) {
60071 $dirFiles[$f] = $f;
60072 if ($f === $file) {
60073 $kFile = $k = $file;
60074 } elseif ($f !== $k = strtolower($f)) {
60075 $dirFiles[$k] = $f;
60076 }
60077 }
60078 }
60079 self::$darwinCache[$kDir][1] = $dirFiles;
60080 }
60081 }
60082
60083 $real .= $dirFiles[$kFile];
60084 }
60085
60086 if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
60087 && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
60088 ) {
60089 throw new \RuntimeException(sprintf('Case mismatch between class and real file names: %s vs %s in %s', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)));
60090 }
60091 }
60092
60093 return true;
60094 }
60095 }
60096 }
60097 <?php
60098
60099
60100
60101
60102
60103
60104
60105
60106
60107
60108 namespace Symfony\Component\Debug;
60109
60110 use Psr\Log\LogLevel;
60111 use Psr\Log\LoggerInterface;
60112 use Symfony\Component\Debug\Exception\ContextErrorException;
60113 use Symfony\Component\Debug\Exception\FatalErrorException;
60114 use Symfony\Component\Debug\Exception\FatalThrowableError;
60115 use Symfony\Component\Debug\Exception\OutOfMemoryException;
60116 use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
60117 use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
60118 use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
60119 use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;
60120
60121
60122
60123
60124
60125
60126
60127
60128
60129
60130
60131
60132
60133
60134
60135
60136
60137
60138
60139
60140
60141
60142
60143 class ErrorHandler
60144 {
60145
60146
60147
60148 const TYPE_DEPRECATION = -100;
60149
60150 private $levels = array(
60151 E_DEPRECATED => 'Deprecated',
60152 E_USER_DEPRECATED => 'User Deprecated',
60153 E_NOTICE => 'Notice',
60154 E_USER_NOTICE => 'User Notice',
60155 E_STRICT => 'Runtime Notice',
60156 E_WARNING => 'Warning',
60157 E_USER_WARNING => 'User Warning',
60158 E_COMPILE_WARNING => 'Compile Warning',
60159 E_CORE_WARNING => 'Core Warning',
60160 E_USER_ERROR => 'User Error',
60161 E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
60162 E_COMPILE_ERROR => 'Compile Error',
60163 E_PARSE => 'Parse Error',
60164 E_ERROR => 'Error',
60165 E_CORE_ERROR => 'Core Error',
60166 );
60167
60168 private $loggers = array(
60169 E_DEPRECATED => array(null, LogLevel::INFO),
60170 E_USER_DEPRECATED => array(null, LogLevel::INFO),
60171 E_NOTICE => array(null, LogLevel::WARNING),
60172 E_USER_NOTICE => array(null, LogLevel::WARNING),
60173 E_STRICT => array(null, LogLevel::WARNING),
60174 E_WARNING => array(null, LogLevel::WARNING),
60175 E_USER_WARNING => array(null, LogLevel::WARNING),
60176 E_COMPILE_WARNING => array(null, LogLevel::WARNING),
60177 E_CORE_WARNING => array(null, LogLevel::WARNING),
60178 E_USER_ERROR => array(null, LogLevel::CRITICAL),
60179 E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL),
60180 E_COMPILE_ERROR => array(null, LogLevel::CRITICAL),
60181 E_PARSE => array(null, LogLevel::CRITICAL),
60182 E_ERROR => array(null, LogLevel::CRITICAL),
60183 E_CORE_ERROR => array(null, LogLevel::CRITICAL),
60184 );
60185
60186 private $thrownErrors = 0x1FFF; 
60187  private $scopedErrors = 0x1FFF; 
60188  private $tracedErrors = 0x77FB; 
60189  private $screamedErrors = 0x55; 
60190  private $loggedErrors = 0;
60191
60192 private $loggedTraces = array();
60193 private $isRecursive = 0;
60194 private $isRoot = false;
60195 private $exceptionHandler;
60196 private $bootstrappingLogger;
60197
60198 private static $reservedMemory;
60199 private static $stackedErrors = array();
60200 private static $stackedErrorLevels = array();
60201 private static $toStringException = null;
60202
60203
60204
60205
60206
60207
60208 private $displayErrors = 0x1FFF;
60209
60210
60211
60212
60213
60214
60215
60216
60217
60218 public static function register($handler = null, $replace = true)
60219 {
60220 if (null === self::$reservedMemory) {
60221 self::$reservedMemory = str_repeat('x', 10240);
60222 register_shutdown_function(__CLASS__.'::handleFatalError');
60223 }
60224
60225 $levels = -1;
60226
60227 if ($handlerIsNew = !$handler instanceof self) {
60228
60229  if (null !== $handler) {
60230 $levels = $replace ? $handler : 0;
60231 $replace = true;
60232 }
60233 $handler = new static();
60234 }
60235
60236 if (null === $prev = set_error_handler(array($handler, 'handleError'))) {
60237 restore_error_handler();
60238
60239  set_error_handler(array($handler, 'handleError'), $handler->thrownErrors | $handler->loggedErrors);
60240 $handler->isRoot = true;
60241 }
60242
60243 if ($handlerIsNew && is_array($prev) && $prev[0] instanceof self) {
60244 $handler = $prev[0];
60245 $replace = false;
60246 }
60247 if ($replace || !$prev) {
60248 $handler->setExceptionHandler(set_exception_handler(array($handler, 'handleException')));
60249 } else {
60250 restore_error_handler();
60251 }
60252
60253 $handler->throwAt($levels & $handler->thrownErrors, true);
60254
60255 return $handler;
60256 }
60257
60258 public function __construct(BufferingLogger $bootstrappingLogger = null)
60259 {
60260 if ($bootstrappingLogger) {
60261 $this->bootstrappingLogger = $bootstrappingLogger;
60262 $this->setDefaultLogger($bootstrappingLogger);
60263 }
60264 }
60265
60266
60267
60268
60269
60270
60271
60272
60273 public function setDefaultLogger(LoggerInterface $logger, $levels = null, $replace = false)
60274 {
60275 $loggers = array();
60276
60277 if (is_array($levels)) {
60278 foreach ($levels as $type => $logLevel) {
60279 if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) {
60280 $loggers[$type] = array($logger, $logLevel);
60281 }
60282 }
60283 } else {
60284 if (null === $levels) {
60285 $levels = E_ALL | E_STRICT;
60286 }
60287 foreach ($this->loggers as $type => $log) {
60288 if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) {
60289 $log[0] = $logger;
60290 $loggers[$type] = $log;
60291 }
60292 }
60293 }
60294
60295 $this->setLoggers($loggers);
60296 }
60297
60298
60299
60300
60301
60302
60303
60304
60305
60306
60307 public function setLoggers(array $loggers)
60308 {
60309 $prevLogged = $this->loggedErrors;
60310 $prev = $this->loggers;
60311 $flush = array();
60312
60313 foreach ($loggers as $type => $log) {
60314 if (!isset($prev[$type])) {
60315 throw new \InvalidArgumentException('Unknown error type: '.$type);
60316 }
60317 if (!is_array($log)) {
60318 $log = array($log);
60319 } elseif (!array_key_exists(0, $log)) {
60320 throw new \InvalidArgumentException('No logger provided');
60321 }
60322 if (null === $log[0]) {
60323 $this->loggedErrors &= ~$type;
60324 } elseif ($log[0] instanceof LoggerInterface) {
60325 $this->loggedErrors |= $type;
60326 } else {
60327 throw new \InvalidArgumentException('Invalid logger provided');
60328 }
60329 $this->loggers[$type] = $log + $prev[$type];
60330
60331 if ($this->bootstrappingLogger && $prev[$type][0] === $this->bootstrappingLogger) {
60332 $flush[$type] = $type;
60333 }
60334 }
60335 $this->reRegister($prevLogged | $this->thrownErrors);
60336
60337 if ($flush) {
60338 foreach ($this->bootstrappingLogger->cleanLogs() as $log) {
60339 $type = $log[2]['type'];
60340 if (!isset($flush[$type])) {
60341 $this->bootstrappingLogger->log($log[0], $log[1], $log[2]);
60342 } elseif ($this->loggers[$type][0]) {
60343 $this->loggers[$type][0]->log($this->loggers[$type][1], $log[1], $log[2]);
60344 }
60345 }
60346 }
60347
60348 return $prev;
60349 }
60350
60351
60352
60353
60354
60355
60356
60357
60358
60359
60360 public function setExceptionHandler($handler)
60361 {
60362 if (null !== $handler && !is_callable($handler)) {
60363 throw new \LogicException('The exception handler must be a valid PHP callable.');
60364 }
60365 $prev = $this->exceptionHandler;
60366 $this->exceptionHandler = $handler;
60367
60368 return $prev;
60369 }
60370
60371
60372
60373
60374
60375
60376
60377
60378
60379 public function throwAt($levels, $replace = false)
60380 {
60381 $prev = $this->thrownErrors;
60382 $this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
60383 if (!$replace) {
60384 $this->thrownErrors |= $prev;
60385 }
60386 $this->reRegister($prev | $this->loggedErrors);
60387
60388
60389  $this->displayErrors = $this->thrownErrors;
60390
60391 return $prev;
60392 }
60393
60394
60395
60396
60397
60398
60399
60400
60401
60402 public function scopeAt($levels, $replace = false)
60403 {
60404 $prev = $this->scopedErrors;
60405 $this->scopedErrors = (int) $levels;
60406 if (!$replace) {
60407 $this->scopedErrors |= $prev;
60408 }
60409
60410 return $prev;
60411 }
60412
60413
60414
60415
60416
60417
60418
60419
60420
60421 public function traceAt($levels, $replace = false)
60422 {
60423 $prev = $this->tracedErrors;
60424 $this->tracedErrors = (int) $levels;
60425 if (!$replace) {
60426 $this->tracedErrors |= $prev;
60427 }
60428
60429 return $prev;
60430 }
60431
60432
60433
60434
60435
60436
60437
60438
60439
60440 public function screamAt($levels, $replace = false)
60441 {
60442 $prev = $this->screamedErrors;
60443 $this->screamedErrors = (int) $levels;
60444 if (!$replace) {
60445 $this->screamedErrors |= $prev;
60446 }
60447
60448 return $prev;
60449 }
60450
60451
60452
60453
60454 private function reRegister($prev)
60455 {
60456 if ($prev !== $this->thrownErrors | $this->loggedErrors) {
60457 $handler = set_error_handler('var_dump');
60458 $handler = is_array($handler) ? $handler[0] : null;
60459 restore_error_handler();
60460 if ($handler === $this) {
60461 restore_error_handler();
60462 if ($this->isRoot) {
60463 set_error_handler(array($this, 'handleError'), $this->thrownErrors | $this->loggedErrors);
60464 } else {
60465 set_error_handler(array($this, 'handleError'));
60466 }
60467 }
60468 }
60469 }
60470
60471
60472
60473
60474
60475
60476
60477
60478
60479
60480
60481
60482
60483
60484
60485 public function handleError($type, $message, $file, $line)
60486 {
60487 $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
60488 $log = $this->loggedErrors & $type;
60489 $throw = $this->thrownErrors & $type & $level;
60490 $type &= $level | $this->screamedErrors;
60491
60492 if (!$type || (!$log && !$throw)) {
60493 return $type && $log;
60494 }
60495 $scope = $this->scopedErrors & $type;
60496
60497 if (4 < $numArgs = func_num_args()) {
60498 $context = $scope ? (func_get_arg(4) ?: array()) : array();
60499 $backtrace = 5 < $numArgs ? func_get_arg(5) : null; 
60500  } else {
60501 $context = array();
60502 $backtrace = null;
60503 }
60504
60505 if (isset($context['GLOBALS']) && $scope) {
60506 $e = $context; 
60507  unset($e['GLOBALS'], $context); 
60508  $context = $e;
60509 }
60510
60511 if (null !== $backtrace && $type & E_ERROR) {
60512
60513  
60514  
60515  $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace'));
60516
60517 return true;
60518 }
60519
60520 if ($throw) {
60521 if (null !== self::$toStringException) {
60522 $throw = self::$toStringException;
60523 self::$toStringException = null;
60524 } elseif ($scope && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
60525
60526  $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
60527 } else {
60528 $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
60529 }
60530
60531 if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) {
60532
60533  
60534  
60535
60536 $throw->errorHandlerCanary = new ErrorHandlerCanary();
60537 }
60538
60539 if (E_USER_ERROR & $type) {
60540 $backtrace = $backtrace ?: $throw->getTrace();
60541
60542 for ($i = 1; isset($backtrace[$i]); ++$i) {
60543 if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function'])
60544 && '__toString' === $backtrace[$i]['function']
60545 && '->' === $backtrace[$i]['type']
60546 && !isset($backtrace[$i - 1]['class'])
60547 && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])
60548 ) {
60549
60550  
60551  
60552  
60553  
60554  
60555
60556 foreach ($context as $e) {
60557 if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) {
60558 if (1 === $i) {
60559
60560  $throw = $e;
60561 break;
60562 }
60563 self::$toStringException = $e;
60564
60565 return true;
60566 }
60567 }
60568
60569 if (1 < $i) {
60570
60571  $this->handleException($throw);
60572
60573
60574  return false;
60575 }
60576 }
60577 }
60578 }
60579
60580 throw $throw;
60581 }
60582
60583
60584  $e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
60585 $trace = true;
60586
60587 if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
60588 $trace = false;
60589 } else {
60590 $this->loggedTraces[$e] = 1;
60591 }
60592
60593 $e = compact('type', 'file', 'line', 'level');
60594
60595 if ($type & $level) {
60596 if ($scope) {
60597 $e['scope_vars'] = $context;
60598 if ($trace) {
60599 $e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
60600 }
60601 } elseif ($trace) {
60602 if (null === $backtrace) {
60603 $e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
60604 } else {
60605 foreach ($backtrace as &$frame) {
60606 unset($frame['args'], $frame);
60607 }
60608 $e['stack'] = $backtrace;
60609 }
60610 }
60611 }
60612
60613 if ($this->isRecursive) {
60614 $log = 0;
60615 } elseif (self::$stackedErrorLevels) {
60616 self::$stackedErrors[] = array($this->loggers[$type][0], ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e);
60617 } else {
60618 try {
60619 $this->isRecursive = true;
60620 $this->loggers[$type][0]->log(($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e);
60621 $this->isRecursive = false;
60622 } catch (\Exception $e) {
60623 $this->isRecursive = false;
60624
60625 throw $e;
60626 } catch (\Throwable $e) {
60627 $this->isRecursive = false;
60628
60629 throw $e;
60630 }
60631 }
60632
60633 return $type && $log;
60634 }
60635
60636
60637
60638
60639
60640
60641
60642
60643
60644 public function handleException($exception, array $error = null)
60645 {
60646 if (!$exception instanceof \Exception) {
60647 $exception = new FatalThrowableError($exception);
60648 }
60649 $type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
60650
60651 if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
60652 $e = array(
60653 'type' => $type,
60654 'file' => $exception->getFile(),
60655 'line' => $exception->getLine(),
60656 'level' => error_reporting(),
60657 'stack' => $exception->getTrace(),
60658 );
60659 if ($exception instanceof FatalErrorException) {
60660 if ($exception instanceof FatalThrowableError) {
60661 $error = array(
60662 'type' => $type,
60663 'message' => $message = $exception->getMessage(),
60664 'file' => $e['file'],
60665 'line' => $e['line'],
60666 );
60667 } else {
60668 $message = 'Fatal '.$exception->getMessage();
60669 }
60670 } elseif ($exception instanceof \ErrorException) {
60671 $message = 'Uncaught '.$exception->getMessage();
60672 if ($exception instanceof ContextErrorException) {
60673 $e['context'] = $exception->getContext();
60674 }
60675 } else {
60676 $message = 'Uncaught Exception: '.$exception->getMessage();
60677 }
60678 }
60679 if ($this->loggedErrors & $type) {
60680 try {
60681 $this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
60682 } catch (\Exception $handlerException) {
60683 } catch (\Throwable $handlerException) {
60684 }
60685 }
60686 if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) {
60687 foreach ($this->getFatalErrorHandlers() as $handler) {
60688 if ($e = $handler->handleError($error, $exception)) {
60689 $exception = $e;
60690 break;
60691 }
60692 }
60693 }
60694 if (empty($this->exceptionHandler)) {
60695 throw $exception; 
60696  }
60697 try {
60698 call_user_func($this->exceptionHandler, $exception);
60699 } catch (\Exception $handlerException) {
60700 } catch (\Throwable $handlerException) {
60701 }
60702 if (isset($handlerException)) {
60703 $this->exceptionHandler = null;
60704 $this->handleException($handlerException);
60705 }
60706 }
60707
60708
60709
60710
60711
60712
60713
60714
60715 public static function handleFatalError(array $error = null)
60716 {
60717 if (null === self::$reservedMemory) {
60718 return;
60719 }
60720
60721 self::$reservedMemory = null;
60722
60723 $handler = set_error_handler('var_dump');
60724 $handler = is_array($handler) ? $handler[0] : null;
60725 restore_error_handler();
60726
60727 if (!$handler instanceof self) {
60728 return;
60729 }
60730
60731 if (null === $error) {
60732 $error = error_get_last();
60733 }
60734
60735 try {
60736 while (self::$stackedErrorLevels) {
60737 static::unstackErrors();
60738 }
60739 } catch (\Exception $exception) {
60740
60741  } catch (\Throwable $exception) {
60742
60743  }
60744
60745 if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) {
60746
60747  $handler->throwAt(0, true);
60748 $trace = isset($error['backtrace']) ? $error['backtrace'] : null;
60749
60750 if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
60751 $exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false, $trace);
60752 } else {
60753 $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace);
60754 }
60755 } elseif (!isset($exception)) {
60756 return;
60757 }
60758
60759 try {
60760 $handler->handleException($exception, $error);
60761 } catch (FatalErrorException $e) {
60762
60763  }
60764 }
60765
60766
60767
60768
60769
60770
60771
60772
60773
60774
60775
60776
60777 public static function stackErrors()
60778 {
60779 self::$stackedErrorLevels[] = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
60780 }
60781
60782
60783
60784
60785 public static function unstackErrors()
60786 {
60787 $level = array_pop(self::$stackedErrorLevels);
60788
60789 if (null !== $level) {
60790 $e = error_reporting($level);
60791 if ($e !== ($level | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR)) {
60792
60793  error_reporting($e);
60794 }
60795 }
60796
60797 if (empty(self::$stackedErrorLevels)) {
60798 $errors = self::$stackedErrors;
60799 self::$stackedErrors = array();
60800
60801 foreach ($errors as $e) {
60802 $e[0]->log($e[1], $e[2], $e[3]);
60803 }
60804 }
60805 }
60806
60807
60808
60809
60810
60811
60812
60813
60814 protected function getFatalErrorHandlers()
60815 {
60816 return array(
60817 new UndefinedFunctionFatalErrorHandler(),
60818 new UndefinedMethodFatalErrorHandler(),
60819 new ClassNotFoundFatalErrorHandler(),
60820 );
60821 }
60822
60823
60824
60825
60826
60827
60828
60829
60830 public function setLevel($level)
60831 {
60832 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
60833
60834 $level = null === $level ? error_reporting() : $level;
60835 $this->throwAt($level, true);
60836 }
60837
60838
60839
60840
60841
60842
60843
60844
60845 public function setDisplayErrors($displayErrors)
60846 {
60847 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
60848
60849 if ($displayErrors) {
60850 $this->throwAt($this->displayErrors, true);
60851 } else {
60852 $displayErrors = $this->displayErrors;
60853 $this->throwAt(0, true);
60854 $this->displayErrors = $displayErrors;
60855 }
60856 }
60857
60858
60859
60860
60861
60862
60863
60864
60865
60866 public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
60867 {
60868 @trigger_error('The '.__METHOD__.' static method is deprecated since version 2.6 and will be removed in 3.0. Use the setLoggers() or setDefaultLogger() methods instead.', E_USER_DEPRECATED);
60869
60870 $handler = set_error_handler('var_dump');
60871 $handler = is_array($handler) ? $handler[0] : null;
60872 restore_error_handler();
60873 if (!$handler instanceof self) {
60874 return;
60875 }
60876 if ('deprecation' === $channel) {
60877 $handler->setDefaultLogger($logger, E_DEPRECATED | E_USER_DEPRECATED, true);
60878 $handler->screamAt(E_DEPRECATED | E_USER_DEPRECATED);
60879 } elseif ('scream' === $channel) {
60880 $handler->setDefaultLogger($logger, E_ALL | E_STRICT, false);
60881 $handler->screamAt(E_ALL | E_STRICT);
60882 } elseif ('emergency' === $channel) {
60883 $handler->setDefaultLogger($logger, E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR, true);
60884 $handler->screamAt(E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
60885 }
60886 }
60887
60888
60889
60890
60891 public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
60892 {
60893 $this->handleError(E_USER_DEPRECATED, 'The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleError() method instead.', __FILE__, __LINE__, array());
60894
60895 return $this->handleError($level, $message, $file, $line, (array) $context);
60896 }
60897
60898
60899
60900
60901
60902
60903 public function handleFatal()
60904 {
60905 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the handleFatalError() method instead.', E_USER_DEPRECATED);
60906
60907 static::handleFatalError();
60908 }
60909 }
60910
60911
60912
60913
60914
60915
60916
60917
60918 class ErrorHandlerCanary
60919 {
60920 private static $displayErrors = null;
60921
60922 public function __construct()
60923 {
60924 if (null === self::$displayErrors) {
60925 self::$displayErrors = ini_set('display_errors', 1);
60926 }
60927 }
60928
60929 public function __destruct()
60930 {
60931 if (null !== self::$displayErrors) {
60932 ini_set('display_errors', self::$displayErrors);
60933 self::$displayErrors = null;
60934 }
60935 }
60936 }
60937 <?php
60938
60939
60940
60941
60942
60943
60944
60945
60946
60947
60948 namespace Symfony\Component\Debug\Exception;
60949
60950
60951
60952
60953
60954
60955 class ClassNotFoundException extends FatalErrorException
60956 {
60957 public function __construct($message, \ErrorException $previous)
60958 {
60959 parent::__construct(
60960 $message,
60961 $previous->getCode(),
60962 $previous->getSeverity(),
60963 $previous->getFile(),
60964 $previous->getLine(),
60965 $previous->getPrevious()
60966 );
60967 $this->setTrace($previous->getTrace());
60968 }
60969 }
60970 <?php
60971
60972
60973
60974
60975
60976
60977
60978
60979
60980
60981 namespace Symfony\Component\Debug\Exception;
60982
60983
60984
60985
60986
60987
60988 class ContextErrorException extends \ErrorException
60989 {
60990 private $context = array();
60991
60992 public function __construct($message, $code, $severity, $filename, $lineno, $context = array())
60993 {
60994 parent::__construct($message, $code, $severity, $filename, $lineno);
60995 $this->context = $context;
60996 }
60997
60998
60999
61000
61001 public function getContext()
61002 {
61003 return $this->context;
61004 }
61005 }
61006 <?php
61007
61008
61009
61010
61011
61012
61013
61014
61015
61016
61017 namespace Symfony\Component\Debug\Exception;
61018
61019 @trigger_error('The '.__NAMESPACE__.'\DummyException class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
61020
61021
61022
61023
61024
61025
61026 class DummyException extends \ErrorException
61027 {
61028 }
61029 <?php
61030
61031
61032
61033
61034
61035
61036
61037
61038
61039
61040 namespace Symfony\Component\HttpKernel\Exception;
61041
61042
61043
61044
61045
61046
61047
61048
61049
61050
61051 class FatalErrorException extends \ErrorException
61052 {
61053 }
61054
61055 namespace Symfony\Component\Debug\Exception;
61056
61057 use Symfony\Component\HttpKernel\Exception\FatalErrorException as LegacyFatalErrorException;
61058
61059
61060
61061
61062
61063
61064 class FatalErrorException extends LegacyFatalErrorException
61065 {
61066 public function __construct($message, $code, $severity, $filename, $lineno, $traceOffset = null, $traceArgs = true, array $trace = null)
61067 {
61068 parent::__construct($message, $code, $severity, $filename, $lineno);
61069
61070 if (null !== $trace) {
61071 if (!$traceArgs) {
61072 foreach ($trace as &$frame) {
61073 unset($frame['args'], $frame['this'], $frame);
61074 }
61075 }
61076
61077 $this->setTrace($trace);
61078 } elseif (null !== $traceOffset) {
61079 if (function_exists('xdebug_get_function_stack')) {
61080 $trace = xdebug_get_function_stack();
61081 if (0 < $traceOffset) {
61082 array_splice($trace, -$traceOffset);
61083 }
61084
61085 foreach ($trace as &$frame) {
61086 if (!isset($frame['type'])) {
61087
61088  if (isset($frame['class'])) {
61089 $frame['type'] = '::';
61090 }
61091 } elseif ('dynamic' === $frame['type']) {
61092 $frame['type'] = '->';
61093 } elseif ('static' === $frame['type']) {
61094 $frame['type'] = '::';
61095 }
61096
61097
61098  if (!$traceArgs) {
61099 unset($frame['params'], $frame['args']);
61100 } elseif (isset($frame['params']) && !isset($frame['args'])) {
61101 $frame['args'] = $frame['params'];
61102 unset($frame['params']);
61103 }
61104 }
61105
61106 unset($frame);
61107 $trace = array_reverse($trace);
61108 } elseif (function_exists('symfony_debug_backtrace')) {
61109 $trace = symfony_debug_backtrace();
61110 if (0 < $traceOffset) {
61111 array_splice($trace, 0, $traceOffset);
61112 }
61113 } else {
61114 $trace = array();
61115 }
61116
61117 $this->setTrace($trace);
61118 }
61119 }
61120
61121 protected function setTrace($trace)
61122 {
61123 $traceReflector = new \ReflectionProperty('Exception', 'trace');
61124 $traceReflector->setAccessible(true);
61125 $traceReflector->setValue($this, $trace);
61126 }
61127 }
61128 <?php
61129
61130
61131
61132
61133
61134
61135
61136
61137
61138
61139 namespace Symfony\Component\Debug\Exception;
61140
61141
61142
61143
61144
61145
61146 class FatalThrowableError extends FatalErrorException
61147 {
61148 public function __construct(\Throwable $e)
61149 {
61150 if ($e instanceof \ParseError) {
61151 $message = 'Parse error: '.$e->getMessage();
61152 $severity = E_PARSE;
61153 } elseif ($e instanceof \TypeError) {
61154 $message = 'Type error: '.$e->getMessage();
61155 $severity = E_RECOVERABLE_ERROR;
61156 } else {
61157 $message = $e->getMessage();
61158 $severity = E_ERROR;
61159 }
61160
61161 \ErrorException::__construct(
61162 $message,
61163 $e->getCode(),
61164 $severity,
61165 $e->getFile(),
61166 $e->getLine()
61167 );
61168
61169 $this->setTrace($e->getTrace());
61170 }
61171 }
61172 <?php
61173
61174
61175
61176
61177
61178
61179
61180
61181
61182
61183 namespace Symfony\Component\HttpKernel\Exception;
61184
61185 use Symfony\Component\Debug\Exception\FlattenException as DebugFlattenException;
61186
61187
61188
61189
61190
61191
61192
61193
61194
61195
61196 class FlattenException
61197 {
61198 private $handler;
61199
61200 public static function __callStatic($method, $args)
61201 {
61202 if (!method_exists('Symfony\Component\Debug\Exception\FlattenException', $method)) {
61203 throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_called_class(), $method));
61204 }
61205
61206 return call_user_func_array(array('Symfony\Component\Debug\Exception\FlattenException', $method), $args);
61207 }
61208
61209 public function __call($method, $args)
61210 {
61211 if (!isset($this->handler)) {
61212 $this->handler = new DebugFlattenException();
61213 }
61214
61215 if (!method_exists($this->handler, $method)) {
61216 throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_class($this), $method));
61217 }
61218
61219 return call_user_func_array(array($this->handler, $method), $args);
61220 }
61221 }
61222
61223 namespace Symfony\Component\Debug\Exception;
61224
61225 use Symfony\Component\HttpKernel\Exception\FlattenException as LegacyFlattenException;
61226 use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
61227
61228
61229
61230
61231
61232
61233
61234
61235 class FlattenException extends LegacyFlattenException
61236 {
61237 private $message;
61238 private $code;
61239 private $previous;
61240 private $trace;
61241 private $class;
61242 private $statusCode;
61243 private $headers;
61244 private $file;
61245 private $line;
61246
61247 public static function create(\Exception $exception, $statusCode = null, array $headers = array())
61248 {
61249 $e = new static();
61250 $e->setMessage($exception->getMessage());
61251 $e->setCode($exception->getCode());
61252
61253 if ($exception instanceof HttpExceptionInterface) {
61254 $statusCode = $exception->getStatusCode();
61255 $headers = array_merge($headers, $exception->getHeaders());
61256 }
61257
61258 if (null === $statusCode) {
61259 $statusCode = 500;
61260 }
61261
61262 $e->setStatusCode($statusCode);
61263 $e->setHeaders($headers);
61264 $e->setTraceFromException($exception);
61265 $e->setClass(get_class($exception));
61266 $e->setFile($exception->getFile());
61267 $e->setLine($exception->getLine());
61268
61269 $previous = $exception->getPrevious();
61270
61271 if ($previous instanceof \Exception) {
61272 $e->setPrevious(static::create($previous));
61273 } elseif ($previous instanceof \Throwable) {
61274 $e->setPrevious(static::create(new FatalThrowableError($previous)));
61275 }
61276
61277 return $e;
61278 }
61279
61280 public function toArray()
61281 {
61282 $exceptions = array();
61283 foreach (array_merge(array($this), $this->getAllPrevious()) as $exception) {
61284 $exceptions[] = array(
61285 'message' => $exception->getMessage(),
61286 'class' => $exception->getClass(),
61287 'trace' => $exception->getTrace(),
61288 );
61289 }
61290
61291 return $exceptions;
61292 }
61293
61294 public function getStatusCode()
61295 {
61296 return $this->statusCode;
61297 }
61298
61299 public function setStatusCode($code)
61300 {
61301 $this->statusCode = $code;
61302 }
61303
61304 public function getHeaders()
61305 {
61306 return $this->headers;
61307 }
61308
61309 public function setHeaders(array $headers)
61310 {
61311 $this->headers = $headers;
61312 }
61313
61314 public function getClass()
61315 {
61316 return $this->class;
61317 }
61318
61319 public function setClass($class)
61320 {
61321 $this->class = $class;
61322 }
61323
61324 public function getFile()
61325 {
61326 return $this->file;
61327 }
61328
61329 public function setFile($file)
61330 {
61331 $this->file = $file;
61332 }
61333
61334 public function getLine()
61335 {
61336 return $this->line;
61337 }
61338
61339 public function setLine($line)
61340 {
61341 $this->line = $line;
61342 }
61343
61344 public function getMessage()
61345 {
61346 return $this->message;
61347 }
61348
61349 public function setMessage($message)
61350 {
61351 $this->message = $message;
61352 }
61353
61354 public function getCode()
61355 {
61356 return $this->code;
61357 }
61358
61359 public function setCode($code)
61360 {
61361 $this->code = $code;
61362 }
61363
61364 public function getPrevious()
61365 {
61366 return $this->previous;
61367 }
61368
61369 public function setPrevious(FlattenException $previous)
61370 {
61371 $this->previous = $previous;
61372 }
61373
61374 public function getAllPrevious()
61375 {
61376 $exceptions = array();
61377 $e = $this;
61378 while ($e = $e->getPrevious()) {
61379 $exceptions[] = $e;
61380 }
61381
61382 return $exceptions;
61383 }
61384
61385 public function getTrace()
61386 {
61387 return $this->trace;
61388 }
61389
61390 public function setTraceFromException(\Exception $exception)
61391 {
61392 $this->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine());
61393 }
61394
61395 public function setTrace($trace, $file, $line)
61396 {
61397 $this->trace = array();
61398 $this->trace[] = array(
61399 'namespace' => '',
61400 'short_class' => '',
61401 'class' => '',
61402 'type' => '',
61403 'function' => '',
61404 'file' => $file,
61405 'line' => $line,
61406 'args' => array(),
61407 );
61408 foreach ($trace as $entry) {
61409 $class = '';
61410 $namespace = '';
61411 if (isset($entry['class'])) {
61412 $parts = explode('\\', $entry['class']);
61413 $class = array_pop($parts);
61414 $namespace = implode('\\', $parts);
61415 }
61416
61417 $this->trace[] = array(
61418 'namespace' => $namespace,
61419 'short_class' => $class,
61420 'class' => isset($entry['class']) ? $entry['class'] : '',
61421 'type' => isset($entry['type']) ? $entry['type'] : '',
61422 'function' => isset($entry['function']) ? $entry['function'] : null,
61423 'file' => isset($entry['file']) ? $entry['file'] : null,
61424 'line' => isset($entry['line']) ? $entry['line'] : null,
61425 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(),
61426 );
61427 }
61428 }
61429
61430 private function flattenArgs($args, $level = 0, &$count = 0)
61431 {
61432 $result = array();
61433 foreach ($args as $key => $value) {
61434 if (++$count > 1e4) {
61435 return array('array', '*SKIPPED over 10000 entries*');
61436 }
61437 if ($value instanceof \__PHP_Incomplete_Class) {
61438
61439  $result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value));
61440 } elseif (is_object($value)) {
61441 $result[$key] = array('object', get_class($value));
61442 } elseif (is_array($value)) {
61443 if ($level > 10) {
61444 $result[$key] = array('array', '*DEEP NESTED ARRAY*');
61445 } else {
61446 $result[$key] = array('array', $this->flattenArgs($value, $level + 1, $count));
61447 }
61448 } elseif (null === $value) {
61449 $result[$key] = array('null', null);
61450 } elseif (is_bool($value)) {
61451 $result[$key] = array('boolean', $value);
61452 } elseif (is_resource($value)) {
61453 $result[$key] = array('resource', get_resource_type($value));
61454 } else {
61455 $result[$key] = array('string', (string) $value);
61456 }
61457 }
61458
61459 return $result;
61460 }
61461
61462 private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value)
61463 {
61464 $array = new \ArrayObject($value);
61465
61466 return $array['__PHP_Incomplete_Class_Name'];
61467 }
61468 }
61469 <?php
61470
61471
61472
61473
61474
61475
61476
61477
61478
61479
61480 namespace Symfony\Component\Debug\Exception;
61481
61482
61483
61484
61485
61486
61487 class OutOfMemoryException extends FatalErrorException
61488 {
61489 }
61490 <?php
61491
61492
61493
61494
61495
61496
61497
61498
61499
61500
61501 namespace Symfony\Component\Debug\Exception;
61502
61503
61504
61505
61506
61507
61508 class UndefinedFunctionException extends FatalErrorException
61509 {
61510 public function __construct($message, \ErrorException $previous)
61511 {
61512 parent::__construct(
61513 $message,
61514 $previous->getCode(),
61515 $previous->getSeverity(),
61516 $previous->getFile(),
61517 $previous->getLine(),
61518 $previous->getPrevious()
61519 );
61520 $this->setTrace($previous->getTrace());
61521 }
61522 }
61523 <?php
61524
61525
61526
61527
61528
61529
61530
61531
61532
61533
61534 namespace Symfony\Component\Debug\Exception;
61535
61536
61537
61538
61539
61540
61541 class UndefinedMethodException extends FatalErrorException
61542 {
61543 public function __construct($message, \ErrorException $previous)
61544 {
61545 parent::__construct(
61546 $message,
61547 $previous->getCode(),
61548 $previous->getSeverity(),
61549 $previous->getFile(),
61550 $previous->getLine(),
61551 $previous->getPrevious()
61552 );
61553 $this->setTrace($previous->getTrace());
61554 }
61555 }
61556 <?php
61557
61558
61559
61560
61561
61562
61563
61564
61565
61566
61567 namespace Symfony\Component\Debug;
61568
61569 use Symfony\Component\HttpFoundation\Response;
61570 use Symfony\Component\Debug\Exception\FlattenException;
61571 use Symfony\Component\Debug\Exception\OutOfMemoryException;
61572
61573
61574
61575
61576
61577
61578
61579
61580
61581
61582
61583
61584
61585 class ExceptionHandler
61586 {
61587 private $debug;
61588 private $charset;
61589 private $handler;
61590 private $caughtBuffer;
61591 private $caughtLength;
61592 private $fileLinkFormat;
61593
61594 public function __construct($debug = true, $charset = null, $fileLinkFormat = null)
61595 {
61596 if (false !== strpos($charset, '%')) {
61597 @trigger_error('Providing $fileLinkFormat as second argument to '.__METHOD__.' is deprecated since version 2.8 and will be unsupported in 3.0. Please provide it as third argument, after $charset.', E_USER_DEPRECATED);
61598
61599
61600  $pivot = $fileLinkFormat;
61601 $fileLinkFormat = $charset;
61602 $charset = $pivot;
61603 }
61604 $this->debug = $debug;
61605 $this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
61606 $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
61607 }
61608
61609
61610
61611
61612
61613
61614
61615
61616
61617
61618 public static function register($debug = true, $charset = null, $fileLinkFormat = null)
61619 {
61620 $handler = new static($debug, $charset, $fileLinkFormat);
61621
61622 $prev = set_exception_handler(array($handler, 'handle'));
61623 if (is_array($prev) && $prev[0] instanceof ErrorHandler) {
61624 restore_exception_handler();
61625 $prev[0]->setExceptionHandler(array($handler, 'handle'));
61626 }
61627
61628 return $handler;
61629 }
61630
61631
61632
61633
61634
61635
61636
61637
61638 public function setHandler($handler)
61639 {
61640 if (null !== $handler && !is_callable($handler)) {
61641 throw new \LogicException('The exception handler must be a valid PHP callable.');
61642 }
61643 $old = $this->handler;
61644 $this->handler = $handler;
61645
61646 return $old;
61647 }
61648
61649
61650
61651
61652
61653
61654
61655
61656 public function setFileLinkFormat($format)
61657 {
61658 $old = $this->fileLinkFormat;
61659 $this->fileLinkFormat = $format;
61660
61661 return $old;
61662 }
61663
61664
61665
61666
61667
61668
61669
61670
61671
61672 public function handle(\Exception $exception)
61673 {
61674 if (null === $this->handler || $exception instanceof OutOfMemoryException) {
61675 $this->failSafeHandle($exception);
61676
61677 return;
61678 }
61679
61680 $caughtLength = $this->caughtLength = 0;
61681
61682 ob_start(array($this, 'catchOutput'));
61683 $this->failSafeHandle($exception);
61684 while (null === $this->caughtBuffer && ob_end_flush()) {
61685
61686  }
61687 if (isset($this->caughtBuffer[0])) {
61688 ob_start(array($this, 'cleanOutput'));
61689 echo $this->caughtBuffer;
61690 $caughtLength = ob_get_length();
61691 }
61692 $this->caughtBuffer = null;
61693
61694 try {
61695 call_user_func($this->handler, $exception);
61696 $this->caughtLength = $caughtLength;
61697 } catch (\Exception $e) {
61698 if (!$caughtLength) {
61699
61700  throw $exception;
61701 }
61702 }
61703 }
61704
61705
61706
61707
61708
61709
61710
61711
61712
61713
61714 private function failSafeHandle(\Exception $exception)
61715 {
61716 if (class_exists('Symfony\Component\HttpFoundation\Response', false)
61717 && __CLASS__ !== get_class($this)
61718 && ($reflector = new \ReflectionMethod($this, 'createResponse'))
61719 && __CLASS__ !== $reflector->class
61720 ) {
61721 $response = $this->createResponse($exception);
61722 $response->sendHeaders();
61723 $response->sendContent();
61724 @trigger_error(sprintf("The %s::createResponse method is deprecated since 2.8 and won't be called anymore when handling an exception in 3.0.", $reflector->class), E_USER_DEPRECATED);
61725
61726 return;
61727 }
61728
61729 $this->sendPhpResponse($exception);
61730 }
61731
61732
61733
61734
61735
61736
61737
61738
61739
61740 public function sendPhpResponse($exception)
61741 {
61742 if (!$exception instanceof FlattenException) {
61743 $exception = FlattenException::create($exception);
61744 }
61745
61746 if (!headers_sent()) {
61747 header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
61748 foreach ($exception->getHeaders() as $name => $value) {
61749 header($name.': '.$value, false);
61750 }
61751 header('Content-Type: text/html; charset='.$this->charset);
61752 }
61753
61754 echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
61755 }
61756
61757
61758
61759
61760
61761
61762
61763
61764
61765
61766 public function createResponse($exception)
61767 {
61768 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
61769
61770 if (!$exception instanceof FlattenException) {
61771 $exception = FlattenException::create($exception);
61772 }
61773
61774 return Response::create($this->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders())->setCharset($this->charset);
61775 }
61776
61777
61778
61779
61780
61781
61782
61783
61784 public function getHtml($exception)
61785 {
61786 if (!$exception instanceof FlattenException) {
61787 $exception = FlattenException::create($exception);
61788 }
61789
61790 return $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
61791 }
61792
61793
61794
61795
61796
61797
61798
61799
61800 public function getContent(FlattenException $exception)
61801 {
61802 switch ($exception->getStatusCode()) {
61803 case 404:
61804 $title = 'Sorry, the page you are looking for could not be found.';
61805 break;
61806 default:
61807 $title = 'Whoops, looks like something went wrong.';
61808 }
61809
61810 $content = '';
61811 if ($this->debug) {
61812 try {
61813 $count = count($exception->getAllPrevious());
61814 $total = $count + 1;
61815 foreach ($exception->toArray() as $position => $e) {
61816 $ind = $count - $position + 1;
61817 $class = $this->formatClass($e['class']);
61818 $message = nl2br($this->escapeHtml($e['message']));
61819 $content .= sprintf(<<<'EOF'
61820                         <h2 class="block_exception clear_fix">
61821                             <span class="exception_counter">%d/%d</span>
61822                             <span class="exception_title">%s%s:</span>
61823                             <span class="exception_message">%s</span>
61824                         </h2>
61825                         <div class="block">
61826                             <ol class="traces list_exception">
61827
61828 EOF
61829 , $ind, $total, $class, $this->formatPath($e['trace'][0]['file'], $e['trace'][0]['line']), $message);
61830 foreach ($e['trace'] as $trace) {
61831 $content .= '       <li>';
61832 if ($trace['function']) {
61833 $content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
61834 }
61835 if (isset($trace['file']) && isset($trace['line'])) {
61836 $content .= $this->formatPath($trace['file'], $trace['line']);
61837 }
61838 $content .= "</li>\n";
61839 }
61840
61841 $content .= "    </ol>\n</div>\n";
61842 }
61843 } catch (\Exception $e) {
61844
61845  if ($this->debug) {
61846 $title = sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $this->escapeHtml($e->getMessage()));
61847 } else {
61848 $title = 'Whoops, looks like something went wrong.';
61849 }
61850 }
61851 }
61852
61853 return <<<EOF
61854             <div id="sf-resetcontent" class="sf-reset">
61855                 <h1>$title</h1>
61856                 $content
61857             </div>
61858 EOF;
61859 }
61860
61861
61862
61863
61864
61865
61866
61867
61868 public function getStylesheet(FlattenException $exception)
61869 {
61870 return <<<'EOF'
61871             .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 }
61872             .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; }
61873             .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; }
61874             .sf-reset .clear_fix { display:inline-block; }
61875             .sf-reset * html .clear_fix { height:1%; }
61876             .sf-reset .clear_fix { display:block; }
61877             .sf-reset, .sf-reset .block { margin: auto }
61878             .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
61879             .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
61880             .sf-reset strong { font-weight:bold; }
61881             .sf-reset a { color:#6c6159; cursor: default; }
61882             .sf-reset a img { border:none; }
61883             .sf-reset a:hover { text-decoration:underline; }
61884             .sf-reset em { font-style:italic; }
61885             .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
61886             .sf-reset .exception_counter { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; float: left; display: block; }
61887             .sf-reset .exception_title { margin-left: 3em; margin-bottom: 0.7em; display: block; }
61888             .sf-reset .exception_message { margin-left: 3em; display: block; }
61889             .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
61890             .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
61891                 -webkit-border-bottom-right-radius: 16px;
61892                 -webkit-border-bottom-left-radius: 16px;
61893                 -moz-border-radius-bottomright: 16px;
61894                 -moz-border-radius-bottomleft: 16px;
61895                 border-bottom-right-radius: 16px;
61896                 border-bottom-left-radius: 16px;
61897                 border-bottom:1px solid #ccc;
61898                 border-right:1px solid #ccc;
61899                 border-left:1px solid #ccc;
61900                 word-wrap: break-word;
61901             }
61902             .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px;
61903                 -webkit-border-top-left-radius: 16px;
61904                 -webkit-border-top-right-radius: 16px;
61905                 -moz-border-radius-topleft: 16px;
61906                 -moz-border-radius-topright: 16px;
61907                 border-top-left-radius: 16px;
61908                 border-top-right-radius: 16px;
61909                 border-top:1px solid #ccc;
61910                 border-right:1px solid #ccc;
61911                 border-left:1px solid #ccc;
61912                 overflow: hidden;
61913                 word-wrap: break-word;
61914             }
61915             .sf-reset a { background:none; color:#868686; text-decoration:none; }
61916             .sf-reset a:hover { background:none; color:#313131; text-decoration:underline; }
61917             .sf-reset ol { padding: 10px 0; }
61918             .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;
61919                 -webkit-border-radius: 10px;
61920                 -moz-border-radius: 10px;
61921                 border-radius: 10px;
61922                 border: 1px solid #ccc;
61923             }
61924 EOF;
61925 }
61926
61927 private function decorate($content, $css)
61928 {
61929 return <<<EOF
61930 <!DOCTYPE html>
61931 <html>
61932     <head>
61933         <meta charset="{$this->charset}" />
61934         <meta name="robots" content="noindex,nofollow" />
61935         <style>
61936             /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
61937             html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}
61938
61939             html { background: #eee; padding: 10px }
61940             img { border: 0; }
61941             #sf-resetcontent { width:970px; margin:0 auto; }
61942             $css
61943         </style>
61944     </head>
61945     <body>
61946         $content
61947     </body>
61948 </html>
61949 EOF;
61950 }
61951
61952 private function formatClass($class)
61953 {
61954 $parts = explode('\\', $class);
61955
61956 return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
61957 }
61958
61959 private function formatPath($path, $line)
61960 {
61961 $path = $this->escapeHtml($path);
61962 $file = preg_match('#[^/\\\\]*$#', $path, $file) ? $file[0] : $path;
61963
61964 if ($linkFormat = $this->fileLinkFormat) {
61965 $link = strtr($this->escapeHtml($linkFormat), array('%f' => $path, '%l' => (int) $line));
61966
61967 return sprintf(' in <a href="%s" title="Go to source">%s line %d</a>', $link, $file, $line);
61968 }
61969
61970 return sprintf(' in <a title="%s line %3$d" ondblclick="var f=this.innerHTML;this.innerHTML=this.title;this.title=f;">%s line %d</a>', $path, $file, $line);
61971 }
61972
61973
61974
61975
61976
61977
61978
61979
61980 private function formatArgs(array $args)
61981 {
61982 $result = array();
61983 foreach ($args as $key => $item) {
61984 if ('object' === $item[0]) {
61985 $formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));
61986 } elseif ('array' === $item[0]) {
61987 $formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
61988 } elseif ('string' === $item[0]) {
61989 $formattedValue = sprintf("'%s'", $this->escapeHtml($item[1]));
61990 } elseif ('null' === $item[0]) {
61991 $formattedValue = '<em>null</em>';
61992 } elseif ('boolean' === $item[0]) {
61993 $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
61994 } elseif ('resource' === $item[0]) {
61995 $formattedValue = '<em>resource</em>';
61996 } else {
61997 $formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true));
61998 }
61999
62000 $result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
62001 }
62002
62003 return implode(', ', $result);
62004 }
62005
62006
62007
62008
62009
62010
62011 protected static function utf8Htmlize($str)
62012 {
62013 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
62014
62015 return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8');
62016 }
62017
62018
62019
62020
62021 private function escapeHtml($str)
62022 {
62023 return htmlspecialchars($str, ENT_QUOTES | (PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset);
62024 }
62025
62026
62027
62028
62029 public function catchOutput($buffer)
62030 {
62031 $this->caughtBuffer = $buffer;
62032
62033 return '';
62034 }
62035
62036
62037
62038
62039 public function cleanOutput($buffer)
62040 {
62041 if ($this->caughtLength) {
62042
62043  $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength);
62044 if (isset($cleanBuffer[0])) {
62045 $buffer = $cleanBuffer;
62046 }
62047 }
62048
62049 return $buffer;
62050 }
62051 }
62052 <?php
62053
62054
62055
62056
62057
62058
62059
62060
62061
62062
62063 namespace Symfony\Component\Debug\FatalErrorHandler;
62064
62065 use Symfony\Component\Debug\Exception\ClassNotFoundException;
62066 use Symfony\Component\Debug\Exception\FatalErrorException;
62067 use Symfony\Component\Debug\DebugClassLoader;
62068 use Composer\Autoload\ClassLoader as ComposerClassLoader;
62069 use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
62070 use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader;
62071
62072
62073
62074
62075
62076
62077 class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
62078 {
62079
62080
62081
62082 public function handleError(array $error, FatalErrorException $exception)
62083 {
62084 $messageLen = strlen($error['message']);
62085 $notFoundSuffix = '\' not found';
62086 $notFoundSuffixLen = strlen($notFoundSuffix);
62087 if ($notFoundSuffixLen > $messageLen) {
62088 return;
62089 }
62090
62091 if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
62092 return;
62093 }
62094
62095 foreach (array('class', 'interface', 'trait') as $typeName) {
62096 $prefix = ucfirst($typeName).' \'';
62097 $prefixLen = strlen($prefix);
62098 if (0 !== strpos($error['message'], $prefix)) {
62099 continue;
62100 }
62101
62102 $fullyQualifiedClassName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
62103 if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
62104 $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
62105 $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
62106 $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
62107 $tail = ' for another namespace?';
62108 } else {
62109 $className = $fullyQualifiedClassName;
62110 $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
62111 $tail = '?';
62112 }
62113
62114 if ($candidates = $this->getClassCandidates($className)) {
62115 $tail = array_pop($candidates).'"?';
62116 if ($candidates) {
62117 $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
62118 } else {
62119 $tail = ' for "'.$tail;
62120 }
62121 }
62122 $message .= "\nDid you forget a \"use\" statement".$tail;
62123
62124 return new ClassNotFoundException($message, $exception);
62125 }
62126 }
62127
62128
62129
62130
62131
62132
62133
62134
62135
62136
62137
62138 private function getClassCandidates($class)
62139 {
62140 if (!is_array($functions = spl_autoload_functions())) {
62141 return array();
62142 }
62143
62144
62145  $classes = array();
62146
62147 foreach ($functions as $function) {
62148 if (!is_array($function)) {
62149 continue;
62150 }
62151
62152  if ($function[0] instanceof DebugClassLoader) {
62153 $function = $function[0]->getClassLoader();
62154
62155
62156  if (is_object($function)) {
62157 $function = array($function);
62158 }
62159
62160 if (!is_array($function)) {
62161 continue;
62162 }
62163 }
62164
62165 if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader || $function[0] instanceof SymfonyUniversalClassLoader) {
62166 foreach ($function[0]->getPrefixes() as $prefix => $paths) {
62167 foreach ($paths as $path) {
62168 $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
62169 }
62170 }
62171 }
62172 if ($function[0] instanceof ComposerClassLoader) {
62173 foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) {
62174 foreach ($paths as $path) {
62175 $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
62176 }
62177 }
62178 }
62179 }
62180
62181 return array_unique($classes);
62182 }
62183
62184
62185
62186
62187
62188
62189
62190
62191 private function findClassInPath($path, $class, $prefix)
62192 {
62193 if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
62194 return array();
62195 }
62196
62197 $classes = array();
62198 $filename = $class.'.php';
62199 foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
62200 if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {
62201 $classes[] = $class;
62202 }
62203 }
62204
62205 return $classes;
62206 }
62207
62208
62209
62210
62211
62212
62213
62214
62215 private function convertFileToClass($path, $file, $prefix)
62216 {
62217 $candidates = array(
62218
62219  $namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
62220
62221  $prefix.$namespacedClass,
62222
62223  $prefix.'\\'.$namespacedClass,
62224
62225  str_replace('\\', '_', $namespacedClass),
62226
62227  str_replace('\\', '_', $prefix.$namespacedClass),
62228
62229  str_replace('\\', '_', $prefix.'\\'.$namespacedClass),
62230 );
62231
62232 if ($prefix) {
62233 $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); });
62234 }
62235
62236
62237  
62238  
62239  foreach ($candidates as $candidate) {
62240 if ($this->classExists($candidate)) {
62241 return $candidate;
62242 }
62243 }
62244
62245 require_once $file;
62246
62247 foreach ($candidates as $candidate) {
62248 if ($this->classExists($candidate)) {
62249 return $candidate;
62250 }
62251 }
62252 }
62253
62254
62255
62256
62257
62258
62259 private function classExists($class)
62260 {
62261 return class_exists($class, false) || interface_exists($class, false) || (function_exists('trait_exists') && trait_exists($class, false));
62262 }
62263 }
62264 <?php
62265
62266
62267
62268
62269
62270
62271
62272
62273
62274
62275 namespace Symfony\Component\Debug\FatalErrorHandler;
62276
62277 use Symfony\Component\Debug\Exception\FatalErrorException;
62278
62279
62280
62281
62282
62283
62284 interface FatalErrorHandlerInterface
62285 {
62286
62287
62288
62289
62290
62291
62292
62293
62294 public function handleError(array $error, FatalErrorException $exception);
62295 }
62296 <?php
62297
62298
62299
62300
62301
62302
62303
62304
62305
62306
62307 namespace Symfony\Component\Debug\FatalErrorHandler;
62308
62309 use Symfony\Component\Debug\Exception\UndefinedFunctionException;
62310 use Symfony\Component\Debug\Exception\FatalErrorException;
62311
62312
62313
62314
62315
62316
62317 class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
62318 {
62319
62320
62321
62322 public function handleError(array $error, FatalErrorException $exception)
62323 {
62324 $messageLen = strlen($error['message']);
62325 $notFoundSuffix = '()';
62326 $notFoundSuffixLen = strlen($notFoundSuffix);
62327 if ($notFoundSuffixLen > $messageLen) {
62328 return;
62329 }
62330
62331 if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
62332 return;
62333 }
62334
62335 $prefix = 'Call to undefined function ';
62336 $prefixLen = strlen($prefix);
62337 if (0 !== strpos($error['message'], $prefix)) {
62338 return;
62339 }
62340
62341 $fullyQualifiedFunctionName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
62342 if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) {
62343 $functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1);
62344 $namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex);
62345 $message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix);
62346 } else {
62347 $functionName = $fullyQualifiedFunctionName;
62348 $message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName);
62349 }
62350
62351 $candidates = array();
62352 foreach (get_defined_functions() as $type => $definedFunctionNames) {
62353 foreach ($definedFunctionNames as $definedFunctionName) {
62354 if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\')) {
62355 $definedFunctionNameBasename = substr($definedFunctionName, $namespaceSeparatorIndex + 1);
62356 } else {
62357 $definedFunctionNameBasename = $definedFunctionName;
62358 }
62359
62360 if ($definedFunctionNameBasename === $functionName) {
62361 $candidates[] = '\\'.$definedFunctionName;
62362 }
62363 }
62364 }
62365
62366 if ($candidates) {
62367 sort($candidates);
62368 $last = array_pop($candidates).'"?';
62369 if ($candidates) {
62370 $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
62371 } else {
62372 $candidates = '"'.$last;
62373 }
62374 $message .= "\nDid you mean to call ".$candidates;
62375 }
62376
62377 return new UndefinedFunctionException($message, $exception);
62378 }
62379 }
62380 <?php
62381
62382
62383
62384
62385
62386
62387
62388
62389
62390
62391 namespace Symfony\Component\Debug\FatalErrorHandler;
62392
62393 use Symfony\Component\Debug\Exception\FatalErrorException;
62394 use Symfony\Component\Debug\Exception\UndefinedMethodException;
62395
62396
62397
62398
62399
62400
62401 class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
62402 {
62403
62404
62405
62406 public function handleError(array $error, FatalErrorException $exception)
62407 {
62408 preg_match('/^Call to undefined method (.*)::(.*)\(\)$/', $error['message'], $matches);
62409 if (!$matches) {
62410 return;
62411 }
62412
62413 $className = $matches[1];
62414 $methodName = $matches[2];
62415
62416 $message = sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className);
62417
62418 if (!class_exists($className) || null === $methods = get_class_methods($className)) {
62419
62420  return new UndefinedMethodException($message, $exception);
62421 }
62422
62423 $candidates = array();
62424 foreach ($methods as $definedMethodName) {
62425 $lev = levenshtein($methodName, $definedMethodName);
62426 if ($lev <= strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {
62427 $candidates[] = $definedMethodName;
62428 }
62429 }
62430
62431 if ($candidates) {
62432 sort($candidates);
62433 $last = array_pop($candidates).'"?';
62434 if ($candidates) {
62435 $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
62436 } else {
62437 $candidates = '"'.$last;
62438 }
62439
62440 $message .= "\nDid you mean to call ".$candidates;
62441 }
62442
62443 return new UndefinedMethodException($message, $exception);
62444 }
62445 }
62446 Copyright (c) 2004-2017 Fabien Potencier
62447
62448 Permission is hereby granted, free of charge, to any person obtaining a copy
62449 of this software and associated documentation files (the "Software"), to deal
62450 in the Software without restriction, including without limitation the rights
62451 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62452 copies of the Software, and to permit persons to whom the Software is furnished
62453 to do so, subject to the following conditions:
62454
62455 The above copyright notice and this permission notice shall be included in all
62456 copies or substantial portions of the Software.
62457
62458 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62459 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62460 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
62461 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62462 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62463 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
62464 THE SOFTWARE.
62465 <?php
62466
62467
62468
62469
62470
62471
62472
62473
62474
62475
62476 namespace Symfony\Component\Filesystem\Exception;
62477
62478
62479
62480
62481
62482
62483 interface ExceptionInterface
62484 {
62485 }
62486 <?php
62487
62488
62489
62490
62491
62492
62493
62494
62495
62496
62497 namespace Symfony\Component\Filesystem\Exception;
62498
62499
62500
62501
62502
62503
62504
62505 class FileNotFoundException extends IOException
62506 {
62507 public function __construct($message = null, $code = 0, \Exception $previous = null, $path = null)
62508 {
62509 if (null === $message) {
62510 if (null === $path) {
62511 $message = 'File could not be found.';
62512 } else {
62513 $message = sprintf('File "%s" could not be found.', $path);
62514 }
62515 }
62516
62517 parent::__construct($message, $code, $previous, $path);
62518 }
62519 }
62520 <?php
62521
62522
62523
62524
62525
62526
62527
62528
62529
62530
62531 namespace Symfony\Component\Filesystem\Exception;
62532
62533
62534
62535
62536
62537
62538
62539
62540 class IOException extends \RuntimeException implements IOExceptionInterface
62541 {
62542 private $path;
62543
62544 public function __construct($message, $code = 0, \Exception $previous = null, $path = null)
62545 {
62546 $this->path = $path;
62547
62548 parent::__construct($message, $code, $previous);
62549 }
62550
62551
62552
62553
62554 public function getPath()
62555 {
62556 return $this->path;
62557 }
62558 }
62559 <?php
62560
62561
62562
62563
62564
62565
62566
62567
62568
62569
62570 namespace Symfony\Component\Filesystem\Exception;
62571
62572
62573
62574
62575
62576
62577 interface IOExceptionInterface extends ExceptionInterface
62578 {
62579
62580
62581
62582
62583
62584 public function getPath();
62585 }
62586 <?php
62587
62588
62589
62590
62591
62592
62593
62594
62595
62596
62597 namespace Symfony\Component\Filesystem;
62598
62599 use Symfony\Component\Filesystem\Exception\IOException;
62600 use Symfony\Component\Filesystem\Exception\FileNotFoundException;
62601
62602
62603
62604
62605
62606
62607 class Filesystem
62608 {
62609
62610
62611
62612
62613
62614
62615
62616
62617
62618
62619
62620
62621
62622
62623 public function copy($originFile, $targetFile, $overwriteNewerFiles = false)
62624 {
62625 if (stream_is_local($originFile) && !is_file($originFile)) {
62626 throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
62627 }
62628
62629 $this->mkdir(dirname($targetFile));
62630
62631 $doCopy = true;
62632 if (!$overwriteNewerFiles && null === parse_url($originFile, PHP_URL_HOST) && is_file($targetFile)) {
62633 $doCopy = filemtime($originFile) > filemtime($targetFile);
62634 }
62635
62636 if ($doCopy) {
62637
62638  if (false === $source = @fopen($originFile, 'r')) {
62639 throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading.', $originFile, $targetFile), 0, null, $originFile);
62640 }
62641
62642
62643  if (false === $target = @fopen($targetFile, 'w', null, stream_context_create(array('ftp' => array('overwrite' => true))))) {
62644 throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing.', $originFile, $targetFile), 0, null, $originFile);
62645 }
62646
62647 $bytesCopied = stream_copy_to_stream($source, $target);
62648 fclose($source);
62649 fclose($target);
62650 unset($source, $target);
62651
62652 if (!is_file($targetFile)) {
62653 throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
62654 }
62655
62656
62657  @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));
62658
62659 if (stream_is_local($originFile) && $bytesCopied !== ($bytesOrigin = filesize($originFile))) {
62660 throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
62661 }
62662 }
62663 }
62664
62665
62666
62667
62668
62669
62670
62671
62672
62673 public function mkdir($dirs, $mode = 0777)
62674 {
62675 foreach ($this->toIterator($dirs) as $dir) {
62676 if (is_dir($dir)) {
62677 continue;
62678 }
62679
62680 if (true !== @mkdir($dir, $mode, true)) {
62681 $error = error_get_last();
62682 if (!is_dir($dir)) {
62683
62684  if ($error) {
62685 throw new IOException(sprintf('Failed to create "%s": %s.', $dir, $error['message']), 0, null, $dir);
62686 }
62687 throw new IOException(sprintf('Failed to create "%s"', $dir), 0, null, $dir);
62688 }
62689 }
62690 }
62691 }
62692
62693
62694
62695
62696
62697
62698
62699
62700 public function exists($files)
62701 {
62702 foreach ($this->toIterator($files) as $file) {
62703 if ('\\' === DIRECTORY_SEPARATOR && strlen($file) > 258) {
62704 throw new IOException('Could not check if file exist because path length exceeds 258 characters.', 0, null, $file);
62705 }
62706
62707 if (!file_exists($file)) {
62708 return false;
62709 }
62710 }
62711
62712 return true;
62713 }
62714
62715
62716
62717
62718
62719
62720
62721
62722
62723
62724 public function touch($files, $time = null, $atime = null)
62725 {
62726 foreach ($this->toIterator($files) as $file) {
62727 $touch = $time ? @touch($file, $time, $atime) : @touch($file);
62728 if (true !== $touch) {
62729 throw new IOException(sprintf('Failed to touch "%s".', $file), 0, null, $file);
62730 }
62731 }
62732 }
62733
62734
62735
62736
62737
62738
62739
62740
62741 public function remove($files)
62742 {
62743 if ($files instanceof \Traversable) {
62744 $files = iterator_to_array($files, false);
62745 } elseif (!is_array($files)) {
62746 $files = array($files);
62747 }
62748 $files = array_reverse($files);
62749 foreach ($files as $file) {
62750 if (is_link($file)) {
62751
62752  if (!@(unlink($file) || '\\' !== DIRECTORY_SEPARATOR || rmdir($file)) && file_exists($file)) {
62753 $error = error_get_last();
62754 throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, $error['message']));
62755 }
62756 } elseif (is_dir($file)) {
62757 $this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));
62758
62759 if (!@rmdir($file) && file_exists($file)) {
62760 $error = error_get_last();
62761 throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, $error['message']));
62762 }
62763 } elseif (!@unlink($file) && file_exists($file)) {
62764 $error = error_get_last();
62765 throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, $error['message']));
62766 }
62767 }
62768 }
62769
62770
62771
62772
62773
62774
62775
62776
62777
62778
62779
62780 public function chmod($files, $mode, $umask = 0000, $recursive = false)
62781 {
62782 foreach ($this->toIterator($files) as $file) {
62783 if (true !== @chmod($file, $mode & ~$umask)) {
62784 throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file);
62785 }
62786 if ($recursive && is_dir($file) && !is_link($file)) {
62787 $this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
62788 }
62789 }
62790 }
62791
62792
62793
62794
62795
62796
62797
62798
62799
62800
62801 public function chown($files, $user, $recursive = false)
62802 {
62803 foreach ($this->toIterator($files) as $file) {
62804 if ($recursive && is_dir($file) && !is_link($file)) {
62805 $this->chown(new \FilesystemIterator($file), $user, true);
62806 }
62807 if (is_link($file) && function_exists('lchown')) {
62808 if (true !== @lchown($file, $user)) {
62809 throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
62810 }
62811 } else {
62812 if (true !== @chown($file, $user)) {
62813 throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
62814 }
62815 }
62816 }
62817 }
62818
62819
62820
62821
62822
62823
62824
62825
62826
62827
62828 public function chgrp($files, $group, $recursive = false)
62829 {
62830 foreach ($this->toIterator($files) as $file) {
62831 if ($recursive && is_dir($file) && !is_link($file)) {
62832 $this->chgrp(new \FilesystemIterator($file), $group, true);
62833 }
62834 if (is_link($file) && function_exists('lchgrp')) {
62835 if (true !== @lchgrp($file, $group) || (defined('HHVM_VERSION') && !posix_getgrnam($group))) {
62836 throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
62837 }
62838 } else {
62839 if (true !== @chgrp($file, $group)) {
62840 throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
62841 }
62842 }
62843 }
62844 }
62845
62846
62847
62848
62849
62850
62851
62852
62853
62854
62855
62856 public function rename($origin, $target, $overwrite = false)
62857 {
62858
62859  if (!$overwrite && $this->isReadable($target)) {
62860 throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
62861 }
62862
62863 if (true !== @rename($origin, $target)) {
62864 throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target), 0, null, $target);
62865 }
62866 }
62867
62868
62869
62870
62871
62872
62873
62874
62875
62876
62877 private function isReadable($filename)
62878 {
62879 if ('\\' === DIRECTORY_SEPARATOR && strlen($filename) > 258) {
62880 throw new IOException('Could not check if file is readable because path length exceeds 258 characters.', 0, null, $filename);
62881 }
62882
62883 return is_readable($filename);
62884 }
62885
62886
62887
62888
62889
62890
62891
62892
62893
62894
62895 public function symlink($originDir, $targetDir, $copyOnWindows = false)
62896 {
62897 if ('\\' === DIRECTORY_SEPARATOR) {
62898 $originDir = strtr($originDir, '/', '\\');
62899 $targetDir = strtr($targetDir, '/', '\\');
62900
62901 if ($copyOnWindows) {
62902 $this->mirror($originDir, $targetDir);
62903
62904 return;
62905 }
62906 }
62907
62908 $this->mkdir(dirname($targetDir));
62909
62910 $ok = false;
62911 if (is_link($targetDir)) {
62912 if (readlink($targetDir) != $originDir) {
62913 $this->remove($targetDir);
62914 } else {
62915 $ok = true;
62916 }
62917 }
62918
62919 if (!$ok && true !== @symlink($originDir, $targetDir)) {
62920 $report = error_get_last();
62921 if (is_array($report)) {
62922 if ('\\' === DIRECTORY_SEPARATOR && false !== strpos($report['message'], 'error code(1314)')) {
62923 throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', 0, null, $targetDir);
62924 }
62925 }
62926 throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
62927 }
62928 }
62929
62930
62931
62932
62933
62934
62935
62936
62937
62938 public function makePathRelative($endPath, $startPath)
62939 {
62940
62941  if ('\\' === DIRECTORY_SEPARATOR) {
62942 $endPath = str_replace('\\', '/', $endPath);
62943 $startPath = str_replace('\\', '/', $startPath);
62944 }
62945
62946
62947  $startPathArr = explode('/', trim($startPath, '/'));
62948 $endPathArr = explode('/', trim($endPath, '/'));
62949
62950
62951  $index = 0;
62952 while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
62953 ++$index;
62954 }
62955
62956
62957  if (count($startPathArr) === 1 && $startPathArr[0] === '') {
62958 $depth = 0;
62959 } else {
62960 $depth = count($startPathArr) - $index;
62961 }
62962
62963
62964  if ('/' === $startPath[0] && 0 === $index && 0 === $depth) {
62965 $traverser = '';
62966 } else {
62967
62968  $traverser = str_repeat('../', $depth);
62969 }
62970
62971 $endPathRemainder = implode('/', array_slice($endPathArr, $index));
62972
62973
62974  $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');
62975
62976 return '' === $relativePath ? './' : $relativePath;
62977 }
62978
62979
62980
62981
62982
62983
62984
62985
62986
62987
62988
62989
62990
62991
62992
62993 public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
62994 {
62995 $targetDir = rtrim($targetDir, '/\\');
62996 $originDir = rtrim($originDir, '/\\');
62997
62998
62999  if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
63000 $deleteIterator = $iterator;
63001 if (null === $deleteIterator) {
63002 $flags = \FilesystemIterator::SKIP_DOTS;
63003 $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST);
63004 }
63005 foreach ($deleteIterator as $file) {
63006 $origin = str_replace($targetDir, $originDir, $file->getPathname());
63007 if (!$this->exists($origin)) {
63008 $this->remove($file);
63009 }
63010 }
63011 }
63012
63013 $copyOnWindows = false;
63014 if (isset($options['copy_on_windows'])) {
63015 $copyOnWindows = $options['copy_on_windows'];
63016 }
63017
63018 if (null === $iterator) {
63019 $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS;
63020 $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
63021 }
63022
63023 if ($this->exists($originDir)) {
63024 $this->mkdir($targetDir);
63025 }
63026
63027 foreach ($iterator as $file) {
63028 $target = str_replace($originDir, $targetDir, $file->getPathname());
63029
63030 if ($copyOnWindows) {
63031 if (is_file($file)) {
63032 $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
63033 } elseif (is_dir($file)) {
63034 $this->mkdir($target);
63035 } else {
63036 throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
63037 }
63038 } else {
63039 if (is_link($file)) {
63040 $this->symlink($file->getLinkTarget(), $target);
63041 } elseif (is_dir($file)) {
63042 $this->mkdir($target);
63043 } elseif (is_file($file)) {
63044 $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
63045 } else {
63046 throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
63047 }
63048 }
63049 }
63050 }
63051
63052
63053
63054
63055
63056
63057
63058
63059 public function isAbsolutePath($file)
63060 {
63061 return strspn($file, '/\\', 0, 1)
63062 || (strlen($file) > 3 && ctype_alpha($file[0])
63063 && substr($file, 1, 1) === ':'
63064 && strspn($file, '/\\', 2, 1)
63065 )
63066 || null !== parse_url($file, PHP_URL_SCHEME)
63067 ;
63068 }
63069
63070
63071
63072
63073
63074
63075
63076
63077
63078
63079 public function tempnam($dir, $prefix)
63080 {
63081 list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir);
63082
63083
63084  if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) {
63085 $tmpFile = @tempnam($hierarchy, $prefix);
63086
63087
63088  if (false !== $tmpFile) {
63089 if (null !== $scheme && 'gs' !== $scheme) {
63090 return $scheme.'://'.$tmpFile;
63091 }
63092
63093 return $tmpFile;
63094 }
63095
63096 throw new IOException('A temporary file could not be created.');
63097 }
63098
63099
63100  for ($i = 0; $i < 10; ++$i) {
63101
63102  $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true);
63103
63104
63105  
63106  $handle = @fopen($tmpFile, 'x+');
63107
63108
63109  if (false === $handle) {
63110 continue;
63111 }
63112
63113
63114  @fclose($handle);
63115
63116 return $tmpFile;
63117 }
63118
63119 throw new IOException('A temporary file could not be created.');
63120 }
63121
63122
63123
63124
63125
63126
63127
63128
63129
63130
63131
63132 public function dumpFile($filename, $content, $mode = 0666)
63133 {
63134 $dir = dirname($filename);
63135
63136 if (!is_dir($dir)) {
63137 $this->mkdir($dir);
63138 }
63139
63140 if (!is_writable($dir)) {
63141 throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
63142 }
63143
63144 $tmpFile = $this->tempnam($dir, basename($filename));
63145
63146 if (false === @file_put_contents($tmpFile, $content)) {
63147 throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
63148 }
63149
63150 if (null !== $mode) {
63151 if (func_num_args() > 2) {
63152 @trigger_error('Support for modifying file permissions is deprecated since version 2.3.12 and will be removed in 3.0.', E_USER_DEPRECATED);
63153 }
63154
63155 $this->chmod($tmpFile, $mode);
63156 }
63157 $this->rename($tmpFile, $filename, true);
63158 }
63159
63160
63161
63162
63163
63164
63165 private function toIterator($files)
63166 {
63167 if (!$files instanceof \Traversable) {
63168 $files = new \ArrayObject(is_array($files) ? $files : array($files));
63169 }
63170
63171 return $files;
63172 }
63173
63174
63175
63176
63177
63178
63179
63180
63181 private function getSchemeAndHierarchy($filename)
63182 {
63183 $components = explode('://', $filename, 2);
63184
63185 return 2 === count($components) ? array($components[0], $components[1]) : array(null, $components[0]);
63186 }
63187 }
63188 Copyright (c) 2004-2017 Fabien Potencier
63189
63190 Permission is hereby granted, free of charge, to any person obtaining a copy
63191 of this software and associated documentation files (the "Software"), to deal
63192 in the Software without restriction, including without limitation the rights
63193 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
63194 copies of the Software, and to permit persons to whom the Software is furnished
63195 to do so, subject to the following conditions:
63196
63197 The above copyright notice and this permission notice shall be included in all
63198 copies or substantial portions of the Software.
63199
63200 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63201 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63202 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63203 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63204 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63205 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63206 THE SOFTWARE.
63207 <?php
63208
63209
63210
63211
63212
63213
63214
63215
63216
63217
63218 namespace Symfony\Component\Filesystem;
63219
63220 use Symfony\Component\Filesystem\Exception\IOException;
63221
63222
63223
63224
63225
63226
63227
63228
63229
63230
63231
63232
63233
63234
63235 class LockHandler
63236 {
63237 private $file;
63238 private $handle;
63239
63240
63241
63242
63243
63244
63245
63246 public function __construct($name, $lockPath = null)
63247 {
63248 $lockPath = $lockPath ?: sys_get_temp_dir();
63249
63250 if (!is_dir($lockPath)) {
63251 $fs = new Filesystem();
63252 $fs->mkdir($lockPath);
63253 }
63254
63255 if (!is_writable($lockPath)) {
63256 throw new IOException(sprintf('The directory "%s" is not writable.', $lockPath), 0, null, $lockPath);
63257 }
63258
63259 $this->file = sprintf('%s/sf.%s.%s.lock', $lockPath, preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name));
63260 }
63261
63262
63263
63264
63265
63266
63267
63268
63269
63270
63271 public function lock($blocking = false)
63272 {
63273 if ($this->handle) {
63274 return true;
63275 }
63276
63277
63278  set_error_handler(function () {});
63279
63280 if (!$this->handle = fopen($this->file, 'r')) {
63281 if ($this->handle = fopen($this->file, 'x')) {
63282 chmod($this->file, 0444);
63283 } elseif (!$this->handle = fopen($this->file, 'r')) {
63284 usleep(100); 
63285  $this->handle = fopen($this->file, 'r');
63286 }
63287 }
63288 restore_error_handler();
63289
63290 if (!$this->handle) {
63291 $error = error_get_last();
63292 throw new IOException($error['message'], 0, null, $this->file);
63293 }
63294
63295
63296  
63297  if (!flock($this->handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) {
63298 fclose($this->handle);
63299 $this->handle = null;
63300
63301 return false;
63302 }
63303
63304 return true;
63305 }
63306
63307
63308
63309
63310 public function release()
63311 {
63312 if ($this->handle) {
63313 flock($this->handle, LOCK_UN | LOCK_NB);
63314 fclose($this->handle);
63315 $this->handle = null;
63316 }
63317 }
63318 }
63319 <?php
63320
63321
63322
63323
63324
63325
63326
63327
63328
63329
63330 namespace Symfony\Component\Finder\Adapter;
63331
63332 @trigger_error('The '.__NAMESPACE__.'\AbstractAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
63333
63334
63335
63336
63337
63338
63339
63340
63341 abstract class AbstractAdapter implements AdapterInterface
63342 {
63343 protected $followLinks = false;
63344 protected $mode = 0;
63345 protected $minDepth = 0;
63346 protected $maxDepth = PHP_INT_MAX;
63347 protected $exclude = array();
63348 protected $names = array();
63349 protected $notNames = array();
63350 protected $contains = array();
63351 protected $notContains = array();
63352 protected $sizes = array();
63353 protected $dates = array();
63354 protected $filters = array();
63355 protected $sort = false;
63356 protected $paths = array();
63357 protected $notPaths = array();
63358 protected $ignoreUnreadableDirs = false;
63359
63360 private static $areSupported = array();
63361
63362
63363
63364
63365 public function isSupported()
63366 {
63367 $name = $this->getName();
63368
63369 if (!array_key_exists($name, self::$areSupported)) {
63370 self::$areSupported[$name] = $this->canBeUsed();
63371 }
63372
63373 return self::$areSupported[$name];
63374 }
63375
63376
63377
63378
63379 public function setFollowLinks($followLinks)
63380 {
63381 $this->followLinks = $followLinks;
63382
63383 return $this;
63384 }
63385
63386
63387
63388
63389 public function setMode($mode)
63390 {
63391 $this->mode = $mode;
63392
63393 return $this;
63394 }
63395
63396
63397
63398
63399 public function setDepths(array $depths)
63400 {
63401 $this->minDepth = 0;
63402 $this->maxDepth = PHP_INT_MAX;
63403
63404 foreach ($depths as $comparator) {
63405 switch ($comparator->getOperator()) {
63406 case '>':
63407 $this->minDepth = $comparator->getTarget() + 1;
63408 break;
63409 case '>=':
63410 $this->minDepth = $comparator->getTarget();
63411 break;
63412 case '<':
63413 $this->maxDepth = $comparator->getTarget() - 1;
63414 break;
63415 case '<=':
63416 $this->maxDepth = $comparator->getTarget();
63417 break;
63418 default:
63419 $this->minDepth = $this->maxDepth = $comparator->getTarget();
63420 }
63421 }
63422
63423 return $this;
63424 }
63425
63426
63427
63428
63429 public function setExclude(array $exclude)
63430 {
63431 $this->exclude = $exclude;
63432
63433 return $this;
63434 }
63435
63436
63437
63438
63439 public function setNames(array $names)
63440 {
63441 $this->names = $names;
63442
63443 return $this;
63444 }
63445
63446
63447
63448
63449 public function setNotNames(array $notNames)
63450 {
63451 $this->notNames = $notNames;
63452
63453 return $this;
63454 }
63455
63456
63457
63458
63459 public function setContains(array $contains)
63460 {
63461 $this->contains = $contains;
63462
63463 return $this;
63464 }
63465
63466
63467
63468
63469 public function setNotContains(array $notContains)
63470 {
63471 $this->notContains = $notContains;
63472
63473 return $this;
63474 }
63475
63476
63477
63478
63479 public function setSizes(array $sizes)
63480 {
63481 $this->sizes = $sizes;
63482
63483 return $this;
63484 }
63485
63486
63487
63488
63489 public function setDates(array $dates)
63490 {
63491 $this->dates = $dates;
63492
63493 return $this;
63494 }
63495
63496
63497
63498
63499 public function setFilters(array $filters)
63500 {
63501 $this->filters = $filters;
63502
63503 return $this;
63504 }
63505
63506
63507
63508
63509 public function setSort($sort)
63510 {
63511 $this->sort = $sort;
63512
63513 return $this;
63514 }
63515
63516
63517
63518
63519 public function setPath(array $paths)
63520 {
63521 $this->paths = $paths;
63522
63523 return $this;
63524 }
63525
63526
63527
63528
63529 public function setNotPath(array $notPaths)
63530 {
63531 $this->notPaths = $notPaths;
63532
63533 return $this;
63534 }
63535
63536
63537
63538
63539 public function ignoreUnreadableDirs($ignore = true)
63540 {
63541 $this->ignoreUnreadableDirs = (bool) $ignore;
63542
63543 return $this;
63544 }
63545
63546
63547
63548
63549
63550
63551
63552
63553
63554
63555
63556
63557 abstract protected function canBeUsed();
63558 }
63559 <?php
63560
63561
63562
63563
63564
63565
63566
63567
63568
63569
63570 namespace Symfony\Component\Finder\Adapter;
63571
63572 @trigger_error('The '.__NAMESPACE__.'\AbstractFindAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
63573
63574 use Symfony\Component\Finder\Exception\AccessDeniedException;
63575 use Symfony\Component\Finder\Iterator;
63576 use Symfony\Component\Finder\Shell\Shell;
63577 use Symfony\Component\Finder\Expression\Expression;
63578 use Symfony\Component\Finder\Shell\Command;
63579 use Symfony\Component\Finder\Comparator\NumberComparator;
63580 use Symfony\Component\Finder\Comparator\DateComparator;
63581
63582
63583
63584
63585
63586
63587
63588
63589 abstract class AbstractFindAdapter extends AbstractAdapter
63590 {
63591
63592
63593
63594 protected $shell;
63595
63596
63597
63598
63599 public function __construct()
63600 {
63601 $this->shell = new Shell();
63602 }
63603
63604
63605
63606
63607 public function searchInDirectory($dir)
63608 {
63609
63610  $dir = realpath($dir);
63611
63612
63613  if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
63614 return new Iterator\FilePathsIterator(array(), $dir);
63615 }
63616
63617 $command = Command::create();
63618 $find = $this->buildFindCommand($command, $dir);
63619
63620 if ($this->followLinks) {
63621 $find->add('-follow');
63622 }
63623
63624 $find->add('-mindepth')->add($this->minDepth + 1);
63625
63626 if (PHP_INT_MAX !== $this->maxDepth) {
63627 $find->add('-maxdepth')->add($this->maxDepth + 1);
63628 }
63629
63630 if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
63631 $find->add('-type d');
63632 } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
63633 $find->add('-type f');
63634 }
63635
63636 $this->buildNamesFiltering($find, $this->names);
63637 $this->buildNamesFiltering($find, $this->notNames, true);
63638 $this->buildPathsFiltering($find, $dir, $this->paths);
63639 $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
63640 $this->buildSizesFiltering($find, $this->sizes);
63641 $this->buildDatesFiltering($find, $this->dates);
63642
63643 $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
63644 $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
63645
63646 if ($useGrep && ($this->contains || $this->notContains)) {
63647 $grep = $command->ins('grep');
63648 $this->buildContentFiltering($grep, $this->contains);
63649 $this->buildContentFiltering($grep, $this->notContains, true);
63650 }
63651
63652 if ($useSort) {
63653 $this->buildSorting($command, $this->sort);
63654 }
63655
63656 $command->setErrorHandler(
63657 $this->ignoreUnreadableDirs
63658
63659  ? function ($stderr) { }
63660 : function ($stderr) { throw new AccessDeniedException($stderr); }
63661 );
63662
63663 $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
63664 $iterator = new Iterator\FilePathsIterator($paths, $dir);
63665
63666 if ($this->exclude) {
63667 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
63668 }
63669
63670 if (!$useGrep && ($this->contains || $this->notContains)) {
63671 $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
63672 }
63673
63674 if ($this->filters) {
63675 $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
63676 }
63677
63678 if (!$useSort && $this->sort) {
63679 $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
63680 $iterator = $iteratorAggregate->getIterator();
63681 }
63682
63683 return $iterator;
63684 }
63685
63686
63687
63688
63689 protected function canBeUsed()
63690 {
63691 return $this->shell->testCommand('find');
63692 }
63693
63694
63695
63696
63697
63698
63699
63700 protected function buildFindCommand(Command $command, $dir)
63701 {
63702 return $command
63703 ->ins('find')
63704 ->add('find ')
63705 ->arg($dir)
63706 ->add('-noleaf'); 
63707  }
63708
63709
63710
63711
63712
63713
63714 private function buildNamesFiltering(Command $command, array $names, $not = false)
63715 {
63716 if (0 === count($names)) {
63717 return;
63718 }
63719
63720 $command->add($not ? '-not' : null)->cmd('(');
63721
63722 foreach ($names as $i => $name) {
63723 $expr = Expression::create($name);
63724
63725
63726  if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
63727 $expr = Expression::create($expr->getGlob()->toRegex(false));
63728 }
63729
63730
63731  
63732  
63733  if ($expr->isRegex()) {
63734 $regex = $expr->getRegex();
63735 $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
63736 ->setStartFlag(false)
63737 ->setStartJoker(true)
63738 ->replaceJokers('[^/]');
63739 if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
63740 $regex->setEndJoker(false)->append('[^/]*');
63741 }
63742 }
63743
63744 $command
63745 ->add($i > 0 ? '-or' : null)
63746 ->add($expr->isRegex()
63747 ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
63748 : ($expr->isCaseSensitive() ? '-name' : '-iname')
63749 )
63750 ->arg($expr->renderPattern());
63751 }
63752
63753 $command->cmd(')');
63754 }
63755
63756
63757
63758
63759
63760
63761
63762 private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
63763 {
63764 if (0 === count($paths)) {
63765 return;
63766 }
63767
63768 $command->add($not ? '-not' : null)->cmd('(');
63769
63770 foreach ($paths as $i => $path) {
63771 $expr = Expression::create($path);
63772
63773
63774  if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
63775 $expr = Expression::create($expr->getGlob()->toRegex(false));
63776 }
63777
63778
63779  if ($expr->isRegex()) {
63780 $regex = $expr->getRegex();
63781 $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
63782 } else {
63783 $expr->prepend('*')->append('*');
63784 }
63785
63786 $command
63787 ->add($i > 0 ? '-or' : null)
63788 ->add($expr->isRegex()
63789 ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
63790 : ($expr->isCaseSensitive() ? '-path' : '-ipath')
63791 )
63792 ->arg($expr->renderPattern());
63793 }
63794
63795 $command->cmd(')');
63796 }
63797
63798
63799
63800
63801
63802 private function buildSizesFiltering(Command $command, array $sizes)
63803 {
63804 foreach ($sizes as $i => $size) {
63805 $command->add($i > 0 ? '-and' : null);
63806
63807 switch ($size->getOperator()) {
63808 case '<=':
63809 $command->add('-size -'.($size->getTarget() + 1).'c');
63810 break;
63811 case '>=':
63812 $command->add('-size +'.($size->getTarget() - 1).'c');
63813 break;
63814 case '>':
63815 $command->add('-size +'.$size->getTarget().'c');
63816 break;
63817 case '!=':
63818 $command->add('-size -'.$size->getTarget().'c');
63819 $command->add('-size +'.$size->getTarget().'c');
63820 break;
63821 case '<':
63822 default:
63823 $command->add('-size -'.$size->getTarget().'c');
63824 }
63825 }
63826 }
63827
63828
63829
63830
63831
63832 private function buildDatesFiltering(Command $command, array $dates)
63833 {
63834 foreach ($dates as $i => $date) {
63835 $command->add($i > 0 ? '-and' : null);
63836
63837 $mins = (int) round((time() - $date->getTarget()) / 60);
63838
63839 if (0 > $mins) {
63840
63841  $command->add(' -mmin -0');
63842
63843  return;
63844 }
63845
63846 switch ($date->getOperator()) {
63847 case '<=':
63848 $command->add('-mmin +'.($mins - 1));
63849 break;
63850 case '>=':
63851 $command->add('-mmin -'.($mins + 1));
63852 break;
63853 case '>':
63854 $command->add('-mmin -'.$mins);
63855 break;
63856 case '!=':
63857 $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
63858 break;
63859 case '<':
63860 default:
63861 $command->add('-mmin +'.$mins);
63862 }
63863 }
63864 }
63865
63866
63867
63868
63869
63870
63871
63872 private function buildSorting(Command $command, $sort)
63873 {
63874 $this->buildFormatSorting($command, $sort);
63875 }
63876
63877
63878
63879
63880
63881 abstract protected function buildFormatSorting(Command $command, $sort);
63882
63883
63884
63885
63886
63887
63888 abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
63889 }
63890 <?php
63891
63892
63893
63894
63895
63896
63897
63898
63899
63900
63901 namespace Symfony\Component\Finder\Adapter;
63902
63903
63904
63905
63906
63907
63908 interface AdapterInterface
63909 {
63910
63911
63912
63913
63914
63915 public function setFollowLinks($followLinks);
63916
63917
63918
63919
63920
63921
63922 public function setMode($mode);
63923
63924
63925
63926
63927
63928
63929 public function setExclude(array $exclude);
63930
63931
63932
63933
63934
63935
63936 public function setDepths(array $depths);
63937
63938
63939
63940
63941
63942
63943 public function setNames(array $names);
63944
63945
63946
63947
63948
63949
63950 public function setNotNames(array $notNames);
63951
63952
63953
63954
63955
63956
63957 public function setContains(array $contains);
63958
63959
63960
63961
63962
63963
63964 public function setNotContains(array $notContains);
63965
63966
63967
63968
63969
63970
63971 public function setSizes(array $sizes);
63972
63973
63974
63975
63976
63977
63978 public function setDates(array $dates);
63979
63980
63981
63982
63983
63984
63985 public function setFilters(array $filters);
63986
63987
63988
63989
63990
63991
63992 public function setSort($sort);
63993
63994
63995
63996
63997
63998
63999 public function setPath(array $paths);
64000
64001
64002
64003
64004
64005
64006 public function setNotPath(array $notPaths);
64007
64008
64009
64010
64011
64012
64013 public function ignoreUnreadableDirs($ignore = true);
64014
64015
64016
64017
64018
64019
64020 public function searchInDirectory($dir);
64021
64022
64023
64024
64025
64026
64027 public function isSupported();
64028
64029
64030
64031
64032
64033
64034 public function getName();
64035 }
64036 <?php
64037
64038
64039
64040
64041
64042
64043
64044
64045
64046
64047 namespace Symfony\Component\Finder\Adapter;
64048
64049 @trigger_error('The '.__NAMESPACE__.'\BsdFindAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
64050
64051 use Symfony\Component\Finder\Shell\Shell;
64052 use Symfony\Component\Finder\Shell\Command;
64053 use Symfony\Component\Finder\Iterator\SortableIterator;
64054 use Symfony\Component\Finder\Expression\Expression;
64055
64056
64057
64058
64059
64060
64061
64062
64063 class BsdFindAdapter extends AbstractFindAdapter
64064 {
64065
64066
64067
64068 public function getName()
64069 {
64070 return 'bsd_find';
64071 }
64072
64073
64074
64075
64076 protected function canBeUsed()
64077 {
64078 return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
64079 }
64080
64081
64082
64083
64084 protected function buildFormatSorting(Command $command, $sort)
64085 {
64086 switch ($sort) {
64087 case SortableIterator::SORT_BY_NAME:
64088 $command->ins('sort')->add('| sort');
64089
64090 return;
64091 case SortableIterator::SORT_BY_TYPE:
64092 $format = '%HT';
64093 break;
64094 case SortableIterator::SORT_BY_ACCESSED_TIME:
64095 $format = '%a';
64096 break;
64097 case SortableIterator::SORT_BY_CHANGED_TIME:
64098 $format = '%c';
64099 break;
64100 case SortableIterator::SORT_BY_MODIFIED_TIME:
64101 $format = '%m';
64102 break;
64103 default:
64104 throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
64105 }
64106
64107 $command
64108 ->add('-print0 | xargs -0 stat -f')
64109 ->arg($format.'%t%N')
64110 ->add('| sort | cut -f 2');
64111 }
64112
64113
64114
64115
64116 protected function buildFindCommand(Command $command, $dir)
64117 {
64118 parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);
64119
64120 return $command;
64121 }
64122
64123
64124
64125
64126 protected function buildContentFiltering(Command $command, array $contains, $not = false)
64127 {
64128 foreach ($contains as $contain) {
64129 $expr = Expression::create($contain);
64130
64131
64132  $command
64133 ->add('| grep -v \'^$\'')
64134 ->add('| xargs -I{} grep -I')
64135 ->add($expr->isCaseSensitive() ? null : '-i')
64136 ->add($not ? '-L' : '-l')
64137 ->add('-Ee')->arg($expr->renderPattern())
64138 ->add('{}')
64139 ;
64140 }
64141 }
64142 }
64143 <?php
64144
64145
64146
64147
64148
64149
64150
64151
64152
64153
64154 namespace Symfony\Component\Finder\Adapter;
64155
64156 @trigger_error('The '.__NAMESPACE__.'\GnuFindAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
64157
64158 use Symfony\Component\Finder\Shell\Shell;
64159 use Symfony\Component\Finder\Shell\Command;
64160 use Symfony\Component\Finder\Iterator\SortableIterator;
64161 use Symfony\Component\Finder\Expression\Expression;
64162
64163
64164
64165
64166
64167
64168
64169
64170 class GnuFindAdapter extends AbstractFindAdapter
64171 {
64172
64173
64174
64175 public function getName()
64176 {
64177 return 'gnu_find';
64178 }
64179
64180
64181
64182
64183 protected function buildFormatSorting(Command $command, $sort)
64184 {
64185 switch ($sort) {
64186 case SortableIterator::SORT_BY_NAME:
64187 $command->ins('sort')->add('| sort');
64188
64189 return;
64190 case SortableIterator::SORT_BY_TYPE:
64191 $format = '%y';
64192 break;
64193 case SortableIterator::SORT_BY_ACCESSED_TIME:
64194 $format = '%A@';
64195 break;
64196 case SortableIterator::SORT_BY_CHANGED_TIME:
64197 $format = '%C@';
64198 break;
64199 case SortableIterator::SORT_BY_MODIFIED_TIME:
64200 $format = '%T@';
64201 break;
64202 default:
64203 throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
64204 }
64205
64206 $command
64207 ->get('find')
64208 ->add('-printf')
64209 ->arg($format.' %h/%f\\n')
64210 ->add('| sort | cut')
64211 ->arg('-d ')
64212 ->arg('-f2-')
64213 ;
64214 }
64215
64216
64217
64218
64219 protected function canBeUsed()
64220 {
64221 return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed();
64222 }
64223
64224
64225
64226
64227 protected function buildFindCommand(Command $command, $dir)
64228 {
64229 return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
64230 }
64231
64232
64233
64234
64235 protected function buildContentFiltering(Command $command, array $contains, $not = false)
64236 {
64237 foreach ($contains as $contain) {
64238 $expr = Expression::create($contain);
64239
64240
64241  $command
64242 ->add('| xargs -I{} -r grep -I')
64243 ->add($expr->isCaseSensitive() ? null : '-i')
64244 ->add($not ? '-L' : '-l')
64245 ->add('-Ee')->arg($expr->renderPattern())
64246 ->add('{}')
64247 ;
64248 }
64249 }
64250 }
64251 <?php
64252
64253
64254
64255
64256
64257
64258
64259
64260
64261
64262 namespace Symfony\Component\Finder\Adapter;
64263
64264 @trigger_error('The '.__NAMESPACE__.'\PhpAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
64265
64266 use Symfony\Component\Finder\Iterator;
64267
64268
64269
64270
64271
64272
64273
64274
64275 class PhpAdapter extends AbstractAdapter
64276 {
64277
64278
64279
64280 public function searchInDirectory($dir)
64281 {
64282 $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
64283
64284 if ($this->followLinks) {
64285 $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
64286 }
64287
64288 $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);
64289
64290 if ($this->exclude) {
64291 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
64292 }
64293
64294 $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
64295
64296 if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
64297 $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
64298 }
64299
64300 if ($this->mode) {
64301 $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
64302 }
64303
64304 if ($this->names || $this->notNames) {
64305 $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
64306 }
64307
64308 if ($this->contains || $this->notContains) {
64309 $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
64310 }
64311
64312 if ($this->sizes) {
64313 $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
64314 }
64315
64316 if ($this->dates) {
64317 $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
64318 }
64319
64320 if ($this->filters) {
64321 $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
64322 }
64323
64324 if ($this->paths || $this->notPaths) {
64325 $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
64326 }
64327
64328 if ($this->sort) {
64329 $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
64330 $iterator = $iteratorAggregate->getIterator();
64331 }
64332
64333 return $iterator;
64334 }
64335
64336
64337
64338
64339 public function getName()
64340 {
64341 return 'php';
64342 }
64343
64344
64345
64346
64347 protected function canBeUsed()
64348 {
64349 return true;
64350 }
64351 }
64352 <?php
64353
64354
64355
64356
64357
64358
64359
64360
64361
64362
64363 namespace Symfony\Component\Finder\Comparator;
64364
64365
64366
64367
64368
64369
64370 class Comparator
64371 {
64372 private $target;
64373 private $operator = '==';
64374
64375
64376
64377
64378
64379
64380 public function getTarget()
64381 {
64382 return $this->target;
64383 }
64384
64385
64386
64387
64388
64389
64390 public function setTarget($target)
64391 {
64392 $this->target = $target;
64393 }
64394
64395
64396
64397
64398
64399
64400 public function getOperator()
64401 {
64402 return $this->operator;
64403 }
64404
64405
64406
64407
64408
64409
64410
64411
64412 public function setOperator($operator)
64413 {
64414 if (!$operator) {
64415 $operator = '==';
64416 }
64417
64418 if (!in_array($operator, array('>', '<', '>=', '<=', '==', '!='))) {
64419 throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
64420 }
64421
64422 $this->operator = $operator;
64423 }
64424
64425
64426
64427
64428
64429
64430
64431
64432 public function test($test)
64433 {
64434 switch ($this->operator) {
64435 case '>':
64436 return $test > $this->target;
64437 case '>=':
64438 return $test >= $this->target;
64439 case '<':
64440 return $test < $this->target;
64441 case '<=':
64442 return $test <= $this->target;
64443 case '!=':
64444 return $test != $this->target;
64445 }
64446
64447 return $test == $this->target;
64448 }
64449 }
64450 <?php
64451
64452
64453
64454
64455
64456
64457
64458
64459
64460
64461 namespace Symfony\Component\Finder\Comparator;
64462
64463
64464
64465
64466
64467
64468 class DateComparator extends Comparator
64469 {
64470
64471
64472
64473
64474
64475
64476
64477 public function __construct($test)
64478 {
64479 if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) {
64480 throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test));
64481 }
64482
64483 try {
64484 $date = new \DateTime($matches[2]);
64485 $target = $date->format('U');
64486 } catch (\Exception $e) {
64487 throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
64488 }
64489
64490 $operator = isset($matches[1]) ? $matches[1] : '==';
64491 if ('since' === $operator || 'after' === $operator) {
64492 $operator = '>';
64493 }
64494
64495 if ('until' === $operator || 'before' === $operator) {
64496 $operator = '<';
64497 }
64498
64499 $this->setOperator($operator);
64500 $this->setTarget($target);
64501 }
64502 }
64503 <?php
64504
64505
64506
64507
64508
64509
64510
64511
64512
64513
64514 namespace Symfony\Component\Finder\Comparator;
64515
64516
64517
64518
64519
64520
64521
64522
64523
64524
64525
64526
64527
64528
64529
64530
64531
64532
64533
64534
64535
64536
64537 class NumberComparator extends Comparator
64538 {
64539
64540
64541
64542
64543
64544
64545
64546 public function __construct($test)
64547 {
64548 if (!preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) {
64549 throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test));
64550 }
64551
64552 $target = $matches[2];
64553 if (!is_numeric($target)) {
64554 throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target));
64555 }
64556 if (isset($matches[3])) {
64557
64558  switch (strtolower($matches[3])) {
64559 case 'k':
64560 $target *= 1000;
64561 break;
64562 case 'ki':
64563 $target *= 1024;
64564 break;
64565 case 'm':
64566 $target *= 1000000;
64567 break;
64568 case 'mi':
64569 $target *= 1024 * 1024;
64570 break;
64571 case 'g':
64572 $target *= 1000000000;
64573 break;
64574 case 'gi':
64575 $target *= 1024 * 1024 * 1024;
64576 break;
64577 }
64578 }
64579
64580 $this->setTarget($target);
64581 $this->setOperator(isset($matches[1]) ? $matches[1] : '==');
64582 }
64583 }
64584 <?php
64585
64586
64587
64588
64589
64590
64591
64592
64593
64594
64595 namespace Symfony\Component\Finder\Exception;
64596
64597
64598
64599
64600 class AccessDeniedException extends \UnexpectedValueException
64601 {
64602 }
64603 <?php
64604
64605
64606
64607
64608
64609
64610
64611
64612
64613
64614 namespace Symfony\Component\Finder\Exception;
64615
64616 @trigger_error('The '.__NAMESPACE__.'\AdapterFailureException class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
64617
64618 use Symfony\Component\Finder\Adapter\AdapterInterface;
64619
64620
64621
64622
64623
64624
64625
64626
64627 class AdapterFailureException extends \RuntimeException implements ExceptionInterface
64628 {
64629
64630
64631
64632 private $adapter;
64633
64634
64635
64636
64637
64638
64639 public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null)
64640 {
64641 $this->adapter = $adapter;
64642 parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous);
64643 }
64644
64645
64646
64647
64648 public function getAdapter()
64649 {
64650 return $this->adapter;
64651 }
64652 }
64653 <?php
64654
64655
64656
64657
64658
64659
64660
64661
64662
64663
64664 namespace Symfony\Component\Finder\Exception;
64665
64666
64667
64668
64669 interface ExceptionInterface
64670 {
64671
64672
64673
64674 public function getAdapter();
64675 }
64676 <?php
64677
64678
64679
64680
64681
64682
64683
64684
64685
64686
64687 namespace Symfony\Component\Finder\Exception;
64688
64689 @trigger_error('The '.__NAMESPACE__.'\OperationNotPermitedException class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
64690
64691
64692
64693
64694
64695
64696 class OperationNotPermitedException extends AdapterFailureException
64697 {
64698 }
64699 <?php
64700
64701
64702
64703
64704
64705
64706
64707
64708
64709
64710 namespace Symfony\Component\Finder\Exception;
64711
64712 @trigger_error('The '.__NAMESPACE__.'\ShellCommandFailureException class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
64713
64714 use Symfony\Component\Finder\Adapter\AdapterInterface;
64715 use Symfony\Component\Finder\Shell\Command;
64716
64717
64718
64719
64720
64721
64722 class ShellCommandFailureException extends AdapterFailureException
64723 {
64724
64725
64726
64727 private $command;
64728
64729
64730
64731
64732
64733
64734 public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null)
64735 {
64736 $this->command = $command;
64737 parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous);
64738 }
64739
64740
64741
64742
64743 public function getCommand()
64744 {
64745 return $this->command;
64746 }
64747 }
64748 <?php
64749
64750
64751
64752
64753
64754
64755
64756
64757
64758
64759 namespace Symfony\Component\Finder\Expression;
64760
64761 @trigger_error('The '.__NAMESPACE__.'\Expression class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
64762
64763
64764
64765
64766 class Expression implements ValueInterface
64767 {
64768 const TYPE_REGEX = 1;
64769 const TYPE_GLOB = 2;
64770
64771
64772
64773
64774 private $value;
64775
64776
64777
64778
64779
64780
64781 public static function create($expr)
64782 {
64783 return new self($expr);
64784 }
64785
64786
64787
64788
64789 public function __construct($expr)
64790 {
64791 try {
64792 $this->value = Regex::create($expr);
64793 } catch (\InvalidArgumentException $e) {
64794 $this->value = new Glob($expr);
64795 }
64796 }
64797
64798
64799
64800
64801 public function __toString()
64802 {
64803 return $this->render();
64804 }
64805
64806
64807
64808
64809 public function render()
64810 {
64811 return $this->value->render();
64812 }
64813
64814
64815
64816
64817 public function renderPattern()
64818 {
64819 return $this->value->renderPattern();
64820 }
64821
64822
64823
64824
64825 public function isCaseSensitive()
64826 {
64827 return $this->value->isCaseSensitive();
64828 }
64829
64830
64831
64832
64833 public function getType()
64834 {
64835 return $this->value->getType();
64836 }
64837
64838
64839
64840
64841 public function prepend($expr)
64842 {
64843 $this->value->prepend($expr);
64844
64845 return $this;
64846 }
64847
64848
64849
64850
64851 public function append($expr)
64852 {
64853 $this->value->append($expr);
64854
64855 return $this;
64856 }
64857
64858
64859
64860
64861 public function isRegex()
64862 {
64863 return self::TYPE_REGEX === $this->value->getType();
64864 }
64865
64866
64867
64868
64869 public function isGlob()
64870 {
64871 return self::TYPE_GLOB === $this->value->getType();
64872 }
64873
64874
64875
64876
64877
64878
64879 public function getGlob()
64880 {
64881 if (self::TYPE_GLOB !== $this->value->getType()) {
64882 throw new \LogicException('Regex can\'t be transformed to glob.');
64883 }
64884
64885 return $this->value;
64886 }
64887
64888
64889
64890
64891 public function getRegex()
64892 {
64893 return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex();
64894 }
64895 }
64896 <?php
64897
64898
64899
64900
64901
64902
64903
64904
64905
64906
64907 namespace Symfony\Component\Finder\Expression;
64908
64909 @trigger_error('The '.__NAMESPACE__.'\Glob class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
64910
64911 use Symfony\Component\Finder\Glob as FinderGlob;
64912
64913
64914
64915
64916 class Glob implements ValueInterface
64917 {
64918
64919
64920
64921 private $pattern;
64922
64923
64924
64925
64926 public function __construct($pattern)
64927 {
64928 $this->pattern = $pattern;
64929 }
64930
64931
64932
64933
64934 public function render()
64935 {
64936 return $this->pattern;
64937 }
64938
64939
64940
64941
64942 public function renderPattern()
64943 {
64944 return $this->pattern;
64945 }
64946
64947
64948
64949
64950 public function getType()
64951 {
64952 return Expression::TYPE_GLOB;
64953 }
64954
64955
64956
64957
64958 public function isCaseSensitive()
64959 {
64960 return true;
64961 }
64962
64963
64964
64965
64966 public function prepend($expr)
64967 {
64968 $this->pattern = $expr.$this->pattern;
64969
64970 return $this;
64971 }
64972
64973
64974
64975
64976 public function append($expr)
64977 {
64978 $this->pattern .= $expr;
64979
64980 return $this;
64981 }
64982
64983
64984
64985
64986
64987
64988 public function isExpandable()
64989 {
64990 return false !== strpos($this->pattern, '{')
64991 && false !== strpos($this->pattern, '}');
64992 }
64993
64994
64995
64996
64997
64998
64999
65000 public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true)
65001 {
65002 $regex = FinderGlob::toRegex($this->pattern, $strictLeadingDot, $strictWildcardSlash, '');
65003
65004 return new Regex($regex);
65005 }
65006 }
65007 <?php
65008
65009
65010
65011
65012
65013
65014
65015
65016
65017
65018 namespace Symfony\Component\Finder\Expression;
65019
65020 @trigger_error('The '.__NAMESPACE__.'\Regex class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
65021
65022
65023
65024
65025 class Regex implements ValueInterface
65026 {
65027 const START_FLAG = '^';
65028 const END_FLAG = '$';
65029 const BOUNDARY = '~';
65030 const JOKER = '.*';
65031 const ESCAPING = '\\';
65032
65033
65034
65035
65036 private $pattern;
65037
65038
65039
65040
65041 private $options;
65042
65043
65044
65045
65046 private $startFlag;
65047
65048
65049
65050
65051 private $endFlag;
65052
65053
65054
65055
65056 private $startJoker;
65057
65058
65059
65060
65061 private $endJoker;
65062
65063
65064
65065
65066
65067
65068
65069
65070 public static function create($expr)
65071 {
65072 if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
65073 $start = substr($m[1], 0, 1);
65074 $end = substr($m[1], -1);
65075
65076 if (
65077 ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
65078 || ($start === '{' && $end === '}')
65079 || ($start === '(' && $end === ')')
65080 ) {
65081 return new self(substr($m[1], 1, -1), $m[2], $end);
65082 }
65083 }
65084
65085 throw new \InvalidArgumentException('Given expression is not a regex.');
65086 }
65087
65088
65089
65090
65091
65092
65093 public function __construct($pattern, $options = '', $delimiter = null)
65094 {
65095 if (null !== $delimiter) {
65096
65097  $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
65098 }
65099
65100 $this->parsePattern($pattern);
65101 $this->options = $options;
65102 }
65103
65104
65105
65106
65107 public function __toString()
65108 {
65109 return $this->render();
65110 }
65111
65112
65113
65114
65115 public function render()
65116 {
65117 return self::BOUNDARY
65118 .$this->renderPattern()
65119 .self::BOUNDARY
65120 .$this->options;
65121 }
65122
65123
65124
65125
65126 public function renderPattern()
65127 {
65128 return ($this->startFlag ? self::START_FLAG : '')
65129 .($this->startJoker ? self::JOKER : '')
65130 .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
65131 .($this->endJoker ? self::JOKER : '')
65132 .($this->endFlag ? self::END_FLAG : '');
65133 }
65134
65135
65136
65137
65138 public function isCaseSensitive()
65139 {
65140 return !$this->hasOption('i');
65141 }
65142
65143
65144
65145
65146 public function getType()
65147 {
65148 return Expression::TYPE_REGEX;
65149 }
65150
65151
65152
65153
65154 public function prepend($expr)
65155 {
65156 $this->pattern = $expr.$this->pattern;
65157
65158 return $this;
65159 }
65160
65161
65162
65163
65164 public function append($expr)
65165 {
65166 $this->pattern .= $expr;
65167
65168 return $this;
65169 }
65170
65171
65172
65173
65174
65175
65176 public function hasOption($option)
65177 {
65178 return false !== strpos($this->options, $option);
65179 }
65180
65181
65182
65183
65184
65185
65186 public function addOption($option)
65187 {
65188 if (!$this->hasOption($option)) {
65189 $this->options .= $option;
65190 }
65191
65192 return $this;
65193 }
65194
65195
65196
65197
65198
65199
65200 public function removeOption($option)
65201 {
65202 $this->options = str_replace($option, '', $this->options);
65203
65204 return $this;
65205 }
65206
65207
65208
65209
65210
65211
65212 public function setStartFlag($startFlag)
65213 {
65214 $this->startFlag = $startFlag;
65215
65216 return $this;
65217 }
65218
65219
65220
65221
65222 public function hasStartFlag()
65223 {
65224 return $this->startFlag;
65225 }
65226
65227
65228
65229
65230
65231
65232 public function setEndFlag($endFlag)
65233 {
65234 $this->endFlag = (bool) $endFlag;
65235
65236 return $this;
65237 }
65238
65239
65240
65241
65242 public function hasEndFlag()
65243 {
65244 return $this->endFlag;
65245 }
65246
65247
65248
65249
65250
65251
65252 public function setStartJoker($startJoker)
65253 {
65254 $this->startJoker = $startJoker;
65255
65256 return $this;
65257 }
65258
65259
65260
65261
65262 public function hasStartJoker()
65263 {
65264 return $this->startJoker;
65265 }
65266
65267
65268
65269
65270
65271
65272 public function setEndJoker($endJoker)
65273 {
65274 $this->endJoker = (bool) $endJoker;
65275
65276 return $this;
65277 }
65278
65279
65280
65281
65282 public function hasEndJoker()
65283 {
65284 return $this->endJoker;
65285 }
65286
65287
65288
65289
65290
65291
65292 public function replaceJokers($replacement)
65293 {
65294 $replace = function ($subject) use ($replacement) {
65295 $subject = $subject[0];
65296 $replace = 0 === substr_count($subject, '\\') % 2;
65297
65298 return $replace ? str_replace('.', $replacement, $subject) : $subject;
65299 };
65300
65301 $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
65302
65303 return $this;
65304 }
65305
65306
65307
65308
65309 private function parsePattern($pattern)
65310 {
65311 if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
65312 $pattern = substr($pattern, 1);
65313 }
65314
65315 if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
65316 $pattern = substr($pattern, 2);
65317 }
65318
65319 if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
65320 $pattern = substr($pattern, 0, -1);
65321 }
65322
65323 if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
65324 $pattern = substr($pattern, 0, -2);
65325 }
65326
65327 $this->pattern = $pattern;
65328 }
65329 }
65330 <?php
65331
65332
65333
65334
65335
65336
65337
65338
65339
65340
65341 namespace Symfony\Component\Finder\Expression;
65342
65343 @trigger_error('The '.__NAMESPACE__.'\ValueInterface interface is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
65344
65345
65346
65347
65348 interface ValueInterface
65349 {
65350
65351
65352
65353
65354
65355 public function render();
65356
65357
65358
65359
65360
65361
65362 public function renderPattern();
65363
65364
65365
65366
65367
65368
65369 public function isCaseSensitive();
65370
65371
65372
65373
65374
65375
65376 public function getType();
65377
65378
65379
65380
65381
65382
65383 public function prepend($expr);
65384
65385
65386
65387
65388
65389
65390 public function append($expr);
65391 }
65392 <?php
65393
65394
65395
65396
65397
65398
65399
65400
65401
65402
65403 namespace Symfony\Component\Finder;
65404
65405 use Symfony\Component\Finder\Adapter\AdapterInterface;
65406 use Symfony\Component\Finder\Adapter\GnuFindAdapter;
65407 use Symfony\Component\Finder\Adapter\BsdFindAdapter;
65408 use Symfony\Component\Finder\Adapter\PhpAdapter;
65409 use Symfony\Component\Finder\Comparator\DateComparator;
65410 use Symfony\Component\Finder\Comparator\NumberComparator;
65411 use Symfony\Component\Finder\Exception\ExceptionInterface;
65412 use Symfony\Component\Finder\Iterator\CustomFilterIterator;
65413 use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
65414 use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
65415 use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
65416 use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
65417 use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
65418 use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
65419 use Symfony\Component\Finder\Iterator\SortableIterator;
65420
65421
65422
65423
65424
65425
65426
65427
65428
65429
65430
65431
65432
65433
65434 class Finder implements \IteratorAggregate, \Countable
65435 {
65436 const IGNORE_VCS_FILES = 1;
65437 const IGNORE_DOT_FILES = 2;
65438
65439 private $mode = 0;
65440 private $names = array();
65441 private $notNames = array();
65442 private $exclude = array();
65443 private $filters = array();
65444 private $depths = array();
65445 private $sizes = array();
65446 private $followLinks = false;
65447 private $sort = false;
65448 private $ignore = 0;
65449 private $dirs = array();
65450 private $dates = array();
65451 private $iterators = array();
65452 private $contains = array();
65453 private $notContains = array();
65454 private $adapters = null;
65455 private $paths = array();
65456 private $notPaths = array();
65457 private $ignoreUnreadableDirs = false;
65458
65459 private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
65460
65461
65462
65463
65464 public function __construct()
65465 {
65466 $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
65467 }
65468
65469
65470
65471
65472
65473
65474 public static function create()
65475 {
65476 return new static();
65477 }
65478
65479
65480
65481
65482
65483
65484
65485
65486
65487
65488
65489 public function addAdapter(AdapterInterface $adapter, $priority = 0)
65490 {
65491 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
65492
65493 $this->initDefaultAdapters();
65494
65495 $this->adapters[$adapter->getName()] = array(
65496 'adapter' => $adapter,
65497 'priority' => $priority,
65498 'selected' => false,
65499 );
65500
65501 return $this->sortAdapters();
65502 }
65503
65504
65505
65506
65507
65508
65509
65510
65511 public function useBestAdapter()
65512 {
65513 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
65514
65515 $this->initDefaultAdapters();
65516
65517 $this->resetAdapterSelection();
65518
65519 return $this->sortAdapters();
65520 }
65521
65522
65523
65524
65525
65526
65527
65528
65529
65530
65531
65532
65533 public function setAdapter($name)
65534 {
65535 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
65536
65537 $this->initDefaultAdapters();
65538
65539 if (!isset($this->adapters[$name])) {
65540 throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
65541 }
65542
65543 $this->resetAdapterSelection();
65544 $this->adapters[$name]['selected'] = true;
65545
65546 return $this->sortAdapters();
65547 }
65548
65549
65550
65551
65552
65553
65554
65555
65556 public function removeAdapters()
65557 {
65558 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
65559
65560 $this->adapters = array();
65561
65562 return $this;
65563 }
65564
65565
65566
65567
65568
65569
65570
65571
65572 public function getAdapters()
65573 {
65574 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
65575
65576 $this->initDefaultAdapters();
65577
65578 return array_values(array_map(function (array $adapter) {
65579 return $adapter['adapter'];
65580 }, $this->adapters));
65581 }
65582
65583
65584
65585
65586
65587
65588 public function directories()
65589 {
65590 $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
65591
65592 return $this;
65593 }
65594
65595
65596
65597
65598
65599
65600 public function files()
65601 {
65602 $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
65603
65604 return $this;
65605 }
65606
65607
65608
65609
65610
65611
65612
65613
65614
65615
65616
65617
65618
65619
65620
65621
65622 public function depth($level)
65623 {
65624 $this->depths[] = new Comparator\NumberComparator($level);
65625
65626 return $this;
65627 }
65628
65629
65630
65631
65632
65633
65634
65635
65636
65637
65638
65639
65640
65641
65642
65643
65644
65645
65646
65647 public function date($date)
65648 {
65649 $this->dates[] = new Comparator\DateComparator($date);
65650
65651 return $this;
65652 }
65653
65654
65655
65656
65657
65658
65659
65660
65661
65662
65663
65664
65665
65666
65667
65668
65669 public function name($pattern)
65670 {
65671 $this->names[] = $pattern;
65672
65673 return $this;
65674 }
65675
65676
65677
65678
65679
65680
65681
65682
65683
65684
65685 public function notName($pattern)
65686 {
65687 $this->notNames[] = $pattern;
65688
65689 return $this;
65690 }
65691
65692
65693
65694
65695
65696
65697
65698
65699
65700
65701
65702
65703
65704
65705
65706 public function contains($pattern)
65707 {
65708 $this->contains[] = $pattern;
65709
65710 return $this;
65711 }
65712
65713
65714
65715
65716
65717
65718
65719
65720
65721
65722
65723
65724
65725
65726
65727 public function notContains($pattern)
65728 {
65729 $this->notContains[] = $pattern;
65730
65731 return $this;
65732 }
65733
65734
65735
65736
65737
65738
65739
65740
65741
65742
65743
65744
65745
65746
65747
65748
65749
65750 public function path($pattern)
65751 {
65752 $this->paths[] = $pattern;
65753
65754 return $this;
65755 }
65756
65757
65758
65759
65760
65761
65762
65763
65764
65765
65766
65767
65768
65769
65770
65771
65772
65773 public function notPath($pattern)
65774 {
65775 $this->notPaths[] = $pattern;
65776
65777 return $this;
65778 }
65779
65780
65781
65782
65783
65784
65785
65786
65787
65788
65789
65790
65791
65792
65793
65794 public function size($size)
65795 {
65796 $this->sizes[] = new Comparator\NumberComparator($size);
65797
65798 return $this;
65799 }
65800
65801
65802
65803
65804
65805
65806
65807
65808
65809
65810 public function exclude($dirs)
65811 {
65812 $this->exclude = array_merge($this->exclude, (array) $dirs);
65813
65814 return $this;
65815 }
65816
65817
65818
65819
65820
65821
65822
65823
65824
65825
65826 public function ignoreDotFiles($ignoreDotFiles)
65827 {
65828 if ($ignoreDotFiles) {
65829 $this->ignore |= static::IGNORE_DOT_FILES;
65830 } else {
65831 $this->ignore &= ~static::IGNORE_DOT_FILES;
65832 }
65833
65834 return $this;
65835 }
65836
65837
65838
65839
65840
65841
65842
65843
65844
65845
65846 public function ignoreVCS($ignoreVCS)
65847 {
65848 if ($ignoreVCS) {
65849 $this->ignore |= static::IGNORE_VCS_FILES;
65850 } else {
65851 $this->ignore &= ~static::IGNORE_VCS_FILES;
65852 }
65853
65854 return $this;
65855 }
65856
65857
65858
65859
65860
65861
65862
65863
65864 public static function addVCSPattern($pattern)
65865 {
65866 foreach ((array) $pattern as $p) {
65867 self::$vcsPatterns[] = $p;
65868 }
65869
65870 self::$vcsPatterns = array_unique(self::$vcsPatterns);
65871 }
65872
65873
65874
65875
65876
65877
65878
65879
65880
65881
65882
65883
65884
65885
65886 public function sort(\Closure $closure)
65887 {
65888 $this->sort = $closure;
65889
65890 return $this;
65891 }
65892
65893
65894
65895
65896
65897
65898
65899
65900
65901
65902 public function sortByName()
65903 {
65904 $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
65905
65906 return $this;
65907 }
65908
65909
65910
65911
65912
65913
65914
65915
65916
65917
65918 public function sortByType()
65919 {
65920 $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
65921
65922 return $this;
65923 }
65924
65925
65926
65927
65928
65929
65930
65931
65932
65933
65934
65935
65936 public function sortByAccessedTime()
65937 {
65938 $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
65939
65940 return $this;
65941 }
65942
65943
65944
65945
65946
65947
65948
65949
65950
65951
65952
65953
65954
65955
65956 public function sortByChangedTime()
65957 {
65958 $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
65959
65960 return $this;
65961 }
65962
65963
65964
65965
65966
65967
65968
65969
65970
65971
65972
65973
65974 public function sortByModifiedTime()
65975 {
65976 $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
65977
65978 return $this;
65979 }
65980
65981
65982
65983
65984
65985
65986
65987
65988
65989
65990
65991
65992
65993 public function filter(\Closure $closure)
65994 {
65995 $this->filters[] = $closure;
65996
65997 return $this;
65998 }
65999
66000
66001
66002
66003
66004
66005 public function followLinks()
66006 {
66007 $this->followLinks = true;
66008
66009 return $this;
66010 }
66011
66012
66013
66014
66015
66016
66017
66018
66019
66020
66021 public function ignoreUnreadableDirs($ignore = true)
66022 {
66023 $this->ignoreUnreadableDirs = (bool) $ignore;
66024
66025 return $this;
66026 }
66027
66028
66029
66030
66031
66032
66033
66034
66035
66036
66037 public function in($dirs)
66038 {
66039 $resolvedDirs = array();
66040
66041 foreach ((array) $dirs as $dir) {
66042 if (is_dir($dir)) {
66043 $resolvedDirs[] = $dir;
66044 } elseif ($glob = glob($dir, (defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR)) {
66045 $resolvedDirs = array_merge($resolvedDirs, $glob);
66046 } else {
66047 throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
66048 }
66049 }
66050
66051 $this->dirs = array_merge($this->dirs, $resolvedDirs);
66052
66053 return $this;
66054 }
66055
66056
66057
66058
66059
66060
66061
66062
66063
66064
66065 public function getIterator()
66066 {
66067 if (0 === count($this->dirs) && 0 === count($this->iterators)) {
66068 throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
66069 }
66070
66071 if (1 === count($this->dirs) && 0 === count($this->iterators)) {
66072 return $this->searchInDirectory($this->dirs[0]);
66073 }
66074
66075 $iterator = new \AppendIterator();
66076 foreach ($this->dirs as $dir) {
66077 $iterator->append($this->searchInDirectory($dir));
66078 }
66079
66080 foreach ($this->iterators as $it) {
66081 $iterator->append($it);
66082 }
66083
66084 return $iterator;
66085 }
66086
66087
66088
66089
66090
66091
66092
66093
66094
66095
66096
66097
66098 public function append($iterator)
66099 {
66100 if ($iterator instanceof \IteratorAggregate) {
66101 $this->iterators[] = $iterator->getIterator();
66102 } elseif ($iterator instanceof \Iterator) {
66103 $this->iterators[] = $iterator;
66104 } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
66105 $it = new \ArrayIterator();
66106 foreach ($iterator as $file) {
66107 $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
66108 }
66109 $this->iterators[] = $it;
66110 } else {
66111 throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
66112 }
66113
66114 return $this;
66115 }
66116
66117
66118
66119
66120
66121
66122 public function count()
66123 {
66124 return iterator_count($this->getIterator());
66125 }
66126
66127
66128
66129
66130 private function sortAdapters()
66131 {
66132 uasort($this->adapters, function (array $a, array $b) {
66133 if ($a['selected'] || $b['selected']) {
66134 return $a['selected'] ? -1 : 1;
66135 }
66136
66137 return $a['priority'] > $b['priority'] ? -1 : 1;
66138 });
66139
66140 return $this;
66141 }
66142
66143
66144
66145
66146
66147
66148 private function searchInDirectory($dir)
66149 {
66150 if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
66151 $this->exclude = array_merge($this->exclude, self::$vcsPatterns);
66152 }
66153
66154 if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
66155 $this->notPaths[] = '#(^|/)\..+(/|$)#';
66156 }
66157
66158 if ($this->adapters) {
66159 foreach ($this->adapters as $adapter) {
66160 if ($adapter['adapter']->isSupported()) {
66161 try {
66162 return $this
66163 ->buildAdapter($adapter['adapter'])
66164 ->searchInDirectory($dir);
66165 } catch (ExceptionInterface $e) {
66166 }
66167 }
66168 }
66169 }
66170
66171 $minDepth = 0;
66172 $maxDepth = PHP_INT_MAX;
66173
66174 foreach ($this->depths as $comparator) {
66175 switch ($comparator->getOperator()) {
66176 case '>':
66177 $minDepth = $comparator->getTarget() + 1;
66178 break;
66179 case '>=':
66180 $minDepth = $comparator->getTarget();
66181 break;
66182 case '<':
66183 $maxDepth = $comparator->getTarget() - 1;
66184 break;
66185 case '<=':
66186 $maxDepth = $comparator->getTarget();
66187 break;
66188 default:
66189 $minDepth = $maxDepth = $comparator->getTarget();
66190 }
66191 }
66192
66193 $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
66194
66195 if ($this->followLinks) {
66196 $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
66197 }
66198
66199 $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);
66200
66201 if ($this->exclude) {
66202 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
66203 }
66204
66205 $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
66206
66207 if ($minDepth > 0 || $maxDepth < PHP_INT_MAX) {
66208 $iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth);
66209 }
66210
66211 if ($this->mode) {
66212 $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
66213 }
66214
66215 if ($this->names || $this->notNames) {
66216 $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
66217 }
66218
66219 if ($this->contains || $this->notContains) {
66220 $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
66221 }
66222
66223 if ($this->sizes) {
66224 $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
66225 }
66226
66227 if ($this->dates) {
66228 $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
66229 }
66230
66231 if ($this->filters) {
66232 $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
66233 }
66234
66235 if ($this->paths || $this->notPaths) {
66236 $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
66237 }
66238
66239 if ($this->sort) {
66240 $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
66241 $iterator = $iteratorAggregate->getIterator();
66242 }
66243
66244 return $iterator;
66245 }
66246
66247
66248
66249
66250
66251
66252 private function buildAdapter(AdapterInterface $adapter)
66253 {
66254 return $adapter
66255 ->setFollowLinks($this->followLinks)
66256 ->setDepths($this->depths)
66257 ->setMode($this->mode)
66258 ->setExclude($this->exclude)
66259 ->setNames($this->names)
66260 ->setNotNames($this->notNames)
66261 ->setContains($this->contains)
66262 ->setNotContains($this->notContains)
66263 ->setSizes($this->sizes)
66264 ->setDates($this->dates)
66265 ->setFilters($this->filters)
66266 ->setSort($this->sort)
66267 ->setPath($this->paths)
66268 ->setNotPath($this->notPaths)
66269 ->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
66270 }
66271
66272
66273
66274
66275 private function resetAdapterSelection()
66276 {
66277 $this->adapters = array_map(function (array $properties) {
66278 $properties['selected'] = false;
66279
66280 return $properties;
66281 }, $this->adapters);
66282 }
66283
66284 private function initDefaultAdapters()
66285 {
66286 if (null === $this->adapters) {
66287 $this->adapters = array();
66288 $this
66289 ->addAdapter(new GnuFindAdapter())
66290 ->addAdapter(new BsdFindAdapter())
66291 ->addAdapter(new PhpAdapter(), -50)
66292 ->setAdapter('php')
66293 ;
66294 }
66295 }
66296 }
66297 <?php
66298
66299
66300
66301
66302
66303
66304
66305
66306
66307
66308 namespace Symfony\Component\Finder;
66309
66310
66311
66312
66313
66314
66315
66316
66317
66318
66319
66320
66321
66322
66323
66324
66325
66326
66327
66328
66329
66330
66331
66332 class Glob
66333 {
66334
66335
66336
66337
66338
66339
66340
66341
66342
66343
66344 public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardSlash = true, $delimiter = '#')
66345 {
66346 $firstByte = true;
66347 $escaping = false;
66348 $inCurlies = 0;
66349 $regex = '';
66350 $sizeGlob = strlen($glob);
66351 for ($i = 0; $i < $sizeGlob; ++$i) {
66352 $car = $glob[$i];
66353 if ($firstByte) {
66354 if ($strictLeadingDot && '.' !== $car) {
66355 $regex .= '(?=[^\.])';
66356 }
66357
66358 $firstByte = false;
66359 }
66360
66361 if ('/' === $car) {
66362 $firstByte = true;
66363 }
66364
66365 if ($delimiter === $car || '.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
66366 $regex .= "\\$car";
66367 } elseif ('*' === $car) {
66368 $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
66369 } elseif ('?' === $car) {
66370 $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
66371 } elseif ('{' === $car) {
66372 $regex .= $escaping ? '\\{' : '(';
66373 if (!$escaping) {
66374 ++$inCurlies;
66375 }
66376 } elseif ('}' === $car && $inCurlies) {
66377 $regex .= $escaping ? '}' : ')';
66378 if (!$escaping) {
66379 --$inCurlies;
66380 }
66381 } elseif (',' === $car && $inCurlies) {
66382 $regex .= $escaping ? ',' : '|';
66383 } elseif ('\\' === $car) {
66384 if ($escaping) {
66385 $regex .= '\\\\';
66386 $escaping = false;
66387 } else {
66388 $escaping = true;
66389 }
66390
66391 continue;
66392 } else {
66393 $regex .= $car;
66394 }
66395 $escaping = false;
66396 }
66397
66398 return $delimiter.'^'.$regex.'$'.$delimiter;
66399 }
66400 }
66401 <?php
66402
66403
66404
66405
66406
66407
66408
66409
66410
66411
66412 namespace Symfony\Component\Finder\Iterator;
66413
66414
66415
66416
66417
66418
66419
66420
66421
66422 class CustomFilterIterator extends FilterIterator
66423 {
66424 private $filters = array();
66425
66426
66427
66428
66429
66430
66431
66432
66433
66434 public function __construct(\Iterator $iterator, array $filters)
66435 {
66436 foreach ($filters as $filter) {
66437 if (!is_callable($filter)) {
66438 throw new \InvalidArgumentException('Invalid PHP callback.');
66439 }
66440 }
66441 $this->filters = $filters;
66442
66443 parent::__construct($iterator);
66444 }
66445
66446
66447
66448
66449
66450
66451 public function accept()
66452 {
66453 $fileinfo = $this->current();
66454
66455 foreach ($this->filters as $filter) {
66456 if (false === call_user_func($filter, $fileinfo)) {
66457 return false;
66458 }
66459 }
66460
66461 return true;
66462 }
66463 }
66464 <?php
66465
66466
66467
66468
66469
66470
66471
66472
66473
66474
66475 namespace Symfony\Component\Finder\Iterator;
66476
66477 use Symfony\Component\Finder\Comparator\DateComparator;
66478
66479
66480
66481
66482
66483
66484 class DateRangeFilterIterator extends FilterIterator
66485 {
66486 private $comparators = array();
66487
66488
66489
66490
66491
66492
66493
66494 public function __construct(\Iterator $iterator, array $comparators)
66495 {
66496 $this->comparators = $comparators;
66497
66498 parent::__construct($iterator);
66499 }
66500
66501
66502
66503
66504
66505
66506 public function accept()
66507 {
66508 $fileinfo = $this->current();
66509
66510 if (!file_exists($fileinfo->getPathname())) {
66511 return false;
66512 }
66513
66514 $filedate = $fileinfo->getMTime();
66515 foreach ($this->comparators as $compare) {
66516 if (!$compare->test($filedate)) {
66517 return false;
66518 }
66519 }
66520
66521 return true;
66522 }
66523 }
66524 <?php
66525
66526
66527
66528
66529
66530
66531
66532
66533
66534
66535 namespace Symfony\Component\Finder\Iterator;
66536
66537
66538
66539
66540
66541
66542 class DepthRangeFilterIterator extends FilterIterator
66543 {
66544 private $minDepth = 0;
66545
66546
66547
66548
66549
66550
66551
66552
66553 public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX)
66554 {
66555 $this->minDepth = $minDepth;
66556 $iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth);
66557
66558 parent::__construct($iterator);
66559 }
66560
66561
66562
66563
66564
66565
66566 public function accept()
66567 {
66568 return $this->getInnerIterator()->getDepth() >= $this->minDepth;
66569 }
66570 }
66571 <?php
66572
66573
66574
66575
66576
66577
66578
66579
66580
66581
66582 namespace Symfony\Component\Finder\Iterator;
66583
66584
66585
66586
66587
66588
66589 class ExcludeDirectoryFilterIterator extends FilterIterator implements \RecursiveIterator
66590 {
66591 private $iterator;
66592 private $isRecursive;
66593 private $excludedDirs = array();
66594 private $excludedPattern;
66595
66596
66597
66598
66599
66600
66601
66602 public function __construct(\Iterator $iterator, array $directories)
66603 {
66604 $this->iterator = $iterator;
66605 $this->isRecursive = $iterator instanceof \RecursiveIterator;
66606 $patterns = array();
66607 foreach ($directories as $directory) {
66608 $directory = rtrim($directory, '/');
66609 if (!$this->isRecursive || false !== strpos($directory, '/')) {
66610 $patterns[] = preg_quote($directory, '#');
66611 } else {
66612 $this->excludedDirs[$directory] = true;
66613 }
66614 }
66615 if ($patterns) {
66616 $this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#';
66617 }
66618
66619 parent::__construct($iterator);
66620 }
66621
66622
66623
66624
66625
66626
66627 public function accept()
66628 {
66629 if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) {
66630 return false;
66631 }
66632
66633 if ($this->excludedPattern) {
66634 $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
66635 $path = str_replace('\\', '/', $path);
66636
66637 return !preg_match($this->excludedPattern, $path);
66638 }
66639
66640 return true;
66641 }
66642
66643 public function hasChildren()
66644 {
66645 return $this->isRecursive && $this->iterator->hasChildren();
66646 }
66647
66648 public function getChildren()
66649 {
66650 $children = new self($this->iterator->getChildren(), array());
66651 $children->excludedDirs = $this->excludedDirs;
66652 $children->excludedPattern = $this->excludedPattern;
66653
66654 return $children;
66655 }
66656 }
66657 <?php
66658
66659
66660
66661
66662
66663
66664
66665
66666
66667
66668 namespace Symfony\Component\Finder\Iterator;
66669
66670 @trigger_error('The '.__NAMESPACE__.'\FilePathsIterator class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
66671
66672 use Symfony\Component\Finder\SplFileInfo;
66673
66674
66675
66676
66677
66678
66679
66680
66681 class FilePathsIterator extends \ArrayIterator
66682 {
66683
66684
66685
66686 private $baseDir;
66687
66688
66689
66690
66691 private $baseDirLength;
66692
66693
66694
66695
66696 private $subPath;
66697
66698
66699
66700
66701 private $subPathname;
66702
66703
66704
66705
66706 private $current;
66707
66708
66709
66710
66711
66712 public function __construct(array $paths, $baseDir)
66713 {
66714 $this->baseDir = $baseDir;
66715 $this->baseDirLength = strlen($baseDir);
66716
66717 parent::__construct($paths);
66718 }
66719
66720
66721
66722
66723
66724
66725
66726 public function __call($name, array $arguments)
66727 {
66728 return call_user_func_array(array($this->current(), $name), $arguments);
66729 }
66730
66731
66732
66733
66734
66735
66736 public function current()
66737 {
66738 return $this->current;
66739 }
66740
66741
66742
66743
66744 public function key()
66745 {
66746 return $this->current->getPathname();
66747 }
66748
66749 public function next()
66750 {
66751 parent::next();
66752 $this->buildProperties();
66753 }
66754
66755 public function rewind()
66756 {
66757 parent::rewind();
66758 $this->buildProperties();
66759 }
66760
66761
66762
66763
66764 public function getSubPath()
66765 {
66766 return $this->subPath;
66767 }
66768
66769
66770
66771
66772 public function getSubPathname()
66773 {
66774 return $this->subPathname;
66775 }
66776
66777 private function buildProperties()
66778 {
66779 $absolutePath = parent::current();
66780
66781 if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) {
66782 $this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\');
66783 $dir = dirname($this->subPathname);
66784 $this->subPath = '.' === $dir ? '' : $dir;
66785 } else {
66786 $this->subPath = $this->subPathname = '';
66787 }
66788
66789 $this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname);
66790 }
66791 }
66792 <?php
66793
66794
66795
66796
66797
66798
66799
66800
66801
66802
66803 namespace Symfony\Component\Finder\Iterator;
66804
66805
66806
66807
66808
66809
66810 class FileTypeFilterIterator extends FilterIterator
66811 {
66812 const ONLY_FILES = 1;
66813 const ONLY_DIRECTORIES = 2;
66814
66815 private $mode;
66816
66817
66818
66819
66820
66821
66822
66823 public function __construct(\Iterator $iterator, $mode)
66824 {
66825 $this->mode = $mode;
66826
66827 parent::__construct($iterator);
66828 }
66829
66830
66831
66832
66833
66834
66835 public function accept()
66836 {
66837 $fileinfo = $this->current();
66838 if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
66839 return false;
66840 } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
66841 return false;
66842 }
66843
66844 return true;
66845 }
66846 }
66847 <?php
66848
66849
66850
66851
66852
66853
66854
66855
66856
66857
66858 namespace Symfony\Component\Finder\Iterator;
66859
66860
66861
66862
66863
66864
66865
66866 class FilecontentFilterIterator extends MultiplePcreFilterIterator
66867 {
66868
66869
66870
66871
66872
66873 public function accept()
66874 {
66875 if (!$this->matchRegexps && !$this->noMatchRegexps) {
66876 return true;
66877 }
66878
66879 $fileinfo = $this->current();
66880
66881 if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
66882 return false;
66883 }
66884
66885 $content = $fileinfo->getContents();
66886 if (!$content) {
66887 return false;
66888 }
66889
66890 return $this->isAccepted($content);
66891 }
66892
66893
66894
66895
66896
66897
66898
66899
66900 protected function toRegex($str)
66901 {
66902 return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
66903 }
66904 }
66905 <?php
66906
66907
66908
66909
66910
66911
66912
66913
66914
66915
66916 namespace Symfony\Component\Finder\Iterator;
66917
66918 use Symfony\Component\Finder\Glob;
66919
66920
66921
66922
66923
66924
66925 class FilenameFilterIterator extends MultiplePcreFilterIterator
66926 {
66927
66928
66929
66930
66931
66932 public function accept()
66933 {
66934 return $this->isAccepted($this->current()->getFilename());
66935 }
66936
66937
66938
66939
66940
66941
66942
66943
66944
66945
66946
66947 protected function toRegex($str)
66948 {
66949 return $this->isRegex($str) ? $str : Glob::toRegex($str);
66950 }
66951 }
66952 <?php
66953
66954
66955
66956
66957
66958
66959
66960
66961
66962
66963 namespace Symfony\Component\Finder\Iterator;
66964
66965
66966
66967
66968
66969
66970
66971
66972
66973 abstract class FilterIterator extends \FilterIterator
66974 {
66975
66976
66977
66978
66979
66980
66981 public function rewind()
66982 {
66983 if (PHP_VERSION_ID > 50607 || (PHP_VERSION_ID > 50523 && PHP_VERSION_ID < 50600)) {
66984 parent::rewind();
66985
66986 return;
66987 }
66988
66989 $iterator = $this;
66990 while ($iterator instanceof \OuterIterator) {
66991 $innerIterator = $iterator->getInnerIterator();
66992
66993 if ($innerIterator instanceof RecursiveDirectoryIterator) {
66994
66995  if ($innerIterator->isRewindable()) {
66996 $innerIterator->next();
66997 $innerIterator->rewind();
66998 }
66999 } elseif ($innerIterator instanceof \FilesystemIterator) {
67000 $innerIterator->next();
67001 $innerIterator->rewind();
67002 }
67003
67004 $iterator = $innerIterator;
67005 }
67006
67007 parent::rewind();
67008 }
67009 }
67010 <?php
67011
67012
67013
67014
67015
67016
67017
67018
67019
67020
67021 namespace Symfony\Component\Finder\Iterator;
67022
67023
67024
67025
67026
67027
67028 abstract class MultiplePcreFilterIterator extends FilterIterator
67029 {
67030 protected $matchRegexps = array();
67031 protected $noMatchRegexps = array();
67032
67033
67034
67035
67036
67037
67038
67039
67040 public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
67041 {
67042 foreach ($matchPatterns as $pattern) {
67043 $this->matchRegexps[] = $this->toRegex($pattern);
67044 }
67045
67046 foreach ($noMatchPatterns as $pattern) {
67047 $this->noMatchRegexps[] = $this->toRegex($pattern);
67048 }
67049
67050 parent::__construct($iterator);
67051 }
67052
67053
67054
67055
67056
67057
67058
67059
67060
67061
67062
67063
67064 protected function isAccepted($string)
67065 {
67066
67067  foreach ($this->noMatchRegexps as $regex) {
67068 if (preg_match($regex, $string)) {
67069 return false;
67070 }
67071 }
67072
67073
67074  if ($this->matchRegexps) {
67075 foreach ($this->matchRegexps as $regex) {
67076 if (preg_match($regex, $string)) {
67077 return true;
67078 }
67079 }
67080
67081 return false;
67082 }
67083
67084
67085  return true;
67086 }
67087
67088
67089
67090
67091
67092
67093
67094
67095 protected function isRegex($str)
67096 {
67097 if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) {
67098 $start = substr($m[1], 0, 1);
67099 $end = substr($m[1], -1);
67100
67101 if ($start === $end) {
67102 return !preg_match('/[*?[:alnum:] \\\\]/', $start);
67103 }
67104
67105 foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) {
67106 if ($start === $delimiters[0] && $end === $delimiters[1]) {
67107 return true;
67108 }
67109 }
67110 }
67111
67112 return false;
67113 }
67114
67115
67116
67117
67118
67119
67120
67121
67122 abstract protected function toRegex($str);
67123 }
67124 <?php
67125
67126
67127
67128
67129
67130
67131
67132
67133
67134
67135 namespace Symfony\Component\Finder\Iterator;
67136
67137
67138
67139
67140
67141
67142
67143 class PathFilterIterator extends MultiplePcreFilterIterator
67144 {
67145
67146
67147
67148
67149
67150 public function accept()
67151 {
67152 $filename = $this->current()->getRelativePathname();
67153
67154 if ('\\' === DIRECTORY_SEPARATOR) {
67155 $filename = str_replace('\\', '/', $filename);
67156 }
67157
67158 return $this->isAccepted($filename);
67159 }
67160
67161
67162
67163
67164
67165
67166
67167
67168
67169
67170
67171
67172
67173
67174
67175 protected function toRegex($str)
67176 {
67177 return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
67178 }
67179 }
67180 <?php
67181
67182
67183
67184
67185
67186
67187
67188
67189
67190
67191 namespace Symfony\Component\Finder\Iterator;
67192
67193 use Symfony\Component\Finder\Exception\AccessDeniedException;
67194 use Symfony\Component\Finder\SplFileInfo;
67195
67196
67197
67198
67199
67200
67201 class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
67202 {
67203
67204
67205
67206 private $ignoreUnreadableDirs;
67207
67208
67209
67210
67211 private $rewindable;
67212
67213
67214  private $rootPath;
67215 private $subPath;
67216 private $directorySeparator = '/';
67217
67218
67219
67220
67221
67222
67223
67224
67225
67226
67227 public function __construct($path, $flags, $ignoreUnreadableDirs = false)
67228 {
67229 if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
67230 throw new \RuntimeException('This iterator only support returning current as fileinfo.');
67231 }
67232
67233 parent::__construct($path, $flags);
67234 $this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
67235 $this->rootPath = (string) $path;
67236 if ('/' !== DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) {
67237 $this->directorySeparator = DIRECTORY_SEPARATOR;
67238 }
67239 }
67240
67241
67242
67243
67244
67245
67246 public function current()
67247 {
67248
67249
67250 if (null === $subPathname = $this->subPath) {
67251 $subPathname = $this->subPath = (string) $this->getSubPath();
67252 }
67253 if ('' !== $subPathname) {
67254 $subPathname .= $this->directorySeparator;
67255 }
67256 $subPathname .= $this->getFilename();
67257
67258 return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname);
67259 }
67260
67261
67262
67263
67264
67265
67266 public function getChildren()
67267 {
67268 try {
67269 $children = parent::getChildren();
67270
67271 if ($children instanceof self) {
67272
67273  $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
67274
67275
67276  $children->rewindable = &$this->rewindable;
67277 $children->rootPath = $this->rootPath;
67278 }
67279
67280 return $children;
67281 } catch (\UnexpectedValueException $e) {
67282 if ($this->ignoreUnreadableDirs) {
67283
67284  return new \RecursiveArrayIterator(array());
67285 } else {
67286 throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
67287 }
67288 }
67289 }
67290
67291
67292
67293
67294 public function rewind()
67295 {
67296 if (false === $this->isRewindable()) {
67297 return;
67298 }
67299
67300
67301  if (PHP_VERSION_ID < 50523 || PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < 50607) {
67302 parent::next();
67303 }
67304
67305 parent::rewind();
67306 }
67307
67308
67309
67310
67311
67312
67313 public function isRewindable()
67314 {
67315 if (null !== $this->rewindable) {
67316 return $this->rewindable;
67317 }
67318
67319
67320  if ('' === $this->getPath()) {
67321 return $this->rewindable = false;
67322 }
67323
67324 if (false !== $stream = @opendir($this->getPath())) {
67325 $infos = stream_get_meta_data($stream);
67326 closedir($stream);
67327
67328 if ($infos['seekable']) {
67329 return $this->rewindable = true;
67330 }
67331 }
67332
67333 return $this->rewindable = false;
67334 }
67335 }
67336 <?php
67337
67338
67339
67340
67341
67342
67343
67344
67345
67346
67347 namespace Symfony\Component\Finder\Iterator;
67348
67349 use Symfony\Component\Finder\Comparator\NumberComparator;
67350
67351
67352
67353
67354
67355
67356 class SizeRangeFilterIterator extends FilterIterator
67357 {
67358 private $comparators = array();
67359
67360
67361
67362
67363
67364
67365
67366 public function __construct(\Iterator $iterator, array $comparators)
67367 {
67368 $this->comparators = $comparators;
67369
67370 parent::__construct($iterator);
67371 }
67372
67373
67374
67375
67376
67377
67378 public function accept()
67379 {
67380 $fileinfo = $this->current();
67381 if (!$fileinfo->isFile()) {
67382 return true;
67383 }
67384
67385 $filesize = $fileinfo->getSize();
67386 foreach ($this->comparators as $compare) {
67387 if (!$compare->test($filesize)) {
67388 return false;
67389 }
67390 }
67391
67392 return true;
67393 }
67394 }
67395 <?php
67396
67397
67398
67399
67400
67401
67402
67403
67404
67405
67406 namespace Symfony\Component\Finder\Iterator;
67407
67408
67409
67410
67411
67412
67413 class SortableIterator implements \IteratorAggregate
67414 {
67415 const SORT_BY_NAME = 1;
67416 const SORT_BY_TYPE = 2;
67417 const SORT_BY_ACCESSED_TIME = 3;
67418 const SORT_BY_CHANGED_TIME = 4;
67419 const SORT_BY_MODIFIED_TIME = 5;
67420
67421 private $iterator;
67422 private $sort;
67423
67424
67425
67426
67427
67428
67429
67430
67431
67432 public function __construct(\Traversable $iterator, $sort)
67433 {
67434 $this->iterator = $iterator;
67435
67436 if (self::SORT_BY_NAME === $sort) {
67437 $this->sort = function ($a, $b) {
67438 return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
67439 };
67440 } elseif (self::SORT_BY_TYPE === $sort) {
67441 $this->sort = function ($a, $b) {
67442 if ($a->isDir() && $b->isFile()) {
67443 return -1;
67444 } elseif ($a->isFile() && $b->isDir()) {
67445 return 1;
67446 }
67447
67448 return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
67449 };
67450 } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
67451 $this->sort = function ($a, $b) {
67452 return $a->getATime() - $b->getATime();
67453 };
67454 } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
67455 $this->sort = function ($a, $b) {
67456 return $a->getCTime() - $b->getCTime();
67457 };
67458 } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
67459 $this->sort = function ($a, $b) {
67460 return $a->getMTime() - $b->getMTime();
67461 };
67462 } elseif (is_callable($sort)) {
67463 $this->sort = $sort;
67464 } else {
67465 throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
67466 }
67467 }
67468
67469 public function getIterator()
67470 {
67471 $array = iterator_to_array($this->iterator, true);
67472 uasort($array, $this->sort);
67473
67474 return new \ArrayIterator($array);
67475 }
67476 }
67477 Copyright (c) 2004-2017 Fabien Potencier
67478
67479 Permission is hereby granted, free of charge, to any person obtaining a copy
67480 of this software and associated documentation files (the "Software"), to deal
67481 in the Software without restriction, including without limitation the rights
67482 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
67483 copies of the Software, and to permit persons to whom the Software is furnished
67484 to do so, subject to the following conditions:
67485
67486 The above copyright notice and this permission notice shall be included in all
67487 copies or substantial portions of the Software.
67488
67489 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
67490 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67491 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
67492 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67493 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67494 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
67495 THE SOFTWARE.
67496 <?php
67497
67498
67499
67500
67501
67502
67503
67504
67505
67506
67507 namespace Symfony\Component\Finder\Shell;
67508
67509 @trigger_error('The '.__NAMESPACE__.'\Command class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
67510
67511
67512
67513
67514
67515
67516 class Command
67517 {
67518
67519
67520
67521 private $parent;
67522
67523
67524
67525
67526 private $bits = array();
67527
67528
67529
67530
67531 private $labels = array();
67532
67533
67534
67535
67536 private $errorHandler;
67537
67538
67539
67540
67541
67542
67543 public function __construct(Command $parent = null)
67544 {
67545 $this->parent = $parent;
67546 }
67547
67548
67549
67550
67551
67552
67553 public function __toString()
67554 {
67555 return $this->join();
67556 }
67557
67558
67559
67560
67561
67562
67563
67564
67565 public static function create(Command $parent = null)
67566 {
67567 return new self($parent);
67568 }
67569
67570
67571
67572
67573
67574
67575
67576
67577 public static function escape($input)
67578 {
67579 return escapeshellcmd($input);
67580 }
67581
67582
67583
67584
67585
67586
67587
67588
67589 public static function quote($input)
67590 {
67591 return escapeshellarg($input);
67592 }
67593
67594
67595
67596
67597
67598
67599
67600
67601 public function add($bit)
67602 {
67603 $this->bits[] = $bit;
67604
67605 return $this;
67606 }
67607
67608
67609
67610
67611
67612
67613
67614
67615 public function top($bit)
67616 {
67617 array_unshift($this->bits, $bit);
67618
67619 foreach ($this->labels as $label => $index) {
67620 $this->labels[$label] += 1;
67621 }
67622
67623 return $this;
67624 }
67625
67626
67627
67628
67629
67630
67631
67632
67633 public function arg($arg)
67634 {
67635 $this->bits[] = self::quote($arg);
67636
67637 return $this;
67638 }
67639
67640
67641
67642
67643
67644
67645
67646
67647 public function cmd($esc)
67648 {
67649 $this->bits[] = self::escape($esc);
67650
67651 return $this;
67652 }
67653
67654
67655
67656
67657
67658
67659
67660
67661
67662
67663 public function ins($label)
67664 {
67665 if (isset($this->labels[$label])) {
67666 throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
67667 }
67668
67669 $this->bits[] = self::create($this);
67670 $this->labels[$label] = count($this->bits) - 1;
67671
67672 return $this->bits[$this->labels[$label]];
67673 }
67674
67675
67676
67677
67678
67679
67680
67681
67682
67683
67684 public function get($label)
67685 {
67686 if (!isset($this->labels[$label])) {
67687 throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
67688 }
67689
67690 return $this->bits[$this->labels[$label]];
67691 }
67692
67693
67694
67695
67696
67697
67698
67699
67700 public function end()
67701 {
67702 if (null === $this->parent) {
67703 throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
67704 }
67705
67706 return $this->parent;
67707 }
67708
67709
67710
67711
67712
67713
67714 public function length()
67715 {
67716 return count($this->bits);
67717 }
67718
67719
67720
67721
67722
67723
67724 public function setErrorHandler(\Closure $errorHandler)
67725 {
67726 $this->errorHandler = $errorHandler;
67727
67728 return $this;
67729 }
67730
67731
67732
67733
67734 public function getErrorHandler()
67735 {
67736 return $this->errorHandler;
67737 }
67738
67739
67740
67741
67742
67743
67744
67745
67746 public function execute()
67747 {
67748 if (null === $errorHandler = $this->errorHandler) {
67749 exec($this->join(), $output);
67750 } else {
67751 $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
67752 $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);
67753
67754 if ($error = stream_get_contents($pipes[2])) {
67755 $errorHandler($error);
67756 }
67757
67758 proc_close($process);
67759 }
67760
67761 return $output ?: array();
67762 }
67763
67764
67765
67766
67767
67768
67769 public function join()
67770 {
67771 return implode(' ', array_filter(
67772 array_map(function ($bit) {
67773 return $bit instanceof Command ? $bit->join() : ($bit ?: null);
67774 }, $this->bits),
67775 function ($bit) { return null !== $bit; }
67776 ));
67777 }
67778
67779
67780
67781
67782
67783
67784
67785
67786
67787 public function addAtIndex($bit, $index)
67788 {
67789 array_splice($this->bits, $index, 0, $bit instanceof self ? array($bit) : $bit);
67790
67791 return $this;
67792 }
67793 }
67794 <?php
67795
67796
67797
67798
67799
67800
67801
67802
67803
67804
67805 namespace Symfony\Component\Finder\Shell;
67806
67807 @trigger_error('The '.__NAMESPACE__.'\Shell class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
67808
67809
67810
67811
67812
67813
67814 class Shell
67815 {
67816 const TYPE_UNIX = 1;
67817 const TYPE_DARWIN = 2;
67818 const TYPE_CYGWIN = 3;
67819 const TYPE_WINDOWS = 4;
67820 const TYPE_BSD = 5;
67821
67822
67823
67824
67825 private $type;
67826
67827
67828
67829
67830
67831
67832 public function getType()
67833 {
67834 if (null === $this->type) {
67835 $this->type = $this->guessType();
67836 }
67837
67838 return $this->type;
67839 }
67840
67841
67842
67843
67844
67845
67846
67847
67848 public function testCommand($command)
67849 {
67850 if (!function_exists('exec')) {
67851 return false;
67852 }
67853
67854
67855  $testCommand = 'which ';
67856 if (self::TYPE_WINDOWS === $this->type) {
67857 $testCommand = 'where ';
67858 }
67859
67860 $command = escapeshellcmd($command);
67861
67862 exec($testCommand.$command, $output, $code);
67863
67864 return 0 === $code && count($output) > 0;
67865 }
67866
67867
67868
67869
67870
67871
67872 private function guessType()
67873 {
67874 $os = strtolower(PHP_OS);
67875
67876 if (false !== strpos($os, 'cygwin')) {
67877 return self::TYPE_CYGWIN;
67878 }
67879
67880 if (false !== strpos($os, 'darwin')) {
67881 return self::TYPE_DARWIN;
67882 }
67883
67884 if (false !== strpos($os, 'bsd')) {
67885 return self::TYPE_BSD;
67886 }
67887
67888 if (0 === strpos($os, 'win')) {
67889 return self::TYPE_WINDOWS;
67890 }
67891
67892 return self::TYPE_UNIX;
67893 }
67894 }
67895 <?php
67896
67897
67898
67899
67900
67901
67902
67903
67904
67905
67906 namespace Symfony\Component\Finder;
67907
67908
67909
67910
67911
67912
67913 class SplFileInfo extends \SplFileInfo
67914 {
67915 private $relativePath;
67916 private $relativePathname;
67917
67918
67919
67920
67921
67922
67923
67924
67925 public function __construct($file, $relativePath, $relativePathname)
67926 {
67927 parent::__construct($file);
67928 $this->relativePath = $relativePath;
67929 $this->relativePathname = $relativePathname;
67930 }
67931
67932
67933
67934
67935
67936
67937
67938
67939 public function getRelativePath()
67940 {
67941 return $this->relativePath;
67942 }
67943
67944
67945
67946
67947
67948
67949
67950
67951 public function getRelativePathname()
67952 {
67953 return $this->relativePathname;
67954 }
67955
67956
67957
67958
67959
67960
67961
67962
67963 public function getContents()
67964 {
67965 $level = error_reporting(0);
67966 $content = file_get_contents($this->getPathname());
67967 error_reporting($level);
67968 if (false === $content) {
67969 $error = error_get_last();
67970 throw new \RuntimeException($error['message']);
67971 }
67972
67973 return $content;
67974 }
67975 }
67976 Copyright (c) 2014-2016 Fabien Potencier
67977
67978 Permission is hereby granted, free of charge, to any person obtaining a copy
67979 of this software and associated documentation files (the "Software"), to deal
67980 in the Software without restriction, including without limitation the rights
67981 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
67982 copies of the Software, and to permit persons to whom the Software is furnished
67983 to do so, subject to the following conditions:
67984
67985 The above copyright notice and this permission notice shall be included in all
67986 copies or substantial portions of the Software.
67987
67988 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
67989 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67990 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
67991 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67992 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67993 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
67994 THE SOFTWARE.
67995 <?php
67996
67997
67998
67999
68000
68001
68002
68003
68004
68005
68006 namespace Symfony\Polyfill\Mbstring;
68007
68008
68009
68010
68011
68012
68013
68014
68015
68016
68017
68018
68019
68020
68021
68022
68023
68024
68025
68026
68027
68028
68029
68030
68031
68032
68033
68034
68035
68036
68037
68038
68039
68040
68041
68042
68043
68044
68045
68046
68047
68048
68049
68050
68051
68052
68053
68054
68055
68056
68057
68058
68059
68060 final class Mbstring
68061 {
68062 const MB_CASE_FOLD = PHP_INT_MAX;
68063
68064 private static $encodingList = array('ASCII', 'UTF-8');
68065 private static $language = 'neutral';
68066 private static $internalEncoding = 'UTF-8';
68067 private static $caseFold = array(
68068 array('µ','ſ',"\xCD\x85",'ς',"\xCF\x90","\xCF\x91","\xCF\x95","\xCF\x96","\xCF\xB0","\xCF\xB1","\xCF\xB5","\xE1\xBA\x9B","\xE1\xBE\xBE"),
68069 array('μ','s','ι', 'σ','β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1",'ι'),
68070 );
68071
68072 public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
68073 {
68074 if (is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
68075 $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
68076 } else {
68077 $fromEncoding = self::getEncoding($fromEncoding);
68078 }
68079
68080 $toEncoding = self::getEncoding($toEncoding);
68081
68082 if ('BASE64' === $fromEncoding) {
68083 $s = base64_decode($s);
68084 $fromEncoding = $toEncoding;
68085 }
68086
68087 if ('BASE64' === $toEncoding) {
68088 return base64_encode($s);
68089 }
68090
68091 if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
68092 if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
68093 $fromEncoding = 'Windows-1252';
68094 }
68095 if ('UTF-8' !== $fromEncoding) {
68096 $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
68097 }
68098
68099 return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
68100 }
68101
68102 if ('HTML-ENTITIES' === $fromEncoding) {
68103 $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
68104 $fromEncoding = 'UTF-8';
68105 }
68106
68107 return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
68108 }
68109
68110 public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
68111 {
68112 $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
68113
68114 $ok = true;
68115 array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
68116 if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
68117 $ok = false;
68118 }
68119 });
68120
68121 return $ok ? $fromEncoding : false;
68122 }
68123
68124 public static function mb_decode_mimeheader($s)
68125 {
68126 return iconv_mime_decode($s, 2, self::$internalEncoding);
68127 }
68128
68129 public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
68130 {
68131 trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
68132 }
68133
68134 public static function mb_convert_case($s, $mode, $encoding = null)
68135 {
68136 if ('' === $s .= '') {
68137 return '';
68138 }
68139
68140 $encoding = self::getEncoding($encoding);
68141
68142 if ('UTF-8' === $encoding) {
68143 $encoding = null;
68144 } else {
68145 $s = iconv($encoding, 'UTF-8//IGNORE', $s);
68146 }
68147
68148 if (MB_CASE_TITLE == $mode) {
68149 $s = preg_replace_callback('/\b\p{Ll}/u', array(__CLASS__, 'title_case_upper'), $s);
68150 $s = preg_replace_callback('/\B[\p{Lu}\p{Lt}]+/u', array(__CLASS__, 'title_case_lower'), $s);
68151 } else {
68152 if (MB_CASE_UPPER == $mode) {
68153 static $upper = null;
68154 if (null === $upper) {
68155 $upper = self::getData('upperCase');
68156 }
68157 $map = $upper;
68158 } else {
68159 if (self::MB_CASE_FOLD === $mode) {
68160 $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
68161 }
68162
68163 static $lower = null;
68164 if (null === $lower) {
68165 $lower = self::getData('lowerCase');
68166 }
68167 $map = $lower;
68168 }
68169
68170 static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
68171
68172 $i = 0;
68173 $len = strlen($s);
68174
68175 while ($i < $len) {
68176 $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
68177 $uchr = substr($s, $i, $ulen);
68178 $i += $ulen;
68179
68180 if (isset($map[$uchr])) {
68181 $uchr = $map[$uchr];
68182 $nlen = strlen($uchr);
68183
68184 if ($nlen == $ulen) {
68185 $nlen = $i;
68186 do {
68187 $s[--$nlen] = $uchr[--$ulen];
68188 } while ($ulen);
68189 } else {
68190 $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
68191 $len += $nlen - $ulen;
68192 $i += $nlen - $ulen;
68193 }
68194 }
68195 }
68196 }
68197
68198 if (null === $encoding) {
68199 return $s;
68200 }
68201
68202 return iconv('UTF-8', $encoding.'//IGNORE', $s);
68203 }
68204
68205 public static function mb_internal_encoding($encoding = null)
68206 {
68207 if (null === $encoding) {
68208 return self::$internalEncoding;
68209 }
68210
68211 $encoding = self::getEncoding($encoding);
68212
68213 if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
68214 self::$internalEncoding = $encoding;
68215
68216 return true;
68217 }
68218
68219 return false;
68220 }
68221
68222 public static function mb_language($lang = null)
68223 {
68224 if (null === $lang) {
68225 return self::$language;
68226 }
68227
68228 switch ($lang = strtolower($lang)) {
68229 case 'uni':
68230 case 'neutral':
68231 self::$language = $lang;
68232
68233 return true;
68234 }
68235
68236 return false;
68237 }
68238
68239 public static function mb_list_encodings()
68240 {
68241 return array('UTF-8');
68242 }
68243
68244 public static function mb_encoding_aliases($encoding)
68245 {
68246 switch (strtoupper($encoding)) {
68247 case 'UTF8':
68248 case 'UTF-8':
68249 return array('utf8');
68250 }
68251
68252 return false;
68253 }
68254
68255 public static function mb_check_encoding($var = null, $encoding = null)
68256 {
68257 if (null === $encoding) {
68258 if (null === $var) {
68259 return false;
68260 }
68261 $encoding = self::$internalEncoding;
68262 }
68263
68264 return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
68265 }
68266
68267 public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
68268 {
68269 if (null === $encodingList) {
68270 $encodingList = self::$encodingList;
68271 } else {
68272 if (!is_array($encodingList)) {
68273 $encodingList = array_map('trim', explode(',', $encodingList));
68274 }
68275 $encodingList = array_map('strtoupper', $encodingList);
68276 }
68277
68278 foreach ($encodingList as $enc) {
68279 switch ($enc) {
68280 case 'ASCII':
68281 if (!preg_match('/[\x80-\xFF]/', $str)) {
68282 return $enc;
68283 }
68284 break;
68285
68286 case 'UTF8':
68287 case 'UTF-8':
68288 if (preg_match('//u', $str)) {
68289 return 'UTF-8';
68290 }
68291 break;
68292
68293 default:
68294 if (0 === strncmp($enc, 'ISO-8859-', 9)) {
68295 return $enc;
68296 }
68297 }
68298 }
68299
68300 return false;
68301 }
68302
68303 public static function mb_detect_order($encodingList = null)
68304 {
68305 if (null === $encodingList) {
68306 return self::$encodingList;
68307 }
68308
68309 if (!is_array($encodingList)) {
68310 $encodingList = array_map('trim', explode(',', $encodingList));
68311 }
68312 $encodingList = array_map('strtoupper', $encodingList);
68313
68314 foreach ($encodingList as $enc) {
68315 switch ($enc) {
68316 default:
68317 if (strncmp($enc, 'ISO-8859-', 9)) {
68318 return false;
68319 }
68320 case 'ASCII':
68321 case 'UTF8':
68322 case 'UTF-8':
68323 }
68324 }
68325
68326 self::$encodingList = $encodingList;
68327
68328 return true;
68329 }
68330
68331 public static function mb_strlen($s, $encoding = null)
68332 {
68333 switch ($encoding = self::getEncoding($encoding)) {
68334 case 'ASCII':
68335 case 'CP850':
68336 return strlen($s);
68337 }
68338
68339 return @iconv_strlen($s, $encoding);
68340 }
68341
68342 public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
68343 {
68344 $encoding = self::getEncoding($encoding);
68345
68346 if ('' === $needle .= '') {
68347 trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
68348
68349 return false;
68350 }
68351
68352 return iconv_strpos($haystack, $needle, $offset, $encoding);
68353 }
68354
68355 public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
68356 {
68357 $encoding = self::getEncoding($encoding);
68358
68359 if ($offset != (int) $offset) {
68360 $offset = 0;
68361 } elseif ($offset = (int) $offset) {
68362 if ($offset < 0) {
68363 $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
68364 $offset = 0;
68365 } else {
68366 $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
68367 }
68368 }
68369
68370 $pos = iconv_strrpos($haystack, $needle, $encoding);
68371
68372 return false !== $pos ? $offset + $pos : false;
68373 }
68374
68375 public static function mb_strtolower($s, $encoding = null)
68376 {
68377 return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
68378 }
68379
68380 public static function mb_strtoupper($s, $encoding = null)
68381 {
68382 return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
68383 }
68384
68385 public static function mb_substitute_character($c = null)
68386 {
68387 if (0 === strcasecmp($c, 'none')) {
68388 return true;
68389 }
68390
68391 return null !== $c ? false : 'none';
68392 }
68393
68394 public static function mb_substr($s, $start, $length = null, $encoding = null)
68395 {
68396 $encoding = self::getEncoding($encoding);
68397
68398 if ($start < 0) {
68399 $start = iconv_strlen($s, $encoding) + $start;
68400 if ($start < 0) {
68401 $start = 0;
68402 }
68403 }
68404
68405 if (null === $length) {
68406 $length = 2147483647;
68407 } elseif ($length < 0) {
68408 $length = iconv_strlen($s, $encoding) + $length - $start;
68409 if ($length < 0) {
68410 return '';
68411 }
68412 }
68413
68414 return iconv_substr($s, $start, $length, $encoding).'';
68415 }
68416
68417 public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
68418 {
68419 $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
68420 $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
68421
68422 return self::mb_strpos($haystack, $needle, $offset, $encoding);
68423 }
68424
68425 public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
68426 {
68427 $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
68428
68429 return self::getSubpart($pos, $part, $haystack, $encoding);
68430 }
68431
68432 public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
68433 {
68434 $encoding = self::getEncoding($encoding);
68435 $needle = self::mb_substr($needle, 0, 1, $encoding);
68436 $pos = iconv_strrpos($haystack, $needle, $encoding);
68437
68438 return self::getSubpart($pos, $part, $haystack, $encoding);
68439 }
68440
68441 public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
68442 {
68443 $needle = self::mb_substr($needle, 0, 1, $encoding);
68444 $pos = self::mb_strripos($haystack, $needle, $encoding);
68445
68446 return self::getSubpart($pos, $part, $haystack, $encoding);
68447 }
68448
68449 public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
68450 {
68451 $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
68452 $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
68453
68454 return self::mb_strrpos($haystack, $needle, $offset, $encoding);
68455 }
68456
68457 public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
68458 {
68459 $pos = strpos($haystack, $needle);
68460 if (false === $pos) {
68461 return false;
68462 }
68463 if ($part) {
68464 return substr($haystack, 0, $pos);
68465 }
68466
68467 return substr($haystack, $pos);
68468 }
68469
68470 public static function mb_get_info($type = 'all')
68471 {
68472 $info = array(
68473 'internal_encoding' => self::$internalEncoding,
68474 'http_output' => 'pass',
68475 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
68476 'func_overload' => 0,
68477 'func_overload_list' => 'no overload',
68478 'mail_charset' => 'UTF-8',
68479 'mail_header_encoding' => 'BASE64',
68480 'mail_body_encoding' => 'BASE64',
68481 'illegal_chars' => 0,
68482 'encoding_translation' => 'Off',
68483 'language' => self::$language,
68484 'detect_order' => self::$encodingList,
68485 'substitute_character' => 'none',
68486 'strict_detection' => 'Off',
68487 );
68488
68489 if ('all' === $type) {
68490 return $info;
68491 }
68492 if (isset($info[$type])) {
68493 return $info[$type];
68494 }
68495
68496 return false;
68497 }
68498
68499 public static function mb_http_input($type = '')
68500 {
68501 return false;
68502 }
68503
68504 public static function mb_http_output($encoding = null)
68505 {
68506 return null !== $encoding ? 'pass' === $encoding : 'pass';
68507 }
68508
68509 public static function mb_strwidth($s, $encoding = null)
68510 {
68511 $encoding = self::getEncoding($encoding);
68512
68513 if ('UTF-8' !== $encoding) {
68514 $s = iconv($encoding, 'UTF-8//IGNORE', $s);
68515 }
68516
68517 $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);
68518
68519 return ($wide << 1) + iconv_strlen($s, 'UTF-8');
68520 }
68521
68522 public static function mb_substr_count($haystack, $needle, $encoding = null)
68523 {
68524 return substr_count($haystack, $needle);
68525 }
68526
68527 public static function mb_output_handler($contents, $status)
68528 {
68529 return $contents;
68530 }
68531
68532 public static function mb_chr($code, $encoding = null)
68533 {
68534 if (0x80 > $code %= 0x200000) {
68535 $s = chr($code);
68536 } elseif (0x800 > $code) {
68537 $s = chr(0xC0 | $code >> 6).chr(0x80 | $code & 0x3F);
68538 } elseif (0x10000 > $code) {
68539 $s = chr(0xE0 | $code >> 12).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F);
68540 } else {
68541 $s = chr(0xF0 | $code >> 18).chr(0x80 | $code >> 12 & 0x3F).chr(0x80 | $code >> 6 & 0x3F).chr(0x80 | $code & 0x3F);
68542 }
68543
68544 if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
68545 $s = mb_convert_encoding($s, $encoding, 'UTF-8');
68546 }
68547
68548 return $s;
68549 }
68550
68551 public static function mb_ord($s, $encoding = null)
68552 {
68553 if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
68554 $s = mb_convert_encoding($s, 'UTF-8', $encoding);
68555 }
68556
68557 $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
68558 if (0xF0 <= $code) {
68559 return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
68560 }
68561 if (0xE0 <= $code) {
68562 return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
68563 }
68564 if (0xC0 <= $code) {
68565 return (($code - 0xC0) << 6) + $s[2] - 0x80;
68566 }
68567
68568 return $code;
68569 }
68570
68571 private static function getSubpart($pos, $part, $haystack, $encoding)
68572 {
68573 if (false === $pos) {
68574 return false;
68575 }
68576 if ($part) {
68577 return self::mb_substr($haystack, 0, $pos, $encoding);
68578 }
68579
68580 return self::mb_substr($haystack, $pos, null, $encoding);
68581 }
68582
68583 private static function html_encoding_callback($m)
68584 {
68585 $i = 1;
68586 $entities = '';
68587 $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
68588
68589 while (isset($m[$i])) {
68590 if (0x80 > $m[$i]) {
68591 $entities .= chr($m[$i++]);
68592 continue;
68593 }
68594 if (0xF0 <= $m[$i]) {
68595 $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
68596 } elseif (0xE0 <= $m[$i]) {
68597 $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
68598 } else {
68599 $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
68600 }
68601
68602 $entities .= '&#'.$c.';';
68603 }
68604
68605 return $entities;
68606 }
68607
68608 private static function title_case_lower($s)
68609 {
68610 return self::mb_convert_case($s[0], MB_CASE_LOWER, 'UTF-8');
68611 }
68612
68613 private static function title_case_upper($s)
68614 {
68615 return self::mb_convert_case($s[0], MB_CASE_UPPER, 'UTF-8');
68616 }
68617
68618 private static function getData($file)
68619 {
68620 if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
68621 return require $file;
68622 }
68623
68624 return false;
68625 }
68626
68627 private static function getEncoding($encoding)
68628 {
68629 if (null === $encoding) {
68630 return self::$internalEncoding;
68631 }
68632
68633 $encoding = strtoupper($encoding);
68634
68635 if ('8BIT' === $encoding || 'BINARY' === $encoding) {
68636 return 'CP850';
68637 }
68638 if ('UTF8' === $encoding) {
68639 return 'UTF-8';
68640 }
68641
68642 return $encoding;
68643 }
68644 }
68645 <?php
68646
68647 static $data = array (
68648 'A' => 'a',
68649 'B' => 'b',
68650 'C' => 'c',
68651 'D' => 'd',
68652 'E' => 'e',
68653 'F' => 'f',
68654 'G' => 'g',
68655 'H' => 'h',
68656 'I' => 'i',
68657 'J' => 'j',
68658 'K' => 'k',
68659 'L' => 'l',
68660 'M' => 'm',
68661 'N' => 'n',
68662 'O' => 'o',
68663 'P' => 'p',
68664 'Q' => 'q',
68665 'R' => 'r',
68666 'S' => 's',
68667 'T' => 't',
68668 'U' => 'u',
68669 'V' => 'v',
68670 'W' => 'w',
68671 'X' => 'x',
68672 'Y' => 'y',
68673 'Z' => 'z',
68674 'À' => 'à',
68675 'Á' => 'á',
68676 'Â' => 'â',
68677 'Ã' => 'ã',
68678 'Ä' => 'ä',
68679 'Å' => 'å',
68680 'Æ' => 'æ',
68681 'Ç' => 'ç',
68682 'È' => 'è',
68683 'É' => 'é',
68684 'Ê' => 'ê',
68685 'Ë' => 'ë',
68686 'Ì' => 'ì',
68687 'Í' => 'í',
68688 'Î' => 'î',
68689 'Ï' => 'ï',
68690 'Ð' => 'ð',
68691 'Ñ' => 'ñ',
68692 'Ò' => 'ò',
68693 'Ó' => 'ó',
68694 'Ô' => 'ô',
68695 'Õ' => 'õ',
68696 'Ö' => 'ö',
68697 'Ø' => 'ø',
68698 'Ù' => 'ù',
68699 'Ú' => 'ú',
68700 'Û' => 'û',
68701 'Ü' => 'ü',
68702 'Ý' => 'ý',
68703 'Þ' => 'þ',
68704 'Ā' => 'ā',
68705 'Ă' => 'ă',
68706 'Ą' => 'ą',
68707 'Ć' => 'ć',
68708 'Ĉ' => 'ĉ',
68709 'Ċ' => 'ċ',
68710 'Č' => 'č',
68711 'Ď' => 'ď',
68712 'Đ' => 'đ',
68713 'Ē' => 'ē',
68714 'Ĕ' => 'ĕ',
68715 'Ė' => 'ė',
68716 'Ę' => 'ę',
68717 'Ě' => 'ě',
68718 'Ĝ' => 'ĝ',
68719 'Ğ' => 'ğ',
68720 'Ġ' => 'ġ',
68721 'Ģ' => 'ģ',
68722 'Ĥ' => 'ĥ',
68723 'Ħ' => 'ħ',
68724 'Ĩ' => 'ĩ',
68725 'Ī' => 'ī',
68726 'Ĭ' => 'ĭ',
68727 'Į' => 'į',
68728 'İ' => 'i',
68729 'IJ' => 'ij',
68730 'Ĵ' => 'ĵ',
68731 'Ķ' => 'ķ',
68732 'Ĺ' => 'ĺ',
68733 'Ļ' => 'ļ',
68734 'Ľ' => 'ľ',
68735 'Ŀ' => 'ŀ',
68736 'Ł' => 'ł',
68737 'Ń' => 'ń',
68738 'Ņ' => 'ņ',
68739 'Ň' => 'ň',
68740 'Ŋ' => 'ŋ',
68741 'Ō' => 'ō',
68742 'Ŏ' => 'ŏ',
68743 'Ő' => 'ő',
68744 'Œ' => 'œ',
68745 'Ŕ' => 'ŕ',
68746 'Ŗ' => 'ŗ',
68747 'Ř' => 'ř',
68748 'Ś' => 'ś',
68749 'Ŝ' => 'ŝ',
68750 'Ş' => 'ş',
68751 'Š' => 'š',
68752 'Ţ' => 'ţ',
68753 'Ť' => 'ť',
68754 'Ŧ' => 'ŧ',
68755 'Ũ' => 'ũ',
68756 'Ū' => 'ū',
68757 'Ŭ' => 'ŭ',
68758 'Ů' => 'ů',
68759 'Ű' => 'ű',
68760 'Ų' => 'ų',
68761 'Ŵ' => 'ŵ',
68762 'Ŷ' => 'ŷ',
68763 'Ÿ' => 'ÿ',
68764 'Ź' => 'ź',
68765 'Ż' => 'ż',
68766 'Ž' => 'ž',
68767 'Ɓ' => 'ɓ',
68768 'Ƃ' => 'ƃ',
68769 'Ƅ' => 'ƅ',
68770 'Ɔ' => 'ɔ',
68771 'Ƈ' => 'ƈ',
68772 'Ɖ' => 'ɖ',
68773 'Ɗ' => 'ɗ',
68774 'Ƌ' => 'ƌ',
68775 'Ǝ' => 'ǝ',
68776 'Ə' => 'ə',
68777 'Ɛ' => 'ɛ',
68778 'Ƒ' => 'ƒ',
68779 'Ɠ' => 'ɠ',
68780 'Ɣ' => 'ɣ',
68781 'Ɩ' => 'ɩ',
68782 'Ɨ' => 'ɨ',
68783 'Ƙ' => 'ƙ',
68784 'Ɯ' => 'ɯ',
68785 'Ɲ' => 'ɲ',
68786 'Ɵ' => 'ɵ',
68787 'Ơ' => 'ơ',
68788 'Ƣ' => 'ƣ',
68789 'Ƥ' => 'ƥ',
68790 'Ʀ' => 'ʀ',
68791 'Ƨ' => 'ƨ',
68792 'Ʃ' => 'ʃ',
68793 'Ƭ' => 'ƭ',
68794 'Ʈ' => 'ʈ',
68795 'Ư' => 'ư',
68796 'Ʊ' => 'ʊ',
68797 'Ʋ' => 'ʋ',
68798 'Ƴ' => 'ƴ',
68799 'Ƶ' => 'ƶ',
68800 'Ʒ' => 'ʒ',
68801 'Ƹ' => 'ƹ',
68802 'Ƽ' => 'ƽ',
68803 'DŽ' => 'dž',
68804 'Dž' => 'dž',
68805 'LJ' => 'lj',
68806 'Lj' => 'lj',
68807 'NJ' => 'nj',
68808 'Nj' => 'nj',
68809 'Ǎ' => 'ǎ',
68810 'Ǐ' => 'ǐ',
68811 'Ǒ' => 'ǒ',
68812 'Ǔ' => 'ǔ',
68813 'Ǖ' => 'ǖ',
68814 'Ǘ' => 'ǘ',
68815 'Ǚ' => 'ǚ',
68816 'Ǜ' => 'ǜ',
68817 'Ǟ' => 'ǟ',
68818 'Ǡ' => 'ǡ',
68819 'Ǣ' => 'ǣ',
68820 'Ǥ' => 'ǥ',
68821 'Ǧ' => 'ǧ',
68822 'Ǩ' => 'ǩ',
68823 'Ǫ' => 'ǫ',
68824 'Ǭ' => 'ǭ',
68825 'Ǯ' => 'ǯ',
68826 'DZ' => 'dz',
68827 'Dz' => 'dz',
68828 'Ǵ' => 'ǵ',
68829 'Ƕ' => 'ƕ',
68830 'Ƿ' => 'ƿ',
68831 'Ǹ' => 'ǹ',
68832 'Ǻ' => 'ǻ',
68833 'Ǽ' => 'ǽ',
68834 'Ǿ' => 'ǿ',
68835 'Ȁ' => 'ȁ',
68836 'Ȃ' => 'ȃ',
68837 'Ȅ' => 'ȅ',
68838 'Ȇ' => 'ȇ',
68839 'Ȉ' => 'ȉ',
68840 'Ȋ' => 'ȋ',
68841 'Ȍ' => 'ȍ',
68842 'Ȏ' => 'ȏ',
68843 'Ȑ' => 'ȑ',
68844 'Ȓ' => 'ȓ',
68845 'Ȕ' => 'ȕ',
68846 'Ȗ' => 'ȗ',
68847 'Ș' => 'ș',
68848 'Ț' => 'ț',
68849 'Ȝ' => 'ȝ',
68850 'Ȟ' => 'ȟ',
68851 'Ƞ' => 'ƞ',
68852 'Ȣ' => 'ȣ',
68853 'Ȥ' => 'ȥ',
68854 'Ȧ' => 'ȧ',
68855 'Ȩ' => 'ȩ',
68856 'Ȫ' => 'ȫ',
68857 'Ȭ' => 'ȭ',
68858 'Ȯ' => 'ȯ',
68859 'Ȱ' => 'ȱ',
68860 'Ȳ' => 'ȳ',
68861 'Ⱥ' => 'ⱥ',
68862 'Ȼ' => 'ȼ',
68863 'Ƚ' => 'ƚ',
68864 'Ⱦ' => 'ⱦ',
68865 'Ɂ' => 'ɂ',
68866 'Ƀ' => 'ƀ',
68867 'Ʉ' => 'ʉ',
68868 'Ʌ' => 'ʌ',
68869 'Ɇ' => 'ɇ',
68870 'Ɉ' => 'ɉ',
68871 'Ɋ' => 'ɋ',
68872 'Ɍ' => 'ɍ',
68873 'Ɏ' => 'ɏ',
68874 'Ͱ' => 'ͱ',
68875 'Ͳ' => 'ͳ',
68876 'Ͷ' => 'ͷ',
68877 'Ϳ' => 'ϳ',
68878 'Ά' => 'ά',
68879 'Έ' => 'έ',
68880 'Ή' => 'ή',
68881 'Ί' => 'ί',
68882 'Ό' => 'ό',
68883 'Ύ' => 'ύ',
68884 'Ώ' => 'ώ',
68885 'Α' => 'α',
68886 'Β' => 'β',
68887 'Γ' => 'γ',
68888 'Δ' => 'δ',
68889 'Ε' => 'ε',
68890 'Ζ' => 'ζ',
68891 'Η' => 'η',
68892 'Θ' => 'θ',
68893 'Ι' => 'ι',
68894 'Κ' => 'κ',
68895 'Λ' => 'λ',
68896 'Μ' => 'μ',
68897 'Ν' => 'ν',
68898 'Ξ' => 'ξ',
68899 'Ο' => 'ο',
68900 'Π' => 'π',
68901 'Ρ' => 'ρ',
68902 'Σ' => 'σ',
68903 'Τ' => 'τ',
68904 'Υ' => 'υ',
68905 'Φ' => 'φ',
68906 'Χ' => 'χ',
68907 'Ψ' => 'ψ',
68908 'Ω' => 'ω',
68909 'Ϊ' => 'ϊ',
68910 'Ϋ' => 'ϋ',
68911 'Ϗ' => 'ϗ',
68912 'Ϙ' => 'ϙ',
68913 'Ϛ' => 'ϛ',
68914 'Ϝ' => 'ϝ',
68915 'Ϟ' => 'ϟ',
68916 'Ϡ' => 'ϡ',
68917 'Ϣ' => 'ϣ',
68918 'Ϥ' => 'ϥ',
68919 'Ϧ' => 'ϧ',
68920 'Ϩ' => 'ϩ',
68921 'Ϫ' => 'ϫ',
68922 'Ϭ' => 'ϭ',
68923 'Ϯ' => 'ϯ',
68924 'ϴ' => 'θ',
68925 'Ϸ' => 'ϸ',
68926 'Ϲ' => 'ϲ',
68927 'Ϻ' => 'ϻ',
68928 'Ͻ' => 'ͻ',
68929 'Ͼ' => 'ͼ',
68930 'Ͽ' => 'ͽ',
68931 'Ѐ' => 'ѐ',
68932 'Ё' => 'ё',
68933 'Ђ' => 'ђ',
68934 'Ѓ' => 'ѓ',
68935 'Є' => 'є',
68936 'Ѕ' => 'ѕ',
68937 'І' => 'і',
68938 'Ї' => 'ї',
68939 'Ј' => 'ј',
68940 'Љ' => 'љ',
68941 'Њ' => 'њ',
68942 'Ћ' => 'ћ',
68943 'Ќ' => 'ќ',
68944 'Ѝ' => 'ѝ',
68945 'Ў' => 'ў',
68946 'Џ' => 'џ',
68947 'А' => 'а',
68948 'Б' => 'б',
68949 'В' => 'в',
68950 'Г' => 'г',
68951 'Д' => 'д',
68952 'Е' => 'е',
68953 'Ж' => 'ж',
68954 'З' => 'з',
68955 'И' => 'и',
68956 'Й' => 'й',
68957 'К' => 'к',
68958 'Л' => 'л',
68959 'М' => 'м',
68960 'Н' => 'н',
68961 'О' => 'о',
68962 'П' => 'п',
68963 'Р' => 'р',
68964 'С' => 'с',
68965 'Т' => 'т',
68966 'У' => 'у',
68967 'Ф' => 'ф',
68968 'Х' => 'х',
68969 'Ц' => 'ц',
68970 'Ч' => 'ч',
68971 'Ш' => 'ш',
68972 'Щ' => 'щ',
68973 'Ъ' => 'ъ',
68974 'Ы' => 'ы',
68975 'Ь' => 'ь',
68976 'Э' => 'э',
68977 'Ю' => 'ю',
68978 'Я' => 'я',
68979 'Ѡ' => 'ѡ',
68980 'Ѣ' => 'ѣ',
68981 'Ѥ' => 'ѥ',
68982 'Ѧ' => 'ѧ',
68983 'Ѩ' => 'ѩ',
68984 'Ѫ' => 'ѫ',
68985 'Ѭ' => 'ѭ',
68986 'Ѯ' => 'ѯ',
68987 'Ѱ' => 'ѱ',
68988 'Ѳ' => 'ѳ',
68989 'Ѵ' => 'ѵ',
68990 'Ѷ' => 'ѷ',
68991 'Ѹ' => 'ѹ',
68992 'Ѻ' => 'ѻ',
68993 'Ѽ' => 'ѽ',
68994 'Ѿ' => 'ѿ',
68995 'Ҁ' => 'ҁ',
68996 'Ҋ' => 'ҋ',
68997 'Ҍ' => 'ҍ',
68998 'Ҏ' => 'ҏ',
68999 'Ґ' => 'ґ',
69000 'Ғ' => 'ғ',
69001 'Ҕ' => 'ҕ',
69002 'Җ' => 'җ',
69003 'Ҙ' => 'ҙ',
69004 'Қ' => 'қ',
69005 'Ҝ' => 'ҝ',
69006 'Ҟ' => 'ҟ',
69007 'Ҡ' => 'ҡ',
69008 'Ң' => 'ң',
69009 'Ҥ' => 'ҥ',
69010 'Ҧ' => 'ҧ',
69011 'Ҩ' => 'ҩ',
69012 'Ҫ' => 'ҫ',
69013 'Ҭ' => 'ҭ',
69014 'Ү' => 'ү',
69015 'Ұ' => 'ұ',
69016 'Ҳ' => 'ҳ',
69017 'Ҵ' => 'ҵ',
69018 'Ҷ' => 'ҷ',
69019 'Ҹ' => 'ҹ',
69020 'Һ' => 'һ',
69021 'Ҽ' => 'ҽ',
69022 'Ҿ' => 'ҿ',
69023 'Ӏ' => 'ӏ',
69024 'Ӂ' => 'ӂ',
69025 'Ӄ' => 'ӄ',
69026 'Ӆ' => 'ӆ',
69027 'Ӈ' => 'ӈ',
69028 'Ӊ' => 'ӊ',
69029 'Ӌ' => 'ӌ',
69030 'Ӎ' => 'ӎ',
69031 'Ӑ' => 'ӑ',
69032 'Ӓ' => 'ӓ',
69033 'Ӕ' => 'ӕ',
69034 'Ӗ' => 'ӗ',
69035 'Ә' => 'ә',
69036 'Ӛ' => 'ӛ',
69037 'Ӝ' => 'ӝ',
69038 'Ӟ' => 'ӟ',
69039 'Ӡ' => 'ӡ',
69040 'Ӣ' => 'ӣ',
69041 'Ӥ' => 'ӥ',
69042 'Ӧ' => 'ӧ',
69043 'Ө' => 'ө',
69044 'Ӫ' => 'ӫ',
69045 'Ӭ' => 'ӭ',
69046 'Ӯ' => 'ӯ',
69047 'Ӱ' => 'ӱ',
69048 'Ӳ' => 'ӳ',
69049 'Ӵ' => 'ӵ',
69050 'Ӷ' => 'ӷ',
69051 'Ӹ' => 'ӹ',
69052 'Ӻ' => 'ӻ',
69053 'Ӽ' => 'ӽ',
69054 'Ӿ' => 'ӿ',
69055 'Ԁ' => 'ԁ',
69056 'Ԃ' => 'ԃ',
69057 'Ԅ' => 'ԅ',
69058 'Ԇ' => 'ԇ',
69059 'Ԉ' => 'ԉ',
69060 'Ԋ' => 'ԋ',
69061 'Ԍ' => 'ԍ',
69062 'Ԏ' => 'ԏ',
69063 'Ԑ' => 'ԑ',
69064 'Ԓ' => 'ԓ',
69065 'Ԕ' => 'ԕ',
69066 'Ԗ' => 'ԗ',
69067 'Ԙ' => 'ԙ',
69068 'Ԛ' => 'ԛ',
69069 'Ԝ' => 'ԝ',
69070 'Ԟ' => 'ԟ',
69071 'Ԡ' => 'ԡ',
69072 'Ԣ' => 'ԣ',
69073 'Ԥ' => 'ԥ',
69074 'Ԧ' => 'ԧ',
69075 'Ԩ' => 'ԩ',
69076 'Ԫ' => 'ԫ',
69077 'Ԭ' => 'ԭ',
69078 'Ԯ' => 'ԯ',
69079 'Ա' => 'ա',
69080 'Բ' => 'բ',
69081 'Գ' => 'գ',
69082 'Դ' => 'դ',
69083 'Ե' => 'ե',
69084 'Զ' => 'զ',
69085 'Է' => 'է',
69086 'Ը' => 'ը',
69087 'Թ' => 'թ',
69088 'Ժ' => 'ժ',
69089 'Ի' => 'ի',
69090 'Լ' => 'լ',
69091 'Խ' => 'խ',
69092 'Ծ' => 'ծ',
69093 'Կ' => 'կ',
69094 'Հ' => 'հ',
69095 'Ձ' => 'ձ',
69096 'Ղ' => 'ղ',
69097 'Ճ' => 'ճ',
69098 'Մ' => 'մ',
69099 'Յ' => 'յ',
69100 'Ն' => 'ն',
69101 'Շ' => 'շ',
69102 'Ո' => 'ո',
69103 'Չ' => 'չ',
69104 'Պ' => 'պ',
69105 'Ջ' => 'ջ',
69106 'Ռ' => 'ռ',
69107 'Ս' => 'ս',
69108 'Վ' => 'վ',
69109 'Տ' => 'տ',
69110 'Ր' => 'ր',
69111 'Ց' => 'ց',
69112 'Ւ' => 'ւ',
69113 'Փ' => 'փ',
69114 'Ք' => 'ք',
69115 'Օ' => 'օ',
69116 'Ֆ' => 'ֆ',
69117 'Ⴀ' => 'ⴀ',
69118 'Ⴁ' => 'ⴁ',
69119 'Ⴂ' => 'ⴂ',
69120 'Ⴃ' => 'ⴃ',
69121 'Ⴄ' => 'ⴄ',
69122 'Ⴅ' => 'ⴅ',
69123 'Ⴆ' => 'ⴆ',
69124 'Ⴇ' => 'ⴇ',
69125 'Ⴈ' => 'ⴈ',
69126 'Ⴉ' => 'ⴉ',
69127 'Ⴊ' => 'ⴊ',
69128 'Ⴋ' => 'ⴋ',
69129 'Ⴌ' => 'ⴌ',
69130 'Ⴍ' => 'ⴍ',
69131 'Ⴎ' => 'ⴎ',
69132 'Ⴏ' => 'ⴏ',
69133 'Ⴐ' => 'ⴐ',
69134 'Ⴑ' => 'ⴑ',
69135 'Ⴒ' => 'ⴒ',
69136 'Ⴓ' => 'ⴓ',
69137 'Ⴔ' => 'ⴔ',
69138 'Ⴕ' => 'ⴕ',
69139 'Ⴖ' => 'ⴖ',
69140 'Ⴗ' => 'ⴗ',
69141 'Ⴘ' => 'ⴘ',
69142 'Ⴙ' => 'ⴙ',
69143 'Ⴚ' => 'ⴚ',
69144 'Ⴛ' => 'ⴛ',
69145 'Ⴜ' => 'ⴜ',
69146 'Ⴝ' => 'ⴝ',
69147 'Ⴞ' => 'ⴞ',
69148 'Ⴟ' => 'ⴟ',
69149 'Ⴠ' => 'ⴠ',
69150 'Ⴡ' => 'ⴡ',
69151 'Ⴢ' => 'ⴢ',
69152 'Ⴣ' => 'ⴣ',
69153 'Ⴤ' => 'ⴤ',
69154 'Ⴥ' => 'ⴥ',
69155 'Ⴧ' => 'ⴧ',
69156 'Ⴭ' => 'ⴭ',
69157 'Ḁ' => 'ḁ',
69158 'Ḃ' => 'ḃ',
69159 'Ḅ' => 'ḅ',
69160 'Ḇ' => 'ḇ',
69161 'Ḉ' => 'ḉ',
69162 'Ḋ' => 'ḋ',
69163 'Ḍ' => 'ḍ',
69164 'Ḏ' => 'ḏ',
69165 'Ḑ' => 'ḑ',
69166 'Ḓ' => 'ḓ',
69167 'Ḕ' => 'ḕ',
69168 'Ḗ' => 'ḗ',
69169 'Ḙ' => 'ḙ',
69170 'Ḛ' => 'ḛ',
69171 'Ḝ' => 'ḝ',
69172 'Ḟ' => 'ḟ',
69173 'Ḡ' => 'ḡ',
69174 'Ḣ' => 'ḣ',
69175 'Ḥ' => 'ḥ',
69176 'Ḧ' => 'ḧ',
69177 'Ḩ' => 'ḩ',
69178 'Ḫ' => 'ḫ',
69179 'Ḭ' => 'ḭ',
69180 'Ḯ' => 'ḯ',
69181 'Ḱ' => 'ḱ',
69182 'Ḳ' => 'ḳ',
69183 'Ḵ' => 'ḵ',
69184 'Ḷ' => 'ḷ',
69185 'Ḹ' => 'ḹ',
69186 'Ḻ' => 'ḻ',
69187 'Ḽ' => 'ḽ',
69188 'Ḿ' => 'ḿ',
69189 'Ṁ' => 'ṁ',
69190 'Ṃ' => 'ṃ',
69191 'Ṅ' => 'ṅ',
69192 'Ṇ' => 'ṇ',
69193 'Ṉ' => 'ṉ',
69194 'Ṋ' => 'ṋ',
69195 'Ṍ' => 'ṍ',
69196 'Ṏ' => 'ṏ',
69197 'Ṑ' => 'ṑ',
69198 'Ṓ' => 'ṓ',
69199 'Ṕ' => 'ṕ',
69200 'Ṗ' => 'ṗ',
69201 'Ṙ' => 'ṙ',
69202 'Ṛ' => 'ṛ',
69203 'Ṝ' => 'ṝ',
69204 'Ṟ' => 'ṟ',
69205 'Ṡ' => 'ṡ',
69206 'Ṣ' => 'ṣ',
69207 'Ṥ' => 'ṥ',
69208 'Ṧ' => 'ṧ',
69209 'Ṩ' => 'ṩ',
69210 'Ṫ' => 'ṫ',
69211 'Ṭ' => 'ṭ',
69212 'Ṯ' => 'ṯ',
69213 'Ṱ' => 'ṱ',
69214 'Ṳ' => 'ṳ',
69215 'Ṵ' => 'ṵ',
69216 'Ṷ' => 'ṷ',
69217 'Ṹ' => 'ṹ',
69218 'Ṻ' => 'ṻ',
69219 'Ṽ' => 'ṽ',
69220 'Ṿ' => 'ṿ',
69221 'Ẁ' => 'ẁ',
69222 'Ẃ' => 'ẃ',
69223 'Ẅ' => 'ẅ',
69224 'Ẇ' => 'ẇ',
69225 'Ẉ' => 'ẉ',
69226 'Ẋ' => 'ẋ',
69227 'Ẍ' => 'ẍ',
69228 'Ẏ' => 'ẏ',
69229 'Ẑ' => 'ẑ',
69230 'Ẓ' => 'ẓ',
69231 'Ẕ' => 'ẕ',
69232 'ẞ' => 'ß',
69233 'Ạ' => 'ạ',
69234 'Ả' => 'ả',
69235 'Ấ' => 'ấ',
69236 'Ầ' => 'ầ',
69237 'Ẩ' => 'ẩ',
69238 'Ẫ' => 'ẫ',
69239 'Ậ' => 'ậ',
69240 'Ắ' => 'ắ',
69241 'Ằ' => 'ằ',
69242 'Ẳ' => 'ẳ',
69243 'Ẵ' => 'ẵ',
69244 'Ặ' => 'ặ',
69245 'Ẹ' => 'ẹ',
69246 'Ẻ' => 'ẻ',
69247 'Ẽ' => 'ẽ',
69248 'Ế' => 'ế',
69249 'Ề' => 'ề',
69250 'Ể' => 'ể',
69251 'Ễ' => 'ễ',
69252 'Ệ' => 'ệ',
69253 'Ỉ' => 'ỉ',
69254 'Ị' => 'ị',
69255 'Ọ' => 'ọ',
69256 'Ỏ' => 'ỏ',
69257 'Ố' => 'ố',
69258 'Ồ' => 'ồ',
69259 'Ổ' => 'ổ',
69260 'Ỗ' => 'ỗ',
69261 'Ộ' => 'ộ',
69262 'Ớ' => 'ớ',
69263 'Ờ' => 'ờ',
69264 'Ở' => 'ở',
69265 'Ỡ' => 'ỡ',
69266 'Ợ' => 'ợ',
69267 'Ụ' => 'ụ',
69268 'Ủ' => 'ủ',
69269 'Ứ' => 'ứ',
69270 'Ừ' => 'ừ',
69271 'Ử' => 'ử',
69272 'Ữ' => 'ữ',
69273 'Ự' => 'ự',
69274 'Ỳ' => 'ỳ',
69275 'Ỵ' => 'ỵ',
69276 'Ỷ' => 'ỷ',
69277 'Ỹ' => 'ỹ',
69278 'Ỻ' => 'ỻ',
69279 'Ỽ' => 'ỽ',
69280 'Ỿ' => 'ỿ',
69281 'Ἀ' => 'ἀ',
69282 'Ἁ' => 'ἁ',
69283 'Ἂ' => 'ἂ',
69284 'Ἃ' => 'ἃ',
69285 'Ἄ' => 'ἄ',
69286 'Ἅ' => 'ἅ',
69287 'Ἆ' => 'ἆ',
69288 'Ἇ' => 'ἇ',
69289 'Ἐ' => 'ἐ',
69290 'Ἑ' => 'ἑ',
69291 'Ἒ' => 'ἒ',
69292 'Ἓ' => 'ἓ',
69293 'Ἔ' => 'ἔ',
69294 'Ἕ' => 'ἕ',
69295 'Ἠ' => 'ἠ',
69296 'Ἡ' => 'ἡ',
69297 'Ἢ' => 'ἢ',
69298 'Ἣ' => 'ἣ',
69299 'Ἤ' => 'ἤ',
69300 'Ἥ' => 'ἥ',
69301 'Ἦ' => 'ἦ',
69302 'Ἧ' => 'ἧ',
69303 'Ἰ' => 'ἰ',
69304 'Ἱ' => 'ἱ',
69305 'Ἲ' => 'ἲ',
69306 'Ἳ' => 'ἳ',
69307 'Ἴ' => 'ἴ',
69308 'Ἵ' => 'ἵ',
69309 'Ἶ' => 'ἶ',
69310 'Ἷ' => 'ἷ',
69311 'Ὀ' => 'ὀ',
69312 'Ὁ' => 'ὁ',
69313 'Ὂ' => 'ὂ',
69314 'Ὃ' => 'ὃ',
69315 'Ὄ' => 'ὄ',
69316 'Ὅ' => 'ὅ',
69317 'Ὑ' => 'ὑ',
69318 'Ὓ' => 'ὓ',
69319 'Ὕ' => 'ὕ',
69320 'Ὗ' => 'ὗ',
69321 'Ὠ' => 'ὠ',
69322 'Ὡ' => 'ὡ',
69323 'Ὢ' => 'ὢ',
69324 'Ὣ' => 'ὣ',
69325 'Ὤ' => 'ὤ',
69326 'Ὥ' => 'ὥ',
69327 'Ὦ' => 'ὦ',
69328 'Ὧ' => 'ὧ',
69329 'ᾈ' => 'ᾀ',
69330 'ᾉ' => 'ᾁ',
69331 'ᾊ' => 'ᾂ',
69332 'ᾋ' => 'ᾃ',
69333 'ᾌ' => 'ᾄ',
69334 'ᾍ' => 'ᾅ',
69335 'ᾎ' => 'ᾆ',
69336 'ᾏ' => 'ᾇ',
69337 'ᾘ' => 'ᾐ',
69338 'ᾙ' => 'ᾑ',
69339 'ᾚ' => 'ᾒ',
69340 'ᾛ' => 'ᾓ',
69341 'ᾜ' => 'ᾔ',
69342 'ᾝ' => 'ᾕ',
69343 'ᾞ' => 'ᾖ',
69344 'ᾟ' => 'ᾗ',
69345 'ᾨ' => 'ᾠ',
69346 'ᾩ' => 'ᾡ',
69347 'ᾪ' => 'ᾢ',
69348 'ᾫ' => 'ᾣ',
69349 'ᾬ' => 'ᾤ',
69350 'ᾭ' => 'ᾥ',
69351 'ᾮ' => 'ᾦ',
69352 'ᾯ' => 'ᾧ',
69353 'Ᾰ' => 'ᾰ',
69354 'Ᾱ' => 'ᾱ',
69355 'Ὰ' => 'ὰ',
69356 'Ά' => 'ά',
69357 'ᾼ' => 'ᾳ',
69358 'Ὲ' => 'ὲ',
69359 'Έ' => 'έ',
69360 'Ὴ' => 'ὴ',
69361 'Ή' => 'ή',
69362 'ῌ' => 'ῃ',
69363 'Ῐ' => 'ῐ',
69364 'Ῑ' => 'ῑ',
69365 'Ὶ' => 'ὶ',
69366 'Ί' => 'ί',
69367 'Ῠ' => 'ῠ',
69368 'Ῡ' => 'ῡ',
69369 'Ὺ' => 'ὺ',
69370 'Ύ' => 'ύ',
69371 'Ῥ' => 'ῥ',
69372 'Ὸ' => 'ὸ',
69373 'Ό' => 'ό',
69374 'Ὼ' => 'ὼ',
69375 'Ώ' => 'ώ',
69376 'ῼ' => 'ῳ',
69377 'Ω' => 'ω',
69378 'K' => 'k',
69379 'Å' => 'å',
69380 'Ⅎ' => 'ⅎ',
69381 'Ⅰ' => 'ⅰ',
69382 'Ⅱ' => 'ⅱ',
69383 'Ⅲ' => 'ⅲ',
69384 'Ⅳ' => 'ⅳ',
69385 'Ⅴ' => 'ⅴ',
69386 'Ⅵ' => 'ⅵ',
69387 'Ⅶ' => 'ⅶ',
69388 'Ⅷ' => 'ⅷ',
69389 'Ⅸ' => 'ⅸ',
69390 'Ⅹ' => 'ⅹ',
69391 'Ⅺ' => 'ⅺ',
69392 'Ⅻ' => 'ⅻ',
69393 'Ⅼ' => 'ⅼ',
69394 'Ⅽ' => 'ⅽ',
69395 'Ⅾ' => 'ⅾ',
69396 'Ⅿ' => 'ⅿ',
69397 'Ↄ' => 'ↄ',
69398 'Ⓐ' => 'ⓐ',
69399 'Ⓑ' => 'ⓑ',
69400 'Ⓒ' => 'ⓒ',
69401 'Ⓓ' => 'ⓓ',
69402 'Ⓔ' => 'ⓔ',
69403 'Ⓕ' => 'ⓕ',
69404 'Ⓖ' => 'ⓖ',
69405 'Ⓗ' => 'ⓗ',
69406 'Ⓘ' => 'ⓘ',
69407 'Ⓙ' => 'ⓙ',
69408 'Ⓚ' => 'ⓚ',
69409 'Ⓛ' => 'ⓛ',
69410 'Ⓜ' => 'ⓜ',
69411 'Ⓝ' => 'ⓝ',
69412 'Ⓞ' => 'ⓞ',
69413 'Ⓟ' => 'ⓟ',
69414 'Ⓠ' => 'ⓠ',
69415 'Ⓡ' => 'ⓡ',
69416 'Ⓢ' => 'ⓢ',
69417 'Ⓣ' => 'ⓣ',
69418 'Ⓤ' => 'ⓤ',
69419 'Ⓥ' => 'ⓥ',
69420 'Ⓦ' => 'ⓦ',
69421 'Ⓧ' => 'ⓧ',
69422 'Ⓨ' => 'ⓨ',
69423 'Ⓩ' => 'ⓩ',
69424 'Ⰰ' => 'ⰰ',
69425 'Ⰱ' => 'ⰱ',
69426 'Ⰲ' => 'ⰲ',
69427 'Ⰳ' => 'ⰳ',
69428 'Ⰴ' => 'ⰴ',
69429 'Ⰵ' => 'ⰵ',
69430 'Ⰶ' => 'ⰶ',
69431 'Ⰷ' => 'ⰷ',
69432 'Ⰸ' => 'ⰸ',
69433 'Ⰹ' => 'ⰹ',
69434 'Ⰺ' => 'ⰺ',
69435 'Ⰻ' => 'ⰻ',
69436 'Ⰼ' => 'ⰼ',
69437 'Ⰽ' => 'ⰽ',
69438 'Ⰾ' => 'ⰾ',
69439 'Ⰿ' => 'ⰿ',
69440 'Ⱀ' => 'ⱀ',
69441 'Ⱁ' => 'ⱁ',
69442 'Ⱂ' => 'ⱂ',
69443 'Ⱃ' => 'ⱃ',
69444 'Ⱄ' => 'ⱄ',
69445 'Ⱅ' => 'ⱅ',
69446 'Ⱆ' => 'ⱆ',
69447 'Ⱇ' => 'ⱇ',
69448 'Ⱈ' => 'ⱈ',
69449 'Ⱉ' => 'ⱉ',
69450 'Ⱊ' => 'ⱊ',
69451 'Ⱋ' => 'ⱋ',
69452 'Ⱌ' => 'ⱌ',
69453 'Ⱍ' => 'ⱍ',
69454 'Ⱎ' => 'ⱎ',
69455 'Ⱏ' => 'ⱏ',
69456 'Ⱐ' => 'ⱐ',
69457 'Ⱑ' => 'ⱑ',
69458 'Ⱒ' => 'ⱒ',
69459 'Ⱓ' => 'ⱓ',
69460 'Ⱔ' => 'ⱔ',
69461 'Ⱕ' => 'ⱕ',
69462 'Ⱖ' => 'ⱖ',
69463 'Ⱗ' => 'ⱗ',
69464 'Ⱘ' => 'ⱘ',
69465 'Ⱙ' => 'ⱙ',
69466 'Ⱚ' => 'ⱚ',
69467 'Ⱛ' => 'ⱛ',
69468 'Ⱜ' => 'ⱜ',
69469 'Ⱝ' => 'ⱝ',
69470 'Ⱞ' => 'ⱞ',
69471 'Ⱡ' => 'ⱡ',
69472 'Ɫ' => 'ɫ',
69473 'Ᵽ' => 'ᵽ',
69474 'Ɽ' => 'ɽ',
69475 'Ⱨ' => 'ⱨ',
69476 'Ⱪ' => 'ⱪ',
69477 'Ⱬ' => 'ⱬ',
69478 'Ɑ' => 'ɑ',
69479 'Ɱ' => 'ɱ',
69480 'Ɐ' => 'ɐ',
69481 'Ɒ' => 'ɒ',
69482 'Ⱳ' => 'ⱳ',
69483 'Ⱶ' => 'ⱶ',
69484 'Ȿ' => 'ȿ',
69485 'Ɀ' => 'ɀ',
69486 'Ⲁ' => 'ⲁ',
69487 'Ⲃ' => 'ⲃ',
69488 'Ⲅ' => 'ⲅ',
69489 'Ⲇ' => 'ⲇ',
69490 'Ⲉ' => 'ⲉ',
69491 'Ⲋ' => 'ⲋ',
69492 'Ⲍ' => 'ⲍ',
69493 'Ⲏ' => 'ⲏ',
69494 'Ⲑ' => 'ⲑ',
69495 'Ⲓ' => 'ⲓ',
69496 'Ⲕ' => 'ⲕ',
69497 'Ⲗ' => 'ⲗ',
69498 'Ⲙ' => 'ⲙ',
69499 'Ⲛ' => 'ⲛ',
69500 'Ⲝ' => 'ⲝ',
69501 'Ⲟ' => 'ⲟ',
69502 'Ⲡ' => 'ⲡ',
69503 'Ⲣ' => 'ⲣ',
69504 'Ⲥ' => 'ⲥ',
69505 'Ⲧ' => 'ⲧ',
69506 'Ⲩ' => 'ⲩ',
69507 'Ⲫ' => 'ⲫ',
69508 'Ⲭ' => 'ⲭ',
69509 'Ⲯ' => 'ⲯ',
69510 'Ⲱ' => 'ⲱ',
69511 'Ⲳ' => 'ⲳ',
69512 'Ⲵ' => 'ⲵ',
69513 'Ⲷ' => 'ⲷ',
69514 'Ⲹ' => 'ⲹ',
69515 'Ⲻ' => 'ⲻ',
69516 'Ⲽ' => 'ⲽ',
69517 'Ⲿ' => 'ⲿ',
69518 'Ⳁ' => 'ⳁ',
69519 'Ⳃ' => 'ⳃ',
69520 'Ⳅ' => 'ⳅ',
69521 'Ⳇ' => 'ⳇ',
69522 'Ⳉ' => 'ⳉ',
69523 'Ⳋ' => 'ⳋ',
69524 'Ⳍ' => 'ⳍ',
69525 'Ⳏ' => 'ⳏ',
69526 'Ⳑ' => 'ⳑ',
69527 'Ⳓ' => 'ⳓ',
69528 'Ⳕ' => 'ⳕ',
69529 'Ⳗ' => 'ⳗ',
69530 'Ⳙ' => 'ⳙ',
69531 'Ⳛ' => 'ⳛ',
69532 'Ⳝ' => 'ⳝ',
69533 'Ⳟ' => 'ⳟ',
69534 'Ⳡ' => 'ⳡ',
69535 'Ⳣ' => 'ⳣ',
69536 'Ⳬ' => 'ⳬ',
69537 'Ⳮ' => 'ⳮ',
69538 'Ⳳ' => 'ⳳ',
69539 'Ꙁ' => 'ꙁ',
69540 'Ꙃ' => 'ꙃ',
69541 'Ꙅ' => 'ꙅ',
69542 'Ꙇ' => 'ꙇ',
69543 'Ꙉ' => 'ꙉ',
69544 'Ꙋ' => 'ꙋ',
69545 'Ꙍ' => 'ꙍ',
69546 'Ꙏ' => 'ꙏ',
69547 'Ꙑ' => 'ꙑ',
69548 'Ꙓ' => 'ꙓ',
69549 'Ꙕ' => 'ꙕ',
69550 'Ꙗ' => 'ꙗ',
69551 'Ꙙ' => 'ꙙ',
69552 'Ꙛ' => 'ꙛ',
69553 'Ꙝ' => 'ꙝ',
69554 'Ꙟ' => 'ꙟ',
69555 'Ꙡ' => 'ꙡ',
69556 'Ꙣ' => 'ꙣ',
69557 'Ꙥ' => 'ꙥ',
69558 'Ꙧ' => 'ꙧ',
69559 'Ꙩ' => 'ꙩ',
69560 'Ꙫ' => 'ꙫ',
69561 'Ꙭ' => 'ꙭ',
69562 'Ꚁ' => 'ꚁ',
69563 'Ꚃ' => 'ꚃ',
69564 'Ꚅ' => 'ꚅ',
69565 'Ꚇ' => 'ꚇ',
69566 'Ꚉ' => 'ꚉ',
69567 'Ꚋ' => 'ꚋ',
69568 'Ꚍ' => 'ꚍ',
69569 'Ꚏ' => 'ꚏ',
69570 'Ꚑ' => 'ꚑ',
69571 'Ꚓ' => 'ꚓ',
69572 'Ꚕ' => 'ꚕ',
69573 'Ꚗ' => 'ꚗ',
69574 'Ꚙ' => 'ꚙ',
69575 'Ꚛ' => 'ꚛ',
69576 'Ꜣ' => 'ꜣ',
69577 'Ꜥ' => 'ꜥ',
69578 'Ꜧ' => 'ꜧ',
69579 'Ꜩ' => 'ꜩ',
69580 'Ꜫ' => 'ꜫ',
69581 'Ꜭ' => 'ꜭ',
69582 'Ꜯ' => 'ꜯ',
69583 'Ꜳ' => 'ꜳ',
69584 'Ꜵ' => 'ꜵ',
69585 'Ꜷ' => 'ꜷ',
69586 'Ꜹ' => 'ꜹ',
69587 'Ꜻ' => 'ꜻ',
69588 'Ꜽ' => 'ꜽ',
69589 'Ꜿ' => 'ꜿ',
69590 'Ꝁ' => 'ꝁ',
69591 'Ꝃ' => 'ꝃ',
69592 'Ꝅ' => 'ꝅ',
69593 'Ꝇ' => 'ꝇ',
69594 'Ꝉ' => 'ꝉ',
69595 'Ꝋ' => 'ꝋ',
69596 'Ꝍ' => 'ꝍ',
69597 'Ꝏ' => 'ꝏ',
69598 'Ꝑ' => 'ꝑ',
69599 'Ꝓ' => 'ꝓ',
69600 'Ꝕ' => 'ꝕ',
69601 'Ꝗ' => 'ꝗ',
69602 'Ꝙ' => 'ꝙ',
69603 'Ꝛ' => 'ꝛ',
69604 'Ꝝ' => 'ꝝ',
69605 'Ꝟ' => 'ꝟ',
69606 'Ꝡ' => 'ꝡ',
69607 'Ꝣ' => 'ꝣ',
69608 'Ꝥ' => 'ꝥ',
69609 'Ꝧ' => 'ꝧ',
69610 'Ꝩ' => 'ꝩ',
69611 'Ꝫ' => 'ꝫ',
69612 'Ꝭ' => 'ꝭ',
69613 'Ꝯ' => 'ꝯ',
69614 'Ꝺ' => 'ꝺ',
69615 'Ꝼ' => 'ꝼ',
69616 'Ᵹ' => 'ᵹ',
69617 'Ꝿ' => 'ꝿ',
69618 'Ꞁ' => 'ꞁ',
69619 'Ꞃ' => 'ꞃ',
69620 'Ꞅ' => 'ꞅ',
69621 'Ꞇ' => 'ꞇ',
69622 'Ꞌ' => 'ꞌ',
69623 'Ɥ' => 'ɥ',
69624 'Ꞑ' => 'ꞑ',
69625 'Ꞓ' => 'ꞓ',
69626 'Ꞗ' => 'ꞗ',
69627 'Ꞙ' => 'ꞙ',
69628 'Ꞛ' => 'ꞛ',
69629 'Ꞝ' => 'ꞝ',
69630 'Ꞟ' => 'ꞟ',
69631 'Ꞡ' => 'ꞡ',
69632 'Ꞣ' => 'ꞣ',
69633 'Ꞥ' => 'ꞥ',
69634 'Ꞧ' => 'ꞧ',
69635 'Ꞩ' => 'ꞩ',
69636 'Ɦ' => 'ɦ',
69637 'Ɜ' => 'ɜ',
69638 'Ɡ' => 'ɡ',
69639 'Ɬ' => 'ɬ',
69640 'Ʞ' => 'ʞ',
69641 'Ʇ' => 'ʇ',
69642 'A' => 'a',
69643 'B' => 'b',
69644 'C' => 'c',
69645 'D' => 'd',
69646 'E' => 'e',
69647 'F' => 'f',
69648 'G' => 'g',
69649 'H' => 'h',
69650 'I' => 'i',
69651 'J' => 'j',
69652 'K' => 'k',
69653 'L' => 'l',
69654 'M' => 'm',
69655 'N' => 'n',
69656 'O' => 'o',
69657 'P' => 'p',
69658 'Q' => 'q',
69659 'R' => 'r',
69660 'S' => 's',
69661 'T' => 't',
69662 'U' => 'u',
69663 'V' => 'v',
69664 'W' => 'w',
69665 'X' => 'x',
69666 'Y' => 'y',
69667 'Z' => 'z',
69668 '𐐀' => '𐐨',
69669 '𐐁' => '𐐩',
69670 '𐐂' => '𐐪',
69671 '𐐃' => '𐐫',
69672 '𐐄' => '𐐬',
69673 '𐐅' => '𐐭',
69674 '𐐆' => '𐐮',
69675 '𐐇' => '𐐯',
69676 '𐐈' => '𐐰',
69677 '𐐉' => '𐐱',
69678 '𐐊' => '𐐲',
69679 '𐐋' => '𐐳',
69680 '𐐌' => '𐐴',
69681 '𐐍' => '𐐵',
69682 '𐐎' => '𐐶',
69683 '𐐏' => '𐐷',
69684 '𐐐' => '𐐸',
69685 '𐐑' => '𐐹',
69686 '𐐒' => '𐐺',
69687 '𐐓' => '𐐻',
69688 '𐐔' => '𐐼',
69689 '𐐕' => '𐐽',
69690 '𐐖' => '𐐾',
69691 '𐐗' => '𐐿',
69692 '𐐘' => '𐑀',
69693 '𐐙' => '𐑁',
69694 '𐐚' => '𐑂',
69695 '𐐛' => '𐑃',
69696 '𐐜' => '𐑄',
69697 '𐐝' => '𐑅',
69698 '𐐞' => '𐑆',
69699 '𐐟' => '𐑇',
69700 '𐐠' => '𐑈',
69701 '𐐡' => '𐑉',
69702 '𐐢' => '𐑊',
69703 '𐐣' => '𐑋',
69704 '𐐤' => '𐑌',
69705 '𐐥' => '𐑍',
69706 '𐐦' => '𐑎',
69707 '𐐧' => '𐑏',
69708 '𑢠' => '𑣀',
69709 '𑢡' => '𑣁',
69710 '𑢢' => '𑣂',
69711 '𑢣' => '𑣃',
69712 '𑢤' => '𑣄',
69713 '𑢥' => '𑣅',
69714 '𑢦' => '𑣆',
69715 '𑢧' => '𑣇',
69716 '𑢨' => '𑣈',
69717 '𑢩' => '𑣉',
69718 '𑢪' => '𑣊',
69719 '𑢫' => '𑣋',
69720 '𑢬' => '𑣌',
69721 '𑢭' => '𑣍',
69722 '𑢮' => '𑣎',
69723 '𑢯' => '𑣏',
69724 '𑢰' => '𑣐',
69725 '𑢱' => '𑣑',
69726 '𑢲' => '𑣒',
69727 '𑢳' => '𑣓',
69728 '𑢴' => '𑣔',
69729 '𑢵' => '𑣕',
69730 '𑢶' => '𑣖',
69731 '𑢷' => '𑣗',
69732 '𑢸' => '𑣘',
69733 '𑢹' => '𑣙',
69734 '𑢺' => '𑣚',
69735 '𑢻' => '𑣛',
69736 '𑢼' => '𑣜',
69737 '𑢽' => '𑣝',
69738 '𑢾' => '𑣞',
69739 '𑢿' => '𑣟',
69740 );
69741
69742 $result =& $data;
69743 unset($data);
69744
69745 return $result;
69746 <?php
69747
69748 static $data = array (
69749 'a' => 'A',
69750 'b' => 'B',
69751 'c' => 'C',
69752 'd' => 'D',
69753 'e' => 'E',
69754 'f' => 'F',
69755 'g' => 'G',
69756 'h' => 'H',
69757 'i' => 'I',
69758 'j' => 'J',
69759 'k' => 'K',
69760 'l' => 'L',
69761 'm' => 'M',
69762 'n' => 'N',
69763 'o' => 'O',
69764 'p' => 'P',
69765 'q' => 'Q',
69766 'r' => 'R',
69767 's' => 'S',
69768 't' => 'T',
69769 'u' => 'U',
69770 'v' => 'V',
69771 'w' => 'W',
69772 'x' => 'X',
69773 'y' => 'Y',
69774 'z' => 'Z',
69775 'µ' => 'Μ',
69776 'à' => 'À',
69777 'á' => 'Á',
69778 'â' => 'Â',
69779 'ã' => 'Ã',
69780 'ä' => 'Ä',
69781 'å' => 'Å',
69782 'æ' => 'Æ',
69783 'ç' => 'Ç',
69784 'è' => 'È',
69785 'é' => 'É',
69786 'ê' => 'Ê',
69787 'ë' => 'Ë',
69788 'ì' => 'Ì',
69789 'í' => 'Í',
69790 'î' => 'Î',
69791 'ï' => 'Ï',
69792 'ð' => 'Ð',
69793 'ñ' => 'Ñ',
69794 'ò' => 'Ò',
69795 'ó' => 'Ó',
69796 'ô' => 'Ô',
69797 'õ' => 'Õ',
69798 'ö' => 'Ö',
69799 'ø' => 'Ø',
69800 'ù' => 'Ù',
69801 'ú' => 'Ú',
69802 'û' => 'Û',
69803 'ü' => 'Ü',
69804 'ý' => 'Ý',
69805 'þ' => 'Þ',
69806 'ÿ' => 'Ÿ',
69807 'ā' => 'Ā',
69808 'ă' => 'Ă',
69809 'ą' => 'Ą',
69810 'ć' => 'Ć',
69811 'ĉ' => 'Ĉ',
69812 'ċ' => 'Ċ',
69813 'č' => 'Č',
69814 'ď' => 'Ď',
69815 'đ' => 'Đ',
69816 'ē' => 'Ē',
69817 'ĕ' => 'Ĕ',
69818 'ė' => 'Ė',
69819 'ę' => 'Ę',
69820 'ě' => 'Ě',
69821 'ĝ' => 'Ĝ',
69822 'ğ' => 'Ğ',
69823 'ġ' => 'Ġ',
69824 'ģ' => 'Ģ',
69825 'ĥ' => 'Ĥ',
69826 'ħ' => 'Ħ',
69827 'ĩ' => 'Ĩ',
69828 'ī' => 'Ī',
69829 'ĭ' => 'Ĭ',
69830 'į' => 'Į',
69831 'ı' => 'I',
69832 'ij' => 'IJ',
69833 'ĵ' => 'Ĵ',
69834 'ķ' => 'Ķ',
69835 'ĺ' => 'Ĺ',
69836 'ļ' => 'Ļ',
69837 'ľ' => 'Ľ',
69838 'ŀ' => 'Ŀ',
69839 'ł' => 'Ł',
69840 'ń' => 'Ń',
69841 'ņ' => 'Ņ',
69842 'ň' => 'Ň',
69843 'ŋ' => 'Ŋ',
69844 'ō' => 'Ō',
69845 'ŏ' => 'Ŏ',
69846 'ő' => 'Ő',
69847 'œ' => 'Œ',
69848 'ŕ' => 'Ŕ',
69849 'ŗ' => 'Ŗ',
69850 'ř' => 'Ř',
69851 'ś' => 'Ś',
69852 'ŝ' => 'Ŝ',
69853 'ş' => 'Ş',
69854 'š' => 'Š',
69855 'ţ' => 'Ţ',
69856 'ť' => 'Ť',
69857 'ŧ' => 'Ŧ',
69858 'ũ' => 'Ũ',
69859 'ū' => 'Ū',
69860 'ŭ' => 'Ŭ',
69861 'ů' => 'Ů',
69862 'ű' => 'Ű',
69863 'ų' => 'Ų',
69864 'ŵ' => 'Ŵ',
69865 'ŷ' => 'Ŷ',
69866 'ź' => 'Ź',
69867 'ż' => 'Ż',
69868 'ž' => 'Ž',
69869 'ſ' => 'S',
69870 'ƀ' => 'Ƀ',
69871 'ƃ' => 'Ƃ',
69872 'ƅ' => 'Ƅ',
69873 'ƈ' => 'Ƈ',
69874 'ƌ' => 'Ƌ',
69875 'ƒ' => 'Ƒ',
69876 'ƕ' => 'Ƕ',
69877 'ƙ' => 'Ƙ',
69878 'ƚ' => 'Ƚ',
69879 'ƞ' => 'Ƞ',
69880 'ơ' => 'Ơ',
69881 'ƣ' => 'Ƣ',
69882 'ƥ' => 'Ƥ',
69883 'ƨ' => 'Ƨ',
69884 'ƭ' => 'Ƭ',
69885 'ư' => 'Ư',
69886 'ƴ' => 'Ƴ',
69887 'ƶ' => 'Ƶ',
69888 'ƹ' => 'Ƹ',
69889 'ƽ' => 'Ƽ',
69890 'ƿ' => 'Ƿ',
69891 'Dž' => 'DŽ',
69892 'dž' => 'DŽ',
69893 'Lj' => 'LJ',
69894 'lj' => 'LJ',
69895 'Nj' => 'NJ',
69896 'nj' => 'NJ',
69897 'ǎ' => 'Ǎ',
69898 'ǐ' => 'Ǐ',
69899 'ǒ' => 'Ǒ',
69900 'ǔ' => 'Ǔ',
69901 'ǖ' => 'Ǖ',
69902 'ǘ' => 'Ǘ',
69903 'ǚ' => 'Ǚ',
69904 'ǜ' => 'Ǜ',
69905 'ǝ' => 'Ǝ',
69906 'ǟ' => 'Ǟ',
69907 'ǡ' => 'Ǡ',
69908 'ǣ' => 'Ǣ',
69909 'ǥ' => 'Ǥ',
69910 'ǧ' => 'Ǧ',
69911 'ǩ' => 'Ǩ',
69912 'ǫ' => 'Ǫ',
69913 'ǭ' => 'Ǭ',
69914 'ǯ' => 'Ǯ',
69915 'Dz' => 'DZ',
69916 'dz' => 'DZ',
69917 'ǵ' => 'Ǵ',
69918 'ǹ' => 'Ǹ',
69919 'ǻ' => 'Ǻ',
69920 'ǽ' => 'Ǽ',
69921 'ǿ' => 'Ǿ',
69922 'ȁ' => 'Ȁ',
69923 'ȃ' => 'Ȃ',
69924 'ȅ' => 'Ȅ',
69925 'ȇ' => 'Ȇ',
69926 'ȉ' => 'Ȉ',
69927 'ȋ' => 'Ȋ',
69928 'ȍ' => 'Ȍ',
69929 'ȏ' => 'Ȏ',
69930 'ȑ' => 'Ȑ',
69931 'ȓ' => 'Ȓ',
69932 'ȕ' => 'Ȕ',
69933 'ȗ' => 'Ȗ',
69934 'ș' => 'Ș',
69935 'ț' => 'Ț',
69936 'ȝ' => 'Ȝ',
69937 'ȟ' => 'Ȟ',
69938 'ȣ' => 'Ȣ',
69939 'ȥ' => 'Ȥ',
69940 'ȧ' => 'Ȧ',
69941 'ȩ' => 'Ȩ',
69942 'ȫ' => 'Ȫ',
69943 'ȭ' => 'Ȭ',
69944 'ȯ' => 'Ȯ',
69945 'ȱ' => 'Ȱ',
69946 'ȳ' => 'Ȳ',
69947 'ȼ' => 'Ȼ',
69948 'ȿ' => 'Ȿ',
69949 'ɀ' => 'Ɀ',
69950 'ɂ' => 'Ɂ',
69951 'ɇ' => 'Ɇ',
69952 'ɉ' => 'Ɉ',
69953 'ɋ' => 'Ɋ',
69954 'ɍ' => 'Ɍ',
69955 'ɏ' => 'Ɏ',
69956 'ɐ' => 'Ɐ',
69957 'ɑ' => 'Ɑ',
69958 'ɒ' => 'Ɒ',
69959 'ɓ' => 'Ɓ',
69960 'ɔ' => 'Ɔ',
69961 'ɖ' => 'Ɖ',
69962 'ɗ' => 'Ɗ',
69963 'ə' => 'Ə',
69964 'ɛ' => 'Ɛ',
69965 'ɜ' => 'Ɜ',
69966 'ɠ' => 'Ɠ',
69967 'ɡ' => 'Ɡ',
69968 'ɣ' => 'Ɣ',
69969 'ɥ' => 'Ɥ',
69970 'ɦ' => 'Ɦ',
69971 'ɨ' => 'Ɨ',
69972 'ɩ' => 'Ɩ',
69973 'ɫ' => 'Ɫ',
69974 'ɬ' => 'Ɬ',
69975 'ɯ' => 'Ɯ',
69976 'ɱ' => 'Ɱ',
69977 'ɲ' => 'Ɲ',
69978 'ɵ' => 'Ɵ',
69979 'ɽ' => 'Ɽ',
69980 'ʀ' => 'Ʀ',
69981 'ʃ' => 'Ʃ',
69982 'ʇ' => 'Ʇ',
69983 'ʈ' => 'Ʈ',
69984 'ʉ' => 'Ʉ',
69985 'ʊ' => 'Ʊ',
69986 'ʋ' => 'Ʋ',
69987 'ʌ' => 'Ʌ',
69988 'ʒ' => 'Ʒ',
69989 'ʞ' => 'Ʞ',
69990 'ͅ' => 'Ι',
69991 'ͱ' => 'Ͱ',
69992 'ͳ' => 'Ͳ',
69993 'ͷ' => 'Ͷ',
69994 'ͻ' => 'Ͻ',
69995 'ͼ' => 'Ͼ',
69996 'ͽ' => 'Ͽ',
69997 'ά' => 'Ά',
69998 'έ' => 'Έ',
69999 'ή' => 'Ή',
70000 'ί' => 'Ί',
70001 'α' => 'Α',
70002 'β' => 'Β',
70003 'γ' => 'Γ',
70004 'δ' => 'Δ',
70005 'ε' => 'Ε',
70006 'ζ' => 'Ζ',
70007 'η' => 'Η',
70008 'θ' => 'Θ',
70009 'ι' => 'Ι',
70010 'κ' => 'Κ',
70011 'λ' => 'Λ',
70012 'μ' => 'Μ',
70013 'ν' => 'Ν',
70014 'ξ' => 'Ξ',
70015 'ο' => 'Ο',
70016 'π' => 'Π',
70017 'ρ' => 'Ρ',
70018 'ς' => 'Σ',
70019 'σ' => 'Σ',
70020 'τ' => 'Τ',
70021 'υ' => 'Υ',
70022 'φ' => 'Φ',
70023 'χ' => 'Χ',
70024 'ψ' => 'Ψ',
70025 'ω' => 'Ω',
70026 'ϊ' => 'Ϊ',
70027 'ϋ' => 'Ϋ',
70028 'ό' => 'Ό',
70029 'ύ' => 'Ύ',
70030 'ώ' => 'Ώ',
70031 'ϐ' => 'Β',
70032 'ϑ' => 'Θ',
70033 'ϕ' => 'Φ',
70034 'ϖ' => 'Π',
70035 'ϗ' => 'Ϗ',
70036 'ϙ' => 'Ϙ',
70037 'ϛ' => 'Ϛ',
70038 'ϝ' => 'Ϝ',
70039 'ϟ' => 'Ϟ',
70040 'ϡ' => 'Ϡ',
70041 'ϣ' => 'Ϣ',
70042 'ϥ' => 'Ϥ',
70043 'ϧ' => 'Ϧ',
70044 'ϩ' => 'Ϩ',
70045 'ϫ' => 'Ϫ',
70046 'ϭ' => 'Ϭ',
70047 'ϯ' => 'Ϯ',
70048 'ϰ' => 'Κ',
70049 'ϱ' => 'Ρ',
70050 'ϲ' => 'Ϲ',
70051 'ϳ' => 'Ϳ',
70052 'ϵ' => 'Ε',
70053 'ϸ' => 'Ϸ',
70054 'ϻ' => 'Ϻ',
70055 'а' => 'А',
70056 'б' => 'Б',
70057 'в' => 'В',
70058 'г' => 'Г',
70059 'д' => 'Д',
70060 'е' => 'Е',
70061 'ж' => 'Ж',
70062 'з' => 'З',
70063 'и' => 'И',
70064 'й' => 'Й',
70065 'к' => 'К',
70066 'л' => 'Л',
70067 'м' => 'М',
70068 'н' => 'Н',
70069 'о' => 'О',
70070 'п' => 'П',
70071 'р' => 'Р',
70072 'с' => 'С',
70073 'т' => 'Т',
70074 'у' => 'У',
70075 'ф' => 'Ф',
70076 'х' => 'Х',
70077 'ц' => 'Ц',
70078 'ч' => 'Ч',
70079 'ш' => 'Ш',
70080 'щ' => 'Щ',
70081 'ъ' => 'Ъ',
70082 'ы' => 'Ы',
70083 'ь' => 'Ь',
70084 'э' => 'Э',
70085 'ю' => 'Ю',
70086 'я' => 'Я',
70087 'ѐ' => 'Ѐ',
70088 'ё' => 'Ё',
70089 'ђ' => 'Ђ',
70090 'ѓ' => 'Ѓ',
70091 'є' => 'Є',
70092 'ѕ' => 'Ѕ',
70093 'і' => 'І',
70094 'ї' => 'Ї',
70095 'ј' => 'Ј',
70096 'љ' => 'Љ',
70097 'њ' => 'Њ',
70098 'ћ' => 'Ћ',
70099 'ќ' => 'Ќ',
70100 'ѝ' => 'Ѝ',
70101 'ў' => 'Ў',
70102 'џ' => 'Џ',
70103 'ѡ' => 'Ѡ',
70104 'ѣ' => 'Ѣ',
70105 'ѥ' => 'Ѥ',
70106 'ѧ' => 'Ѧ',
70107 'ѩ' => 'Ѩ',
70108 'ѫ' => 'Ѫ',
70109 'ѭ' => 'Ѭ',
70110 'ѯ' => 'Ѯ',
70111 'ѱ' => 'Ѱ',
70112 'ѳ' => 'Ѳ',
70113 'ѵ' => 'Ѵ',
70114 'ѷ' => 'Ѷ',
70115 'ѹ' => 'Ѹ',
70116 'ѻ' => 'Ѻ',
70117 'ѽ' => 'Ѽ',
70118 'ѿ' => 'Ѿ',
70119 'ҁ' => 'Ҁ',
70120 'ҋ' => 'Ҋ',
70121 'ҍ' => 'Ҍ',
70122 'ҏ' => 'Ҏ',
70123 'ґ' => 'Ґ',
70124 'ғ' => 'Ғ',
70125 'ҕ' => 'Ҕ',
70126 'җ' => 'Җ',
70127 'ҙ' => 'Ҙ',
70128 'қ' => 'Қ',
70129 'ҝ' => 'Ҝ',
70130 'ҟ' => 'Ҟ',
70131 'ҡ' => 'Ҡ',
70132 'ң' => 'Ң',
70133 'ҥ' => 'Ҥ',
70134 'ҧ' => 'Ҧ',
70135 'ҩ' => 'Ҩ',
70136 'ҫ' => 'Ҫ',
70137 'ҭ' => 'Ҭ',
70138 'ү' => 'Ү',
70139 'ұ' => 'Ұ',
70140 'ҳ' => 'Ҳ',
70141 'ҵ' => 'Ҵ',
70142 'ҷ' => 'Ҷ',
70143 'ҹ' => 'Ҹ',
70144 'һ' => 'Һ',
70145 'ҽ' => 'Ҽ',
70146 'ҿ' => 'Ҿ',
70147 'ӂ' => 'Ӂ',
70148 'ӄ' => 'Ӄ',
70149 'ӆ' => 'Ӆ',
70150 'ӈ' => 'Ӈ',
70151 'ӊ' => 'Ӊ',
70152 'ӌ' => 'Ӌ',
70153 'ӎ' => 'Ӎ',
70154 'ӏ' => 'Ӏ',
70155 'ӑ' => 'Ӑ',
70156 'ӓ' => 'Ӓ',
70157 'ӕ' => 'Ӕ',
70158 'ӗ' => 'Ӗ',
70159 'ә' => 'Ә',
70160 'ӛ' => 'Ӛ',
70161 'ӝ' => 'Ӝ',
70162 'ӟ' => 'Ӟ',
70163 'ӡ' => 'Ӡ',
70164 'ӣ' => 'Ӣ',
70165 'ӥ' => 'Ӥ',
70166 'ӧ' => 'Ӧ',
70167 'ө' => 'Ө',
70168 'ӫ' => 'Ӫ',
70169 'ӭ' => 'Ӭ',
70170 'ӯ' => 'Ӯ',
70171 'ӱ' => 'Ӱ',
70172 'ӳ' => 'Ӳ',
70173 'ӵ' => 'Ӵ',
70174 'ӷ' => 'Ӷ',
70175 'ӹ' => 'Ӹ',
70176 'ӻ' => 'Ӻ',
70177 'ӽ' => 'Ӽ',
70178 'ӿ' => 'Ӿ',
70179 'ԁ' => 'Ԁ',
70180 'ԃ' => 'Ԃ',
70181 'ԅ' => 'Ԅ',
70182 'ԇ' => 'Ԇ',
70183 'ԉ' => 'Ԉ',
70184 'ԋ' => 'Ԋ',
70185 'ԍ' => 'Ԍ',
70186 'ԏ' => 'Ԏ',
70187 'ԑ' => 'Ԑ',
70188 'ԓ' => 'Ԓ',
70189 'ԕ' => 'Ԕ',
70190 'ԗ' => 'Ԗ',
70191 'ԙ' => 'Ԙ',
70192 'ԛ' => 'Ԛ',
70193 'ԝ' => 'Ԝ',
70194 'ԟ' => 'Ԟ',
70195 'ԡ' => 'Ԡ',
70196 'ԣ' => 'Ԣ',
70197 'ԥ' => 'Ԥ',
70198 'ԧ' => 'Ԧ',
70199 'ԩ' => 'Ԩ',
70200 'ԫ' => 'Ԫ',
70201 'ԭ' => 'Ԭ',
70202 'ԯ' => 'Ԯ',
70203 'ա' => 'Ա',
70204 'բ' => 'Բ',
70205 'գ' => 'Գ',
70206 'դ' => 'Դ',
70207 'ե' => 'Ե',
70208 'զ' => 'Զ',
70209 'է' => 'Է',
70210 'ը' => 'Ը',
70211 'թ' => 'Թ',
70212 'ժ' => 'Ժ',
70213 'ի' => 'Ի',
70214 'լ' => 'Լ',
70215 'խ' => 'Խ',
70216 'ծ' => 'Ծ',
70217 'կ' => 'Կ',
70218 'հ' => 'Հ',
70219 'ձ' => 'Ձ',
70220 'ղ' => 'Ղ',
70221 'ճ' => 'Ճ',
70222 'մ' => 'Մ',
70223 'յ' => 'Յ',
70224 'ն' => 'Ն',
70225 'շ' => 'Շ',
70226 'ո' => 'Ո',
70227 'չ' => 'Չ',
70228 'պ' => 'Պ',
70229 'ջ' => 'Ջ',
70230 'ռ' => 'Ռ',
70231 'ս' => 'Ս',
70232 'վ' => 'Վ',
70233 'տ' => 'Տ',
70234 'ր' => 'Ր',
70235 'ց' => 'Ց',
70236 'ւ' => 'Ւ',
70237 'փ' => 'Փ',
70238 'ք' => 'Ք',
70239 'օ' => 'Օ',
70240 'ֆ' => 'Ֆ',
70241 'ᵹ' => 'Ᵹ',
70242 'ᵽ' => 'Ᵽ',
70243 'ḁ' => 'Ḁ',
70244 'ḃ' => 'Ḃ',
70245 'ḅ' => 'Ḅ',
70246 'ḇ' => 'Ḇ',
70247 'ḉ' => 'Ḉ',
70248 'ḋ' => 'Ḋ',
70249 'ḍ' => 'Ḍ',
70250 'ḏ' => 'Ḏ',
70251 'ḑ' => 'Ḑ',
70252 'ḓ' => 'Ḓ',
70253 'ḕ' => 'Ḕ',
70254 'ḗ' => 'Ḗ',
70255 'ḙ' => 'Ḙ',
70256 'ḛ' => 'Ḛ',
70257 'ḝ' => 'Ḝ',
70258 'ḟ' => 'Ḟ',
70259 'ḡ' => 'Ḡ',
70260 'ḣ' => 'Ḣ',
70261 'ḥ' => 'Ḥ',
70262 'ḧ' => 'Ḧ',
70263 'ḩ' => 'Ḩ',
70264 'ḫ' => 'Ḫ',
70265 'ḭ' => 'Ḭ',
70266 'ḯ' => 'Ḯ',
70267 'ḱ' => 'Ḱ',
70268 'ḳ' => 'Ḳ',
70269 'ḵ' => 'Ḵ',
70270 'ḷ' => 'Ḷ',
70271 'ḹ' => 'Ḹ',
70272 'ḻ' => 'Ḻ',
70273 'ḽ' => 'Ḽ',
70274 'ḿ' => 'Ḿ',
70275 'ṁ' => 'Ṁ',
70276 'ṃ' => 'Ṃ',
70277 'ṅ' => 'Ṅ',
70278 'ṇ' => 'Ṇ',
70279 'ṉ' => 'Ṉ',
70280 'ṋ' => 'Ṋ',
70281 'ṍ' => 'Ṍ',
70282 'ṏ' => 'Ṏ',
70283 'ṑ' => 'Ṑ',
70284 'ṓ' => 'Ṓ',
70285 'ṕ' => 'Ṕ',
70286 'ṗ' => 'Ṗ',
70287 'ṙ' => 'Ṙ',
70288 'ṛ' => 'Ṛ',
70289 'ṝ' => 'Ṝ',
70290 'ṟ' => 'Ṟ',
70291 'ṡ' => 'Ṡ',
70292 'ṣ' => 'Ṣ',
70293 'ṥ' => 'Ṥ',
70294 'ṧ' => 'Ṧ',
70295 'ṩ' => 'Ṩ',
70296 'ṫ' => 'Ṫ',
70297 'ṭ' => 'Ṭ',
70298 'ṯ' => 'Ṯ',
70299 'ṱ' => 'Ṱ',
70300 'ṳ' => 'Ṳ',
70301 'ṵ' => 'Ṵ',
70302 'ṷ' => 'Ṷ',
70303 'ṹ' => 'Ṹ',
70304 'ṻ' => 'Ṻ',
70305 'ṽ' => 'Ṽ',
70306 'ṿ' => 'Ṿ',
70307 'ẁ' => 'Ẁ',
70308 'ẃ' => 'Ẃ',
70309 'ẅ' => 'Ẅ',
70310 'ẇ' => 'Ẇ',
70311 'ẉ' => 'Ẉ',
70312 'ẋ' => 'Ẋ',
70313 'ẍ' => 'Ẍ',
70314 'ẏ' => 'Ẏ',
70315 'ẑ' => 'Ẑ',
70316 'ẓ' => 'Ẓ',
70317 'ẕ' => 'Ẕ',
70318 'ẛ' => 'Ṡ',
70319 'ạ' => 'Ạ',
70320 'ả' => 'Ả',
70321 'ấ' => 'Ấ',
70322 'ầ' => 'Ầ',
70323 'ẩ' => 'Ẩ',
70324 'ẫ' => 'Ẫ',
70325 'ậ' => 'Ậ',
70326 'ắ' => 'Ắ',
70327 'ằ' => 'Ằ',
70328 'ẳ' => 'Ẳ',
70329 'ẵ' => 'Ẵ',
70330 'ặ' => 'Ặ',
70331 'ẹ' => 'Ẹ',
70332 'ẻ' => 'Ẻ',
70333 'ẽ' => 'Ẽ',
70334 'ế' => 'Ế',
70335 'ề' => 'Ề',
70336 'ể' => 'Ể',
70337 'ễ' => 'Ễ',
70338 'ệ' => 'Ệ',
70339 'ỉ' => 'Ỉ',
70340 'ị' => 'Ị',
70341 'ọ' => 'Ọ',
70342 'ỏ' => 'Ỏ',
70343 'ố' => 'Ố',
70344 'ồ' => 'Ồ',
70345 'ổ' => 'Ổ',
70346 'ỗ' => 'Ỗ',
70347 'ộ' => 'Ộ',
70348 'ớ' => 'Ớ',
70349 'ờ' => 'Ờ',
70350 'ở' => 'Ở',
70351 'ỡ' => 'Ỡ',
70352 'ợ' => 'Ợ',
70353 'ụ' => 'Ụ',
70354 'ủ' => 'Ủ',
70355 'ứ' => 'Ứ',
70356 'ừ' => 'Ừ',
70357 'ử' => 'Ử',
70358 'ữ' => 'Ữ',
70359 'ự' => 'Ự',
70360 'ỳ' => 'Ỳ',
70361 'ỵ' => 'Ỵ',
70362 'ỷ' => 'Ỷ',
70363 'ỹ' => 'Ỹ',
70364 'ỻ' => 'Ỻ',
70365 'ỽ' => 'Ỽ',
70366 'ỿ' => 'Ỿ',
70367 'ἀ' => 'Ἀ',
70368 'ἁ' => 'Ἁ',
70369 'ἂ' => 'Ἂ',
70370 'ἃ' => 'Ἃ',
70371 'ἄ' => 'Ἄ',
70372 'ἅ' => 'Ἅ',
70373 'ἆ' => 'Ἆ',
70374 'ἇ' => 'Ἇ',
70375 'ἐ' => 'Ἐ',
70376 'ἑ' => 'Ἑ',
70377 'ἒ' => 'Ἒ',
70378 'ἓ' => 'Ἓ',
70379 'ἔ' => 'Ἔ',
70380 'ἕ' => 'Ἕ',
70381 'ἠ' => 'Ἠ',
70382 'ἡ' => 'Ἡ',
70383 'ἢ' => 'Ἢ',
70384 'ἣ' => 'Ἣ',
70385 'ἤ' => 'Ἤ',
70386 'ἥ' => 'Ἥ',
70387 'ἦ' => 'Ἦ',
70388 'ἧ' => 'Ἧ',
70389 'ἰ' => 'Ἰ',
70390 'ἱ' => 'Ἱ',
70391 'ἲ' => 'Ἲ',
70392 'ἳ' => 'Ἳ',
70393 'ἴ' => 'Ἴ',
70394 'ἵ' => 'Ἵ',
70395 'ἶ' => 'Ἶ',
70396 'ἷ' => 'Ἷ',
70397 'ὀ' => 'Ὀ',
70398 'ὁ' => 'Ὁ',
70399 'ὂ' => 'Ὂ',
70400 'ὃ' => 'Ὃ',
70401 'ὄ' => 'Ὄ',
70402 'ὅ' => 'Ὅ',
70403 'ὑ' => 'Ὑ',
70404 'ὓ' => 'Ὓ',
70405 'ὕ' => 'Ὕ',
70406 'ὗ' => 'Ὗ',
70407 'ὠ' => 'Ὠ',
70408 'ὡ' => 'Ὡ',
70409 'ὢ' => 'Ὢ',
70410 'ὣ' => 'Ὣ',
70411 'ὤ' => 'Ὤ',
70412 'ὥ' => 'Ὥ',
70413 'ὦ' => 'Ὦ',
70414 'ὧ' => 'Ὧ',
70415 'ὰ' => 'Ὰ',
70416 'ά' => 'Ά',
70417 'ὲ' => 'Ὲ',
70418 'έ' => 'Έ',
70419 'ὴ' => 'Ὴ',
70420 'ή' => 'Ή',
70421 'ὶ' => 'Ὶ',
70422 'ί' => 'Ί',
70423 'ὸ' => 'Ὸ',
70424 'ό' => 'Ό',
70425 'ὺ' => 'Ὺ',
70426 'ύ' => 'Ύ',
70427 'ὼ' => 'Ὼ',
70428 'ώ' => 'Ώ',
70429 'ᾀ' => 'ᾈ',
70430 'ᾁ' => 'ᾉ',
70431 'ᾂ' => 'ᾊ',
70432 'ᾃ' => 'ᾋ',
70433 'ᾄ' => 'ᾌ',
70434 'ᾅ' => 'ᾍ',
70435 'ᾆ' => 'ᾎ',
70436 'ᾇ' => 'ᾏ',
70437 'ᾐ' => 'ᾘ',
70438 'ᾑ' => 'ᾙ',
70439 'ᾒ' => 'ᾚ',
70440 'ᾓ' => 'ᾛ',
70441 'ᾔ' => 'ᾜ',
70442 'ᾕ' => 'ᾝ',
70443 'ᾖ' => 'ᾞ',
70444 'ᾗ' => 'ᾟ',
70445 'ᾠ' => 'ᾨ',
70446 'ᾡ' => 'ᾩ',
70447 'ᾢ' => 'ᾪ',
70448 'ᾣ' => 'ᾫ',
70449 'ᾤ' => 'ᾬ',
70450 'ᾥ' => 'ᾭ',
70451 'ᾦ' => 'ᾮ',
70452 'ᾧ' => 'ᾯ',
70453 'ᾰ' => 'Ᾰ',
70454 'ᾱ' => 'Ᾱ',
70455 'ᾳ' => 'ᾼ',
70456 'ι' => 'Ι',
70457 'ῃ' => 'ῌ',
70458 'ῐ' => 'Ῐ',
70459 'ῑ' => 'Ῑ',
70460 'ῠ' => 'Ῠ',
70461 'ῡ' => 'Ῡ',
70462 'ῥ' => 'Ῥ',
70463 'ῳ' => 'ῼ',
70464 'ⅎ' => 'Ⅎ',
70465 'ⅰ' => 'Ⅰ',
70466 'ⅱ' => 'Ⅱ',
70467 'ⅲ' => 'Ⅲ',
70468 'ⅳ' => 'Ⅳ',
70469 'ⅴ' => 'Ⅴ',
70470 'ⅵ' => 'Ⅵ',
70471 'ⅶ' => 'Ⅶ',
70472 'ⅷ' => 'Ⅷ',
70473 'ⅸ' => 'Ⅸ',
70474 'ⅹ' => 'Ⅹ',
70475 'ⅺ' => 'Ⅺ',
70476 'ⅻ' => 'Ⅻ',
70477 'ⅼ' => 'Ⅼ',
70478 'ⅽ' => 'Ⅽ',
70479 'ⅾ' => 'Ⅾ',
70480 'ⅿ' => 'Ⅿ',
70481 'ↄ' => 'Ↄ',
70482 'ⓐ' => 'Ⓐ',
70483 'ⓑ' => 'Ⓑ',
70484 'ⓒ' => 'Ⓒ',
70485 'ⓓ' => 'Ⓓ',
70486 'ⓔ' => 'Ⓔ',
70487 'ⓕ' => 'Ⓕ',
70488 'ⓖ' => 'Ⓖ',
70489 'ⓗ' => 'Ⓗ',
70490 'ⓘ' => 'Ⓘ',
70491 'ⓙ' => 'Ⓙ',
70492 'ⓚ' => 'Ⓚ',
70493 'ⓛ' => 'Ⓛ',
70494 'ⓜ' => 'Ⓜ',
70495 'ⓝ' => 'Ⓝ',
70496 'ⓞ' => 'Ⓞ',
70497 'ⓟ' => 'Ⓟ',
70498 'ⓠ' => 'Ⓠ',
70499 'ⓡ' => 'Ⓡ',
70500 'ⓢ' => 'Ⓢ',
70501 'ⓣ' => 'Ⓣ',
70502 'ⓤ' => 'Ⓤ',
70503 'ⓥ' => 'Ⓥ',
70504 'ⓦ' => 'Ⓦ',
70505 'ⓧ' => 'Ⓧ',
70506 'ⓨ' => 'Ⓨ',
70507 'ⓩ' => 'Ⓩ',
70508 'ⰰ' => 'Ⰰ',
70509 'ⰱ' => 'Ⰱ',
70510 'ⰲ' => 'Ⰲ',
70511 'ⰳ' => 'Ⰳ',
70512 'ⰴ' => 'Ⰴ',
70513 'ⰵ' => 'Ⰵ',
70514 'ⰶ' => 'Ⰶ',
70515 'ⰷ' => 'Ⰷ',
70516 'ⰸ' => 'Ⰸ',
70517 'ⰹ' => 'Ⰹ',
70518 'ⰺ' => 'Ⰺ',
70519 'ⰻ' => 'Ⰻ',
70520 'ⰼ' => 'Ⰼ',
70521 'ⰽ' => 'Ⰽ',
70522 'ⰾ' => 'Ⰾ',
70523 'ⰿ' => 'Ⰿ',
70524 'ⱀ' => 'Ⱀ',
70525 'ⱁ' => 'Ⱁ',
70526 'ⱂ' => 'Ⱂ',
70527 'ⱃ' => 'Ⱃ',
70528 'ⱄ' => 'Ⱄ',
70529 'ⱅ' => 'Ⱅ',
70530 'ⱆ' => 'Ⱆ',
70531 'ⱇ' => 'Ⱇ',
70532 'ⱈ' => 'Ⱈ',
70533 'ⱉ' => 'Ⱉ',
70534 'ⱊ' => 'Ⱊ',
70535 'ⱋ' => 'Ⱋ',
70536 'ⱌ' => 'Ⱌ',
70537 'ⱍ' => 'Ⱍ',
70538 'ⱎ' => 'Ⱎ',
70539 'ⱏ' => 'Ⱏ',
70540 'ⱐ' => 'Ⱐ',
70541 'ⱑ' => 'Ⱑ',
70542 'ⱒ' => 'Ⱒ',
70543 'ⱓ' => 'Ⱓ',
70544 'ⱔ' => 'Ⱔ',
70545 'ⱕ' => 'Ⱕ',
70546 'ⱖ' => 'Ⱖ',
70547 'ⱗ' => 'Ⱗ',
70548 'ⱘ' => 'Ⱘ',
70549 'ⱙ' => 'Ⱙ',
70550 'ⱚ' => 'Ⱚ',
70551 'ⱛ' => 'Ⱛ',
70552 'ⱜ' => 'Ⱜ',
70553 'ⱝ' => 'Ⱝ',
70554 'ⱞ' => 'Ⱞ',
70555 'ⱡ' => 'Ⱡ',
70556 'ⱥ' => 'Ⱥ',
70557 'ⱦ' => 'Ⱦ',
70558 'ⱨ' => 'Ⱨ',
70559 'ⱪ' => 'Ⱪ',
70560 'ⱬ' => 'Ⱬ',
70561 'ⱳ' => 'Ⱳ',
70562 'ⱶ' => 'Ⱶ',
70563 'ⲁ' => 'Ⲁ',
70564 'ⲃ' => 'Ⲃ',
70565 'ⲅ' => 'Ⲅ',
70566 'ⲇ' => 'Ⲇ',
70567 'ⲉ' => 'Ⲉ',
70568 'ⲋ' => 'Ⲋ',
70569 'ⲍ' => 'Ⲍ',
70570 'ⲏ' => 'Ⲏ',
70571 'ⲑ' => 'Ⲑ',
70572 'ⲓ' => 'Ⲓ',
70573 'ⲕ' => 'Ⲕ',
70574 'ⲗ' => 'Ⲗ',
70575 'ⲙ' => 'Ⲙ',
70576 'ⲛ' => 'Ⲛ',
70577 'ⲝ' => 'Ⲝ',
70578 'ⲟ' => 'Ⲟ',
70579 'ⲡ' => 'Ⲡ',
70580 'ⲣ' => 'Ⲣ',
70581 'ⲥ' => 'Ⲥ',
70582 'ⲧ' => 'Ⲧ',
70583 'ⲩ' => 'Ⲩ',
70584 'ⲫ' => 'Ⲫ',
70585 'ⲭ' => 'Ⲭ',
70586 'ⲯ' => 'Ⲯ',
70587 'ⲱ' => 'Ⲱ',
70588 'ⲳ' => 'Ⲳ',
70589 'ⲵ' => 'Ⲵ',
70590 'ⲷ' => 'Ⲷ',
70591 'ⲹ' => 'Ⲹ',
70592 'ⲻ' => 'Ⲻ',
70593 'ⲽ' => 'Ⲽ',
70594 'ⲿ' => 'Ⲿ',
70595 'ⳁ' => 'Ⳁ',
70596 'ⳃ' => 'Ⳃ',
70597 'ⳅ' => 'Ⳅ',
70598 'ⳇ' => 'Ⳇ',
70599 'ⳉ' => 'Ⳉ',
70600 'ⳋ' => 'Ⳋ',
70601 'ⳍ' => 'Ⳍ',
70602 'ⳏ' => 'Ⳏ',
70603 'ⳑ' => 'Ⳑ',
70604 'ⳓ' => 'Ⳓ',
70605 'ⳕ' => 'Ⳕ',
70606 'ⳗ' => 'Ⳗ',
70607 'ⳙ' => 'Ⳙ',
70608 'ⳛ' => 'Ⳛ',
70609 'ⳝ' => 'Ⳝ',
70610 'ⳟ' => 'Ⳟ',
70611 'ⳡ' => 'Ⳡ',
70612 'ⳣ' => 'Ⳣ',
70613 'ⳬ' => 'Ⳬ',
70614 'ⳮ' => 'Ⳮ',
70615 'ⳳ' => 'Ⳳ',
70616 'ⴀ' => 'Ⴀ',
70617 'ⴁ' => 'Ⴁ',
70618 'ⴂ' => 'Ⴂ',
70619 'ⴃ' => 'Ⴃ',
70620 'ⴄ' => 'Ⴄ',
70621 'ⴅ' => 'Ⴅ',
70622 'ⴆ' => 'Ⴆ',
70623 'ⴇ' => 'Ⴇ',
70624 'ⴈ' => 'Ⴈ',
70625 'ⴉ' => 'Ⴉ',
70626 'ⴊ' => 'Ⴊ',
70627 'ⴋ' => 'Ⴋ',
70628 'ⴌ' => 'Ⴌ',
70629 'ⴍ' => 'Ⴍ',
70630 'ⴎ' => 'Ⴎ',
70631 'ⴏ' => 'Ⴏ',
70632 'ⴐ' => 'Ⴐ',
70633 'ⴑ' => 'Ⴑ',
70634 'ⴒ' => 'Ⴒ',
70635 'ⴓ' => 'Ⴓ',
70636 'ⴔ' => 'Ⴔ',
70637 'ⴕ' => 'Ⴕ',
70638 'ⴖ' => 'Ⴖ',
70639 'ⴗ' => 'Ⴗ',
70640 'ⴘ' => 'Ⴘ',
70641 'ⴙ' => 'Ⴙ',
70642 'ⴚ' => 'Ⴚ',
70643 'ⴛ' => 'Ⴛ',
70644 'ⴜ' => 'Ⴜ',
70645 'ⴝ' => 'Ⴝ',
70646 'ⴞ' => 'Ⴞ',
70647 'ⴟ' => 'Ⴟ',
70648 'ⴠ' => 'Ⴠ',
70649 'ⴡ' => 'Ⴡ',
70650 'ⴢ' => 'Ⴢ',
70651 'ⴣ' => 'Ⴣ',
70652 'ⴤ' => 'Ⴤ',
70653 'ⴥ' => 'Ⴥ',
70654 'ⴧ' => 'Ⴧ',
70655 'ⴭ' => 'Ⴭ',
70656 'ꙁ' => 'Ꙁ',
70657 'ꙃ' => 'Ꙃ',
70658 'ꙅ' => 'Ꙅ',
70659 'ꙇ' => 'Ꙇ',
70660 'ꙉ' => 'Ꙉ',
70661 'ꙋ' => 'Ꙋ',
70662 'ꙍ' => 'Ꙍ',
70663 'ꙏ' => 'Ꙏ',
70664 'ꙑ' => 'Ꙑ',
70665 'ꙓ' => 'Ꙓ',
70666 'ꙕ' => 'Ꙕ',
70667 'ꙗ' => 'Ꙗ',
70668 'ꙙ' => 'Ꙙ',
70669 'ꙛ' => 'Ꙛ',
70670 'ꙝ' => 'Ꙝ',
70671 'ꙟ' => 'Ꙟ',
70672 'ꙡ' => 'Ꙡ',
70673 'ꙣ' => 'Ꙣ',
70674 'ꙥ' => 'Ꙥ',
70675 'ꙧ' => 'Ꙧ',
70676 'ꙩ' => 'Ꙩ',
70677 'ꙫ' => 'Ꙫ',
70678 'ꙭ' => 'Ꙭ',
70679 'ꚁ' => 'Ꚁ',
70680 'ꚃ' => 'Ꚃ',
70681 'ꚅ' => 'Ꚅ',
70682 'ꚇ' => 'Ꚇ',
70683 'ꚉ' => 'Ꚉ',
70684 'ꚋ' => 'Ꚋ',
70685 'ꚍ' => 'Ꚍ',
70686 'ꚏ' => 'Ꚏ',
70687 'ꚑ' => 'Ꚑ',
70688 'ꚓ' => 'Ꚓ',
70689 'ꚕ' => 'Ꚕ',
70690 'ꚗ' => 'Ꚗ',
70691 'ꚙ' => 'Ꚙ',
70692 'ꚛ' => 'Ꚛ',
70693 'ꜣ' => 'Ꜣ',
70694 'ꜥ' => 'Ꜥ',
70695 'ꜧ' => 'Ꜧ',
70696 'ꜩ' => 'Ꜩ',
70697 'ꜫ' => 'Ꜫ',
70698 'ꜭ' => 'Ꜭ',
70699 'ꜯ' => 'Ꜯ',
70700 'ꜳ' => 'Ꜳ',
70701 'ꜵ' => 'Ꜵ',
70702 'ꜷ' => 'Ꜷ',
70703 'ꜹ' => 'Ꜹ',
70704 'ꜻ' => 'Ꜻ',
70705 'ꜽ' => 'Ꜽ',
70706 'ꜿ' => 'Ꜿ',
70707 'ꝁ' => 'Ꝁ',
70708 'ꝃ' => 'Ꝃ',
70709 'ꝅ' => 'Ꝅ',
70710 'ꝇ' => 'Ꝇ',
70711 'ꝉ' => 'Ꝉ',
70712 'ꝋ' => 'Ꝋ',
70713 'ꝍ' => 'Ꝍ',
70714 'ꝏ' => 'Ꝏ',
70715 'ꝑ' => 'Ꝑ',
70716 'ꝓ' => 'Ꝓ',
70717 'ꝕ' => 'Ꝕ',
70718 'ꝗ' => 'Ꝗ',
70719 'ꝙ' => 'Ꝙ',
70720 'ꝛ' => 'Ꝛ',
70721 'ꝝ' => 'Ꝝ',
70722 'ꝟ' => 'Ꝟ',
70723 'ꝡ' => 'Ꝡ',
70724 'ꝣ' => 'Ꝣ',
70725 'ꝥ' => 'Ꝥ',
70726 'ꝧ' => 'Ꝧ',
70727 'ꝩ' => 'Ꝩ',
70728 'ꝫ' => 'Ꝫ',
70729 'ꝭ' => 'Ꝭ',
70730 'ꝯ' => 'Ꝯ',
70731 'ꝺ' => 'Ꝺ',
70732 'ꝼ' => 'Ꝼ',
70733 'ꝿ' => 'Ꝿ',
70734 'ꞁ' => 'Ꞁ',
70735 'ꞃ' => 'Ꞃ',
70736 'ꞅ' => 'Ꞅ',
70737 'ꞇ' => 'Ꞇ',
70738 'ꞌ' => 'Ꞌ',
70739 'ꞑ' => 'Ꞑ',
70740 'ꞓ' => 'Ꞓ',
70741 'ꞗ' => 'Ꞗ',
70742 'ꞙ' => 'Ꞙ',
70743 'ꞛ' => 'Ꞛ',
70744 'ꞝ' => 'Ꞝ',
70745 'ꞟ' => 'Ꞟ',
70746 'ꞡ' => 'Ꞡ',
70747 'ꞣ' => 'Ꞣ',
70748 'ꞥ' => 'Ꞥ',
70749 'ꞧ' => 'Ꞧ',
70750 'ꞩ' => 'Ꞩ',
70751 'a' => 'A',
70752 'b' => 'B',
70753 'c' => 'C',
70754 'd' => 'D',
70755 'e' => 'E',
70756 'f' => 'F',
70757 'g' => 'G',
70758 'h' => 'H',
70759 'i' => 'I',
70760 'j' => 'J',
70761 'k' => 'K',
70762 'l' => 'L',
70763 'm' => 'M',
70764 'n' => 'N',
70765 'o' => 'O',
70766 'p' => 'P',
70767 'q' => 'Q',
70768 'r' => 'R',
70769 's' => 'S',
70770 't' => 'T',
70771 'u' => 'U',
70772 'v' => 'V',
70773 'w' => 'W',
70774 'x' => 'X',
70775 'y' => 'Y',
70776 'z' => 'Z',
70777 '𐐨' => '𐐀',
70778 '𐐩' => '𐐁',
70779 '𐐪' => '𐐂',
70780 '𐐫' => '𐐃',
70781 '𐐬' => '𐐄',
70782 '𐐭' => '𐐅',
70783 '𐐮' => '𐐆',
70784 '𐐯' => '𐐇',
70785 '𐐰' => '𐐈',
70786 '𐐱' => '𐐉',
70787 '𐐲' => '𐐊',
70788 '𐐳' => '𐐋',
70789 '𐐴' => '𐐌',
70790 '𐐵' => '𐐍',
70791 '𐐶' => '𐐎',
70792 '𐐷' => '𐐏',
70793 '𐐸' => '𐐐',
70794 '𐐹' => '𐐑',
70795 '𐐺' => '𐐒',
70796 '𐐻' => '𐐓',
70797 '𐐼' => '𐐔',
70798 '𐐽' => '𐐕',
70799 '𐐾' => '𐐖',
70800 '𐐿' => '𐐗',
70801 '𐑀' => '𐐘',
70802 '𐑁' => '𐐙',
70803 '𐑂' => '𐐚',
70804 '𐑃' => '𐐛',
70805 '𐑄' => '𐐜',
70806 '𐑅' => '𐐝',
70807 '𐑆' => '𐐞',
70808 '𐑇' => '𐐟',
70809 '𐑈' => '𐐠',
70810 '𐑉' => '𐐡',
70811 '𐑊' => '𐐢',
70812 '𐑋' => '𐐣',
70813 '𐑌' => '𐐤',
70814 '𐑍' => '𐐥',
70815 '𐑎' => '𐐦',
70816 '𐑏' => '𐐧',
70817 '𑣀' => '𑢠',
70818 '𑣁' => '𑢡',
70819 '𑣂' => '𑢢',
70820 '𑣃' => '𑢣',
70821 '𑣄' => '𑢤',
70822 '𑣅' => '𑢥',
70823 '𑣆' => '𑢦',
70824 '𑣇' => '𑢧',
70825 '𑣈' => '𑢨',
70826 '𑣉' => '𑢩',
70827 '𑣊' => '𑢪',
70828 '𑣋' => '𑢫',
70829 '𑣌' => '𑢬',
70830 '𑣍' => '𑢭',
70831 '𑣎' => '𑢮',
70832 '𑣏' => '𑢯',
70833 '𑣐' => '𑢰',
70834 '𑣑' => '𑢱',
70835 '𑣒' => '𑢲',
70836 '𑣓' => '𑢳',
70837 '𑣔' => '𑢴',
70838 '𑣕' => '𑢵',
70839 '𑣖' => '𑢶',
70840 '𑣗' => '𑢷',
70841 '𑣘' => '𑢸',
70842 '𑣙' => '𑢹',
70843 '𑣚' => '𑢺',
70844 '𑣛' => '𑢻',
70845 '𑣜' => '𑢼',
70846 '𑣝' => '𑢽',
70847 '𑣞' => '𑢾',
70848 '𑣟' => '𑢿',
70849 );
70850
70851 $result =& $data;
70852 unset($data);
70853
70854 return $result;
70855 <?php
70856
70857
70858
70859
70860
70861
70862
70863
70864
70865
70866 use Symfony\Polyfill\Mbstring as p;
70867
70868 if (!function_exists('mb_strlen')) {
70869 define('MB_CASE_UPPER', 0);
70870 define('MB_CASE_LOWER', 1);
70871 define('MB_CASE_TITLE', 2);
70872
70873 function mb_convert_encoding($s, $to, $from = null) { return p\Mbstring::mb_convert_encoding($s, $to, $from); }
70874 function mb_decode_mimeheader($s) { return p\Mbstring::mb_decode_mimeheader($s); }
70875 function mb_encode_mimeheader($s, $charset = null, $transferEnc = null, $lf = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($s, $charset, $transferEnc, $lf, $indent); }
70876 function mb_convert_case($s, $mode, $enc = null) { return p\Mbstring::mb_convert_case($s, $mode, $enc); }
70877 function mb_internal_encoding($enc = null) { return p\Mbstring::mb_internal_encoding($enc); }
70878 function mb_language($lang = null) { return p\Mbstring::mb_language($lang); }
70879 function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
70880 function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
70881 function mb_check_encoding($var = null, $encoding = null) { return p\Mbstring::mb_check_encoding($var, $encoding); }
70882 function mb_detect_encoding($str, $encodingList = null, $strict = false) { return p\Mbstring::mb_detect_encoding($str, $encodingList, $strict); }
70883 function mb_detect_order($encodingList = null) { return p\Mbstring::mb_detect_order($encodingList); }
70884 function mb_parse_str($s, &$result = array()) { parse_str($s, $result); }
70885 function mb_strlen($s, $enc = null) { return p\Mbstring::mb_strlen($s, $enc); }
70886 function mb_strpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strpos($s, $needle, $offset, $enc); }
70887 function mb_strtolower($s, $enc = null) { return p\Mbstring::mb_strtolower($s, $enc); }
70888 function mb_strtoupper($s, $enc = null) { return p\Mbstring::mb_strtoupper($s, $enc); }
70889 function mb_substitute_character($char = null) { return p\Mbstring::mb_substitute_character($char); }
70890 function mb_substr($s, $start, $length = 2147483647, $enc = null) { return p\Mbstring::mb_substr($s, $start, $length, $enc); }
70891 function mb_stripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_stripos($s, $needle, $offset, $enc); }
70892 function mb_stristr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_stristr($s, $needle, $part, $enc); }
70893 function mb_strrchr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrchr($s, $needle, $part, $enc); }
70894 function mb_strrichr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strrichr($s, $needle, $part, $enc); }
70895 function mb_strripos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strripos($s, $needle, $offset, $enc); }
70896 function mb_strrpos($s, $needle, $offset = 0, $enc = null) { return p\Mbstring::mb_strrpos($s, $needle, $offset, $enc); }
70897 function mb_strstr($s, $needle, $part = false, $enc = null) { return p\Mbstring::mb_strstr($s, $needle, $part, $enc); }
70898 function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
70899 function mb_http_output($enc = null) { return p\Mbstring::mb_http_output($enc); }
70900 function mb_strwidth($s, $enc = null) { return p\Mbstring::mb_strwidth($s, $enc); }
70901 function mb_substr_count($haystack, $needle, $enc = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $enc); }
70902 function mb_output_handler($contents, $status) { return p\Mbstring::mb_output_handler($contents, $status); }
70903 function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
70904 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); }
70905 }
70906 if (!function_exists('mb_chr')) {
70907 function mb_ord($s, $enc = null) { return p\Mbstring::mb_ord($s, $enc); }
70908 function mb_chr($code, $enc = null) { return p\Mbstring::mb_chr($code, $enc); }
70909 function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
70910 }
70911 <?php
70912
70913
70914
70915
70916
70917
70918
70919
70920
70921
70922 namespace Symfony\Component\Process\Exception;
70923
70924
70925
70926
70927
70928
70929 interface ExceptionInterface
70930 {
70931 }
70932 <?php
70933
70934
70935
70936
70937
70938
70939
70940
70941
70942
70943 namespace Symfony\Component\Process\Exception;
70944
70945
70946
70947
70948
70949
70950 class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
70951 {
70952 }
70953 <?php
70954
70955
70956
70957
70958
70959
70960
70961
70962
70963
70964 namespace Symfony\Component\Process\Exception;
70965
70966
70967
70968
70969
70970
70971 class LogicException extends \LogicException implements ExceptionInterface
70972 {
70973 }
70974 <?php
70975
70976
70977
70978
70979
70980
70981
70982
70983
70984
70985 namespace Symfony\Component\Process\Exception;
70986
70987 use Symfony\Component\Process\Process;
70988
70989
70990
70991
70992
70993
70994 class ProcessFailedException extends RuntimeException
70995 {
70996 private $process;
70997
70998 public function __construct(Process $process)
70999 {
71000 if ($process->isSuccessful()) {
71001 throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
71002 }
71003
71004 $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
71005 $process->getCommandLine(),
71006 $process->getExitCode(),
71007 $process->getExitCodeText(),
71008 $process->getWorkingDirectory()
71009 );
71010
71011 if (!$process->isOutputDisabled()) {
71012 $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
71013 $process->getOutput(),
71014 $process->getErrorOutput()
71015 );
71016 }
71017
71018 parent::__construct($error);
71019
71020 $this->process = $process;
71021 }
71022
71023 public function getProcess()
71024 {
71025 return $this->process;
71026 }
71027 }
71028 <?php
71029
71030
71031
71032
71033
71034
71035
71036
71037
71038
71039 namespace Symfony\Component\Process\Exception;
71040
71041 use Symfony\Component\Process\Process;
71042
71043
71044
71045
71046
71047
71048 class ProcessTimedOutException extends RuntimeException
71049 {
71050 const TYPE_GENERAL = 1;
71051 const TYPE_IDLE = 2;
71052
71053 private $process;
71054 private $timeoutType;
71055
71056 public function __construct(Process $process, $timeoutType)
71057 {
71058 $this->process = $process;
71059 $this->timeoutType = $timeoutType;
71060
71061 parent::__construct(sprintf(
71062 'The process "%s" exceeded the timeout of %s seconds.',
71063 $process->getCommandLine(),
71064 $this->getExceededTimeout()
71065 ));
71066 }
71067
71068 public function getProcess()
71069 {
71070 return $this->process;
71071 }
71072
71073 public function isGeneralTimeout()
71074 {
71075 return $this->timeoutType === self::TYPE_GENERAL;
71076 }
71077
71078 public function isIdleTimeout()
71079 {
71080 return $this->timeoutType === self::TYPE_IDLE;
71081 }
71082
71083 public function getExceededTimeout()
71084 {
71085 switch ($this->timeoutType) {
71086 case self::TYPE_GENERAL:
71087 return $this->process->getTimeout();
71088
71089 case self::TYPE_IDLE:
71090 return $this->process->getIdleTimeout();
71091
71092 default:
71093 throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType));
71094 }
71095 }
71096 }
71097 <?php
71098
71099
71100
71101
71102
71103
71104
71105
71106
71107
71108 namespace Symfony\Component\Process\Exception;
71109
71110
71111
71112
71113
71114
71115 class RuntimeException extends \RuntimeException implements ExceptionInterface
71116 {
71117 }
71118 <?php
71119
71120
71121
71122
71123
71124
71125
71126
71127
71128
71129 namespace Symfony\Component\Process;
71130
71131
71132
71133
71134
71135
71136
71137 class ExecutableFinder
71138 {
71139 private $suffixes = array('.exe', '.bat', '.cmd', '.com');
71140
71141
71142
71143
71144
71145
71146 public function setSuffixes(array $suffixes)
71147 {
71148 $this->suffixes = $suffixes;
71149 }
71150
71151
71152
71153
71154
71155
71156 public function addSuffix($suffix)
71157 {
71158 $this->suffixes[] = $suffix;
71159 }
71160
71161
71162
71163
71164
71165
71166
71167
71168
71169
71170 public function find($name, $default = null, array $extraDirs = array())
71171 {
71172 if (ini_get('open_basedir')) {
71173 $searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir'));
71174 $dirs = array();
71175 foreach ($searchPath as $path) {
71176
71177  if (@is_dir($path)) {
71178 $dirs[] = $path;
71179 } else {
71180 if (basename($path) == $name && @is_executable($path)) {
71181 return $path;
71182 }
71183 }
71184 }
71185 } else {
71186 $dirs = array_merge(
71187 explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
71188 $extraDirs
71189 );
71190 }
71191
71192 $suffixes = array('');
71193 if ('\\' === DIRECTORY_SEPARATOR) {
71194 $pathExt = getenv('PATHEXT');
71195 $suffixes = array_merge($suffixes, $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes);
71196 }
71197 foreach ($suffixes as $suffix) {
71198 foreach ($dirs as $dir) {
71199 if (@is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === DIRECTORY_SEPARATOR || is_executable($file))) {
71200 return $file;
71201 }
71202 }
71203 }
71204
71205 return $default;
71206 }
71207 }
71208 Copyright (c) 2004-2017 Fabien Potencier
71209
71210 Permission is hereby granted, free of charge, to any person obtaining a copy
71211 of this software and associated documentation files (the "Software"), to deal
71212 in the Software without restriction, including without limitation the rights
71213 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
71214 copies of the Software, and to permit persons to whom the Software is furnished
71215 to do so, subject to the following conditions:
71216
71217 The above copyright notice and this permission notice shall be included in all
71218 copies or substantial portions of the Software.
71219
71220 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
71221 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
71222 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
71223 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71224 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
71225 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
71226 THE SOFTWARE.
71227 <?php
71228
71229
71230
71231
71232
71233
71234
71235
71236
71237
71238 namespace Symfony\Component\Process;
71239
71240
71241
71242
71243
71244
71245
71246 class PhpExecutableFinder
71247 {
71248 private $executableFinder;
71249
71250 public function __construct()
71251 {
71252 $this->executableFinder = new ExecutableFinder();
71253 }
71254
71255
71256
71257
71258
71259
71260
71261
71262 public function find($includeArgs = true)
71263 {
71264 $args = $this->findArguments();
71265 $args = $includeArgs && $args ? ' '.implode(' ', $args) : '';
71266
71267
71268  if (defined('HHVM_VERSION')) {
71269 return (getenv('PHP_BINARY') ?: PHP_BINARY).$args;
71270 }
71271
71272
71273  if (defined('PHP_BINARY') && PHP_BINARY && in_array(PHP_SAPI, array('cli', 'cli-server', 'phpdbg')) && is_file(PHP_BINARY)) {
71274 return PHP_BINARY.$args;
71275 }
71276
71277 if ($php = getenv('PHP_PATH')) {
71278 if (!is_executable($php)) {
71279 return false;
71280 }
71281
71282 return $php;
71283 }
71284
71285 if ($php = getenv('PHP_PEAR_PHP_BIN')) {
71286 if (is_executable($php)) {
71287 return $php;
71288 }
71289 }
71290
71291 $dirs = array(PHP_BINDIR);
71292 if ('\\' === DIRECTORY_SEPARATOR) {
71293 $dirs[] = 'C:\xampp\php\\';
71294 }
71295
71296 return $this->executableFinder->find('php', false, $dirs);
71297 }
71298
71299
71300
71301
71302
71303
71304 public function findArguments()
71305 {
71306 $arguments = array();
71307
71308 if (defined('HHVM_VERSION')) {
71309 $arguments[] = '--php';
71310 } elseif ('phpdbg' === PHP_SAPI) {
71311 $arguments[] = '-qrr';
71312 }
71313
71314 return $arguments;
71315 }
71316 }
71317 <?php
71318
71319
71320
71321
71322
71323
71324
71325
71326
71327
71328 namespace Symfony\Component\Process;
71329
71330 use Symfony\Component\Process\Exception\RuntimeException;
71331
71332
71333
71334
71335
71336
71337
71338
71339
71340
71341 class PhpProcess extends Process
71342 {
71343
71344
71345
71346
71347
71348
71349
71350
71351
71352 public function __construct($script, $cwd = null, array $env = null, $timeout = 60, array $options = array())
71353 {
71354 $executableFinder = new PhpExecutableFinder();
71355 if (false === $php = $executableFinder->find()) {
71356 $php = null;
71357 }
71358 if ('phpdbg' === PHP_SAPI) {
71359 $file = tempnam(sys_get_temp_dir(), 'dbg');
71360 file_put_contents($file, $script);
71361 register_shutdown_function('unlink', $file);
71362 $php .= ' '.ProcessUtils::escapeArgument($file);
71363 $script = null;
71364 }
71365 if ('\\' !== DIRECTORY_SEPARATOR && null !== $php) {
71366
71367  
71368  
71369  $php = 'exec '.$php;
71370 }
71371
71372 parent::__construct($php, $cwd, $env, $script, $timeout, $options);
71373 }
71374
71375
71376
71377
71378 public function setPhpBinary($php)
71379 {
71380 $this->setCommandLine($php);
71381 }
71382
71383
71384
71385
71386 public function start($callback = null)
71387 {
71388 if (null === $this->getCommandLine()) {
71389 throw new RuntimeException('Unable to find the PHP executable.');
71390 }
71391
71392 parent::start($callback);
71393 }
71394 }
71395 <?php
71396
71397
71398
71399
71400
71401
71402
71403
71404
71405
71406 namespace Symfony\Component\Process\Pipes;
71407
71408
71409
71410
71411
71412
71413 abstract class AbstractPipes implements PipesInterface
71414 {
71415
71416 public $pipes = array();
71417
71418
71419 private $inputBuffer = '';
71420
71421 private $input;
71422
71423 private $blocked = true;
71424
71425 public function __construct($input)
71426 {
71427 if (is_resource($input)) {
71428 $this->input = $input;
71429 } elseif (is_string($input)) {
71430 $this->inputBuffer = $input;
71431 } else {
71432 $this->inputBuffer = (string) $input;
71433 }
71434 }
71435
71436
71437
71438
71439 public function close()
71440 {
71441 foreach ($this->pipes as $pipe) {
71442 fclose($pipe);
71443 }
71444 $this->pipes = array();
71445 }
71446
71447
71448
71449
71450
71451
71452 protected function hasSystemCallBeenInterrupted()
71453 {
71454 $lastError = error_get_last();
71455
71456
71457  return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call');
71458 }
71459
71460
71461
71462
71463 protected function unblock()
71464 {
71465 if (!$this->blocked) {
71466 return;
71467 }
71468
71469 foreach ($this->pipes as $pipe) {
71470 stream_set_blocking($pipe, 0);
71471 }
71472 if (null !== $this->input) {
71473 stream_set_blocking($this->input, 0);
71474 }
71475
71476 $this->blocked = false;
71477 }
71478
71479
71480
71481
71482 protected function write()
71483 {
71484 if (!isset($this->pipes[0])) {
71485 return;
71486 }
71487 $input = $this->input;
71488 $r = $e = array();
71489 $w = array($this->pipes[0]);
71490
71491
71492  if (false === $n = @stream_select($r, $w, $e, 0, 0)) {
71493 return;
71494 }
71495
71496 foreach ($w as $stdin) {
71497 if (isset($this->inputBuffer[0])) {
71498 $written = fwrite($stdin, $this->inputBuffer);
71499 $this->inputBuffer = substr($this->inputBuffer, $written);
71500 if (isset($this->inputBuffer[0])) {
71501 return array($this->pipes[0]);
71502 }
71503 }
71504
71505 if ($input) {
71506 for (;;) {
71507 $data = fread($input, self::CHUNK_SIZE);
71508 if (!isset($data[0])) {
71509 break;
71510 }
71511 $written = fwrite($stdin, $data);
71512 $data = substr($data, $written);
71513 if (isset($data[0])) {
71514 $this->inputBuffer = $data;
71515
71516 return array($this->pipes[0]);
71517 }
71518 }
71519 if (feof($input)) {
71520
71521  
71522  $this->input = null;
71523 }
71524 }
71525 }
71526
71527
71528  if (null === $this->input && !isset($this->inputBuffer[0])) {
71529 fclose($this->pipes[0]);
71530 unset($this->pipes[0]);
71531 } elseif (!$w) {
71532 return array($this->pipes[0]);
71533 }
71534 }
71535 }
71536 <?php
71537
71538
71539
71540
71541
71542
71543
71544
71545
71546
71547 namespace Symfony\Component\Process\Pipes;
71548
71549
71550
71551
71552
71553
71554
71555
71556 interface PipesInterface
71557 {
71558 const CHUNK_SIZE = 16384;
71559
71560
71561
71562
71563
71564
71565 public function getDescriptors();
71566
71567
71568
71569
71570
71571
71572 public function getFiles();
71573
71574
71575
71576
71577
71578
71579
71580
71581
71582 public function readAndWrite($blocking, $close = false);
71583
71584
71585
71586
71587
71588
71589 public function areOpen();
71590
71591
71592
71593
71594 public function close();
71595 }
71596 <?php
71597
71598
71599
71600
71601
71602
71603
71604
71605
71606
71607 namespace Symfony\Component\Process\Pipes;
71608
71609 use Symfony\Component\Process\Process;
71610
71611
71612
71613
71614
71615
71616
71617
71618 class UnixPipes extends AbstractPipes
71619 {
71620
71621 private $ttyMode;
71622
71623 private $ptyMode;
71624
71625 private $disableOutput;
71626
71627 public function __construct($ttyMode, $ptyMode, $input, $disableOutput)
71628 {
71629 $this->ttyMode = (bool) $ttyMode;
71630 $this->ptyMode = (bool) $ptyMode;
71631 $this->disableOutput = (bool) $disableOutput;
71632
71633 parent::__construct($input);
71634 }
71635
71636 public function __destruct()
71637 {
71638 $this->close();
71639 }
71640
71641
71642
71643
71644 public function getDescriptors()
71645 {
71646 if ($this->disableOutput) {
71647 $nullstream = fopen('/dev/null', 'c');
71648
71649 return array(
71650 array('pipe', 'r'),
71651 $nullstream,
71652 $nullstream,
71653 );
71654 }
71655
71656 if ($this->ttyMode) {
71657 return array(
71658 array('file', '/dev/tty', 'r'),
71659 array('file', '/dev/tty', 'w'),
71660 array('file', '/dev/tty', 'w'),
71661 );
71662 }
71663
71664 if ($this->ptyMode && Process::isPtySupported()) {
71665 return array(
71666 array('pty'),
71667 array('pty'),
71668 array('pty'),
71669 );
71670 }
71671
71672 return array(
71673 array('pipe', 'r'),
71674 array('pipe', 'w'), 
71675  array('pipe', 'w'), 
71676  );
71677 }
71678
71679
71680
71681
71682 public function getFiles()
71683 {
71684 return array();
71685 }
71686
71687
71688
71689
71690 public function readAndWrite($blocking, $close = false)
71691 {
71692 $this->unblock();
71693 $w = $this->write();
71694
71695 $read = $e = array();
71696 $r = $this->pipes;
71697 unset($r[0]);
71698
71699
71700  if (($r || $w) && false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
71701
71702  
71703  if (!$this->hasSystemCallBeenInterrupted()) {
71704 $this->pipes = array();
71705 }
71706
71707 return $read;
71708 }
71709
71710 foreach ($r as $pipe) {
71711
71712  
71713  $read[$type = array_search($pipe, $this->pipes, true)] = '';
71714
71715 do {
71716 $data = fread($pipe, self::CHUNK_SIZE);
71717 $read[$type] .= $data;
71718 } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));
71719
71720 if (!isset($read[$type][0])) {
71721 unset($read[$type]);
71722 }
71723
71724 if ($close && feof($pipe)) {
71725 fclose($pipe);
71726 unset($this->pipes[$type]);
71727 }
71728 }
71729
71730 return $read;
71731 }
71732
71733
71734
71735
71736 public function areOpen()
71737 {
71738 return (bool) $this->pipes;
71739 }
71740
71741
71742
71743
71744
71745
71746
71747
71748
71749 public static function create(Process $process, $input)
71750 {
71751 return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled());
71752 }
71753 }
71754 <?php
71755
71756
71757
71758
71759
71760
71761
71762
71763
71764
71765 namespace Symfony\Component\Process\Pipes;
71766
71767 use Symfony\Component\Process\Process;
71768 use Symfony\Component\Process\Exception\RuntimeException;
71769
71770
71771
71772
71773
71774
71775
71776
71777
71778
71779
71780 class WindowsPipes extends AbstractPipes
71781 {
71782
71783 private $files = array();
71784
71785 private $fileHandles = array();
71786
71787 private $readBytes = array(
71788 Process::STDOUT => 0,
71789 Process::STDERR => 0,
71790 );
71791
71792 private $disableOutput;
71793
71794 public function __construct($disableOutput, $input)
71795 {
71796 $this->disableOutput = (bool) $disableOutput;
71797
71798 if (!$this->disableOutput) {
71799
71800  
71801  
71802  
71803  $pipes = array(
71804 Process::STDOUT => Process::OUT,
71805 Process::STDERR => Process::ERR,
71806 );
71807 $tmpCheck = false;
71808 $tmpDir = sys_get_temp_dir();
71809 $lastError = 'unknown reason';
71810 set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
71811 for ($i = 0;; ++$i) {
71812 foreach ($pipes as $pipe => $name) {
71813 $file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
71814 if (file_exists($file) && !unlink($file)) {
71815 continue 2;
71816 }
71817 $h = fopen($file, 'xb');
71818 if (!$h) {
71819 $error = $lastError;
71820 if ($tmpCheck || $tmpCheck = unlink(tempnam(false, 'sf_check_'))) {
71821 continue;
71822 }
71823 restore_error_handler();
71824 throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $error));
71825 }
71826 if (!$h || !$this->fileHandles[$pipe] = fopen($file, 'rb')) {
71827 continue 2;
71828 }
71829 if (isset($this->files[$pipe])) {
71830 unlink($this->files[$pipe]);
71831 }
71832 $this->files[$pipe] = $file;
71833 }
71834 break;
71835 }
71836 restore_error_handler();
71837 }
71838
71839 parent::__construct($input);
71840 }
71841
71842 public function __destruct()
71843 {
71844 $this->close();
71845 $this->removeFiles();
71846 }
71847
71848
71849
71850
71851 public function getDescriptors()
71852 {
71853 if ($this->disableOutput) {
71854 $nullstream = fopen('NUL', 'c');
71855
71856 return array(
71857 array('pipe', 'r'),
71858 $nullstream,
71859 $nullstream,
71860 );
71861 }
71862
71863
71864  
71865  
71866  return array(
71867 array('pipe', 'r'),
71868 array('file', 'NUL', 'w'),
71869 array('file', 'NUL', 'w'),
71870 );
71871 }
71872
71873
71874
71875
71876 public function getFiles()
71877 {
71878 return $this->files;
71879 }
71880
71881
71882
71883
71884 public function readAndWrite($blocking, $close = false)
71885 {
71886 $this->unblock();
71887 $w = $this->write();
71888 $read = $r = $e = array();
71889
71890 if ($blocking) {
71891 if ($w) {
71892 @stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6);
71893 } elseif ($this->fileHandles) {
71894 usleep(Process::TIMEOUT_PRECISION * 1E6);
71895 }
71896 }
71897 foreach ($this->fileHandles as $type => $fileHandle) {
71898 $data = stream_get_contents($fileHandle, -1, $this->readBytes[$type]);
71899
71900 if (isset($data[0])) {
71901 $this->readBytes[$type] += strlen($data);
71902 $read[$type] = $data;
71903 }
71904 if ($close) {
71905 fclose($fileHandle);
71906 unset($this->fileHandles[$type]);
71907 }
71908 }
71909
71910 return $read;
71911 }
71912
71913
71914
71915
71916 public function areOpen()
71917 {
71918 return $this->pipes && $this->fileHandles;
71919 }
71920
71921
71922
71923
71924 public function close()
71925 {
71926 parent::close();
71927 foreach ($this->fileHandles as $handle) {
71928 fclose($handle);
71929 }
71930 $this->fileHandles = array();
71931 }
71932
71933
71934
71935
71936
71937
71938
71939
71940
71941 public static function create(Process $process, $input)
71942 {
71943 return new static($process->isOutputDisabled(), $input);
71944 }
71945
71946
71947
71948
71949 private function removeFiles()
71950 {
71951 foreach ($this->files as $filename) {
71952 if (file_exists($filename)) {
71953 @unlink($filename);
71954 }
71955 }
71956 $this->files = array();
71957 }
71958 }
71959 <?php
71960
71961
71962
71963
71964
71965
71966
71967
71968
71969
71970 namespace Symfony\Component\Process;
71971
71972 use Symfony\Component\Process\Exception\InvalidArgumentException;
71973 use Symfony\Component\Process\Exception\LogicException;
71974 use Symfony\Component\Process\Exception\ProcessFailedException;
71975 use Symfony\Component\Process\Exception\ProcessTimedOutException;
71976 use Symfony\Component\Process\Exception\RuntimeException;
71977 use Symfony\Component\Process\Pipes\PipesInterface;
71978 use Symfony\Component\Process\Pipes\UnixPipes;
71979 use Symfony\Component\Process\Pipes\WindowsPipes;
71980
71981
71982
71983
71984
71985
71986
71987
71988 class Process
71989 {
71990 const ERR = 'err';
71991 const OUT = 'out';
71992
71993 const STATUS_READY = 'ready';
71994 const STATUS_STARTED = 'started';
71995 const STATUS_TERMINATED = 'terminated';
71996
71997 const STDIN = 0;
71998 const STDOUT = 1;
71999 const STDERR = 2;
72000
72001
72002  const TIMEOUT_PRECISION = 0.2;
72003
72004 private $callback;
72005 private $commandline;
72006 private $cwd;
72007 private $env;
72008 private $input;
72009 private $starttime;
72010 private $lastOutputTime;
72011 private $timeout;
72012 private $idleTimeout;
72013 private $options;
72014 private $exitcode;
72015 private $fallbackStatus = array();
72016 private $processInformation;
72017 private $outputDisabled = false;
72018 private $stdout;
72019 private $stderr;
72020 private $enhanceWindowsCompatibility = true;
72021 private $enhanceSigchildCompatibility;
72022 private $process;
72023 private $status = self::STATUS_READY;
72024 private $incrementalOutputOffset = 0;
72025 private $incrementalErrorOutputOffset = 0;
72026 private $tty;
72027 private $pty;
72028
72029 private $useFileHandles = false;
72030
72031 private $processPipes;
72032
72033 private $latestSignal;
72034
72035 private static $sigchild;
72036
72037
72038
72039
72040
72041
72042
72043
72044 public static $exitCodes = array(
72045 0 => 'OK',
72046 1 => 'General error',
72047 2 => 'Misuse of shell builtins',
72048
72049 126 => 'Invoked command cannot execute',
72050 127 => 'Command not found',
72051 128 => 'Invalid exit argument',
72052
72053
72054  129 => 'Hangup',
72055 130 => 'Interrupt',
72056 131 => 'Quit and dump core',
72057 132 => 'Illegal instruction',
72058 133 => 'Trace/breakpoint trap',
72059 134 => 'Process aborted',
72060 135 => 'Bus error: "access to undefined portion of memory object"',
72061 136 => 'Floating point exception: "erroneous arithmetic operation"',
72062 137 => 'Kill (terminate immediately)',
72063 138 => 'User-defined 1',
72064 139 => 'Segmentation violation',
72065 140 => 'User-defined 2',
72066 141 => 'Write to pipe with no one reading',
72067 142 => 'Signal raised by alarm',
72068 143 => 'Termination (request to terminate)',
72069
72070  145 => 'Child process terminated, stopped (or continued*)',
72071 146 => 'Continue if stopped',
72072 147 => 'Stop executing temporarily',
72073 148 => 'Terminal stop signal',
72074 149 => 'Background process attempting to read from tty ("in")',
72075 150 => 'Background process attempting to write to tty ("out")',
72076 151 => 'Urgent data available on socket',
72077 152 => 'CPU time limit exceeded',
72078 153 => 'File size limit exceeded',
72079 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"',
72080 155 => 'Profiling timer expired',
72081
72082  157 => 'Pollable event',
72083
72084  159 => 'Bad syscall',
72085 );
72086
72087
72088
72089
72090
72091
72092
72093
72094
72095
72096
72097
72098
72099 public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array())
72100 {
72101 if (!function_exists('proc_open')) {
72102 throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');
72103 }
72104
72105 $this->commandline = $commandline;
72106 $this->cwd = $cwd;
72107
72108
72109  
72110  
72111  
72112  if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DIRECTORY_SEPARATOR)) {
72113 $this->cwd = getcwd();
72114 }
72115 if (null !== $env) {
72116 $this->setEnv($env);
72117 }
72118
72119 $this->setInput($input);
72120 $this->setTimeout($timeout);
72121 $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
72122 $this->pty = false;
72123 $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled();
72124 $this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options);
72125 }
72126
72127 public function __destruct()
72128 {
72129 $this->stop(0);
72130 }
72131
72132 public function __clone()
72133 {
72134 $this->resetProcessData();
72135 }
72136
72137
72138
72139
72140
72141
72142
72143
72144
72145
72146
72147
72148
72149
72150
72151
72152
72153
72154
72155
72156 public function run($callback = null)
72157 {
72158 $this->start($callback);
72159
72160 return $this->wait();
72161 }
72162
72163
72164
72165
72166
72167
72168
72169
72170
72171
72172
72173
72174
72175
72176 public function mustRun($callback = null)
72177 {
72178 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
72179 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
72180 }
72181
72182 if (0 !== $this->run($callback)) {
72183 throw new ProcessFailedException($this);
72184 }
72185
72186 return $this;
72187 }
72188
72189
72190
72191
72192
72193
72194
72195
72196
72197
72198
72199
72200
72201
72202
72203
72204
72205
72206
72207
72208 public function start($callback = null)
72209 {
72210 if ($this->isRunning()) {
72211 throw new RuntimeException('Process is already running');
72212 }
72213 if ($this->outputDisabled && null !== $callback) {
72214 throw new LogicException('Output has been disabled, enable it to allow the use of a callback.');
72215 }
72216
72217 $this->resetProcessData();
72218 $this->starttime = $this->lastOutputTime = microtime(true);
72219 $this->callback = $this->buildCallback($callback);
72220 $descriptors = $this->getDescriptors();
72221
72222 $commandline = $this->commandline;
72223
72224 if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
72225 $commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')';
72226 foreach ($this->processPipes->getFiles() as $offset => $filename) {
72227 $commandline .= ' '.$offset.'>'.ProcessUtils::escapeArgument($filename);
72228 }
72229 $commandline .= '"';
72230
72231 if (!isset($this->options['bypass_shell'])) {
72232 $this->options['bypass_shell'] = true;
72233 }
72234 } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
72235
72236  $descriptors[3] = array('pipe', 'w');
72237
72238
72239  $commandline = '{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
72240 $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
72241
72242
72243  
72244  $ptsWorkaround = fopen(__FILE__, 'r');
72245 }
72246
72247 $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options);
72248
72249 if (!is_resource($this->process)) {
72250 throw new RuntimeException('Unable to launch a new process.');
72251 }
72252 $this->status = self::STATUS_STARTED;
72253
72254 if (isset($descriptors[3])) {
72255 $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
72256 }
72257
72258 if ($this->tty) {
72259 return;
72260 }
72261
72262 $this->updateStatus(false);
72263 $this->checkTimeout();
72264 }
72265
72266
72267
72268
72269
72270
72271
72272
72273
72274
72275
72276
72277
72278
72279
72280
72281 public function restart($callback = null)
72282 {
72283 if ($this->isRunning()) {
72284 throw new RuntimeException('Process is already running');
72285 }
72286
72287 $process = clone $this;
72288 $process->start($callback);
72289
72290 return $process;
72291 }
72292
72293
72294
72295
72296
72297
72298
72299
72300
72301
72302
72303
72304
72305
72306
72307
72308 public function wait($callback = null)
72309 {
72310 $this->requireProcessIsStarted(__FUNCTION__);
72311
72312 $this->updateStatus(false);
72313 if (null !== $callback) {
72314 $this->callback = $this->buildCallback($callback);
72315 }
72316
72317 do {
72318 $this->checkTimeout();
72319 $running = '\\' === DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
72320 $this->readPipes($running, '\\' !== DIRECTORY_SEPARATOR || !$running);
72321 } while ($running);
72322
72323 while ($this->isRunning()) {
72324 usleep(1000);
72325 }
72326
72327 if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
72328 throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
72329 }
72330
72331 return $this->exitcode;
72332 }
72333
72334
72335
72336
72337
72338
72339 public function getPid()
72340 {
72341 return $this->isRunning() ? $this->processInformation['pid'] : null;
72342 }
72343
72344
72345
72346
72347
72348
72349
72350
72351
72352
72353
72354
72355 public function signal($signal)
72356 {
72357 $this->doSignal($signal, true);
72358
72359 return $this;
72360 }
72361
72362
72363
72364
72365
72366
72367
72368
72369
72370 public function disableOutput()
72371 {
72372 if ($this->isRunning()) {
72373 throw new RuntimeException('Disabling output while the process is running is not possible.');
72374 }
72375 if (null !== $this->idleTimeout) {
72376 throw new LogicException('Output can not be disabled while an idle timeout is set.');
72377 }
72378
72379 $this->outputDisabled = true;
72380
72381 return $this;
72382 }
72383
72384
72385
72386
72387
72388
72389
72390
72391 public function enableOutput()
72392 {
72393 if ($this->isRunning()) {
72394 throw new RuntimeException('Enabling output while the process is running is not possible.');
72395 }
72396
72397 $this->outputDisabled = false;
72398
72399 return $this;
72400 }
72401
72402
72403
72404
72405
72406
72407 public function isOutputDisabled()
72408 {
72409 return $this->outputDisabled;
72410 }
72411
72412
72413
72414
72415
72416
72417
72418
72419
72420 public function getOutput()
72421 {
72422 $this->readPipesForOutput(__FUNCTION__);
72423
72424 if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
72425 return '';
72426 }
72427
72428 return $ret;
72429 }
72430
72431
72432
72433
72434
72435
72436
72437
72438
72439
72440
72441
72442 public function getIncrementalOutput()
72443 {
72444 $this->readPipesForOutput(__FUNCTION__);
72445
72446 $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
72447 $this->incrementalOutputOffset = ftell($this->stdout);
72448
72449 if (false === $latest) {
72450 return '';
72451 }
72452
72453 return $latest;
72454 }
72455
72456
72457
72458
72459
72460
72461 public function clearOutput()
72462 {
72463 ftruncate($this->stdout, 0);
72464 fseek($this->stdout, 0);
72465 $this->incrementalOutputOffset = 0;
72466
72467 return $this;
72468 }
72469
72470
72471
72472
72473
72474
72475
72476
72477
72478 public function getErrorOutput()
72479 {
72480 $this->readPipesForOutput(__FUNCTION__);
72481
72482 if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
72483 return '';
72484 }
72485
72486 return $ret;
72487 }
72488
72489
72490
72491
72492
72493
72494
72495
72496
72497
72498
72499
72500
72501 public function getIncrementalErrorOutput()
72502 {
72503 $this->readPipesForOutput(__FUNCTION__);
72504
72505 $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
72506 $this->incrementalErrorOutputOffset = ftell($this->stderr);
72507
72508 if (false === $latest) {
72509 return '';
72510 }
72511
72512 return $latest;
72513 }
72514
72515
72516
72517
72518
72519
72520 public function clearErrorOutput()
72521 {
72522 ftruncate($this->stderr, 0);
72523 fseek($this->stderr, 0);
72524 $this->incrementalErrorOutputOffset = 0;
72525
72526 return $this;
72527 }
72528
72529
72530
72531
72532
72533
72534
72535
72536 public function getExitCode()
72537 {
72538 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
72539 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
72540 }
72541
72542 $this->updateStatus(false);
72543
72544 return $this->exitcode;
72545 }
72546
72547
72548
72549
72550
72551
72552
72553
72554
72555
72556
72557
72558 public function getExitCodeText()
72559 {
72560 if (null === $exitcode = $this->getExitCode()) {
72561 return;
72562 }
72563
72564 return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
72565 }
72566
72567
72568
72569
72570
72571
72572 public function isSuccessful()
72573 {
72574 return 0 === $this->getExitCode();
72575 }
72576
72577
72578
72579
72580
72581
72582
72583
72584
72585
72586
72587 public function hasBeenSignaled()
72588 {
72589 $this->requireProcessIsTerminated(__FUNCTION__);
72590
72591 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
72592 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
72593 }
72594
72595 return $this->processInformation['signaled'];
72596 }
72597
72598
72599
72600
72601
72602
72603
72604
72605
72606
72607
72608 public function getTermSignal()
72609 {
72610 $this->requireProcessIsTerminated(__FUNCTION__);
72611
72612 if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 === $this->processInformation['termsig'])) {
72613 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
72614 }
72615
72616 return $this->processInformation['termsig'];
72617 }
72618
72619
72620
72621
72622
72623
72624
72625
72626
72627
72628 public function hasBeenStopped()
72629 {
72630 $this->requireProcessIsTerminated(__FUNCTION__);
72631
72632 return $this->processInformation['stopped'];
72633 }
72634
72635
72636
72637
72638
72639
72640
72641
72642
72643
72644 public function getStopSignal()
72645 {
72646 $this->requireProcessIsTerminated(__FUNCTION__);
72647
72648 return $this->processInformation['stopsig'];
72649 }
72650
72651
72652
72653
72654
72655
72656 public function isRunning()
72657 {
72658 if (self::STATUS_STARTED !== $this->status) {
72659 return false;
72660 }
72661
72662 $this->updateStatus(false);
72663
72664 return $this->processInformation['running'];
72665 }
72666
72667
72668
72669
72670
72671
72672 public function isStarted()
72673 {
72674 return $this->status != self::STATUS_READY;
72675 }
72676
72677
72678
72679
72680
72681
72682 public function isTerminated()
72683 {
72684 $this->updateStatus(false);
72685
72686 return $this->status == self::STATUS_TERMINATED;
72687 }
72688
72689
72690
72691
72692
72693
72694
72695
72696 public function getStatus()
72697 {
72698 $this->updateStatus(false);
72699
72700 return $this->status;
72701 }
72702
72703
72704
72705
72706
72707
72708
72709
72710
72711 public function stop($timeout = 10, $signal = null)
72712 {
72713 $timeoutMicro = microtime(true) + $timeout;
72714 if ($this->isRunning()) {
72715
72716  $this->doSignal(15, false);
72717 do {
72718 usleep(1000);
72719 } while ($this->isRunning() && microtime(true) < $timeoutMicro);
72720
72721 if ($this->isRunning()) {
72722
72723  
72724  $this->doSignal($signal ?: 9, false);
72725 }
72726 }
72727
72728 if ($this->isRunning()) {
72729 if (isset($this->fallbackStatus['pid'])) {
72730 unset($this->fallbackStatus['pid']);
72731
72732 return $this->stop(0, $signal);
72733 }
72734 $this->close();
72735 }
72736
72737 return $this->exitcode;
72738 }
72739
72740
72741
72742
72743
72744
72745
72746
72747 public function addOutput($line)
72748 {
72749 $this->lastOutputTime = microtime(true);
72750
72751 fseek($this->stdout, 0, SEEK_END);
72752 fwrite($this->stdout, $line);
72753 fseek($this->stdout, $this->incrementalOutputOffset);
72754 }
72755
72756
72757
72758
72759
72760
72761
72762
72763 public function addErrorOutput($line)
72764 {
72765 $this->lastOutputTime = microtime(true);
72766
72767 fseek($this->stderr, 0, SEEK_END);
72768 fwrite($this->stderr, $line);
72769 fseek($this->stderr, $this->incrementalErrorOutputOffset);
72770 }
72771
72772
72773
72774
72775
72776
72777 public function getCommandLine()
72778 {
72779 return $this->commandline;
72780 }
72781
72782
72783
72784
72785
72786
72787
72788
72789 public function setCommandLine($commandline)
72790 {
72791 $this->commandline = $commandline;
72792
72793 return $this;
72794 }
72795
72796
72797
72798
72799
72800
72801 public function getTimeout()
72802 {
72803 return $this->timeout;
72804 }
72805
72806
72807
72808
72809
72810
72811 public function getIdleTimeout()
72812 {
72813 return $this->idleTimeout;
72814 }
72815
72816
72817
72818
72819
72820
72821
72822
72823
72824
72825
72826
72827 public function setTimeout($timeout)
72828 {
72829 $this->timeout = $this->validateTimeout($timeout);
72830
72831 return $this;
72832 }
72833
72834
72835
72836
72837
72838
72839
72840
72841
72842
72843
72844
72845
72846 public function setIdleTimeout($timeout)
72847 {
72848 if (null !== $timeout && $this->outputDisabled) {
72849 throw new LogicException('Idle timeout can not be set while the output is disabled.');
72850 }
72851
72852 $this->idleTimeout = $this->validateTimeout($timeout);
72853
72854 return $this;
72855 }
72856
72857
72858
72859
72860
72861
72862
72863
72864
72865
72866 public function setTty($tty)
72867 {
72868 if ('\\' === DIRECTORY_SEPARATOR && $tty) {
72869 throw new RuntimeException('TTY mode is not supported on Windows platform.');
72870 }
72871 if ($tty) {
72872 static $isTtySupported;
72873
72874 if (null === $isTtySupported) {
72875 $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes);
72876 }
72877
72878 if (!$isTtySupported) {
72879 throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.');
72880 }
72881 }
72882
72883 $this->tty = (bool) $tty;
72884
72885 return $this;
72886 }
72887
72888
72889
72890
72891
72892
72893 public function isTty()
72894 {
72895 return $this->tty;
72896 }
72897
72898
72899
72900
72901
72902
72903
72904
72905 public function setPty($bool)
72906 {
72907 $this->pty = (bool) $bool;
72908
72909 return $this;
72910 }
72911
72912
72913
72914
72915
72916
72917 public function isPty()
72918 {
72919 return $this->pty;
72920 }
72921
72922
72923
72924
72925
72926
72927 public function getWorkingDirectory()
72928 {
72929 if (null === $this->cwd) {
72930
72931  
72932  return getcwd() ?: null;
72933 }
72934
72935 return $this->cwd;
72936 }
72937
72938
72939
72940
72941
72942
72943
72944
72945 public function setWorkingDirectory($cwd)
72946 {
72947 $this->cwd = $cwd;
72948
72949 return $this;
72950 }
72951
72952
72953
72954
72955
72956
72957 public function getEnv()
72958 {
72959 return $this->env;
72960 }
72961
72962
72963
72964
72965
72966
72967
72968
72969
72970
72971
72972
72973
72974
72975 public function setEnv(array $env)
72976 {
72977
72978  $env = array_filter($env, function ($value) {
72979 return !is_array($value);
72980 });
72981
72982 $this->env = array();
72983 foreach ($env as $key => $value) {
72984 $this->env[$key] = (string) $value;
72985 }
72986
72987 return $this;
72988 }
72989
72990
72991
72992
72993
72994
72995
72996
72997
72998
72999 public function getStdin()
73000 {
73001 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the getInput() method instead.', E_USER_DEPRECATED);
73002
73003 return $this->getInput();
73004 }
73005
73006
73007
73008
73009
73010
73011 public function getInput()
73012 {
73013 return $this->input;
73014 }
73015
73016
73017
73018
73019
73020
73021
73022
73023
73024
73025
73026
73027
73028
73029 public function setStdin($stdin)
73030 {
73031 @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the setInput() method instead.', E_USER_DEPRECATED);
73032
73033 return $this->setInput($stdin);
73034 }
73035
73036
73037
73038
73039
73040
73041
73042
73043
73044
73045
73046
73047
73048
73049 public function setInput($input)
73050 {
73051 if ($this->isRunning()) {
73052 throw new LogicException('Input can not be set while the process is running.');
73053 }
73054
73055 $this->input = ProcessUtils::validateInput(__METHOD__, $input);
73056
73057 return $this;
73058 }
73059
73060
73061
73062
73063
73064
73065 public function getOptions()
73066 {
73067 return $this->options;
73068 }
73069
73070
73071
73072
73073
73074
73075
73076
73077 public function setOptions(array $options)
73078 {
73079 $this->options = $options;
73080
73081 return $this;
73082 }
73083
73084
73085
73086
73087
73088
73089
73090
73091 public function getEnhanceWindowsCompatibility()
73092 {
73093 return $this->enhanceWindowsCompatibility;
73094 }
73095
73096
73097
73098
73099
73100
73101
73102
73103 public function setEnhanceWindowsCompatibility($enhance)
73104 {
73105 $this->enhanceWindowsCompatibility = (bool) $enhance;
73106
73107 return $this;
73108 }
73109
73110
73111
73112
73113
73114
73115 public function getEnhanceSigchildCompatibility()
73116 {
73117 return $this->enhanceSigchildCompatibility;
73118 }
73119
73120
73121
73122
73123
73124
73125
73126
73127
73128
73129
73130
73131 public function setEnhanceSigchildCompatibility($enhance)
73132 {
73133 $this->enhanceSigchildCompatibility = (bool) $enhance;
73134
73135 return $this;
73136 }
73137
73138
73139
73140
73141
73142
73143
73144
73145
73146 public function checkTimeout()
73147 {
73148 if ($this->status !== self::STATUS_STARTED) {
73149 return;
73150 }
73151
73152 if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {
73153 $this->stop(0);
73154
73155 throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL);
73156 }
73157
73158 if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {
73159 $this->stop(0);
73160
73161 throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE);
73162 }
73163 }
73164
73165
73166
73167
73168
73169
73170 public static function isPtySupported()
73171 {
73172 static $result;
73173
73174 if (null !== $result) {
73175 return $result;
73176 }
73177
73178 if ('\\' === DIRECTORY_SEPARATOR) {
73179 return $result = false;
73180 }
73181
73182 return $result = (bool) @proc_open('echo 1 >/dev/null', array(array('pty'), array('pty'), array('pty')), $pipes);
73183 }
73184
73185
73186
73187
73188
73189
73190 private function getDescriptors()
73191 {
73192 if ('\\' === DIRECTORY_SEPARATOR) {
73193 $this->processPipes = WindowsPipes::create($this, $this->input);
73194 } else {
73195 $this->processPipes = UnixPipes::create($this, $this->input);
73196 }
73197
73198 return $this->processPipes->getDescriptors();
73199 }
73200
73201
73202
73203
73204
73205
73206
73207
73208
73209
73210
73211 protected function buildCallback($callback)
73212 {
73213 $that = $this;
73214 $out = self::OUT;
73215 $callback = function ($type, $data) use ($that, $callback, $out) {
73216 if ($out == $type) {
73217 $that->addOutput($data);
73218 } else {
73219 $that->addErrorOutput($data);
73220 }
73221
73222 if (null !== $callback) {
73223 call_user_func($callback, $type, $data);
73224 }
73225 };
73226
73227 return $callback;
73228 }
73229
73230
73231
73232
73233
73234
73235 protected function updateStatus($blocking)
73236 {
73237 if (self::STATUS_STARTED !== $this->status) {
73238 return;
73239 }
73240
73241 $this->processInformation = proc_get_status($this->process);
73242 $running = $this->processInformation['running'];
73243
73244 $this->readPipes($running && $blocking, '\\' !== DIRECTORY_SEPARATOR || !$running);
73245
73246 if ($this->fallbackStatus && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
73247 $this->processInformation = $this->fallbackStatus + $this->processInformation;
73248 }
73249
73250 if (!$running) {
73251 $this->close();
73252 }
73253 }
73254
73255
73256
73257
73258
73259
73260 protected function isSigchildEnabled()
73261 {
73262 if (null !== self::$sigchild) {
73263 return self::$sigchild;
73264 }
73265
73266 if (!function_exists('phpinfo') || defined('HHVM_VERSION')) {
73267 return self::$sigchild = false;
73268 }
73269
73270 ob_start();
73271 phpinfo(INFO_GENERAL);
73272
73273 return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
73274 }
73275
73276
73277
73278
73279
73280
73281
73282
73283 private function readPipesForOutput($caller)
73284 {
73285 if ($this->outputDisabled) {
73286 throw new LogicException('Output has been disabled.');
73287 }
73288
73289 $this->requireProcessIsStarted($caller);
73290
73291 $this->updateStatus(false);
73292 }
73293
73294
73295
73296
73297
73298
73299
73300
73301
73302
73303 private function validateTimeout($timeout)
73304 {
73305 $timeout = (float) $timeout;
73306
73307 if (0.0 === $timeout) {
73308 $timeout = null;
73309 } elseif ($timeout < 0) {
73310 throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
73311 }
73312
73313 return $timeout;
73314 }
73315
73316
73317
73318
73319
73320
73321
73322 private function readPipes($blocking, $close)
73323 {
73324 $result = $this->processPipes->readAndWrite($blocking, $close);
73325
73326 $callback = $this->callback;
73327 foreach ($result as $type => $data) {
73328 if (3 !== $type) {
73329 $callback($type === self::STDOUT ? self::OUT : self::ERR, $data);
73330 } elseif (!isset($this->fallbackStatus['signaled'])) {
73331 $this->fallbackStatus['exitcode'] = (int) $data;
73332 }
73333 }
73334 }
73335
73336
73337
73338
73339
73340
73341 private function close()
73342 {
73343 $this->processPipes->close();
73344 if (is_resource($this->process)) {
73345 proc_close($this->process);
73346 }
73347 $this->exitcode = $this->processInformation['exitcode'];
73348 $this->status = self::STATUS_TERMINATED;
73349
73350 if (-1 === $this->exitcode) {
73351 if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {
73352
73353  $this->exitcode = 128 + $this->processInformation['termsig'];
73354 } elseif ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
73355 $this->processInformation['signaled'] = true;
73356 $this->processInformation['termsig'] = -1;
73357 }
73358 }
73359
73360
73361  
73362  
73363  $this->callback = null;
73364
73365 return $this->exitcode;
73366 }
73367
73368
73369
73370
73371 private function resetProcessData()
73372 {
73373 $this->starttime = null;
73374 $this->callback = null;
73375 $this->exitcode = null;
73376 $this->fallbackStatus = array();
73377 $this->processInformation = null;
73378 $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
73379 $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
73380 $this->process = null;
73381 $this->latestSignal = null;
73382 $this->status = self::STATUS_READY;
73383 $this->incrementalOutputOffset = 0;
73384 $this->incrementalErrorOutputOffset = 0;
73385 }
73386
73387
73388
73389
73390
73391
73392
73393
73394
73395
73396
73397
73398
73399 private function doSignal($signal, $throwException)
73400 {
73401 if (null === $pid = $this->getPid()) {
73402 if ($throwException) {
73403 throw new LogicException('Can not send signal on a non running process.');
73404 }
73405
73406 return false;
73407 }
73408
73409 if ('\\' === DIRECTORY_SEPARATOR) {
73410 exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
73411 if ($exitCode && $this->isRunning()) {
73412 if ($throwException) {
73413 throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output)));
73414 }
73415
73416 return false;
73417 }
73418 } else {
73419 if (!$this->enhanceSigchildCompatibility || !$this->isSigchildEnabled()) {
73420 $ok = @proc_terminate($this->process, $signal);
73421 } elseif (function_exists('posix_kill')) {
73422 $ok = @posix_kill($pid, $signal);
73423 } elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), array(2 => array('pipe', 'w')), $pipes)) {
73424 $ok = false === fgets($pipes[2]);
73425 }
73426 if (!$ok) {
73427 if ($throwException) {
73428 throw new RuntimeException(sprintf('Error while sending signal `%s`.', $signal));
73429 }
73430
73431 return false;
73432 }
73433 }
73434
73435 $this->latestSignal = (int) $signal;
73436 $this->fallbackStatus['signaled'] = true;
73437 $this->fallbackStatus['exitcode'] = -1;
73438 $this->fallbackStatus['termsig'] = $this->latestSignal;
73439
73440 return true;
73441 }
73442
73443
73444
73445
73446
73447
73448
73449
73450 private function requireProcessIsStarted($functionName)
73451 {
73452 if (!$this->isStarted()) {
73453 throw new LogicException(sprintf('Process must be started before calling %s.', $functionName));
73454 }
73455 }
73456
73457
73458
73459
73460
73461
73462
73463
73464 private function requireProcessIsTerminated($functionName)
73465 {
73466 if (!$this->isTerminated()) {
73467 throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName));
73468 }
73469 }
73470 }
73471 <?php
73472
73473
73474
73475
73476
73477
73478
73479
73480
73481
73482 namespace Symfony\Component\Process;
73483
73484 use Symfony\Component\Process\Exception\InvalidArgumentException;
73485 use Symfony\Component\Process\Exception\LogicException;
73486
73487
73488
73489
73490
73491
73492 class ProcessBuilder
73493 {
73494 private $arguments;
73495 private $cwd;
73496 private $env = array();
73497 private $input;
73498 private $timeout = 60;
73499 private $options = array();
73500 private $inheritEnv = true;
73501 private $prefix = array();
73502 private $outputDisabled = false;
73503
73504
73505
73506
73507
73508
73509 public function __construct(array $arguments = array())
73510 {
73511 $this->arguments = $arguments;
73512 }
73513
73514
73515
73516
73517
73518
73519
73520
73521 public static function create(array $arguments = array())
73522 {
73523 return new static($arguments);
73524 }
73525
73526
73527
73528
73529
73530
73531
73532
73533 public function add($argument)
73534 {
73535 $this->arguments[] = $argument;
73536
73537 return $this;
73538 }
73539
73540
73541
73542
73543
73544
73545
73546
73547
73548
73549 public function setPrefix($prefix)
73550 {
73551 $this->prefix = is_array($prefix) ? $prefix : array($prefix);
73552
73553 return $this;
73554 }
73555
73556
73557
73558
73559
73560
73561
73562
73563
73564
73565
73566 public function setArguments(array $arguments)
73567 {
73568 $this->arguments = $arguments;
73569
73570 return $this;
73571 }
73572
73573
73574
73575
73576
73577
73578
73579
73580 public function setWorkingDirectory($cwd)
73581 {
73582 $this->cwd = $cwd;
73583
73584 return $this;
73585 }
73586
73587
73588
73589
73590
73591
73592
73593
73594 public function inheritEnvironmentVariables($inheritEnv = true)
73595 {
73596 $this->inheritEnv = $inheritEnv;
73597
73598 return $this;
73599 }
73600
73601
73602
73603
73604
73605
73606
73607
73608
73609
73610
73611
73612 public function setEnv($name, $value)
73613 {
73614 $this->env[$name] = $value;
73615
73616 return $this;
73617 }
73618
73619
73620
73621
73622
73623
73624
73625
73626
73627
73628
73629
73630 public function addEnvironmentVariables(array $variables)
73631 {
73632 $this->env = array_replace($this->env, $variables);
73633
73634 return $this;
73635 }
73636
73637
73638
73639
73640
73641
73642
73643
73644
73645
73646
73647
73648 public function setInput($input)
73649 {
73650 $this->input = ProcessUtils::validateInput(__METHOD__, $input);
73651
73652 return $this;
73653 }
73654
73655
73656
73657
73658
73659
73660
73661
73662
73663
73664
73665
73666 public function setTimeout($timeout)
73667 {
73668 if (null === $timeout) {
73669 $this->timeout = null;
73670
73671 return $this;
73672 }
73673
73674 $timeout = (float) $timeout;
73675
73676 if ($timeout < 0) {
73677 throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
73678 }
73679
73680 $this->timeout = $timeout;
73681
73682 return $this;
73683 }
73684
73685
73686
73687
73688
73689
73690
73691
73692
73693 public function setOption($name, $value)
73694 {
73695 $this->options[$name] = $value;
73696
73697 return $this;
73698 }
73699
73700
73701
73702
73703
73704
73705 public function disableOutput()
73706 {
73707 $this->outputDisabled = true;
73708
73709 return $this;
73710 }
73711
73712
73713
73714
73715
73716
73717 public function enableOutput()
73718 {
73719 $this->outputDisabled = false;
73720
73721 return $this;
73722 }
73723
73724
73725
73726
73727
73728
73729
73730
73731 public function getProcess()
73732 {
73733 if (0 === count($this->prefix) && 0 === count($this->arguments)) {
73734 throw new LogicException('You must add() command arguments before calling getProcess().');
73735 }
73736
73737 $options = $this->options;
73738
73739 $arguments = array_merge($this->prefix, $this->arguments);
73740 $script = implode(' ', array_map(array(__NAMESPACE__.'\\ProcessUtils', 'escapeArgument'), $arguments));
73741
73742 if ($this->inheritEnv) {
73743
73744  $env = array_replace($_ENV, $_SERVER, $this->env);
73745 } else {
73746 $env = $this->env;
73747 }
73748
73749 $process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options);
73750
73751 if ($this->outputDisabled) {
73752 $process->disableOutput();
73753 }
73754
73755 return $process;
73756 }
73757 }
73758 <?php
73759
73760
73761
73762
73763
73764
73765
73766
73767
73768
73769 namespace Symfony\Component\Process;
73770
73771 use Symfony\Component\Process\Exception\InvalidArgumentException;
73772
73773
73774
73775
73776
73777
73778
73779
73780 class ProcessUtils
73781 {
73782
73783
73784
73785 private function __construct()
73786 {
73787 }
73788
73789
73790
73791
73792
73793
73794
73795
73796 public static function escapeArgument($argument)
73797 {
73798
73799  
73800  
73801  
73802  if ('\\' === DIRECTORY_SEPARATOR) {
73803 if ('' === $argument) {
73804 return escapeshellarg($argument);
73805 }
73806
73807 $escapedArgument = '';
73808 $quote = false;
73809 foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
73810 if ('"' === $part) {
73811 $escapedArgument .= '\\"';
73812 } elseif (self::isSurroundedBy($part, '%')) {
73813
73814  $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%';
73815 } else {
73816
73817  if ('\\' === substr($part, -1)) {
73818 $part .= '\\';
73819 }
73820 $quote = true;
73821 $escapedArgument .= $part;
73822 }
73823 }
73824 if ($quote) {
73825 $escapedArgument = '"'.$escapedArgument.'"';
73826 }
73827
73828 return $escapedArgument;
73829 }
73830
73831 return "'".str_replace("'", "'\\''", $argument)."'";
73832 }
73833
73834
73835
73836
73837
73838
73839
73840
73841
73842
73843
73844
73845
73846 public static function validateInput($caller, $input)
73847 {
73848 if (null !== $input) {
73849 if (is_resource($input)) {
73850 return $input;
73851 }
73852 if (is_string($input)) {
73853 return $input;
73854 }
73855 if (is_scalar($input)) {
73856 return (string) $input;
73857 }
73858
73859  if (is_object($input) && method_exists($input, '__toString')) {
73860 @trigger_error('Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
73861
73862 return (string) $input;
73863 }
73864
73865 throw new InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller));
73866 }
73867
73868 return $input;
73869 }
73870
73871 private static function isSurroundedBy($arg, $char)
73872 {
73873 return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
73874 }
73875 }
73876 Copyright (c) 2011 Jordi Boggiano
73877
73878 Permission is hereby granted, free of charge, to any person obtaining a copy
73879 of this software and associated documentation files (the "Software"), to deal
73880 in the Software without restriction, including without limitation the rights
73881 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
73882 copies of the Software, and to permit persons to whom the Software is furnished
73883 to do so, subject to the following conditions:
73884
73885 The above copyright notice and this permission notice shall be included in all
73886 copies or substantial portions of the Software.
73887
73888 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
73889 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
73890 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
73891 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
73892 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
73893 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
73894 THE SOFTWARE.
73895 <?php
73896
73897
73898
73899
73900
73901
73902
73903
73904
73905
73906 namespace Seld\JsonLint;
73907
73908 class DuplicateKeyException extends ParsingException
73909 {
73910 public function __construct($message, $key, array $details = array())
73911 {
73912 $details['key'] = $key;
73913 parent::__construct($message, $details);
73914 }
73915
73916 public function getKey()
73917 {
73918 return $this->details['key'];
73919 }
73920 }
73921 <?php
73922
73923
73924
73925
73926
73927
73928
73929
73930
73931
73932 namespace Seld\JsonLint;
73933 use stdClass;
73934
73935
73936
73937
73938
73939
73940
73941
73942
73943
73944
73945
73946
73947
73948 class JsonParser
73949 {
73950 const DETECT_KEY_CONFLICTS = 1;
73951 const ALLOW_DUPLICATE_KEYS = 2;
73952 const PARSE_TO_ASSOC = 4;
73953
73954 private $lexer;
73955
73956 private $flags;
73957 private $stack;
73958 private $vstack; 
73959  private $lstack; 
73960
73961 private $symbols = array(
73962 'error' => 2,
73963 'JSONString' => 3,
73964 'STRING' => 4,
73965 'JSONNumber' => 5,
73966 'NUMBER' => 6,
73967 'JSONNullLiteral' => 7,
73968 'NULL' => 8,
73969 'JSONBooleanLiteral' => 9,
73970 'TRUE' => 10,
73971 'FALSE' => 11,
73972 'JSONText' => 12,
73973 'JSONValue' => 13,
73974 'EOF' => 14,
73975 'JSONObject' => 15,
73976 'JSONArray' => 16,
73977 '{' => 17,
73978 '}' => 18,
73979 'JSONMemberList' => 19,
73980 'JSONMember' => 20,
73981 ':' => 21,
73982 ',' => 22,
73983 '[' => 23,
73984 ']' => 24,
73985 'JSONElementList' => 25,
73986 '$accept' => 0,
73987 '$end' => 1,
73988 );
73989
73990 private $terminals_ = array(
73991 2 => "error",
73992 4 => "STRING",
73993 6 => "NUMBER",
73994 8 => "NULL",
73995 10 => "TRUE",
73996 11 => "FALSE",
73997 14 => "EOF",
73998 17 => "{",
73999 18 => "}",
74000 21 => ":",
74001 22 => ",",
74002 23 => "[",
74003 24 => "]",
74004 );
74005
74006 private $productions_ = array(
74007 0,
74008 array(3, 1),
74009 array(5, 1),
74010 array(7, 1),
74011 array(9, 1),
74012 array(9, 1),
74013 array(12, 2),
74014 array(13, 1),
74015 array(13, 1),
74016 array(13, 1),
74017 array(13, 1),
74018 array(13, 1),
74019 array(13, 1),
74020 array(15, 2),
74021 array(15, 3),
74022 array(20, 3),
74023 array(19, 1),
74024 array(19, 3),
74025 array(16, 2),
74026 array(16, 3),
74027 array(25, 1),
74028 array(25, 3)
74029 );
74030
74031 private $table = array(array(3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 12 => 1, 13 => 2, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15)), array( 1 => array(3)), array( 14 => array(1,16)), array( 14 => array(2,7), 18 => array(2,7), 22 => array(2,7), 24 => array(2,7)), array( 14 => array(2,8), 18 => array(2,8), 22 => array(2,8), 24 => array(2,8)), array( 14 => array(2,9), 18 => array(2,9), 22 => array(2,9), 24 => array(2,9)), array( 14 => array(2,10), 18 => array(2,10), 22 => array(2,10), 24 => array(2,10)), array( 14 => array(2,11), 18 => array(2,11), 22 => array(2,11), 24 => array(2,11)), array( 14 => array(2,12), 18 => array(2,12), 22 => array(2,12), 24 => array(2,12)), array( 14 => array(2,3), 18 => array(2,3), 22 => array(2,3), 24 => array(2,3)), array( 14 => array(2,4), 18 => array(2,4), 22 => array(2,4), 24 => array(2,4)), array( 14 => array(2,5), 18 => array(2,5), 22 => array(2,5), 24 => array(2,5)), array( 14 => array(2,1), 18 => array(2,1), 21 => array(2,1), 22 => array(2,1), 24 => array(2,1)), array( 14 => array(2,2), 18 => array(2,2), 22 => array(2,2), 24 => array(2,2)), array( 3 => 20, 4 => array(1,12), 18 => array(1,17), 19 => 18, 20 => 19 ), array( 3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 13 => 23, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15), 24 => array(1,21), 25 => 22 ), array( 1 => array(2,6)), array( 14 => array(2,13), 18 => array(2,13), 22 => array(2,13), 24 => array(2,13)), array( 18 => array(1,24), 22 => array(1,25)), array( 18 => array(2,16), 22 => array(2,16)), array( 21 => array(1,26)), array( 14 => array(2,18), 18 => array(2,18), 22 => array(2,18), 24 => array(2,18)), array( 22 => array(1,28), 24 => array(1,27)), array( 22 => array(2,20), 24 => array(2,20)), array( 14 => array(2,14), 18 => array(2,14), 22 => array(2,14), 24 => array(2,14)), array( 3 => 20, 4 => array(1,12), 20 => 29 ), array( 3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 13 => 30, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15)), array( 14 => array(2,19), 18 => array(2,19), 22 => array(2,19), 24 => array(2,19)), array( 3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 13 => 31, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15)), array( 18 => array(2,17), 22 => array(2,17)), array( 18 => array(2,15), 22 => array(2,15)), array( 22 => array(2,21), 24 => array(2,21)),
74032 );
74033
74034 private $defaultActions = array(
74035 16 => array(2, 6)
74036 );
74037
74038
74039
74040
74041
74042
74043 public function lint($input, $flags = 0)
74044 {
74045 try {
74046 $this->parse($input, $flags);
74047 } catch (ParsingException $e) {
74048 return $e;
74049 }
74050 }
74051
74052
74053
74054
74055
74056
74057
74058 public function parse($input, $flags = 0)
74059 {
74060 $this->failOnBOM($input);
74061
74062 $this->flags = $flags;
74063
74064 $this->stack = array(0);
74065 $this->vstack = array(null);
74066 $this->lstack = array();
74067
74068 $yytext = '';
74069 $yylineno = 0;
74070 $yyleng = 0;
74071 $recovering = 0;
74072 $TERROR = 2;
74073 $EOF = 1;
74074
74075 $this->lexer = new Lexer();
74076 $this->lexer->setInput($input);
74077
74078 $yyloc = $this->lexer->yylloc;
74079 $this->lstack[] = $yyloc;
74080
74081 $symbol = null;
74082 $preErrorSymbol = null;
74083 $state = null;
74084 $action = null;
74085 $a = null;
74086 $r = null;
74087 $yyval = new stdClass;
74088 $p = null;
74089 $len = null;
74090 $newState = null;
74091 $expected = null;
74092 $errStr = null;
74093
74094 while (true) {
74095
74096  $state = $this->stack[count($this->stack)-1];
74097
74098
74099  if (isset($this->defaultActions[$state])) {
74100 $action = $this->defaultActions[$state];
74101 } else {
74102 if ($symbol == null) {
74103 $symbol = $this->lex();
74104 }
74105
74106  $action = isset($this->table[$state][$symbol]) ? $this->table[$state][$symbol] : false;
74107 }
74108
74109
74110  if (!$action || !$action[0]) {
74111 if (!$recovering) {
74112
74113  $expected = array();
74114 foreach ($this->table[$state] as $p => $ignore) {
74115 if (isset($this->terminals_[$p]) && $p > 2) {
74116 $expected[] = "'" . $this->terminals_[$p] . "'";
74117 }
74118 }
74119
74120 $message = null;
74121 if (in_array("'STRING'", $expected) && in_array(substr($this->lexer->match, 0, 1), array('"', "'"))) {
74122 $message = "Invalid string";
74123 if ("'" === substr($this->lexer->match, 0, 1)) {
74124 $message .= ", it appears you used single quotes instead of double quotes";
74125 } elseif (preg_match('{".+?(\\\\[^"bfnrt/\\\\u])}', $this->lexer->getUpcomingInput(), $match)) {
74126 $message .= ", it appears you have an unescaped backslash at: ".$match[1];
74127 } elseif (preg_match('{"(?:[^"]+|\\\\")*$}m', $this->lexer->getUpcomingInput())) {
74128 $message .= ", it appears you forgot to terminate a string, or attempted to write a multiline string which is invalid";
74129 }
74130 }
74131
74132 $errStr = 'Parse error on line ' . ($yylineno+1) . ":\n";
74133 $errStr .= $this->lexer->showPosition() . "\n";
74134 if ($message) {
74135 $errStr .= $message;
74136 } else {
74137 $errStr .= (count($expected) > 1) ? "Expected one of: " : "Expected: ";
74138 $errStr .= implode(', ', $expected);
74139 }
74140
74141 if (',' === substr(trim($this->lexer->getPastInput()), -1)) {
74142 $errStr .= " - It appears you have an extra trailing comma";
74143 }
74144
74145 $this->parseError($errStr, array(
74146 'text' => $this->lexer->match,
74147 'token' => !empty($this->terminals_[$symbol]) ? $this->terminals_[$symbol] : $symbol,
74148 'line' => $this->lexer->yylineno,
74149 'loc' => $yyloc,
74150 'expected' => $expected,
74151 ));
74152 }
74153
74154
74155  if ($recovering == 3) {
74156 if ($symbol == $EOF) {
74157 throw new ParsingException($errStr ?: 'Parsing halted.');
74158 }
74159
74160
74161  $yyleng = $this->lexer->yyleng;
74162 $yytext = $this->lexer->yytext;
74163 $yylineno = $this->lexer->yylineno;
74164 $yyloc = $this->lexer->yylloc;
74165 $symbol = $this->lex();
74166 }
74167
74168
74169  while (true) {
74170
74171  if (array_key_exists($TERROR, $this->table[$state])) {
74172 break;
74173 }
74174 if ($state == 0) {
74175 throw new ParsingException($errStr ?: 'Parsing halted.');
74176 }
74177 $this->popStack(1);
74178 $state = $this->stack[count($this->stack)-1];
74179 }
74180
74181 $preErrorSymbol = $symbol; 
74182  $symbol = $TERROR; 
74183  $state = $this->stack[count($this->stack)-1];
74184 $action = isset($this->table[$state][$TERROR]) ? $this->table[$state][$TERROR] : false;
74185 $recovering = 3; 
74186  }
74187
74188
74189  if (is_array($action[0]) && count($action) > 1) {
74190 throw new ParsingException('Parse Error: multiple actions possible at state: ' . $state . ', token: ' . $symbol);
74191 }
74192
74193 switch ($action[0]) {
74194 case 1: 
74195  $this->stack[] = $symbol;
74196 $this->vstack[] = $this->lexer->yytext;
74197 $this->lstack[] = $this->lexer->yylloc;
74198 $this->stack[] = $action[1]; 
74199  $symbol = null;
74200 if (!$preErrorSymbol) { 
74201  $yyleng = $this->lexer->yyleng;
74202 $yytext = $this->lexer->yytext;
74203 $yylineno = $this->lexer->yylineno;
74204 $yyloc = $this->lexer->yylloc;
74205 if ($recovering > 0) {
74206 $recovering--;
74207 }
74208 } else { 
74209  $symbol = $preErrorSymbol;
74210 $preErrorSymbol = null;
74211 }
74212 break;
74213
74214 case 2: 
74215  $len = $this->productions_[$action[1]][1];
74216
74217
74218  $yyval->token = $this->vstack[count($this->vstack) - $len]; 
74219  
74220  $yyval->store = array( 
74221  'first_line' => $this->lstack[count($this->lstack) - ($len ?: 1)]['first_line'],
74222 'last_line' => $this->lstack[count($this->lstack) - 1]['last_line'],
74223 'first_column' => $this->lstack[count($this->lstack) - ($len ?: 1)]['first_column'],
74224 'last_column' => $this->lstack[count($this->lstack) - 1]['last_column'],
74225 );
74226 $r = $this->performAction($yyval, $yytext, $yyleng, $yylineno, $action[1], $this->vstack, $this->lstack);
74227
74228 if (!$r instanceof Undefined) {
74229 return $r;
74230 }
74231
74232 if ($len) {
74233 $this->popStack($len);
74234 }
74235
74236 $this->stack[] = $this->productions_[$action[1]][0]; 
74237  $this->vstack[] = $yyval->token;
74238 $this->lstack[] = $yyval->store;
74239 $newState = $this->table[$this->stack[count($this->stack)-2]][$this->stack[count($this->stack)-1]];
74240 $this->stack[] = $newState;
74241 break;
74242
74243 case 3: 
74244
74245 return true;
74246 }
74247 }
74248
74249 return true;
74250 }
74251
74252 protected function parseError($str, $hash)
74253 {
74254 throw new ParsingException($str, $hash);
74255 }
74256
74257
74258  
74259  
74260  private function performAction(stdClass $yyval, $yytext, $yyleng, $yylineno, $yystate, &$tokens)
74261 {
74262
74263  $len = count($tokens) - 1;
74264 switch ($yystate) {
74265 case 1:
74266 $yytext = preg_replace_callback('{(?:\\\\["bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4})}', array($this, 'stringInterpolation'), $yytext);
74267 $yyval->token = $yytext;
74268 break;
74269 case 2:
74270 if (strpos($yytext, 'e') !== false || strpos($yytext, 'E') !== false) {
74271 $yyval->token = floatval($yytext);
74272 } else {
74273 $yyval->token = strpos($yytext, '.') === false ? intval($yytext) : floatval($yytext);
74274 }
74275 break;
74276 case 3:
74277 $yyval->token = null;
74278 break;
74279 case 4:
74280 $yyval->token = true;
74281 break;
74282 case 5:
74283 $yyval->token = false;
74284 break;
74285 case 6:
74286 return $yyval->token = $tokens[$len-1];
74287 case 13:
74288 if ($this->flags & self::PARSE_TO_ASSOC) {
74289 $yyval->token = array();
74290 } else {
74291 $yyval->token = new stdClass;
74292 }
74293 break;
74294 case 14:
74295 $yyval->token = $tokens[$len-1];
74296 break;
74297 case 15:
74298 $yyval->token = array($tokens[$len-2], $tokens[$len]);
74299 break;
74300 case 16:
74301 if (PHP_VERSION_ID < 70100) {
74302 $property = $tokens[$len][0] === '' ? '_empty_' : $tokens[$len][0];
74303 } else {
74304 $property = $tokens[$len][0];
74305 }
74306 if ($this->flags & self::PARSE_TO_ASSOC) {
74307 $yyval->token = array();
74308 $yyval->token[$property] = $tokens[$len][1];
74309 } else {
74310 $yyval->token = new stdClass;
74311 $yyval->token->$property = $tokens[$len][1];
74312 }
74313 break;
74314 case 17:
74315 if ($this->flags & self::PARSE_TO_ASSOC) {
74316 $yyval->token =& $tokens[$len-2];
74317 $key = $tokens[$len][0];
74318 if (($this->flags & self::DETECT_KEY_CONFLICTS) && isset($tokens[$len-2][$key])) {
74319 $errStr = 'Parse error on line ' . ($yylineno+1) . ":\n";
74320 $errStr .= $this->lexer->showPosition() . "\n";
74321 $errStr .= "Duplicate key: ".$tokens[$len][0];
74322 throw new DuplicateKeyException($errStr, $tokens[$len][0], array('line' => $yylineno+1));
74323 } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($tokens[$len-2][$key])) {
74324 $duplicateCount = 1;
74325 do {
74326 $duplicateKey = $key . '.' . $duplicateCount++;
74327 } while (isset($tokens[$len-2][$duplicateKey]));
74328 $key = $duplicateKey;
74329 }
74330 $tokens[$len-2][$key] = $tokens[$len][1];
74331 } else {
74332 $yyval->token = $tokens[$len-2];
74333 if (PHP_VERSION_ID < 70100) {
74334 $key = $tokens[$len][0] === '' ? '_empty_' : $tokens[$len][0];
74335 } else {
74336 $key = $tokens[$len][0];
74337 }
74338 if (($this->flags & self::DETECT_KEY_CONFLICTS) && isset($tokens[$len-2]->{$key})) {
74339 $errStr = 'Parse error on line ' . ($yylineno+1) . ":\n";
74340 $errStr .= $this->lexer->showPosition() . "\n";
74341 $errStr .= "Duplicate key: ".$tokens[$len][0];
74342 throw new DuplicateKeyException($errStr, $tokens[$len][0], array('line' => $yylineno+1));
74343 } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($tokens[$len-2]->{$key})) {
74344 $duplicateCount = 1;
74345 do {
74346 $duplicateKey = $key . '.' . $duplicateCount++;
74347 } while (isset($tokens[$len-2]->$duplicateKey));
74348 $key = $duplicateKey;
74349 }
74350 $tokens[$len-2]->$key = $tokens[$len][1];
74351 }
74352 break;
74353 case 18:
74354 $yyval->token = array();
74355 break;
74356 case 19:
74357 $yyval->token = $tokens[$len-1];
74358 break;
74359 case 20:
74360 $yyval->token = array($tokens[$len]);
74361 break;
74362 case 21:
74363 $tokens[$len-2][] = $tokens[$len];
74364 $yyval->token = $tokens[$len-2];
74365 break;
74366 }
74367
74368 return new Undefined();
74369 }
74370
74371 private function stringInterpolation($match)
74372 {
74373 switch ($match[0]) {
74374 case '\\\\':
74375 return '\\';
74376 case '\"':
74377 return '"';
74378 case '\b':
74379 return chr(8);
74380 case '\f':
74381 return chr(12);
74382 case '\n':
74383 return "\n";
74384 case '\r':
74385 return "\r";
74386 case '\t':
74387 return "\t";
74388 case '\/':
74389 return "/";
74390 default:
74391 return html_entity_decode('&#x'.ltrim(substr($match[0], 2), '0').';', 0, 'UTF-8');
74392 }
74393 }
74394
74395 private function popStack($n)
74396 {
74397 $this->stack = array_slice($this->stack, 0, - (2 * $n));
74398 $this->vstack = array_slice($this->vstack, 0, - $n);
74399 $this->lstack = array_slice($this->lstack, 0, - $n);
74400 }
74401
74402 private function lex()
74403 {
74404 $token = $this->lexer->lex() ?: 1; 
74405  
74406  if (!is_numeric($token)) {
74407 $token = isset($this->symbols[$token]) ? $this->symbols[$token] : $token;
74408 }
74409
74410 return $token;
74411 }
74412
74413 private function failOnBOM($input)
74414 {
74415
74416  $bom = "\xEF\xBB\xBF";
74417
74418 if (substr($input, 0, 3) === $bom) {
74419 $this->parseError("BOM detected, make sure your input does not include a Unicode Byte-Order-Mark", array());
74420 }
74421 }
74422 }
74423 <?php
74424
74425
74426
74427
74428
74429
74430
74431
74432
74433
74434 namespace Seld\JsonLint;
74435
74436
74437
74438
74439
74440
74441 class Lexer
74442 {
74443 private $EOF = 1;
74444 private $rules = array(
74445 0 => '/^\s+/',
74446 1 => '/^-?([0-9]|[1-9][0-9]+)(\.[0-9]+)?([eE][+-]?[0-9]+)?\b/',
74447 2 => '{^"(?>\\\\["bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\0-\x1f\\\\"]++)*+"}',
74448 3 => '/^\{/',
74449 4 => '/^\}/',
74450 5 => '/^\[/',
74451 6 => '/^\]/',
74452 7 => '/^,/',
74453 8 => '/^:/',
74454 9 => '/^true\b/',
74455 10 => '/^false\b/',
74456 11 => '/^null\b/',
74457 12 => '/^$/',
74458 13 => '/^./',
74459 );
74460
74461 private $conditions = array(
74462 "INITIAL" => array(
74463 "rules" => array(0,1,2,3,4,5,6,7,8,9,10,11,12,13),
74464 "inclusive" => true,
74465 ),
74466 );
74467
74468 private $conditionStack;
74469 private $input;
74470 private $more;
74471 private $done;
74472 private $matched;
74473
74474 public $match;
74475 public $yylineno;
74476 public $yyleng;
74477 public $yytext;
74478 public $yylloc;
74479
74480 public function lex()
74481 {
74482 $r = $this->next();
74483 if (!$r instanceof Undefined) {
74484 return $r;
74485 }
74486
74487 return $this->lex();
74488 }
74489
74490 public function setInput($input)
74491 {
74492 $this->input = $input;
74493 $this->more = false;
74494 $this->done = false;
74495 $this->yylineno = $this->yyleng = 0;
74496 $this->yytext = $this->matched = $this->match = '';
74497 $this->conditionStack = array('INITIAL');
74498 $this->yylloc = array('first_line' => 1, 'first_column' => 0, 'last_line' => 1, 'last_column' => 0);
74499
74500 return $this;
74501 }
74502
74503 public function showPosition()
74504 {
74505 $pre = str_replace("\n", '', $this->getPastInput());
74506 $c = str_repeat('-', max(0, strlen($pre) - 1)); 
74507
74508 return $pre . str_replace("\n", '', $this->getUpcomingInput()) . "\n" . $c . "^";
74509 }
74510
74511 public function getPastInput()
74512 {
74513 $past = substr($this->matched, 0, strlen($this->matched) - strlen($this->match));
74514
74515 return (strlen($past) > 20 ? '...' : '') . substr($past, -20);
74516 }
74517
74518 public function getUpcomingInput()
74519 {
74520 $next = $this->match;
74521 if (strlen($next) < 20) {
74522 $next .= substr($this->input, 0, 20 - strlen($next));
74523 }
74524
74525 return substr($next, 0, 20) . (strlen($next) > 20 ? '...' : '');
74526 }
74527
74528 protected function parseError($str, $hash)
74529 {
74530 throw new \Exception($str);
74531 }
74532
74533 private function next()
74534 {
74535 if ($this->done) {
74536 return $this->EOF;
74537 }
74538 if (!$this->input) {
74539 $this->done = true;
74540 }
74541
74542 $token = null;
74543 $match = null;
74544 $col = null;
74545 $lines = null;
74546
74547 if (!$this->more) {
74548 $this->yytext = '';
74549 $this->match = '';
74550 }
74551
74552 $rules = $this->getCurrentRules();
74553 $rulesLen = count($rules);
74554
74555 for ($i=0; $i < $rulesLen; $i++) {
74556 if (preg_match($this->rules[$rules[$i]], $this->input, $match)) {
74557 preg_match_all('/\n.*/', $match[0], $lines);
74558 $lines = $lines[0];
74559 if ($lines) {
74560 $this->yylineno += count($lines);
74561 }
74562
74563 $this->yylloc = array(
74564 'first_line' => $this->yylloc['last_line'],
74565 'last_line' => $this->yylineno+1,
74566 'first_column' => $this->yylloc['last_column'],
74567 'last_column' => $lines ? strlen($lines[count($lines) - 1]) - 1 : $this->yylloc['last_column'] + strlen($match[0]),
74568 );
74569 $this->yytext .= $match[0];
74570 $this->match .= $match[0];
74571 $this->yyleng = strlen($this->yytext);
74572 $this->more = false;
74573 $this->input = substr($this->input, strlen($match[0]));
74574 $this->matched .= $match[0];
74575 $token = $this->performAction($rules[$i], $this->conditionStack[count($this->conditionStack)-1]);
74576 if ($token) {
74577 return $token;
74578 }
74579
74580 return new Undefined();
74581 }
74582 }
74583
74584 if ($this->input === "") {
74585 return $this->EOF;
74586 }
74587
74588 $this->parseError(
74589 'Lexical error on line ' . ($this->yylineno+1) . ". Unrecognized text.\n" . $this->showPosition(),
74590 array(
74591 'text' => "",
74592 'token' => null,
74593 'line' => $this->yylineno,
74594 )
74595 );
74596 }
74597
74598 private function getCurrentRules()
74599 {
74600 return $this->conditions[$this->conditionStack[count($this->conditionStack)-1]]['rules'];
74601 }
74602
74603 private function performAction($avoiding_name_collisions, $YY_START)
74604 {
74605 switch ($avoiding_name_collisions) {
74606 case 0:
74607 break;
74608 case 1:
74609 return 6;
74610 break;
74611 case 2:
74612 $this->yytext = substr($this->yytext, 1, $this->yyleng-2);
74613
74614 return 4;
74615 case 3:
74616 return 17;
74617 case 4:
74618 return 18;
74619 case 5:
74620 return 23;
74621 case 6:
74622 return 24;
74623 case 7:
74624 return 22;
74625 case 8:
74626 return 21;
74627 case 9:
74628 return 10;
74629 case 10:
74630 return 11;
74631 case 11:
74632 return 8;
74633 case 12:
74634 return 14;
74635 case 13:
74636 return 'INVALID';
74637 }
74638 }
74639 }
74640 <?php
74641
74642
74643
74644
74645
74646
74647
74648
74649
74650
74651 namespace Seld\JsonLint;
74652
74653 class ParsingException extends \Exception
74654 {
74655 protected $details;
74656
74657 public function __construct($message, $details = array())
74658 {
74659 $this->details = $details;
74660 parent::__construct($message);
74661 }
74662
74663 public function getDetails()
74664 {
74665 return $this->details;
74666 }
74667 }
74668 <?php
74669
74670
74671
74672
74673
74674
74675
74676
74677
74678
74679 namespace Seld\JsonLint;
74680
74681 class Undefined
74682 {
74683 }
74684 Copyright (c) 2015 Jordi Boggiano
74685
74686 Permission is hereby granted, free of charge, to any person obtaining a copy
74687 of this software and associated documentation files (the "Software"), to deal
74688 in the Software without restriction, including without limitation the rights
74689 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
74690 copies of the Software, and to permit persons to whom the Software is furnished
74691 to do so, subject to the following conditions:
74692
74693 The above copyright notice and this permission notice shall be included in all
74694 copies or substantial portions of the Software.
74695
74696 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74697 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74698 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
74699 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74700 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
74701 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
74702 THE SOFTWARE.
74703 <?php
74704
74705 require __DIR__.'/../vendor/autoload.php';
74706
74707 echo 'Say hello (visible): ';
74708
74709 $answer = Seld\CliPrompt\CliPrompt::prompt();
74710
74711 echo 'You answered: '.$answer . PHP_EOL;
74712
74713 echo 'Say hello (hidden): ';
74714
74715 $answer = Seld\CliPrompt\CliPrompt::hiddenPrompt();
74716
74717 echo 'You answered: '.$answer . PHP_EOL;
74718 <?php
74719
74720
74721
74722
74723
74724
74725
74726
74727
74728
74729 namespace Seld\CliPrompt;
74730
74731 class CliPrompt
74732 {
74733
74734
74735
74736
74737
74738 public static function prompt()
74739 {
74740 $stdin = fopen('php://stdin', 'r');
74741 $answer = self::trimAnswer(fgets($stdin, 4096));
74742 fclose($stdin);
74743
74744 return $answer;
74745 }
74746
74747
74748
74749
74750
74751
74752
74753
74754
74755
74756 public static function hiddenPrompt($allowFallback = false)
74757 {
74758
74759  if (defined('PHP_WINDOWS_VERSION_BUILD')) {
74760
74761  $exe = __DIR__.'\\..\\res\\hiddeninput.exe';
74762
74763
74764  if ('phar:' === substr(__FILE__, 0, 5)) {
74765 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
74766
74767
74768  
74769  $source = fopen($exe, 'r');
74770 $target = fopen($tmpExe, 'w+');
74771 stream_copy_to_stream($source, $target);
74772 fclose($source);
74773 fclose($target);
74774 unset($source, $target);
74775
74776 $exe = $tmpExe;
74777 }
74778
74779 $answer = self::trimAnswer(shell_exec($exe));
74780
74781
74782  if (isset($tmpExe)) {
74783 unlink($tmpExe);
74784 }
74785
74786
74787  echo PHP_EOL;
74788
74789 return $answer;
74790 }
74791
74792 if (file_exists('/usr/bin/env')) {
74793
74794  $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
74795 foreach (array('bash', 'zsh', 'ksh', 'csh', 'sh') as $sh) {
74796 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
74797 $shell = $sh;
74798 break;
74799 }
74800 }
74801
74802 if (isset($shell)) {
74803 $readCmd = ($shell === 'csh') ? 'set mypassword = $<' : 'read -r mypassword';
74804 $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
74805 $value = self::trimAnswer(shell_exec($command));
74806
74807
74808  echo PHP_EOL;
74809
74810 return $value;
74811 }
74812 }
74813
74814
74815  if (!$allowFallback) {
74816 throw new \RuntimeException('Could not prompt for input in a secure fashion, aborting');
74817 }
74818
74819 return self::prompt();
74820 }
74821
74822 private static function trimAnswer($str)
74823 {
74824 return preg_replace('{\r?\n$}D', '', $str);
74825 }
74826 }
74827 MIT License
74828
74829 Copyright (c) 2016
74830
74831 Permission is hereby granted, free of charge, to any person obtaining a copy
74832 of this software and associated documentation files (the "Software"), to deal
74833 in the Software without restriction, including without limitation the rights
74834 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
74835 copies of the Software, and to permit persons to whom the Software is
74836 furnished to do so, subject to the following conditions:
74837
74838 The above copyright notice and this permission notice shall be included in all
74839 copies or substantial portions of the Software.
74840
74841 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74842 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74843 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
74844 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74845 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
74846 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
74847 SOFTWARE.
74848 <?php
74849
74850 require __DIR__ . '/../vendor/autoload.php';
74851
74852 $data = json_decode(file_get_contents('data.json'));
74853
74854
74855 $validator = new JsonSchema\Validator();
74856 $validator->check($data, (object) array('$ref' => 'file://' . realpath('schema.json')));
74857
74858 if ($validator->isValid()) {
74859 echo "The supplied JSON validates against the schema.\n";
74860 } else {
74861 echo "JSON does not validate. Violations:\n";
74862 foreach ($validator->getErrors() as $error) {
74863 echo sprintf("[%s] %s\n", $error['property'], $error['message']);
74864 }
74865 }
74866 <?php
74867
74868
74869
74870
74871
74872
74873
74874
74875 namespace JsonSchema\Constraints;
74876
74877 use JsonSchema\Entity\JsonPointer;
74878 use JsonSchema\Exception\ValidationException;
74879
74880
74881
74882
74883
74884 class BaseConstraint
74885 {
74886
74887
74888
74889 protected $errors = array();
74890
74891
74892
74893
74894 protected $factory;
74895
74896
74897
74898
74899 public function __construct(Factory $factory = null)
74900 {
74901 $this->factory = $factory ?: new Factory();
74902 }
74903
74904 public function addError(JsonPointer $path = null, $message, $constraint = '', array $more = null)
74905 {
74906 $error = array(
74907 'property' => $this->convertJsonPointerIntoPropertyPath($path ?: new JsonPointer('')),
74908 'pointer' => ltrim(strval($path ?: new JsonPointer('')), '#'),
74909 'message' => $message,
74910 'constraint' => $constraint,
74911 );
74912
74913 if ($this->factory->getConfig(Constraint::CHECK_MODE_EXCEPTIONS)) {
74914 throw new ValidationException(sprintf('Error validating %s: %s', $error['pointer'], $error['message']));
74915 }
74916
74917 if (is_array($more) && count($more) > 0) {
74918 $error += $more;
74919 }
74920
74921 $this->errors[] = $error;
74922 }
74923
74924 public function addErrors(array $errors)
74925 {
74926 if ($errors) {
74927 $this->errors = array_merge($this->errors, $errors);
74928 }
74929 }
74930
74931 public function getErrors()
74932 {
74933 return $this->errors;
74934 }
74935
74936 public function isValid()
74937 {
74938 return !$this->getErrors();
74939 }
74940
74941
74942
74943
74944
74945 public function reset()
74946 {
74947 $this->errors = array();
74948 }
74949 }
74950 <?php
74951
74952
74953
74954
74955
74956
74957
74958
74959 namespace JsonSchema\Constraints;
74960
74961 use JsonSchema\Entity\JsonPointer;
74962
74963
74964
74965
74966
74967
74968
74969 class CollectionConstraint extends Constraint
74970 {
74971
74972
74973
74974 public function check(&$value, $schema = null, JsonPointer $path = null, $i = null)
74975 {
74976
74977  if (isset($schema->minItems) && count($value) < $schema->minItems) {
74978 $this->addError($path, 'There must be a minimum of ' . $schema->minItems . ' items in the array', 'minItems', array('minItems' => $schema->minItems));
74979 }
74980
74981
74982  if (isset($schema->maxItems) && count($value) > $schema->maxItems) {
74983 $this->addError($path, 'There must be a maximum of ' . $schema->maxItems . ' items in the array', 'maxItems', array('maxItems' => $schema->maxItems));
74984 }
74985
74986
74987  if (isset($schema->uniqueItems) && $schema->uniqueItems) {
74988 $unique = $value;
74989 if (is_array($value) && count($value)) {
74990 $unique = array_map(function ($e) {
74991 return var_export($e, true);
74992 }, $value);
74993 }
74994 if (count(array_unique($unique)) != count($value)) {
74995 $this->addError($path, 'There are no duplicates allowed in the array', 'uniqueItems');
74996 }
74997 }
74998
74999
75000  if (isset($schema->items)) {
75001 $this->validateItems($value, $schema, $path, $i);
75002 }
75003 }
75004
75005
75006
75007
75008
75009
75010
75011
75012
75013 protected function validateItems(&$value, $schema = null, JsonPointer $path = null, $i = null)
75014 {
75015 if (is_object($schema->items)) {
75016
75017
75018 if (isset($schema->items->type)
75019 && (
75020 $schema->items->type == 'string'
75021 || $schema->items->type == 'number'
75022 || $schema->items->type == 'integer'
75023 )
75024 && !isset($schema->additionalItems)
75025 ) {
75026
75027  $type = $schema->items->type;
75028 $typeValidator = $this->factory->createInstanceFor('type');
75029 $validator = $this->factory->createInstanceFor($type === 'integer' ? 'number' : $type);
75030
75031 foreach ($value as $k => &$v) {
75032 $k_path = $this->incrementPath($path, $k);
75033 $typeValidator->check($v, $schema->items, $k_path, $i);
75034
75035 $validator->check($v, $schema->items, $k_path, $i);
75036 }
75037 unset($v); 
75038  
75039  $this->addErrors($typeValidator->getErrors());
75040 $this->addErrors($validator->getErrors());
75041 } else {
75042 foreach ($value as $k => &$v) {
75043 $initErrors = $this->getErrors();
75044
75045
75046  $this->checkUndefined($v, $schema->items, $path, $k);
75047
75048
75049  if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) {
75050 $secondErrors = $this->getErrors();
75051 $this->checkUndefined($v, $schema->additionalItems, $path, $k);
75052 }
75053
75054
75055  if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) {
75056 $this->errors = $secondErrors;
75057 } elseif (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) {
75058 $this->errors = $initErrors;
75059 }
75060 }
75061 unset($v); 
75062  
75063  }
75064 } else {
75065
75066  foreach ($value as $k => &$v) {
75067 if (array_key_exists($k, $schema->items)) {
75068 $this->checkUndefined($v, $schema->items[$k], $path, $k);
75069 } else {
75070
75071  if (property_exists($schema, 'additionalItems')) {
75072 if ($schema->additionalItems !== false) {
75073 $this->checkUndefined($v, $schema->additionalItems, $path, $k);
75074 } else {
75075 $this->addError(
75076 $path, 'The item ' . $i . '[' . $k . '] is not defined and the definition does not allow additional items', 'additionalItems', array('additionalItems' => $schema->additionalItems));
75077 }
75078 } else {
75079
75080  $this->checkUndefined($v, new \stdClass(), $path, $k);
75081 }
75082 }
75083 }
75084 unset($v); 
75085  
75086
75087
75088  if (count($value) > 0) {
75089 for ($k = count($value); $k < count($schema->items); $k++) {
75090 $undefinedInstance = $this->factory->createInstanceFor('undefined');
75091 $this->checkUndefined($undefinedInstance, $schema->items[$k], $path, $k);
75092 }
75093 }
75094 }
75095 }
75096 }
75097 <?php
75098
75099
75100
75101
75102
75103
75104
75105
75106 namespace JsonSchema\Constraints;
75107
75108 use JsonSchema\Entity\JsonPointer;
75109 use JsonSchema\SchemaStorage;
75110 use JsonSchema\Uri\UriRetriever;
75111 use JsonSchema\UriRetrieverInterface;
75112
75113
75114
75115
75116
75117
75118
75119 abstract class Constraint extends BaseConstraint implements ConstraintInterface
75120 {
75121 protected $inlineSchemaProperty = '$schema';
75122
75123 const CHECK_MODE_NONE = 0x00000000;
75124 const CHECK_MODE_NORMAL = 0x00000001;
75125 const CHECK_MODE_TYPE_CAST = 0x00000002;
75126 const CHECK_MODE_COERCE_TYPES = 0x00000004;
75127 const CHECK_MODE_APPLY_DEFAULTS = 0x00000008;
75128 const CHECK_MODE_EXCEPTIONS = 0x00000010;
75129
75130
75131
75132
75133
75134
75135
75136
75137
75138 protected function incrementPath(JsonPointer $path = null, $i)
75139 {
75140 $path = $path ?: new JsonPointer('');
75141 $path = $path->withPropertyPaths(
75142 array_merge(
75143 $path->getPropertyPaths(),
75144 array_filter(array($i), 'strlen')
75145 )
75146 );
75147
75148 return $path;
75149 }
75150
75151
75152
75153
75154
75155
75156
75157
75158
75159 protected function checkArray(&$value, $schema = null, JsonPointer $path = null, $i = null)
75160 {
75161 $validator = $this->factory->createInstanceFor('collection');
75162 $validator->check($value, $schema, $path, $i);
75163
75164 $this->addErrors($validator->getErrors());
75165 }
75166
75167
75168
75169
75170
75171
75172
75173
75174
75175
75176 protected function checkObject(&$value, $schema = null, JsonPointer $path = null, $i = null, $patternProperties = null)
75177 {
75178 $validator = $this->factory->createInstanceFor('object');
75179 $validator->check($value, $schema, $path, $i, $patternProperties);
75180
75181 $this->addErrors($validator->getErrors());
75182 }
75183
75184
75185
75186
75187
75188
75189
75190
75191
75192 protected function checkType(&$value, $schema = null, JsonPointer $path = null, $i = null)
75193 {
75194 $validator = $this->factory->createInstanceFor('type');
75195 $validator->check($value, $schema, $path, $i);
75196
75197 $this->addErrors($validator->getErrors());
75198 }
75199
75200
75201
75202
75203
75204
75205
75206
75207
75208 protected function checkUndefined(&$value, $schema = null, JsonPointer $path = null, $i = null)
75209 {
75210 $validator = $this->factory->createInstanceFor('undefined');
75211
75212 $validator->check($value, $this->factory->getSchemaStorage()->resolveRefSchema($schema), $path, $i);
75213
75214 $this->addErrors($validator->getErrors());
75215 }
75216
75217
75218
75219
75220
75221
75222
75223
75224
75225 protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null)
75226 {
75227 $validator = $this->factory->createInstanceFor('string');
75228 $validator->check($value, $schema, $path, $i);
75229
75230 $this->addErrors($validator->getErrors());
75231 }
75232
75233
75234
75235
75236
75237
75238
75239
75240
75241 protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null)
75242 {
75243 $validator = $this->factory->createInstanceFor('number');
75244 $validator->check($value, $schema, $path, $i);
75245
75246 $this->addErrors($validator->getErrors());
75247 }
75248
75249
75250
75251
75252
75253
75254
75255
75256
75257 protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null)
75258 {
75259 $validator = $this->factory->createInstanceFor('enum');
75260 $validator->check($value, $schema, $path, $i);
75261
75262 $this->addErrors($validator->getErrors());
75263 }
75264
75265
75266
75267
75268
75269
75270
75271
75272
75273 protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null)
75274 {
75275 $validator = $this->factory->createInstanceFor('format');
75276 $validator->check($value, $schema, $path, $i);
75277
75278 $this->addErrors($validator->getErrors());
75279 }
75280
75281
75282
75283
75284
75285
75286 protected function getTypeCheck()
75287 {
75288 return $this->factory->getTypeCheck();
75289 }
75290
75291
75292
75293
75294
75295
75296 protected function convertJsonPointerIntoPropertyPath(JsonPointer $pointer)
75297 {
75298 $result = array_map(
75299 function ($path) {
75300 return sprintf(is_numeric($path) ? '[%d]' : '.%s', $path);
75301 },
75302 $pointer->getPropertyPaths()
75303 );
75304
75305 return trim(implode('', $result), '.');
75306 }
75307 }
75308 <?php
75309
75310
75311
75312
75313
75314
75315
75316
75317 namespace JsonSchema\Constraints;
75318
75319 use JsonSchema\Entity\JsonPointer;
75320
75321
75322
75323
75324
75325
75326 interface ConstraintInterface
75327 {
75328
75329
75330
75331
75332
75333 public function getErrors();
75334
75335
75336
75337
75338
75339
75340 public function addErrors(array $errors);
75341
75342
75343
75344
75345
75346
75347
75348
75349
75350 public function addError(JsonPointer $path = null, $message, $constraint='', array $more = null);
75351
75352
75353
75354
75355
75356
75357 public function isValid();
75358
75359
75360
75361
75362
75363
75364
75365
75366
75367
75368
75369
75370
75371 public function check(&$value, $schema = null, JsonPointer $path = null, $i = null);
75372 }
75373 <?php
75374
75375
75376
75377
75378
75379
75380
75381
75382 namespace JsonSchema\Constraints;
75383
75384 use JsonSchema\Entity\JsonPointer;
75385
75386
75387
75388
75389
75390
75391
75392 class EnumConstraint extends Constraint
75393 {
75394
75395
75396
75397 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
75398 {
75399
75400  if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) {
75401 return;
75402 }
75403 $type = gettype($element);
75404
75405 foreach ($schema->enum as $enum) {
75406 $enumType = gettype($enum);
75407 if ($this->factory->getConfig(self::CHECK_MODE_TYPE_CAST) && $type == 'array' && $enumType == 'object') {
75408 if ((object) $element == $enum) {
75409 return;
75410 }
75411 }
75412
75413 if ($type === gettype($enum)) {
75414 if ($type == 'object') {
75415 if ($element == $enum) {
75416 return;
75417 }
75418 } elseif ($element === $enum) {
75419 return;
75420 }
75421 }
75422 }
75423
75424 $this->addError($path, 'Does not have a value in the enumeration ' . json_encode($schema->enum), 'enum', array('enum' => $schema->enum));
75425 }
75426 }
75427 <?php
75428
75429
75430
75431
75432
75433
75434
75435
75436 namespace JsonSchema\Constraints;
75437
75438 use JsonSchema\Constraints\Constraint;
75439 use JsonSchema\Exception\InvalidArgumentException;
75440 use JsonSchema\Exception\InvalidConfigException;
75441 use JsonSchema\SchemaStorage;
75442 use JsonSchema\SchemaStorageInterface;
75443 use JsonSchema\Uri\UriRetriever;
75444 use JsonSchema\UriRetrieverInterface;
75445
75446
75447
75448
75449 class Factory
75450 {
75451
75452
75453
75454 protected $schemaStorage;
75455
75456
75457
75458
75459 protected $uriRetriever;
75460
75461
75462
75463
75464 private $checkMode = Constraint::CHECK_MODE_NORMAL;
75465
75466
75467
75468
75469 private $typeCheck = array();
75470
75471
75472
75473
75474 protected $constraintMap = array(
75475 'array' => 'JsonSchema\Constraints\CollectionConstraint',
75476 'collection' => 'JsonSchema\Constraints\CollectionConstraint',
75477 'object' => 'JsonSchema\Constraints\ObjectConstraint',
75478 'type' => 'JsonSchema\Constraints\TypeConstraint',
75479 'undefined' => 'JsonSchema\Constraints\UndefinedConstraint',
75480 'string' => 'JsonSchema\Constraints\StringConstraint',
75481 'number' => 'JsonSchema\Constraints\NumberConstraint',
75482 'enum' => 'JsonSchema\Constraints\EnumConstraint',
75483 'format' => 'JsonSchema\Constraints\FormatConstraint',
75484 'schema' => 'JsonSchema\Constraints\SchemaConstraint',
75485 'validator' => 'JsonSchema\Validator'
75486 );
75487
75488
75489
75490
75491 private $instanceCache = array();
75492
75493
75494
75495
75496
75497
75498 public function __construct(
75499 SchemaStorageInterface $schemaStorage = null,
75500 UriRetrieverInterface $uriRetriever = null,
75501 $checkMode = Constraint::CHECK_MODE_NORMAL
75502 ) {
75503
75504  $this->setConfig($checkMode);
75505
75506 $this->uriRetriever = $uriRetriever ?: new UriRetriever();
75507 $this->schemaStorage = $schemaStorage ?: new SchemaStorage($this->uriRetriever);
75508 }
75509
75510
75511
75512
75513
75514
75515 public function setConfig($checkMode = Constraint::CHECK_MODE_NORMAL)
75516 {
75517 $this->checkMode = $checkMode;
75518 }
75519
75520
75521
75522
75523
75524
75525 public function addConfig($options)
75526 {
75527 $this->checkMode |= $options;
75528 }
75529
75530
75531
75532
75533
75534
75535 public function removeConfig($options)
75536 {
75537 $this->checkMode &= ~$options;
75538 }
75539
75540
75541
75542
75543
75544
75545
75546
75547 public function getConfig($options = null)
75548 {
75549 if ($options === null) {
75550 return $this->checkMode;
75551 }
75552
75553 return $this->checkMode & $options;
75554 }
75555
75556
75557
75558
75559 public function getUriRetriever()
75560 {
75561 return $this->uriRetriever;
75562 }
75563
75564 public function getSchemaStorage()
75565 {
75566 return $this->schemaStorage;
75567 }
75568
75569 public function getTypeCheck()
75570 {
75571 if (!isset($this->typeCheck[$this->checkMode])) {
75572 $this->typeCheck[$this->checkMode] = ($this->checkMode & Constraint::CHECK_MODE_TYPE_CAST)
75573 ? new TypeCheck\LooseTypeCheck()
75574 : new TypeCheck\StrictTypeCheck();
75575 }
75576
75577 return $this->typeCheck[$this->checkMode];
75578 }
75579
75580
75581
75582
75583
75584
75585
75586 public function setConstraintClass($name, $class)
75587 {
75588
75589  if (!class_exists($class)) {
75590 throw new InvalidArgumentException('Unknown constraint ' . $name);
75591 }
75592
75593  if (!in_array('JsonSchema\Constraints\ConstraintInterface', class_implements($class))) {
75594 throw new InvalidArgumentException('Invalid class ' . $name);
75595 }
75596 $this->constraintMap[$name] = $class;
75597
75598 return $this;
75599 }
75600
75601
75602
75603
75604
75605
75606
75607
75608
75609
75610 public function createInstanceFor($constraintName)
75611 {
75612 if (!isset($this->constraintMap[$constraintName])) {
75613 throw new InvalidArgumentException('Unknown constraint ' . $constraintName);
75614 }
75615
75616 if (!isset($this->instanceCache[$constraintName])) {
75617 $this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName]($this);
75618 }
75619
75620 return clone $this->instanceCache[$constraintName];
75621 }
75622 }
75623 <?php
75624
75625
75626
75627
75628
75629
75630
75631
75632 namespace JsonSchema\Constraints;
75633
75634 use JsonSchema\Entity\JsonPointer;
75635 use JsonSchema\Rfc3339;
75636
75637
75638
75639
75640
75641
75642
75643
75644 class FormatConstraint extends Constraint
75645 {
75646
75647
75648
75649 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
75650 {
75651 if (!isset($schema->format)) {
75652 return;
75653 }
75654
75655 switch ($schema->format) {
75656 case 'date':
75657 if (!$date = $this->validateDateTime($element, 'Y-m-d')) {
75658 $this->addError($path, sprintf('Invalid date %s, expected format YYYY-MM-DD', json_encode($element)), 'format', array('format' => $schema->format));
75659 }
75660 break;
75661
75662 case 'time':
75663 if (!$this->validateDateTime($element, 'H:i:s')) {
75664 $this->addError($path, sprintf('Invalid time %s, expected format hh:mm:ss', json_encode($element)), 'format', array('format' => $schema->format));
75665 }
75666 break;
75667
75668 case 'date-time':
75669 if (null === Rfc3339::createFromString($element)) {
75670 $this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)), 'format', array('format' => $schema->format));
75671 }
75672 break;
75673
75674 case 'utc-millisec':
75675 if (!$this->validateDateTime($element, 'U')) {
75676 $this->addError($path, sprintf('Invalid time %s, expected integer of milliseconds since Epoch', json_encode($element)), 'format', array('format' => $schema->format));
75677 }
75678 break;
75679
75680 case 'regex':
75681 if (!$this->validateRegex($element)) {
75682 $this->addError($path, 'Invalid regex format ' . $element, 'format', array('format' => $schema->format));
75683 }
75684 break;
75685
75686 case 'color':
75687 if (!$this->validateColor($element)) {
75688 $this->addError($path, 'Invalid color', 'format', array('format' => $schema->format));
75689 }
75690 break;
75691
75692 case 'style':
75693 if (!$this->validateStyle($element)) {
75694 $this->addError($path, 'Invalid style', 'format', array('format' => $schema->format));
75695 }
75696 break;
75697
75698 case 'phone':
75699 if (!$this->validatePhone($element)) {
75700 $this->addError($path, 'Invalid phone number', 'format', array('format' => $schema->format));
75701 }
75702 break;
75703
75704 case 'uri':
75705 if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
75706 $this->addError($path, 'Invalid URL format', 'format', array('format' => $schema->format));
75707 }
75708 break;
75709
75710 case 'email':
75711 if (null === filter_var($element, FILTER_VALIDATE_EMAIL, FILTER_NULL_ON_FAILURE)) {
75712 $this->addError($path, 'Invalid email', 'format', array('format' => $schema->format));
75713 }
75714 break;
75715
75716 case 'ip-address':
75717 case 'ipv4':
75718 if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV4)) {
75719 $this->addError($path, 'Invalid IP address', 'format', array('format' => $schema->format));
75720 }
75721 break;
75722
75723 case 'ipv6':
75724 if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV6)) {
75725 $this->addError($path, 'Invalid IP address', 'format', array('format' => $schema->format));
75726 }
75727 break;
75728
75729 case 'host-name':
75730 case 'hostname':
75731 if (!$this->validateHostname($element)) {
75732 $this->addError($path, 'Invalid hostname', 'format', array('format' => $schema->format));
75733 }
75734 break;
75735
75736 default:
75737
75738  
75739  
75740  
75741  
75742  
75743  break;
75744 }
75745 }
75746
75747 protected function validateDateTime($datetime, $format)
75748 {
75749 $dt = \DateTime::createFromFormat($format, $datetime);
75750
75751 if (!$dt) {
75752 return false;
75753 }
75754
75755 if ($datetime === $dt->format($format)) {
75756 return true;
75757 }
75758
75759
75760  
75761  
75762  
75763  if ((strpos('u', $format) !== -1) && (preg_match('/\.\d+Z$/', $datetime))) {
75764 return true;
75765 }
75766
75767 return false;
75768 }
75769
75770 protected function validateRegex($regex)
75771 {
75772 return false !== @preg_match('/' . $regex . '/u', '');
75773 }
75774
75775 protected function validateColor($color)
75776 {
75777 if (in_array(strtolower($color), array('aqua', 'black', 'blue', 'fuchsia',
75778 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple',
75779 'red', 'silver', 'teal', 'white', 'yellow'))) {
75780 return true;
75781 }
75782
75783 return preg_match('/^#([a-f0-9]{3}|[a-f0-9]{6})$/i', $color);
75784 }
75785
75786 protected function validateStyle($style)
75787 {
75788 $properties = explode(';', rtrim($style, ';'));
75789 $invalidEntries = preg_grep('/^\s*[-a-z]+\s*:\s*.+$/i', $properties, PREG_GREP_INVERT);
75790
75791 return empty($invalidEntries);
75792 }
75793
75794 protected function validatePhone($phone)
75795 {
75796 return preg_match('/^\+?(\(\d{3}\)|\d{3}) \d{3} \d{4}$/', $phone);
75797 }
75798
75799 protected function validateHostname($host)
75800 {
75801 $hostnameRegex = '/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/i';
75802
75803 return preg_match($hostnameRegex, $host);
75804 }
75805 }
75806 <?php
75807
75808
75809
75810
75811
75812
75813
75814
75815 namespace JsonSchema\Constraints;
75816
75817 use JsonSchema\Entity\JsonPointer;
75818
75819
75820
75821
75822
75823
75824
75825 class NumberConstraint extends Constraint
75826 {
75827
75828
75829
75830 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
75831 {
75832
75833  if (isset($schema->exclusiveMinimum)) {
75834 if (isset($schema->minimum)) {
75835 if ($schema->exclusiveMinimum && $element <= $schema->minimum) {
75836 $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'exclusiveMinimum', array('minimum' => $schema->minimum));
75837 } elseif ($element < $schema->minimum) {
75838 $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'minimum', array('minimum' => $schema->minimum));
75839 }
75840 } else {
75841 $this->addError($path, 'Use of exclusiveMinimum requires presence of minimum', 'missingMinimum');
75842 }
75843 } elseif (isset($schema->minimum) && $element < $schema->minimum) {
75844 $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'minimum', array('minimum' => $schema->minimum));
75845 }
75846
75847
75848  if (isset($schema->exclusiveMaximum)) {
75849 if (isset($schema->maximum)) {
75850 if ($schema->exclusiveMaximum && $element >= $schema->maximum) {
75851 $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'exclusiveMaximum', array('maximum' => $schema->maximum));
75852 } elseif ($element > $schema->maximum) {
75853 $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'maximum', array('maximum' => $schema->maximum));
75854 }
75855 } else {
75856 $this->addError($path, 'Use of exclusiveMaximum requires presence of maximum', 'missingMaximum');
75857 }
75858 } elseif (isset($schema->maximum) && $element > $schema->maximum) {
75859 $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'maximum', array('maximum' => $schema->maximum));
75860 }
75861
75862
75863  if (isset($schema->divisibleBy) && $this->fmod($element, $schema->divisibleBy) != 0) {
75864 $this->addError($path, 'Is not divisible by ' . $schema->divisibleBy, 'divisibleBy', array('divisibleBy' => $schema->divisibleBy));
75865 }
75866
75867
75868  if (isset($schema->multipleOf) && $this->fmod($element, $schema->multipleOf) != 0) {
75869 $this->addError($path, 'Must be a multiple of ' . $schema->multipleOf, 'multipleOf', array('multipleOf' => $schema->multipleOf));
75870 }
75871
75872 $this->checkFormat($element, $schema, $path, $i);
75873 }
75874
75875 private function fmod($number1, $number2)
75876 {
75877 $number1 = abs($number1);
75878 $modulus = fmod($number1, $number2);
75879 $precision = abs(0.0000000001);
75880 $diff = (float) ($modulus - $number2);
75881
75882 if (-$precision < $diff && $diff < $precision) {
75883 return 0.0;
75884 }
75885
75886 $decimals1 = mb_strpos($number1, '.') ? mb_strlen($number1) - mb_strpos($number1, '.') - 1 : 0;
75887 $decimals2 = mb_strpos($number2, '.') ? mb_strlen($number2) - mb_strpos($number2, '.') - 1 : 0;
75888
75889 return (float) round($modulus, max($decimals1, $decimals2));
75890 }
75891 }
75892 <?php
75893
75894
75895
75896
75897
75898
75899
75900
75901 namespace JsonSchema\Constraints;
75902
75903 use JsonSchema\Entity\JsonPointer;
75904
75905
75906
75907
75908
75909
75910
75911 class ObjectConstraint extends Constraint
75912 {
75913
75914
75915
75916 public function check(&$element, $definition = null, JsonPointer $path = null, $additionalProp = null, $patternProperties = null)
75917 {
75918 if ($element instanceof UndefinedConstraint) {
75919 return;
75920 }
75921
75922 $matches = array();
75923 if ($patternProperties) {
75924 $matches = $this->validatePatternProperties($element, $path, $patternProperties);
75925 }
75926
75927 if ($definition) {
75928
75929  $this->validateDefinition($element, $definition, $path);
75930 }
75931
75932
75933  $this->validateElement($element, $matches, $definition, $path, $additionalProp);
75934 }
75935
75936 public function validatePatternProperties($element, JsonPointer $path = null, $patternProperties)
75937 {
75938 $try = array('/', '#', '+', '~', '%');
75939 $matches = array();
75940 foreach ($patternProperties as $pregex => $schema) {
75941 $delimiter = '/';
75942
75943  foreach ($try as $delimiter) {
75944 if (strpos($pregex, $delimiter) === false) { 
75945  break;
75946 }
75947 }
75948
75949
75950  if (@preg_match($delimiter . $pregex . $delimiter . 'u', '') === false) {
75951 $this->addError($path, 'The pattern "' . $pregex . '" is invalid', 'pregex', array('pregex' => $pregex));
75952 continue;
75953 }
75954 foreach ($element as $i => $value) {
75955 if (preg_match($delimiter . $pregex . $delimiter . 'u', $i)) {
75956 $matches[] = $i;
75957 $this->checkUndefined($value, $schema ?: new \stdClass(), $path, $i);
75958 }
75959 }
75960 }
75961
75962 return $matches;
75963 }
75964
75965
75966
75967
75968
75969
75970
75971
75972
75973
75974 public function validateElement($element, $matches, $objectDefinition = null, JsonPointer $path = null, $additionalProp = null)
75975 {
75976 $this->validateMinMaxConstraint($element, $objectDefinition, $path);
75977
75978 foreach ($element as $i => $value) {
75979 $definition = $this->getProperty($objectDefinition, $i);
75980
75981
75982  if (!in_array($i, $matches) && $additionalProp === false && $this->inlineSchemaProperty !== $i && !$definition) {
75983 $this->addError($path, 'The property ' . $i . ' is not defined and the definition does not allow additional properties', 'additionalProp');
75984 }
75985
75986
75987  if (!in_array($i, $matches) && $additionalProp && !$definition) {
75988 if ($additionalProp === true) {
75989 $this->checkUndefined($value, null, $path, $i);
75990 } else {
75991 $this->checkUndefined($value, $additionalProp, $path, $i);
75992 }
75993 }
75994
75995
75996  $require = $this->getProperty($definition, 'requires');
75997 if ($require && !$this->getProperty($element, $require)) {
75998 $this->addError($path, 'The presence of the property ' . $i . ' requires that ' . $require . ' also be present', 'requires');
75999 }
76000
76001 $property = $this->getProperty($element, $i, $this->factory->createInstanceFor('undefined'));
76002 if (is_object($property)) {
76003 $this->validateMinMaxConstraint(!($property instanceof UndefinedConstraint) ? $property : $element, $definition, $path);
76004 }
76005 }
76006 }
76007
76008
76009
76010
76011
76012
76013
76014
76015 public function validateDefinition(&$element, $objectDefinition = null, JsonPointer $path = null)
76016 {
76017 $undefinedConstraint = $this->factory->createInstanceFor('undefined');
76018
76019 foreach ($objectDefinition as $i => $value) {
76020 $property = &$this->getProperty($element, $i, $undefinedConstraint);
76021 $definition = $this->getProperty($objectDefinition, $i);
76022
76023 if (is_object($definition)) {
76024
76025  $this->checkUndefined($property, $definition, $path, $i);
76026 }
76027 }
76028 }
76029
76030
76031
76032
76033
76034
76035
76036
76037
76038
76039 protected function &getProperty(&$element, $property, $fallback = null)
76040 {
76041 if (is_array($element) && (isset($element[$property]) || array_key_exists($property, $element)) ) {
76042 return $element[$property];
76043 } elseif (is_object($element) && property_exists($element, $property)) {
76044 return $element->$property;
76045 }
76046
76047 return $fallback;
76048 }
76049
76050
76051
76052
76053
76054
76055
76056
76057 protected function validateMinMaxConstraint($element, $objectDefinition, JsonPointer $path = null)
76058 {
76059
76060  if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) {
76061 if ($this->getTypeCheck()->propertyCount($element) < $objectDefinition->minProperties) {
76062 $this->addError($path, 'Must contain a minimum of ' . $objectDefinition->minProperties . ' properties', 'minProperties', array('minProperties' => $objectDefinition->minProperties));
76063 }
76064 }
76065
76066  if (isset($objectDefinition->maxProperties) && !is_object($objectDefinition->maxProperties)) {
76067 if ($this->getTypeCheck()->propertyCount($element) > $objectDefinition->maxProperties) {
76068 $this->addError($path, 'Must contain no more than ' . $objectDefinition->maxProperties . ' properties', 'maxProperties', array('maxProperties' => $objectDefinition->maxProperties));
76069 }
76070 }
76071 }
76072 }
76073 <?php
76074
76075
76076
76077
76078
76079
76080
76081
76082 namespace JsonSchema\Constraints;
76083
76084 use JsonSchema\Entity\JsonPointer;
76085 use JsonSchema\Exception\InvalidArgumentException;
76086
76087
76088
76089
76090
76091
76092
76093 class SchemaConstraint extends Constraint
76094 {
76095
76096
76097
76098 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
76099 {
76100 if ($schema !== null) {
76101
76102  $this->checkUndefined($element, $schema, $path, $i);
76103 } elseif ($this->getTypeCheck()->propertyExists($element, $this->inlineSchemaProperty)) {
76104 $inlineSchema = $this->getTypeCheck()->propertyGet($element, $this->inlineSchemaProperty);
76105 if (is_array($inlineSchema)) {
76106 $inlineSchema = json_decode(json_encode($inlineSchema));
76107 }
76108
76109  $this->checkUndefined($element, $inlineSchema, $path, $i);
76110 } else {
76111 throw new InvalidArgumentException('no schema found to verify against');
76112 }
76113 }
76114 }
76115 <?php
76116
76117
76118
76119
76120
76121
76122
76123
76124 namespace JsonSchema\Constraints;
76125
76126 use JsonSchema\Entity\JsonPointer;
76127
76128
76129
76130
76131
76132
76133
76134 class StringConstraint extends Constraint
76135 {
76136
76137
76138
76139 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
76140 {
76141
76142  if (isset($schema->maxLength) && $this->strlen($element) > $schema->maxLength) {
76143 $this->addError($path, 'Must be at most ' . $schema->maxLength . ' characters long', 'maxLength', array(
76144 'maxLength' => $schema->maxLength,
76145 ));
76146 }
76147
76148
76149  if (isset($schema->minLength) && $this->strlen($element) < $schema->minLength) {
76150 $this->addError($path, 'Must be at least ' . $schema->minLength . ' characters long', 'minLength', array(
76151 'minLength' => $schema->minLength,
76152 ));
76153 }
76154
76155
76156  if (isset($schema->pattern) && !preg_match('#' . str_replace('#', '\\#', $schema->pattern) . '#u', $element)) {
76157 $this->addError($path, 'Does not match the regex pattern ' . $schema->pattern, 'pattern', array(
76158 'pattern' => $schema->pattern,
76159 ));
76160 }
76161
76162 $this->checkFormat($element, $schema, $path, $i);
76163 }
76164
76165 private function strlen($string)
76166 {
76167 if (extension_loaded('mbstring')) {
76168 return mb_strlen($string, mb_detect_encoding($string));
76169 }
76170
76171 return strlen($string);
76172 }
76173 }
76174 <?php
76175
76176 namespace JsonSchema\Constraints\TypeCheck;
76177
76178 class LooseTypeCheck implements TypeCheckInterface
76179 {
76180 public static function isObject($value)
76181 {
76182 return
76183 is_object($value) ||
76184 (is_array($value) && (count($value) == 0 || self::isAssociativeArray($value)));
76185 }
76186
76187 public static function isArray($value)
76188 {
76189 return
76190 is_array($value) &&
76191 (count($value) == 0 || !self::isAssociativeArray($value));
76192 }
76193
76194 public static function propertyGet($value, $property)
76195 {
76196 if (is_object($value)) {
76197 return $value->{$property};
76198 }
76199
76200 return $value[$property];
76201 }
76202
76203 public static function propertySet(&$value, $property, $data)
76204 {
76205 if (is_object($value)) {
76206 $value->{$property} = $data;
76207 } else {
76208 $value[$property] = $data;
76209 }
76210 }
76211
76212 public static function propertyExists($value, $property)
76213 {
76214 if (is_object($value)) {
76215 return property_exists($value, $property);
76216 }
76217
76218 return array_key_exists($property, $value);
76219 }
76220
76221 public static function propertyCount($value)
76222 {
76223 if (is_object($value)) {
76224 return count(get_object_vars($value));
76225 }
76226
76227 return count($value);
76228 }
76229
76230
76231
76232
76233
76234
76235
76236
76237 private static function isAssociativeArray($arr)
76238 {
76239 return array_keys($arr) !== range(0, count($arr) - 1);
76240 }
76241 }
76242 <?php
76243
76244 namespace JsonSchema\Constraints\TypeCheck;
76245
76246 class StrictTypeCheck implements TypeCheckInterface
76247 {
76248 public static function isObject($value)
76249 {
76250 return is_object($value);
76251 }
76252
76253 public static function isArray($value)
76254 {
76255 return is_array($value);
76256 }
76257
76258 public static function propertyGet($value, $property)
76259 {
76260 return $value->{$property};
76261 }
76262
76263 public static function propertySet(&$value, $property, $data)
76264 {
76265 $value->{$property} = $data;
76266 }
76267
76268 public static function propertyExists($value, $property)
76269 {
76270 return property_exists($value, $property);
76271 }
76272
76273 public static function propertyCount($value)
76274 {
76275 return count(get_object_vars($value));
76276 }
76277 }
76278 <?php
76279
76280 namespace JsonSchema\Constraints\TypeCheck;
76281
76282 interface TypeCheckInterface
76283 {
76284 public static function isObject($value);
76285
76286 public static function isArray($value);
76287
76288 public static function propertyGet($value, $property);
76289
76290 public static function propertySet(&$value, $property, $data);
76291
76292 public static function propertyExists($value, $property);
76293
76294 public static function propertyCount($value);
76295 }
76296 <?php
76297
76298
76299
76300
76301
76302
76303
76304
76305 namespace JsonSchema\Constraints;
76306
76307 use JsonSchema\Entity\JsonPointer;
76308 use JsonSchema\Exception\InvalidArgumentException;
76309 use UnexpectedValueException as StandardUnexpectedValueException;
76310
76311
76312
76313
76314
76315
76316
76317 class TypeConstraint extends Constraint
76318 {
76319
76320
76321
76322 public static $wording = array(
76323 'integer' => 'an integer',
76324 'number' => 'a number',
76325 'boolean' => 'a boolean',
76326 'object' => 'an object',
76327 'array' => 'an array',
76328 'string' => 'a string',
76329 'null' => 'a null',
76330 'any' => null, 
76331  0 => null, 
76332  );
76333
76334
76335
76336
76337 public function check(&$value = null, $schema = null, JsonPointer $path = null, $i = null)
76338 {
76339 $type = isset($schema->type) ? $schema->type : null;
76340 $isValid = false;
76341 $wording = array();
76342
76343 if (is_array($type)) {
76344 $this->validateTypesArray($value, $type, $wording, $isValid, $path);
76345 } elseif (is_object($type)) {
76346 $this->checkUndefined($value, $type, $path);
76347
76348 return;
76349 } else {
76350 $isValid = $this->validateType($value, $type);
76351 }
76352
76353 if ($isValid === false) {
76354 if (!is_array($type)) {
76355 $this->validateTypeNameWording($type);
76356 $wording[] = self::$wording[$type];
76357 }
76358 $this->addError($path, ucwords(gettype($value)) . ' value found, but ' .
76359 $this->implodeWith($wording, ', ', 'or') . ' is required', 'type');
76360 }
76361 }
76362
76363
76364
76365
76366
76367
76368
76369
76370
76371
76372
76373
76374 protected function validateTypesArray(&$value, array $type, &$validTypesWording, &$isValid, $path)
76375 {
76376 foreach ($type as $tp) {
76377
76378  
76379  if (is_object($tp)) {
76380 if (!$isValid) {
76381 $validator = $this->factory->createInstanceFor('type');
76382 $subSchema = new \stdClass();
76383 $subSchema->type = $tp;
76384 $validator->check($value, $subSchema, $path, null);
76385 $error = $validator->getErrors();
76386 $isValid = !(bool) $error;
76387 $validTypesWording[] = self::$wording['object'];
76388 }
76389 } else {
76390 $this->validateTypeNameWording($tp);
76391 $validTypesWording[] = self::$wording[$tp];
76392 if (!$isValid) {
76393 $isValid = $this->validateType($value, $tp);
76394 }
76395 }
76396 }
76397 }
76398
76399
76400
76401
76402
76403
76404
76405
76406
76407
76408
76409
76410 protected function implodeWith(array $elements, $delimiter = ', ', $listEnd = false)
76411 {
76412 if ($listEnd === false || !isset($elements[1])) {
76413 return implode($delimiter, $elements);
76414 }
76415 $lastElement = array_slice($elements, -1);
76416 $firsElements = join($delimiter, array_slice($elements, 0, -1));
76417 $implodedElements = array_merge(array($firsElements), $lastElement);
76418
76419 return join(" $listEnd ", $implodedElements);
76420 }
76421
76422
76423
76424
76425
76426
76427
76428
76429
76430 protected function validateTypeNameWording($type)
76431 {
76432 if (!isset(self::$wording[$type])) {
76433 throw new StandardUnexpectedValueException(
76434 sprintf(
76435 'No wording for %s available, expected wordings are: [%s]',
76436 var_export($type, true),
76437 implode(', ', array_filter(self::$wording)))
76438 );
76439 }
76440 }
76441
76442
76443
76444
76445
76446
76447
76448
76449
76450
76451
76452 protected function validateType(&$value, $type)
76453 {
76454
76455  if (!$type) {
76456 return true;
76457 }
76458
76459 if ('any' === $type) {
76460 return true;
76461 }
76462
76463 if ('object' === $type) {
76464 return $this->getTypeCheck()->isObject($value);
76465 }
76466
76467 if ('array' === $type) {
76468 return $this->getTypeCheck()->isArray($value);
76469 }
76470
76471 $coerce = $this->factory->getConfig(Constraint::CHECK_MODE_COERCE_TYPES);
76472
76473 if ('integer' === $type) {
76474 if ($coerce) {
76475 $value = $this->toInteger($value);
76476 }
76477
76478 return is_int($value);
76479 }
76480
76481 if ('number' === $type) {
76482 if ($coerce) {
76483 $value = $this->toNumber($value);
76484 }
76485
76486 return is_numeric($value) && !is_string($value);
76487 }
76488
76489 if ('boolean' === $type) {
76490 if ($coerce) {
76491 $value = $this->toBoolean($value);
76492 }
76493
76494 return is_bool($value);
76495 }
76496
76497 if ('string' === $type) {
76498 return is_string($value);
76499 }
76500
76501 if ('email' === $type) {
76502 return is_string($value);
76503 }
76504
76505 if ('null' === $type) {
76506 return is_null($value);
76507 }
76508
76509 throw new InvalidArgumentException((is_object($value) ? 'object' : $value) . ' is an invalid type for ' . $type);
76510 }
76511
76512
76513
76514
76515
76516
76517
76518
76519 protected function toBoolean($value)
76520 {
76521 if ($value === 'true') {
76522 return true;
76523 }
76524
76525 if ($value === 'false') {
76526 return false;
76527 }
76528
76529 return $value;
76530 }
76531
76532
76533
76534
76535
76536
76537
76538
76539 protected function toNumber($value)
76540 {
76541 if (is_numeric($value)) {
76542 return $value + 0; 
76543  }
76544
76545 return $value;
76546 }
76547
76548 protected function toInteger($value)
76549 {
76550 if (is_numeric($value) && (int) $value == $value) {
76551 return (int) $value; 
76552  }
76553
76554 return $value;
76555 }
76556 }
76557 <?php
76558
76559
76560
76561
76562
76563
76564
76565
76566 namespace JsonSchema\Constraints;
76567
76568 use JsonSchema\Constraints\TypeCheck\LooseTypeCheck;
76569 use JsonSchema\Entity\JsonPointer;
76570 use JsonSchema\Uri\UriResolver;
76571
76572
76573
76574
76575
76576
76577
76578 class UndefinedConstraint extends Constraint
76579 {
76580
76581
76582
76583 public function check(&$value, $schema = null, JsonPointer $path = null, $i = null)
76584 {
76585 if (is_null($schema) || !is_object($schema)) {
76586 return;
76587 }
76588
76589 $path = $this->incrementPath($path ?: new JsonPointer(''), $i);
76590
76591
76592  $this->validateCommonProperties($value, $schema, $path, $i);
76593
76594
76595  $this->validateOfProperties($value, $schema, $path, '');
76596
76597
76598  $this->validateTypes($value, $schema, $path, $i);
76599 }
76600
76601
76602
76603
76604
76605
76606
76607
76608
76609 public function validateTypes(&$value, $schema = null, JsonPointer $path, $i = null)
76610 {
76611
76612  if ($this->getTypeCheck()->isArray($value)) {
76613 $this->checkArray($value, $schema, $path, $i);
76614 }
76615
76616
76617  if (LooseTypeCheck::isObject($value)) { 
76618  
76619  
76620  $this->checkObject(
76621 $value,
76622 isset($schema->properties) ? $this->factory->getSchemaStorage()->resolveRefSchema($schema->properties) : $schema,
76623 $path,
76624 isset($schema->additionalProperties) ? $schema->additionalProperties : null,
76625 isset($schema->patternProperties) ? $schema->patternProperties : null
76626 );
76627 }
76628
76629
76630  if (is_string($value)) {
76631 $this->checkString($value, $schema, $path, $i);
76632 }
76633
76634
76635  if (is_numeric($value)) {
76636 $this->checkNumber($value, $schema, $path, $i);
76637 }
76638
76639
76640  if (isset($schema->enum)) {
76641 $this->checkEnum($value, $schema, $path, $i);
76642 }
76643 }
76644
76645
76646
76647
76648
76649
76650
76651
76652
76653 protected function validateCommonProperties(&$value, $schema = null, JsonPointer $path, $i = '')
76654 {
76655
76656  if (isset($schema->extends)) {
76657 if (is_string($schema->extends)) {
76658 $schema->extends = $this->validateUri($schema, $schema->extends);
76659 }
76660 if (is_array($schema->extends)) {
76661 foreach ($schema->extends as $extends) {
76662 $this->checkUndefined($value, $extends, $path, $i);
76663 }
76664 } else {
76665 $this->checkUndefined($value, $schema->extends, $path, $i);
76666 }
76667 }
76668
76669
76670  if ($this->factory->getConfig(self::CHECK_MODE_APPLY_DEFAULTS)) {
76671 if ($this->getTypeCheck()->isObject($value) && isset($schema->properties)) {
76672
76673  foreach ($schema->properties as $i => $propertyDefinition) {
76674 if (!$this->getTypeCheck()->propertyExists($value, $i) && isset($propertyDefinition->default)) {
76675 if (is_object($propertyDefinition->default)) {
76676 $this->getTypeCheck()->propertySet($value, $i, clone $propertyDefinition->default);
76677 } else {
76678 $this->getTypeCheck()->propertySet($value, $i, $propertyDefinition->default);
76679 }
76680 }
76681 }
76682 } elseif ($this->getTypeCheck()->isArray($value)) {
76683 if (isset($schema->properties)) {
76684
76685  foreach ($schema->properties as $i => $propertyDefinition) {
76686 if (!isset($value[$i]) && isset($propertyDefinition->default)) {
76687 if (is_object($propertyDefinition->default)) {
76688 $value[$i] = clone $propertyDefinition->default;
76689 } else {
76690 $value[$i] = $propertyDefinition->default;
76691 }
76692 }
76693 }
76694 } elseif (isset($schema->items)) {
76695
76696  foreach ($schema->items as $i => $itemDefinition) {
76697 if (!isset($value[$i]) && isset($itemDefinition->default)) {
76698 if (is_object($itemDefinition->default)) {
76699 $value[$i] = clone $itemDefinition->default;
76700 } else {
76701 $value[$i] = $itemDefinition->default;
76702 }
76703 }
76704 }
76705 }
76706 } elseif (($value instanceof self || $value === null) && isset($schema->default)) {
76707
76708  $value = is_object($schema->default) ? clone $schema->default : $schema->default;
76709 }
76710 }
76711
76712
76713  if ($this->getTypeCheck()->isObject($value)) {
76714 if (!($value instanceof self) && isset($schema->required) && is_array($schema->required)) {
76715
76716  foreach ($schema->required as $required) {
76717 if (!$this->getTypeCheck()->propertyExists($value, $required)) {
76718 $this->addError(
76719 $this->incrementPath($path ?: new JsonPointer(''), $required),
76720 'The property ' . $required . ' is required',
76721 'required'
76722 );
76723 }
76724 }
76725 } elseif (isset($schema->required) && !is_array($schema->required)) {
76726
76727  if ($schema->required && $value instanceof self) {
76728 $this->addError($path, 'Is missing and it is required', 'required');
76729 }
76730 }
76731 }
76732
76733
76734  if (!($value instanceof self)) {
76735 $this->checkType($value, $schema, $path, $i);
76736 }
76737
76738
76739  if (isset($schema->disallow)) {
76740 $initErrors = $this->getErrors();
76741
76742 $typeSchema = new \stdClass();
76743 $typeSchema->type = $schema->disallow;
76744 $this->checkType($value, $typeSchema, $path);
76745
76746
76747  if (count($this->getErrors()) == count($initErrors)) {
76748 $this->addError($path, 'Disallowed value was matched', 'disallow');
76749 } else {
76750 $this->errors = $initErrors;
76751 }
76752 }
76753
76754 if (isset($schema->not)) {
76755 $initErrors = $this->getErrors();
76756 $this->checkUndefined($value, $schema->not, $path, $i);
76757
76758
76759  if (count($this->getErrors()) == count($initErrors)) {
76760 $this->addError($path, 'Matched a schema which it should not', 'not');
76761 } else {
76762 $this->errors = $initErrors;
76763 }
76764 }
76765
76766
76767  if (isset($schema->dependencies) && $this->getTypeCheck()->isObject($value)) {
76768 $this->validateDependencies($value, $schema->dependencies, $path);
76769 }
76770 }
76771
76772
76773
76774
76775
76776
76777
76778
76779
76780 protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i = '')
76781 {
76782
76783  if ($value instanceof self) {
76784 return;
76785 }
76786
76787 if (isset($schema->allOf)) {
76788 $isValid = true;
76789 foreach ($schema->allOf as $allOf) {
76790 $initErrors = $this->getErrors();
76791 $this->checkUndefined($value, $allOf, $path, $i);
76792 $isValid = $isValid && (count($this->getErrors()) == count($initErrors));
76793 }
76794 if (!$isValid) {
76795 $this->addError($path, 'Failed to match all schemas', 'allOf');
76796 }
76797 }
76798
76799 if (isset($schema->anyOf)) {
76800 $isValid = false;
76801 $startErrors = $this->getErrors();
76802 foreach ($schema->anyOf as $anyOf) {
76803 $initErrors = $this->getErrors();
76804 $this->checkUndefined($value, $anyOf, $path, $i);
76805 if ($isValid = (count($this->getErrors()) == count($initErrors))) {
76806 break;
76807 }
76808 }
76809 if (!$isValid) {
76810 $this->addError($path, 'Failed to match at least one schema', 'anyOf');
76811 } else {
76812 $this->errors = $startErrors;
76813 }
76814 }
76815
76816 if (isset($schema->oneOf)) {
76817 $allErrors = array();
76818 $matchedSchemas = 0;
76819 $startErrors = $this->getErrors();
76820 foreach ($schema->oneOf as $oneOf) {
76821 $this->errors = array();
76822 $this->checkUndefined($value, $oneOf, $path, $i);
76823 if (count($this->getErrors()) == 0) {
76824 $matchedSchemas++;
76825 }
76826 $allErrors = array_merge($allErrors, array_values($this->getErrors()));
76827 }
76828 if ($matchedSchemas !== 1) {
76829 $this->addErrors(array_merge($allErrors, $startErrors));
76830 $this->addError($path, 'Failed to match exactly one schema', 'oneOf');
76831 } else {
76832 $this->errors = $startErrors;
76833 }
76834 }
76835 }
76836
76837
76838
76839
76840
76841
76842
76843
76844
76845 protected function validateDependencies($value, $dependencies, JsonPointer $path, $i = '')
76846 {
76847 foreach ($dependencies as $key => $dependency) {
76848 if ($this->getTypeCheck()->propertyExists($value, $key)) {
76849 if (is_string($dependency)) {
76850
76851  if (!$this->getTypeCheck()->propertyExists($value, $dependency)) {
76852 $this->addError($path, "$key depends on $dependency and $dependency is missing", 'dependencies');
76853 }
76854 } elseif (is_array($dependency)) {
76855
76856  foreach ($dependency as $d) {
76857 if (!$this->getTypeCheck()->propertyExists($value, $d)) {
76858 $this->addError($path, "$key depends on $d and $d is missing", 'dependencies');
76859 }
76860 }
76861 } elseif (is_object($dependency)) {
76862
76863  $this->checkUndefined($value, $dependency, $path, $i);
76864 }
76865 }
76866 }
76867 }
76868
76869 protected function validateUri($schema, $schemaUri = null)
76870 {
76871 $resolver = new UriResolver();
76872 $retriever = $this->factory->getUriRetriever();
76873
76874 $jsonSchema = null;
76875 if ($resolver->isValid($schemaUri)) {
76876 $schemaId = property_exists($schema, 'id') ? $schema->id : null;
76877 $jsonSchema = $retriever->retrieve($schemaId, $schemaUri);
76878 }
76879
76880 return $jsonSchema;
76881 }
76882 }
76883 <?php
76884
76885
76886
76887
76888
76889
76890
76891
76892 namespace JsonSchema\Entity;
76893
76894
76895
76896
76897
76898
76899 class JsonPointer
76900 {
76901
76902 private $filename;
76903
76904
76905 private $propertyPaths = array();
76906
76907
76908
76909
76910
76911
76912 public function __construct($value)
76913 {
76914 if (!is_string($value)) {
76915 throw new \InvalidArgumentException('Ref value must be a string');
76916 }
76917
76918 $splitRef = explode('#', $value, 2);
76919 $this->filename = $splitRef[0];
76920 if (array_key_exists(1, $splitRef)) {
76921 $this->propertyPaths = $this->decodePropertyPaths($splitRef[1]);
76922 }
76923 }
76924
76925
76926
76927
76928
76929
76930 private function decodePropertyPaths($propertyPathString)
76931 {
76932 $paths = array();
76933 foreach (explode('/', trim($propertyPathString, '/')) as $path) {
76934 $path = $this->decodePath($path);
76935 if (is_string($path) && '' !== $path) {
76936 $paths[] = $path;
76937 }
76938 }
76939
76940 return $paths;
76941 }
76942
76943
76944
76945
76946 private function encodePropertyPaths()
76947 {
76948 return array_map(
76949 array($this, 'encodePath'),
76950 $this->getPropertyPaths()
76951 );
76952 }
76953
76954
76955
76956
76957
76958
76959 private function decodePath($path)
76960 {
76961 return strtr($path, array('~1' => '/', '~0' => '~', '%25' => '%'));
76962 }
76963
76964
76965
76966
76967
76968
76969 private function encodePath($path)
76970 {
76971 return strtr($path, array('/' => '~1', '~' => '~0', '%' => '%25'));
76972 }
76973
76974
76975
76976
76977 public function getFilename()
76978 {
76979 return $this->filename;
76980 }
76981
76982
76983
76984
76985 public function getPropertyPaths()
76986 {
76987 return $this->propertyPaths;
76988 }
76989
76990
76991
76992
76993
76994
76995 public function withPropertyPaths(array $propertyPaths)
76996 {
76997 $new = clone $this;
76998 $new->propertyPaths = $propertyPaths;
76999
77000 return $new;
77001 }
77002
77003
77004
77005
77006 public function getPropertyPathAsString()
77007 {
77008 return rtrim('#/' . implode('/', $this->encodePropertyPaths()), '/');
77009 }
77010
77011
77012
77013
77014 public function __toString()
77015 {
77016 return $this->getFilename() . $this->getPropertyPathAsString();
77017 }
77018 }
77019 <?php
77020
77021 namespace JsonSchema\Exception;
77022
77023 interface ExceptionInterface
77024 {
77025 }
77026 <?php
77027
77028
77029
77030
77031
77032
77033
77034
77035 namespace JsonSchema\Exception;
77036
77037
77038
77039
77040 class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
77041 {
77042 }
77043 <?php
77044
77045
77046
77047
77048
77049
77050
77051
77052 namespace JsonSchema\Exception;
77053
77054
77055
77056
77057 class InvalidConfigException extends RuntimeException
77058 {
77059 }
77060 <?php
77061
77062
77063
77064
77065
77066
77067
77068
77069 namespace JsonSchema\Exception;
77070
77071
77072
77073
77074 class InvalidSchemaMediaTypeException extends RuntimeException
77075 {
77076 }
77077 <?php
77078
77079
77080
77081
77082
77083
77084
77085
77086 namespace JsonSchema\Exception;
77087
77088
77089
77090
77091 class InvalidSourceUriException extends InvalidArgumentException
77092 {
77093 }
77094 <?php
77095
77096
77097
77098
77099
77100
77101
77102
77103 namespace JsonSchema\Exception;
77104
77105
77106
77107
77108 class JsonDecodingException extends RuntimeException
77109 {
77110 public function __construct($code = JSON_ERROR_NONE, \Exception $previous = null)
77111 {
77112 switch ($code) {
77113 case JSON_ERROR_DEPTH:
77114 $message = 'The maximum stack depth has been exceeded';
77115 break;
77116 case JSON_ERROR_STATE_MISMATCH:
77117 $message = 'Invalid or malformed JSON';
77118 break;
77119 case JSON_ERROR_CTRL_CHAR:
77120 $message = 'Control character error, possibly incorrectly encoded';
77121 break;
77122 case JSON_ERROR_UTF8:
77123 $message = 'Malformed UTF-8 characters, possibly incorrectly encoded';
77124 break;
77125 case JSON_ERROR_SYNTAX:
77126 $message = 'JSON syntax is malformed';
77127 break;
77128 default:
77129 $message = 'Syntax error';
77130 }
77131 parent::__construct($message, $code, $previous);
77132 }
77133 }
77134 <?php
77135
77136
77137
77138
77139
77140
77141
77142
77143 namespace JsonSchema\Exception;
77144
77145
77146
77147
77148 class ResourceNotFoundException extends RuntimeException
77149 {
77150 }
77151 <?php
77152
77153
77154
77155
77156
77157
77158
77159
77160 namespace JsonSchema\Exception;
77161
77162
77163
77164
77165 class RuntimeException extends \RuntimeException implements ExceptionInterface
77166 {
77167 }
77168 <?php
77169
77170
77171
77172
77173
77174
77175
77176
77177 namespace JsonSchema\Exception;
77178
77179
77180
77181
77182
77183
77184 class UnresolvableJsonPointerException extends InvalidArgumentException
77185 {
77186 }
77187 <?php
77188
77189
77190
77191
77192
77193
77194
77195
77196 namespace JsonSchema\Exception;
77197
77198
77199
77200
77201 class UriResolverException extends RuntimeException
77202 {
77203 }
77204 <?php
77205
77206
77207
77208
77209
77210
77211
77212
77213 namespace JsonSchema\Exception;
77214
77215 class ValidationException extends RuntimeException
77216 {
77217 }
77218 <?php
77219
77220
77221
77222
77223
77224
77225
77226
77227 namespace JsonSchema\Iterator;
77228
77229
77230
77231
77232
77233
77234 class ObjectIterator implements \Iterator, \Countable
77235 {
77236
77237 private $object;
77238
77239
77240 private $position = 0;
77241
77242
77243 private $data = array();
77244
77245
77246 private $initialized = false;
77247
77248
77249
77250
77251 public function __construct($object)
77252 {
77253 $this->object = $object;
77254 }
77255
77256
77257
77258
77259 public function current()
77260 {
77261 $this->initialize();
77262
77263 return $this->data[$this->position];
77264 }
77265
77266
77267
77268
77269 public function next()
77270 {
77271 $this->initialize();
77272 $this->position++;
77273 }
77274
77275
77276
77277
77278 public function key()
77279 {
77280 $this->initialize();
77281
77282 return $this->position;
77283 }
77284
77285
77286
77287
77288 public function valid()
77289 {
77290 $this->initialize();
77291
77292 return isset($this->data[$this->position]);
77293 }
77294
77295
77296
77297
77298 public function rewind()
77299 {
77300 $this->initialize();
77301 $this->position = 0;
77302 }
77303
77304
77305
77306
77307 public function count()
77308 {
77309 $this->initialize();
77310
77311 return count($this->data);
77312 }
77313
77314
77315
77316
77317 private function initialize()
77318 {
77319 if (!$this->initialized) {
77320 $this->data = $this->buildDataFromObject($this->object);
77321 $this->initialized = true;
77322 }
77323 }
77324
77325
77326
77327
77328
77329
77330 private function buildDataFromObject($object)
77331 {
77332 $result = array();
77333
77334 $stack = new \SplStack();
77335 $stack->push($object);
77336
77337 while (!$stack->isEmpty()) {
77338 $current = $stack->pop();
77339 if (is_object($current)) {
77340 array_push($result, $current);
77341 }
77342
77343 foreach ($this->getDataFromItem($current) as $propertyName => $propertyValue) {
77344 if (is_object($propertyValue) || is_array($propertyValue)) {
77345 $stack->push($propertyValue);
77346 }
77347 }
77348 }
77349
77350 return $result;
77351 }
77352
77353
77354
77355
77356
77357
77358 private function getDataFromItem($item)
77359 {
77360 if (!is_object($item) && !is_array($item)) {
77361 return array();
77362 }
77363
77364 return is_object($item) ? get_object_vars($item) : $item;
77365 }
77366 }
77367 <?php
77368
77369 namespace JsonSchema;
77370
77371 class Rfc3339
77372 {
77373 const REGEX = '/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(\.\d+)?(Z|([+-]\d{2}):?(\d{2}))$/';
77374
77375
77376
77377
77378
77379
77380
77381
77382 public static function createFromString($string)
77383 {
77384 if (!preg_match(self::REGEX, strtoupper($string), $matches)) {
77385 return null;
77386 }
77387
77388 $dateAndTime = $matches[1];
77389 $microseconds = $matches[2] ?: '.000000';
77390 $timeZone = 'Z' !== $matches[3] ? $matches[4] . ':' . $matches[5] : '+00:00';
77391
77392 $dateTime = \DateTime::createFromFormat('Y-m-d\TH:i:s.uP', $dateAndTime . $microseconds . $timeZone, new \DateTimeZone('UTC'));
77393
77394 return $dateTime ?: null;
77395 }
77396 }
77397 <?php
77398
77399 namespace JsonSchema;
77400
77401 use JsonSchema\Entity\JsonPointer;
77402 use JsonSchema\Exception\UnresolvableJsonPointerException;
77403 use JsonSchema\Iterator\ObjectIterator;
77404 use JsonSchema\Uri\UriResolver;
77405 use JsonSchema\Uri\UriRetriever;
77406
77407 class SchemaStorage implements SchemaStorageInterface
77408 {
77409 protected $uriRetriever;
77410 protected $uriResolver;
77411 protected $schemas = array();
77412
77413 public function __construct(
77414 UriRetrieverInterface $uriRetriever = null,
77415 UriResolverInterface $uriResolver = null
77416 ) {
77417 $this->uriRetriever = $uriRetriever ?: new UriRetriever();
77418 $this->uriResolver = $uriResolver ?: new UriResolver();
77419 }
77420
77421
77422
77423
77424 public function getUriRetriever()
77425 {
77426 return $this->uriRetriever;
77427 }
77428
77429
77430
77431
77432 public function getUriResolver()
77433 {
77434 return $this->uriResolver;
77435 }
77436
77437
77438
77439
77440 public function addSchema($id, $schema = null)
77441 {
77442 if (is_null($schema)) {
77443 $schema = $this->uriRetriever->retrieve($id);
77444 }
77445 $objectIterator = new ObjectIterator($schema);
77446 foreach ($objectIterator as $toResolveSchema) {
77447 if (property_exists($toResolveSchema, '$ref') && is_string($toResolveSchema->{'$ref'})) {
77448 $jsonPointer = new JsonPointer($this->uriResolver->resolve($toResolveSchema->{'$ref'}, $id));
77449 $toResolveSchema->{'$ref'} = (string) $jsonPointer;
77450 }
77451 }
77452 $this->schemas[$id] = $schema;
77453 }
77454
77455
77456
77457
77458 public function getSchema($id)
77459 {
77460 if (!array_key_exists($id, $this->schemas)) {
77461 $this->addSchema($id);
77462 }
77463
77464 return $this->schemas[$id];
77465 }
77466
77467
77468
77469
77470 public function resolveRef($ref)
77471 {
77472 $jsonPointer = new JsonPointer($ref);
77473 $refSchema = $this->getSchema($jsonPointer->getFilename());
77474
77475 foreach ($jsonPointer->getPropertyPaths() as $path) {
77476 if (is_object($refSchema) && property_exists($refSchema, $path)) {
77477 $refSchema = $this->resolveRefSchema($refSchema->{$path});
77478 } elseif (is_array($refSchema) && array_key_exists($path, $refSchema)) {
77479 $refSchema = $this->resolveRefSchema($refSchema[$path]);
77480 } else {
77481 throw new UnresolvableJsonPointerException(sprintf(
77482 'File: %s is found, but could not resolve fragment: %s',
77483 $jsonPointer->getFilename(),
77484 $jsonPointer->getPropertyPathAsString()
77485 ));
77486 }
77487 }
77488
77489 return $refSchema;
77490 }
77491
77492
77493
77494
77495 public function resolveRefSchema($refSchema)
77496 {
77497 if (is_object($refSchema) && property_exists($refSchema, '$ref') && is_string($refSchema->{'$ref'})) {
77498 $newSchema = $this->resolveRef($refSchema->{'$ref'});
77499 $refSchema = (object) (get_object_vars($refSchema) + get_object_vars($newSchema));
77500 unset($refSchema->{'$ref'});
77501 }
77502
77503 return $refSchema;
77504 }
77505 }
77506 <?php
77507
77508 namespace JsonSchema;
77509
77510 interface SchemaStorageInterface
77511 {
77512
77513
77514
77515
77516
77517
77518 public function addSchema($id, $schema = null);
77519
77520
77521
77522
77523
77524
77525
77526
77527 public function getSchema($id);
77528
77529
77530
77531
77532
77533
77534
77535
77536 public function resolveRef($ref);
77537
77538
77539
77540
77541
77542
77543
77544
77545 public function resolveRefSchema($refSchema);
77546 }
77547 <?php
77548
77549
77550
77551
77552
77553
77554 namespace JsonSchema\Uri\Retrievers;
77555
77556
77557
77558
77559
77560
77561
77562 abstract class AbstractRetriever implements UriRetrieverInterface
77563 {
77564
77565
77566
77567
77568
77569 protected $contentType;
77570
77571
77572
77573
77574
77575
77576 public function getContentType()
77577 {
77578 return $this->contentType;
77579 }
77580 }
77581 <?php
77582
77583
77584
77585
77586
77587
77588
77589
77590 namespace JsonSchema\Uri\Retrievers;
77591
77592 use JsonSchema\Validator;
77593
77594
77595
77596
77597
77598
77599 class Curl extends AbstractRetriever
77600 {
77601 protected $messageBody;
77602
77603 public function __construct()
77604 {
77605 if (!function_exists('curl_init')) {
77606 throw new \RuntimeException('cURL not installed');
77607 }
77608 }
77609
77610
77611
77612
77613
77614
77615 public function retrieve($uri)
77616 {
77617 $ch = curl_init();
77618
77619 curl_setopt($ch, CURLOPT_URL, $uri);
77620 curl_setopt($ch, CURLOPT_HEADER, true);
77621 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
77622 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: ' . Validator::SCHEMA_MEDIA_TYPE));
77623
77624 $response = curl_exec($ch);
77625 if (false === $response) {
77626 throw new \JsonSchema\Exception\ResourceNotFoundException('JSON schema not found');
77627 }
77628
77629 $this->fetchMessageBody($response);
77630 $this->fetchContentType($response);
77631
77632 curl_close($ch);
77633
77634 return $this->messageBody;
77635 }
77636
77637
77638
77639
77640 private function fetchMessageBody($response)
77641 {
77642 preg_match("/(?:\r\n){2}(.*)$/ms", $response, $match);
77643 $this->messageBody = $match[1];
77644 }
77645
77646
77647
77648
77649
77650
77651 protected function fetchContentType($response)
77652 {
77653 if (0 < preg_match("/Content-Type:(\V*)/ims", $response, $match)) {
77654 $this->contentType = trim($match[1]);
77655
77656 return true;
77657 }
77658
77659 return false;
77660 }
77661 }
77662 <?php
77663
77664
77665
77666
77667
77668
77669
77670
77671 namespace JsonSchema\Uri\Retrievers;
77672
77673 use JsonSchema\Exception\ResourceNotFoundException;
77674
77675
77676
77677
77678
77679
77680 class FileGetContents extends AbstractRetriever
77681 {
77682 protected $messageBody;
77683
77684
77685
77686
77687
77688
77689 public function retrieve($uri)
77690 {
77691 $errorMessage = null;
77692 set_error_handler(function ($errno, $errstr) use (&$errorMessage) {
77693 $errorMessage = $errstr;
77694 });
77695 $response = file_get_contents($uri);
77696 restore_error_handler();
77697
77698 if ($errorMessage) {
77699 throw new ResourceNotFoundException($errorMessage);
77700 }
77701
77702 if (false === $response) {
77703 throw new ResourceNotFoundException('JSON schema not found at ' . $uri);
77704 }
77705
77706 if ($response == ''
77707 && substr($uri, 0, 7) == 'file://' && substr($uri, -1) == '/'
77708 ) {
77709 throw new ResourceNotFoundException('JSON schema not found at ' . $uri);
77710 }
77711
77712 $this->messageBody = $response;
77713 if (!empty($http_response_header)) {
77714 $this->fetchContentType($http_response_header);
77715 } else {
77716
77717  $this->contentType = null;
77718 }
77719
77720 return $this->messageBody;
77721 }
77722
77723
77724
77725
77726
77727
77728 private function fetchContentType(array $headers)
77729 {
77730 foreach ($headers as $header) {
77731 if ($this->contentType = self::getContentTypeMatchInHeader($header)) {
77732 return true;
77733 }
77734 }
77735
77736 return false;
77737 }
77738
77739
77740
77741
77742
77743
77744 protected static function getContentTypeMatchInHeader($header)
77745 {
77746 if (0 < preg_match("/Content-Type:(\V*)/ims", $header, $match)) {
77747 return trim($match[1]);
77748 }
77749
77750 return null;
77751 }
77752 }
77753 <?php
77754
77755 namespace JsonSchema\Uri\Retrievers;
77756
77757 use JsonSchema\Validator;
77758
77759
77760
77761
77762
77763
77764
77765
77766
77767
77768
77769
77770
77771 class PredefinedArray extends AbstractRetriever
77772 {
77773
77774
77775
77776
77777
77778 private $schemas;
77779
77780
77781
77782
77783
77784
77785
77786 public function __construct(array $schemas, $contentType = Validator::SCHEMA_MEDIA_TYPE)
77787 {
77788 $this->schemas = $schemas;
77789 $this->contentType = $contentType;
77790 }
77791
77792
77793
77794
77795
77796
77797 public function retrieve($uri)
77798 {
77799 if (!array_key_exists($uri, $this->schemas)) {
77800 throw new \JsonSchema\Exception\ResourceNotFoundException(sprintf(
77801 'The JSON schema "%s" was not found.',
77802 $uri
77803 ));
77804 }
77805
77806 return $this->schemas[$uri];
77807 }
77808 }
77809 <?php
77810
77811
77812
77813
77814
77815
77816
77817
77818 namespace JsonSchema\Uri\Retrievers;
77819
77820
77821
77822
77823
77824
77825 interface UriRetrieverInterface
77826 {
77827
77828
77829
77830
77831
77832
77833
77834
77835
77836 public function retrieve($uri);
77837
77838
77839
77840
77841
77842
77843 public function getContentType();
77844 }
77845 <?php
77846
77847
77848
77849
77850
77851
77852
77853
77854 namespace JsonSchema\Uri;
77855
77856 use JsonSchema\Exception\UriResolverException;
77857 use JsonSchema\UriResolverInterface;
77858
77859
77860
77861
77862
77863
77864 class UriResolver implements UriResolverInterface
77865 {
77866
77867
77868
77869
77870
77871
77872
77873 public function parse($uri)
77874 {
77875 preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match);
77876
77877 $components = array();
77878 if (5 < count($match)) {
77879 $components = array(
77880 'scheme' => $match[2],
77881 'authority' => $match[4],
77882 'path' => $match[5]
77883 );
77884 }
77885 if (7 < count($match)) {
77886 $components['query'] = $match[7];
77887 }
77888 if (9 < count($match)) {
77889 $components['fragment'] = $match[9];
77890 }
77891
77892 return $components;
77893 }
77894
77895
77896
77897
77898
77899
77900
77901
77902 public function generate(array $components)
77903 {
77904 $uri = $components['scheme'] . '://'
77905 . $components['authority']
77906 . $components['path'];
77907
77908 if (array_key_exists('query', $components)) {
77909 $uri .= $components['query'];
77910 }
77911 if (array_key_exists('fragment', $components)) {
77912 $uri .= '#' . $components['fragment'];
77913 }
77914
77915 return $uri;
77916 }
77917
77918
77919
77920
77921 public function resolve($uri, $baseUri = null)
77922 {
77923 if ($uri == '') {
77924 return $baseUri;
77925 }
77926
77927 $components = $this->parse($uri);
77928 $path = $components['path'];
77929
77930 if (!empty($components['scheme'])) {
77931 return $uri;
77932 }
77933 $baseComponents = $this->parse($baseUri);
77934 $basePath = $baseComponents['path'];
77935
77936 $baseComponents['path'] = self::combineRelativePathWithBasePath($path, $basePath);
77937 if (isset($components['fragment'])) {
77938 $baseComponents['fragment'] = $components['fragment'];
77939 }
77940
77941 return $this->generate($baseComponents);
77942 }
77943
77944
77945
77946
77947
77948
77949
77950
77951
77952
77953
77954 public static function combineRelativePathWithBasePath($relativePath, $basePath)
77955 {
77956 $relativePath = self::normalizePath($relativePath);
77957 if ($relativePath == '') {
77958 return $basePath;
77959 }
77960 if ($relativePath[0] == '/') {
77961 return $relativePath;
77962 }
77963
77964 $basePathSegments = explode('/', $basePath);
77965
77966 preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match);
77967 $numLevelUp = strlen($match[0]) /3 + 1;
77968 if ($numLevelUp >= count($basePathSegments)) {
77969 throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath));
77970 }
77971
77972 $basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp);
77973 $path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath);
77974
77975 return implode('/', $basePathSegments) . '/' . $path;
77976 }
77977
77978
77979
77980
77981
77982
77983
77984
77985 private static function normalizePath($path)
77986 {
77987 $path = preg_replace('|((?<!\.)\./)*|', '', $path);
77988 $path = preg_replace('|//|', '/', $path);
77989
77990 return $path;
77991 }
77992
77993
77994
77995
77996
77997
77998 public function isValid($uri)
77999 {
78000 $components = $this->parse($uri);
78001
78002 return !empty($components);
78003 }
78004 }
78005 <?php
78006
78007
78008
78009
78010
78011
78012
78013
78014 namespace JsonSchema\Uri;
78015
78016 use JsonSchema\Exception\InvalidSchemaMediaTypeException;
78017 use JsonSchema\Exception\JsonDecodingException;
78018 use JsonSchema\Exception\ResourceNotFoundException;
78019 use JsonSchema\Uri\Retrievers\FileGetContents;
78020 use JsonSchema\Uri\Retrievers\UriRetrieverInterface;
78021 use JsonSchema\UriRetrieverInterface as BaseUriRetrieverInterface;
78022 use JsonSchema\Validator;
78023
78024
78025
78026
78027
78028
78029 class UriRetriever implements BaseUriRetrieverInterface
78030 {
78031
78032
78033
78034 protected $uriRetriever = null;
78035
78036
78037
78038
78039
78040
78041 private $schemaCache = array();
78042
78043
78044
78045
78046
78047
78048
78049
78050
78051 public function confirmMediaType($uriRetriever, $uri)
78052 {
78053 $contentType = $uriRetriever->getContentType();
78054
78055 if (is_null($contentType)) {
78056
78057  return;
78058 }
78059
78060 if (in_array($contentType, array(Validator::SCHEMA_MEDIA_TYPE, 'application/json'))) {
78061 return;
78062 }
78063
78064 if (substr($uri, 0, 23) == 'http://json-schema.org/') {
78065
78066  return true;
78067 }
78068
78069 throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE));
78070 }
78071
78072
78073
78074
78075
78076
78077
78078
78079
78080 public function getUriRetriever()
78081 {
78082 if (is_null($this->uriRetriever)) {
78083 $this->setUriRetriever(new FileGetContents());
78084 }
78085
78086 return $this->uriRetriever;
78087 }
78088
78089
78090
78091
78092
78093
78094
78095
78096
78097
78098
78099
78100
78101
78102
78103 public function resolvePointer($jsonSchema, $uri)
78104 {
78105 $resolver = new UriResolver();
78106 $parsed = $resolver->parse($uri);
78107 if (empty($parsed['fragment'])) {
78108 return $jsonSchema;
78109 }
78110
78111 $path = explode('/', $parsed['fragment']);
78112 while ($path) {
78113 $pathElement = array_shift($path);
78114 if (!empty($pathElement)) {
78115 $pathElement = str_replace('~1', '/', $pathElement);
78116 $pathElement = str_replace('~0', '~', $pathElement);
78117 if (!empty($jsonSchema->$pathElement)) {
78118 $jsonSchema = $jsonSchema->$pathElement;
78119 } else {
78120 throw new ResourceNotFoundException(
78121 'Fragment "' . $parsed['fragment'] . '" not found'
78122 . ' in ' . $uri
78123 );
78124 }
78125
78126 if (!is_object($jsonSchema)) {
78127 throw new ResourceNotFoundException(
78128 'Fragment part "' . $pathElement . '" is no object '
78129 . ' in ' . $uri
78130 );
78131 }
78132 }
78133 }
78134
78135 return $jsonSchema;
78136 }
78137
78138
78139
78140
78141 public function retrieve($uri, $baseUri = null)
78142 {
78143 $resolver = new UriResolver();
78144 $resolvedUri = $fetchUri = $resolver->resolve($uri, $baseUri);
78145
78146
78147  $arParts = $resolver->parse($resolvedUri);
78148 if (isset($arParts['fragment'])) {
78149 unset($arParts['fragment']);
78150 $fetchUri = $resolver->generate($arParts);
78151 }
78152
78153 $jsonSchema = $this->loadSchema($fetchUri);
78154
78155
78156  $jsonSchema = $this->resolvePointer($jsonSchema, $resolvedUri);
78157
78158 if ($jsonSchema instanceof \stdClass) {
78159 $jsonSchema->id = $resolvedUri;
78160 }
78161
78162 return $jsonSchema;
78163 }
78164
78165
78166
78167
78168
78169
78170
78171
78172
78173 protected function loadSchema($fetchUri)
78174 {
78175 if (isset($this->schemaCache[$fetchUri])) {
78176 return $this->schemaCache[$fetchUri];
78177 }
78178
78179 $uriRetriever = $this->getUriRetriever();
78180 $contents = $this->uriRetriever->retrieve($fetchUri);
78181 $this->confirmMediaType($uriRetriever, $fetchUri);
78182 $jsonSchema = json_decode($contents);
78183
78184 if (JSON_ERROR_NONE < $error = json_last_error()) {
78185 throw new JsonDecodingException($error);
78186 }
78187
78188 $this->schemaCache[$fetchUri] = $jsonSchema;
78189
78190 return $jsonSchema;
78191 }
78192
78193
78194
78195
78196
78197
78198
78199
78200 public function setUriRetriever(UriRetrieverInterface $uriRetriever)
78201 {
78202 $this->uriRetriever = $uriRetriever;
78203
78204 return $this;
78205 }
78206
78207
78208
78209
78210
78211
78212
78213
78214 public function parse($uri)
78215 {
78216 preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match);
78217
78218 $components = array();
78219 if (5 < count($match)) {
78220 $components = array(
78221 'scheme' => $match[2],
78222 'authority' => $match[4],
78223 'path' => $match[5]
78224 );
78225 }
78226
78227 if (7 < count($match)) {
78228 $components['query'] = $match[7];
78229 }
78230
78231 if (9 < count($match)) {
78232 $components['fragment'] = $match[9];
78233 }
78234
78235 return $components;
78236 }
78237
78238
78239
78240
78241
78242
78243
78244
78245 public function generate(array $components)
78246 {
78247 $uri = $components['scheme'] . '://'
78248 . $components['authority']
78249 . $components['path'];
78250
78251 if (array_key_exists('query', $components)) {
78252 $uri .= $components['query'];
78253 }
78254
78255 if (array_key_exists('fragment', $components)) {
78256 $uri .= $components['fragment'];
78257 }
78258
78259 return $uri;
78260 }
78261
78262
78263
78264
78265
78266
78267
78268
78269
78270 public function resolve($uri, $baseUri = null)
78271 {
78272 $components = $this->parse($uri);
78273 $path = $components['path'];
78274
78275 if ((array_key_exists('scheme', $components)) && ('http' === $components['scheme'])) {
78276 return $uri;
78277 }
78278
78279 $baseComponents = $this->parse($baseUri);
78280 $basePath = $baseComponents['path'];
78281
78282 $baseComponents['path'] = UriResolver::combineRelativePathWithBasePath($path, $basePath);
78283
78284 return $this->generate($baseComponents);
78285 }
78286
78287
78288
78289
78290
78291
78292 public function isValid($uri)
78293 {
78294 $components = $this->parse($uri);
78295
78296 return !empty($components);
78297 }
78298 }
78299 <?php
78300
78301
78302
78303
78304
78305
78306
78307
78308 namespace JsonSchema;
78309
78310
78311
78312
78313 interface UriResolverInterface
78314 {
78315
78316
78317
78318
78319
78320
78321
78322
78323 public function resolve($uri, $baseUri = null);
78324 }
78325 <?php
78326
78327
78328
78329
78330
78331
78332
78333
78334 namespace JsonSchema;
78335
78336
78337
78338
78339 interface UriRetrieverInterface
78340 {
78341
78342
78343
78344
78345
78346
78347
78348
78349 public function retrieve($uri, $baseUri = null);
78350 }
78351 <?php
78352
78353
78354
78355
78356
78357
78358
78359
78360 namespace JsonSchema;
78361
78362 use JsonSchema\Constraints\BaseConstraint;
78363 use JsonSchema\Constraints\Constraint;
78364 use JsonSchema\Exception\InvalidConfigException;
78365
78366
78367
78368
78369
78370
78371
78372
78373
78374 class Validator extends BaseConstraint
78375 {
78376 const SCHEMA_MEDIA_TYPE = 'application/schema+json';
78377
78378
78379
78380
78381
78382
78383
78384
78385
78386
78387 public function validate(&$value, $schema = null, $checkMode = null)
78388 {
78389 $initialCheckMode = $this->factory->getConfig();
78390 if ($checkMode !== null) {
78391 $this->factory->setConfig($checkMode);
78392 }
78393
78394 $validator = $this->factory->createInstanceFor('schema');
78395 $validator->check($value, $schema);
78396
78397 $this->factory->setConfig($initialCheckMode);
78398
78399 $this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR));
78400 }
78401
78402
78403
78404
78405 public function check($value, $schema)
78406 {
78407 return $this->validate($value, $schema);
78408 }
78409
78410
78411
78412
78413 public function coerce(&$value, $schema)
78414 {
78415 return $this->validate($value, $schema, Constraint::CHECK_MODE_COERCE_TYPES);
78416 }
78417 }
78418 Copyright (C) 2015 Composer
78419
78420 Permission is hereby granted, free of charge, to any person obtaining a copy of
78421 this software and associated documentation files (the "Software"), to deal in
78422 the Software without restriction, including without limitation the rights to
78423 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
78424 of the Software, and to permit persons to whom the Software is furnished to do
78425 so, subject to the following conditions:
78426
78427 The above copyright notice and this permission notice shall be included in all
78428 copies or substantial portions of the Software.
78429
78430 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
78431 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
78432 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
78433 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
78434 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
78435 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
78436 SOFTWARE.
78437 <?php
78438
78439
78440
78441
78442
78443
78444
78445
78446
78447
78448 namespace Composer\Spdx;
78449
78450 class SpdxLicenses
78451 {
78452
78453 const LICENSES_FILE = 'spdx-licenses.json';
78454
78455
78456 const EXCEPTIONS_FILE = 'spdx-exceptions.json';
78457
78458
78459
78460
78461
78462
78463
78464
78465
78466
78467
78468
78469
78470
78471 private $licenses;
78472
78473
78474
78475
78476 private $licensesExpression;
78477
78478
78479
78480
78481
78482
78483
78484
78485
78486
78487
78488
78489
78490
78491 private $exceptions;
78492
78493
78494
78495
78496 private $exceptionsExpression;
78497
78498 public function __construct()
78499 {
78500 $this->loadLicenses();
78501 $this->loadExceptions();
78502 }
78503
78504
78505
78506
78507
78508
78509
78510
78511
78512
78513
78514
78515
78516 public function getLicenseByIdentifier($identifier)
78517 {
78518 if (!isset($this->licenses[$identifier])) {
78519 return;
78520 }
78521
78522 $license = $this->licenses[$identifier];
78523 $license[] = 'https://spdx.org/licenses/' . $identifier . '.html#licenseText';
78524
78525 return $license;
78526 }
78527
78528
78529
78530
78531
78532
78533
78534
78535
78536
78537
78538
78539
78540 public function getExceptionByIdentifier($identifier)
78541 {
78542 if (!isset($this->exceptions[$identifier])) {
78543 return;
78544 }
78545
78546 $license = $this->exceptions[$identifier];
78547 $license[] = 'https://spdx.org/licenses/' . $identifier . '.html#licenseExceptionText';
78548
78549 return $license;
78550 }
78551
78552
78553
78554
78555
78556
78557
78558
78559 public function getIdentifierByName($name)
78560 {
78561 foreach ($this->licenses as $identifier => $licenseData) {
78562 if ($licenseData[0] === $name) {
78563 return $identifier;
78564 }
78565 }
78566
78567 foreach ($this->exceptions as $identifier => $licenseData) {
78568 if ($licenseData[0] === $name) {
78569 return $identifier;
78570 }
78571 }
78572 }
78573
78574
78575
78576
78577
78578
78579
78580
78581 public function isOsiApprovedByIdentifier($identifier)
78582 {
78583 return $this->licenses[$identifier][1];
78584 }
78585
78586
78587
78588
78589
78590
78591
78592
78593 public function validate($license)
78594 {
78595 if (is_array($license)) {
78596 $count = count($license);
78597 if ($count !== count(array_filter($license, 'is_string'))) {
78598 throw new \InvalidArgumentException('Array of strings expected.');
78599 }
78600 $license = $count > 1 ? '(' . implode(' OR ', $license) . ')' : (string) reset($license);
78601 }
78602
78603 if (!is_string($license)) {
78604 throw new \InvalidArgumentException(sprintf(
78605 'Array or String expected, %s given.',
78606 gettype($license)
78607 ));
78608 }
78609
78610 return $this->isValidLicenseString($license);
78611 }
78612
78613
78614
78615
78616 public static function getResourcesDir()
78617 {
78618 return dirname(__DIR__) . '/res';
78619 }
78620
78621 private function loadLicenses()
78622 {
78623 if (null === $this->licenses) {
78624 $json = file_get_contents(self::getResourcesDir() . '/' . self::LICENSES_FILE);
78625 $this->licenses = json_decode($json, true);
78626 }
78627 }
78628
78629 private function loadExceptions()
78630 {
78631 if (null === $this->exceptions) {
78632 $json = file_get_contents(self::getResourcesDir() . '/' . self::EXCEPTIONS_FILE);
78633 $this->exceptions = json_decode($json, true);
78634 }
78635 }
78636
78637
78638
78639
78640 private function getLicensesExpression()
78641 {
78642 if (null === $this->licensesExpression) {
78643 $licenses = array_map('preg_quote', array_keys($this->licenses));
78644 rsort($licenses);
78645 $licenses = implode('|', $licenses);
78646 $this->licensesExpression = $licenses;
78647 }
78648
78649 return $this->licensesExpression;
78650 }
78651
78652
78653
78654
78655 private function getExceptionsExpression()
78656 {
78657 if (null === $this->exceptionsExpression) {
78658 $exceptions = array_map('preg_quote', array_keys($this->exceptions));
78659 rsort($exceptions);
78660 $exceptions = implode('|', $exceptions);
78661 $this->exceptionsExpression = $exceptions;
78662 }
78663
78664 return $this->exceptionsExpression;
78665 }
78666
78667
78668
78669
78670
78671
78672
78673
78674 private function isValidLicenseString($license)
78675 {
78676 if (isset($this->licenses[$license])) {
78677 return true;
78678 }
78679
78680 $licenses = $this->getLicensesExpression();
78681 $exceptions = $this->getExceptionsExpression();
78682
78683 $regex = <<<REGEX
78684 {
78685 (?(DEFINE)
78686     # idstring: 1*( ALPHA / DIGIT / - / . )
78687     (?<idstring>[\pL\pN.-]{1,})
78688
78689     # license-id: taken from list
78690     (?<licenseid>${licenses})
78691
78692     # license-exception-id: taken from list
78693     (?<licenseexceptionid>${exceptions})
78694
78695     # license-ref: [DocumentRef-1*(idstring):]LicenseRef-1*(idstring)
78696     (?<licenseref>(?:DocumentRef-(?&idstring):)?LicenseRef-(?&idstring))
78697
78698     # simple-expresssion: license-id / license-id+ / license-ref
78699     (?<simple_expression>(?&licenseid)\+? | (?&licenseid) | (?&licenseref))
78700
78701     # compound-expression: 1*(
78702     #   simple-expression /
78703     #   simple-expression WITH license-exception-id /
78704     #   compound-expression AND compound-expression /
78705     #   compound-expression OR compound-expression
78706     # ) / ( compound-expression ) )
78707     (?<compound_head>
78708         (?&simple_expression) ( \s+ (?:with|WITH) \s+ (?&licenseexceptionid))?
78709             | \( \s* (?&compound_expression) \s* \)
78710     )
78711     (?<compound_expression>
78712         (?&compound_head) (?: \s+ (?:and|AND|or|OR) \s+ (?&compound_expression))?
78713     )
78714
78715     # license-expression: 1*1(simple-expression / compound-expression)
78716     (?<license_expression>(?&compound_expression) | (?&simple_expression))
78717 ) # end of define
78718
78719 ^(NONE | NOASSERTION | (?&license_expression))$
78720 }x
78721 REGEX;
78722
78723 $match = preg_match($regex, $license);
78724
78725 if (0 === $match) {
78726 return false;
78727 }
78728
78729 if (false === $match) {
78730 throw new \RuntimeException('Regex failed to compile/run.');
78731 }
78732
78733 return true;
78734 }
78735 }
78736 Copyright (C) 2015 Composer
78737
78738 Permission is hereby granted, free of charge, to any person obtaining a copy of
78739 this software and associated documentation files (the "Software"), to deal in
78740 the Software without restriction, including without limitation the rights to
78741 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
78742 of the Software, and to permit persons to whom the Software is furnished to do
78743 so, subject to the following conditions:
78744
78745 The above copyright notice and this permission notice shall be included in all
78746 copies or substantial portions of the Software.
78747
78748 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
78749 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
78750 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
78751 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
78752 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
78753 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
78754 SOFTWARE.
78755 <?php
78756
78757
78758
78759
78760
78761
78762
78763
78764
78765
78766 namespace Composer\Semver;
78767
78768 use Composer\Semver\Constraint\Constraint;
78769
78770 class Comparator
78771 {
78772
78773
78774
78775
78776
78777
78778
78779
78780 public static function greaterThan($version1, $version2)
78781 {
78782 return self::compare($version1, '>', $version2);
78783 }
78784
78785
78786
78787
78788
78789
78790
78791
78792
78793 public static function greaterThanOrEqualTo($version1, $version2)
78794 {
78795 return self::compare($version1, '>=', $version2);
78796 }
78797
78798
78799
78800
78801
78802
78803
78804
78805
78806 public static function lessThan($version1, $version2)
78807 {
78808 return self::compare($version1, '<', $version2);
78809 }
78810
78811
78812
78813
78814
78815
78816
78817
78818
78819 public static function lessThanOrEqualTo($version1, $version2)
78820 {
78821 return self::compare($version1, '<=', $version2);
78822 }
78823
78824
78825
78826
78827
78828
78829
78830
78831
78832 public static function equalTo($version1, $version2)
78833 {
78834 return self::compare($version1, '==', $version2);
78835 }
78836
78837
78838
78839
78840
78841
78842
78843
78844
78845 public static function notEqualTo($version1, $version2)
78846 {
78847 return self::compare($version1, '!=', $version2);
78848 }
78849
78850
78851
78852
78853
78854
78855
78856
78857
78858
78859 public static function compare($version1, $operator, $version2)
78860 {
78861 $constraint = new Constraint($operator, $version2);
78862
78863 return $constraint->matches(new Constraint('==', $version1));
78864 }
78865 }
78866 <?php
78867
78868
78869
78870
78871
78872
78873
78874
78875
78876
78877 namespace Composer\Semver\Constraint;
78878
78879 trigger_error('The ' . __CLASS__ . ' abstract class is deprecated, there is no replacement for it, it will be removed in the next major version.', E_USER_DEPRECATED);
78880
78881
78882
78883
78884 abstract class AbstractConstraint implements ConstraintInterface
78885 {
78886
78887 protected $prettyString;
78888
78889
78890
78891
78892
78893
78894 public function matches(ConstraintInterface $provider)
78895 {
78896 if ($provider instanceof $this) {
78897
78898  return $this->matchSpecific($provider);
78899 }
78900
78901
78902  return $provider->matches($this);
78903 }
78904
78905
78906
78907
78908 public function setPrettyString($prettyString)
78909 {
78910 $this->prettyString = $prettyString;
78911 }
78912
78913
78914
78915
78916 public function getPrettyString()
78917 {
78918 if ($this->prettyString) {
78919 return $this->prettyString;
78920 }
78921
78922 return $this->__toString();
78923 }
78924
78925
78926  
78927  
78928 }
78929 <?php
78930
78931
78932
78933
78934
78935
78936
78937
78938
78939
78940 namespace Composer\Semver\Constraint;
78941
78942
78943
78944
78945 class Constraint implements ConstraintInterface
78946 {
78947
78948 const OP_EQ = 0;
78949 const OP_LT = 1;
78950 const OP_LE = 2;
78951 const OP_GT = 3;
78952 const OP_GE = 4;
78953 const OP_NE = 5;
78954
78955
78956
78957
78958
78959
78960 private static $transOpStr = array(
78961 '=' => self::OP_EQ,
78962 '==' => self::OP_EQ,
78963 '<' => self::OP_LT,
78964 '<=' => self::OP_LE,
78965 '>' => self::OP_GT,
78966 '>=' => self::OP_GE,
78967 '<>' => self::OP_NE,
78968 '!=' => self::OP_NE,
78969 );
78970
78971
78972
78973
78974
78975
78976 private static $transOpInt = array(
78977 self::OP_EQ => '==',
78978 self::OP_LT => '<',
78979 self::OP_LE => '<=',
78980 self::OP_GT => '>',
78981 self::OP_GE => '>=',
78982 self::OP_NE => '!=',
78983 );
78984
78985
78986 protected $operator;
78987
78988
78989 protected $version;
78990
78991
78992 protected $prettyString;
78993
78994
78995
78996
78997
78998
78999 public function matches(ConstraintInterface $provider)
79000 {
79001 if ($provider instanceof $this) {
79002 return $this->matchSpecific($provider);
79003 }
79004
79005
79006  return $provider->matches($this);
79007 }
79008
79009
79010
79011
79012 public function setPrettyString($prettyString)
79013 {
79014 $this->prettyString = $prettyString;
79015 }
79016
79017
79018
79019
79020 public function getPrettyString()
79021 {
79022 if ($this->prettyString) {
79023 return $this->prettyString;
79024 }
79025
79026 return $this->__toString();
79027 }
79028
79029
79030
79031
79032
79033
79034 public static function getSupportedOperators()
79035 {
79036 return array_keys(self::$transOpStr);
79037 }
79038
79039
79040
79041
79042
79043
79044
79045
79046
79047 public function __construct($operator, $version)
79048 {
79049 if (!isset(self::$transOpStr[$operator])) {
79050 throw new \InvalidArgumentException(sprintf(
79051 'Invalid operator "%s" given, expected one of: %s',
79052 $operator,
79053 implode(', ', self::getSupportedOperators())
79054 ));
79055 }
79056
79057 $this->operator = self::$transOpStr[$operator];
79058 $this->version = $version;
79059 }
79060
79061
79062
79063
79064
79065
79066
79067
79068
79069
79070
79071 public function versionCompare($a, $b, $operator, $compareBranches = false)
79072 {
79073 if (!isset(self::$transOpStr[$operator])) {
79074 throw new \InvalidArgumentException(sprintf(
79075 'Invalid operator "%s" given, expected one of: %s',
79076 $operator,
79077 implode(', ', self::getSupportedOperators())
79078 ));
79079 }
79080
79081 $aIsBranch = 'dev-' === substr($a, 0, 4);
79082 $bIsBranch = 'dev-' === substr($b, 0, 4);
79083
79084 if ($aIsBranch && $bIsBranch) {
79085 return $operator === '==' && $a === $b;
79086 }
79087
79088
79089  if (!$compareBranches && ($aIsBranch || $bIsBranch)) {
79090 return false;
79091 }
79092
79093 return version_compare($a, $b, $operator);
79094 }
79095
79096
79097
79098
79099
79100
79101
79102 public function matchSpecific(Constraint $provider, $compareBranches = false)
79103 {
79104 $noEqualOp = str_replace('=', '', self::$transOpInt[$this->operator]);
79105 $providerNoEqualOp = str_replace('=', '', self::$transOpInt[$provider->operator]);
79106
79107 $isEqualOp = self::OP_EQ === $this->operator;
79108 $isNonEqualOp = self::OP_NE === $this->operator;
79109 $isProviderEqualOp = self::OP_EQ === $provider->operator;
79110 $isProviderNonEqualOp = self::OP_NE === $provider->operator;
79111
79112
79113  
79114  if ($isNonEqualOp || $isProviderNonEqualOp) {
79115 return !$isEqualOp && !$isProviderEqualOp
79116 || $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
79117 }
79118
79119
79120  
79121  if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) {
79122 return true;
79123 }
79124
79125 if ($this->versionCompare($provider->version, $this->version, self::$transOpInt[$this->operator], $compareBranches)) {
79126
79127  
79128  if ($provider->version === $this->version
79129 && self::$transOpInt[$provider->operator] === $providerNoEqualOp
79130 && self::$transOpInt[$this->operator] !== $noEqualOp) {
79131 return false;
79132 }
79133
79134 return true;
79135 }
79136
79137 return false;
79138 }
79139
79140
79141
79142
79143 public function __toString()
79144 {
79145 return self::$transOpInt[$this->operator] . ' ' . $this->version;
79146 }
79147 }
79148 <?php
79149
79150
79151
79152
79153
79154
79155
79156
79157
79158
79159 namespace Composer\Semver\Constraint;
79160
79161 interface ConstraintInterface
79162 {
79163
79164
79165
79166
79167
79168 public function matches(ConstraintInterface $provider);
79169
79170
79171
79172
79173 public function getPrettyString();
79174
79175
79176
79177
79178 public function __toString();
79179 }
79180 <?php
79181
79182
79183
79184
79185
79186
79187
79188
79189
79190
79191 namespace Composer\Semver\Constraint;
79192
79193
79194
79195
79196 class EmptyConstraint implements ConstraintInterface
79197 {
79198
79199 protected $prettyString;
79200
79201
79202
79203
79204
79205
79206 public function matches(ConstraintInterface $provider)
79207 {
79208 return true;
79209 }
79210
79211
79212
79213
79214 public function setPrettyString($prettyString)
79215 {
79216 $this->prettyString = $prettyString;
79217 }
79218
79219
79220
79221
79222 public function getPrettyString()
79223 {
79224 if ($this->prettyString) {
79225 return $this->prettyString;
79226 }
79227
79228 return $this->__toString();
79229 }
79230
79231
79232
79233
79234 public function __toString()
79235 {
79236 return '[]';
79237 }
79238 }
79239 <?php
79240
79241
79242
79243
79244
79245
79246
79247
79248
79249
79250 namespace Composer\Semver\Constraint;
79251
79252
79253
79254
79255 class MultiConstraint implements ConstraintInterface
79256 {
79257
79258 protected $constraints;
79259
79260
79261 protected $prettyString;
79262
79263
79264 protected $conjunctive;
79265
79266
79267
79268
79269
79270 public function __construct(array $constraints, $conjunctive = true)
79271 {
79272 $this->constraints = $constraints;
79273 $this->conjunctive = $conjunctive;
79274 }
79275
79276
79277
79278
79279 public function getConstraints()
79280 {
79281 return $this->constraints;
79282 }
79283
79284
79285
79286
79287 public function isConjunctive()
79288 {
79289 return $this->conjunctive;
79290 }
79291
79292
79293
79294
79295 public function isDisjunctive()
79296 {
79297 return !$this->conjunctive;
79298 }
79299
79300
79301
79302
79303
79304
79305 public function matches(ConstraintInterface $provider)
79306 {
79307 if (false === $this->conjunctive) {
79308 foreach ($this->constraints as $constraint) {
79309 if ($constraint->matches($provider)) {
79310 return true;
79311 }
79312 }
79313
79314 return false;
79315 }
79316
79317 foreach ($this->constraints as $constraint) {
79318 if (!$constraint->matches($provider)) {
79319 return false;
79320 }
79321 }
79322
79323 return true;
79324 }
79325
79326
79327
79328
79329 public function setPrettyString($prettyString)
79330 {
79331 $this->prettyString = $prettyString;
79332 }
79333
79334
79335
79336
79337 public function getPrettyString()
79338 {
79339 if ($this->prettyString) {
79340 return $this->prettyString;
79341 }
79342
79343 return $this->__toString();
79344 }
79345
79346
79347
79348
79349 public function __toString()
79350 {
79351 $constraints = array();
79352 foreach ($this->constraints as $constraint) {
79353 $constraints[] = (string) $constraint;
79354 }
79355
79356 return '[' . implode($this->conjunctive ? ' ' : ' || ', $constraints) . ']';
79357 }
79358 }
79359 <?php
79360
79361
79362
79363
79364
79365
79366
79367
79368
79369
79370 namespace Composer\Semver;
79371
79372 use Composer\Semver\Constraint\Constraint;
79373
79374 class Semver
79375 {
79376 const SORT_ASC = 1;
79377 const SORT_DESC = -1;
79378
79379
79380 private static $versionParser;
79381
79382
79383
79384
79385
79386
79387
79388
79389
79390 public static function satisfies($version, $constraints)
79391 {
79392 if (null === self::$versionParser) {
79393 self::$versionParser = new VersionParser();
79394 }
79395
79396 $versionParser = self::$versionParser;
79397 $provider = new Constraint('==', $versionParser->normalize($version));
79398 $constraints = $versionParser->parseConstraints($constraints);
79399
79400 return $constraints->matches($provider);
79401 }
79402
79403
79404
79405
79406
79407
79408
79409
79410
79411 public static function satisfiedBy(array $versions, $constraints)
79412 {
79413 $versions = array_filter($versions, function ($version) use ($constraints) {
79414 return Semver::satisfies($version, $constraints);
79415 });
79416
79417 return array_values($versions);
79418 }
79419
79420
79421
79422
79423
79424
79425
79426
79427 public static function sort(array $versions)
79428 {
79429 return self::usort($versions, self::SORT_ASC);
79430 }
79431
79432
79433
79434
79435
79436
79437
79438
79439 public static function rsort(array $versions)
79440 {
79441 return self::usort($versions, self::SORT_DESC);
79442 }
79443
79444
79445
79446
79447
79448
79449
79450 private static function usort(array $versions, $direction)
79451 {
79452 if (null === self::$versionParser) {
79453 self::$versionParser = new VersionParser();
79454 }
79455
79456 $versionParser = self::$versionParser;
79457 $normalized = array();
79458
79459
79460  
79461  foreach ($versions as $key => $version) {
79462 $normalized[] = array($versionParser->normalize($version), $key);
79463 }
79464
79465 usort($normalized, function (array $left, array $right) use ($direction) {
79466 if ($left[0] === $right[0]) {
79467 return 0;
79468 }
79469
79470 if (Comparator::lessThan($left[0], $right[0])) {
79471 return -$direction;
79472 }
79473
79474 return $direction;
79475 });
79476
79477
79478  $sorted = array();
79479 foreach ($normalized as $item) {
79480 $sorted[] = $versions[$item[1]];
79481 }
79482
79483 return $sorted;
79484 }
79485 }
79486 <?php
79487
79488
79489
79490
79491
79492
79493
79494
79495
79496
79497 namespace Composer\Semver;
79498
79499 use Composer\Semver\Constraint\ConstraintInterface;
79500 use Composer\Semver\Constraint\EmptyConstraint;
79501 use Composer\Semver\Constraint\MultiConstraint;
79502 use Composer\Semver\Constraint\Constraint;
79503
79504
79505
79506
79507
79508
79509 class VersionParser
79510 {
79511
79512
79513
79514
79515
79516
79517
79518
79519
79520
79521
79522
79523
79524 private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*+)?)?([.-]?dev)?';
79525
79526
79527 private static $stabilities = array('stable', 'RC', 'beta', 'alpha', 'dev');
79528
79529
79530
79531
79532
79533
79534
79535
79536 public static function parseStability($version)
79537 {
79538 $version = preg_replace('{#.+$}i', '', $version);
79539
79540 if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) {
79541 return 'dev';
79542 }
79543
79544 preg_match('{' . self::$modifierRegex . '(?:\+.*)?$}i', strtolower($version), $match);
79545 if (!empty($match[3])) {
79546 return 'dev';
79547 }
79548
79549 if (!empty($match[1])) {
79550 if ('beta' === $match[1] || 'b' === $match[1]) {
79551 return 'beta';
79552 }
79553 if ('alpha' === $match[1] || 'a' === $match[1]) {
79554 return 'alpha';
79555 }
79556 if ('rc' === $match[1]) {
79557 return 'RC';
79558 }
79559 }
79560
79561 return 'stable';
79562 }
79563
79564
79565
79566
79567
79568
79569 public static function normalizeStability($stability)
79570 {
79571 $stability = strtolower($stability);
79572
79573 return $stability === 'rc' ? 'RC' : $stability;
79574 }
79575
79576
79577
79578
79579
79580
79581
79582
79583
79584
79585
79586 public function normalize($version, $fullVersion = null)
79587 {
79588 $version = trim($version);
79589 if (null === $fullVersion) {
79590 $fullVersion = $version;
79591 }
79592
79593
79594  if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $version, $match)) {
79595 $version = $match[1];
79596 }
79597
79598
79599  if (preg_match('{^(?:dev-)?(?:master|trunk|default)$}i', $version)) {
79600 return '9999999-dev';
79601 }
79602
79603
79604  if ('dev-' === strtolower(substr($version, 0, 4))) {
79605 return 'dev-' . substr($version, 4);
79606 }
79607
79608
79609  if (preg_match('{^([^,\s+]++)\+[^\s]++$}', $version, $match)) {
79610 $version = $match[1];
79611 }
79612
79613
79614  if (preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
79615 $version = $matches[1]
79616 . (!empty($matches[2]) ? $matches[2] : '.0')
79617 . (!empty($matches[3]) ? $matches[3] : '.0')
79618 . (!empty($matches[4]) ? $matches[4] : '.0');
79619 $index = 5;
79620
79621  } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) {
79622 $version = preg_replace('{\D}', '.', $matches[1]);
79623 $index = 2;
79624 }
79625
79626
79627  if (isset($index)) {
79628 if (!empty($matches[$index])) {
79629 if ('stable' === $matches[$index]) {
79630 return $version;
79631 }
79632 $version .= '-' . $this->expandStability($matches[$index]) . (!empty($matches[$index + 1]) ? ltrim($matches[$index + 1], '.-') : '');
79633 }
79634
79635 if (!empty($matches[$index + 2])) {
79636 $version .= '-dev';
79637 }
79638
79639 return $version;
79640 }
79641
79642
79643  if (preg_match('{(.*?)[.-]?dev$}i', $version, $match)) {
79644 try {
79645 return $this->normalizeBranch($match[1]);
79646 } catch (\Exception $e) {
79647 }
79648 }
79649
79650 $extraMessage = '';
79651 if (preg_match('{ +as +' . preg_quote($version) . '$}', $fullVersion)) {
79652 $extraMessage = ' in "' . $fullVersion . '", the alias must be an exact version';
79653 } elseif (preg_match('{^' . preg_quote($version) . ' +as +}', $fullVersion)) {
79654 $extraMessage = ' in "' . $fullVersion . '", the alias source must be an exact version, if it is a branch name you should prefix it with dev-';
79655 }
79656
79657 throw new \UnexpectedValueException('Invalid version string "' . $version . '"' . $extraMessage);
79658 }
79659
79660
79661
79662
79663
79664
79665
79666
79667 public function parseNumericAliasPrefix($branch)
79668 {
79669 if (preg_match('{^(?P<version>(\d++\\.)*\d++)(?:\.x)?-dev$}i', $branch, $matches)) {
79670 return $matches['version'] . '.';
79671 }
79672
79673 return false;
79674 }
79675
79676
79677
79678
79679
79680
79681
79682
79683 public function normalizeBranch($name)
79684 {
79685 $name = trim($name);
79686
79687 if (in_array($name, array('master', 'trunk', 'default'))) {
79688 return $this->normalize($name);
79689 }
79690
79691 if (preg_match('{^v?(\d++)(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?$}i', $name, $matches)) {
79692 $version = '';
79693 for ($i = 1; $i < 5; ++$i) {
79694 $version .= isset($matches[$i]) ? str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x';
79695 }
79696
79697 return str_replace('x', '9999999', $version) . '-dev';
79698 }
79699
79700 return 'dev-' . $name;
79701 }
79702
79703
79704
79705
79706
79707
79708
79709
79710 public function parseConstraints($constraints)
79711 {
79712 $prettyConstraint = $constraints;
79713
79714 if (preg_match('{^([^,\s]*?)@(' . implode('|', self::$stabilities) . ')$}i', $constraints, $match)) {
79715 $constraints = empty($match[1]) ? '*' : $match[1];
79716 }
79717
79718 if (preg_match('{^(dev-[^,\s@]+?|[^,\s@]+?\.x-dev)#.+$}i', $constraints, $match)) {
79719 $constraints = $match[1];
79720 }
79721
79722 $orConstraints = preg_split('{\s*\|\|?\s*}', trim($constraints));
79723 $orGroups = array();
79724 foreach ($orConstraints as $constraints) {
79725 $andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
79726 if (count($andConstraints) > 1) {
79727 $constraintObjects = array();
79728 foreach ($andConstraints as $constraint) {
79729 foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
79730 $constraintObjects[] = $parsedConstraint;
79731 }
79732 }
79733 } else {
79734 $constraintObjects = $this->parseConstraint($andConstraints[0]);
79735 }
79736
79737 if (1 === count($constraintObjects)) {
79738 $constraint = $constraintObjects[0];
79739 } else {
79740 $constraint = new MultiConstraint($constraintObjects);
79741 }
79742
79743 $orGroups[] = $constraint;
79744 }
79745
79746 if (1 === count($orGroups)) {
79747 $constraint = $orGroups[0];
79748 } elseif (2 === count($orGroups)
79749
79750  
79751  && $orGroups[0] instanceof MultiConstraint
79752 && $orGroups[1] instanceof MultiConstraint
79753 && 2 === count($orGroups[0]->getConstraints())
79754 && 2 === count($orGroups[1]->getConstraints())
79755 && ($a = (string) $orGroups[0])
79756 && substr($a, 0, 3) === '[>=' && (false !== ($posA = strpos($a, '<', 4)))
79757 && ($b = (string) $orGroups[1])
79758 && substr($b, 0, 3) === '[>=' && (false !== ($posB = strpos($b, '<', 4)))
79759 && substr($a, $posA + 2, -1) === substr($b, 4, $posB - 5)
79760 ) {
79761 $constraint = new MultiConstraint(array(
79762 new Constraint('>=', substr($a, 4, $posA - 5)),
79763 new Constraint('<', substr($b, $posB + 2, -1)),
79764 ));
79765 } else {
79766 $constraint = new MultiConstraint($orGroups, false);
79767 }
79768
79769 $constraint->setPrettyString($prettyConstraint);
79770
79771 return $constraint;
79772 }
79773
79774
79775
79776
79777
79778
79779
79780
79781 private function parseConstraint($constraint)
79782 {
79783 if (preg_match('{^([^,\s]+?)@(' . implode('|', self::$stabilities) . ')$}i', $constraint, $match)) {
79784 $constraint = $match[1];
79785 if ($match[2] !== 'stable') {
79786 $stabilityModifier = $match[2];
79787 }
79788 }
79789
79790 if (preg_match('{^v?[xX*](\.[xX*])*$}i', $constraint)) {
79791 return array(new EmptyConstraint());
79792 }
79793
79794 $versionRegex = 'v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.(\d++))?' . self::$modifierRegex . '(?:\+[^\s]+)?';
79795
79796
79797  
79798  
79799  
79800  
79801  if (preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
79802 if (substr($constraint, 0, 2) === '~>') {
79803 throw new \UnexpectedValueException(
79804 'Could not parse version constraint ' . $constraint . ': ' .
79805 'Invalid operator "~>", you probably meant to use the "~" operator'
79806 );
79807 }
79808
79809
79810  if (isset($matches[4]) && '' !== $matches[4]) {
79811 $position = 4;
79812 } elseif (isset($matches[3]) && '' !== $matches[3]) {
79813 $position = 3;
79814 } elseif (isset($matches[2]) && '' !== $matches[2]) {
79815 $position = 2;
79816 } else {
79817 $position = 1;
79818 }
79819
79820
79821  $stabilitySuffix = '';
79822 if (!empty($matches[5])) {
79823 $stabilitySuffix .= '-' . $this->expandStability($matches[5]) . (!empty($matches[6]) ? $matches[6] : '');
79824 }
79825
79826 if (!empty($matches[7])) {
79827 $stabilitySuffix .= '-dev';
79828 }
79829
79830 if (!$stabilitySuffix) {
79831 $stabilitySuffix = '-dev';
79832 }
79833
79834 $lowVersion = $this->manipulateVersionString($matches, $position, 0) . $stabilitySuffix;
79835 $lowerBound = new Constraint('>=', $lowVersion);
79836
79837
79838  
79839  $highPosition = max(1, $position - 1);
79840 $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
79841 $upperBound = new Constraint('<', $highVersion);
79842
79843 return array(
79844 $lowerBound,
79845 $upperBound,
79846 );
79847 }
79848
79849
79850  
79851  
79852  
79853  
79854  if (preg_match('{^\^' . $versionRegex . '($)}i', $constraint, $matches)) {
79855
79856  if ('0' !== $matches[1] || '' === $matches[2]) {
79857 $position = 1;
79858 } elseif ('0' !== $matches[2] || '' === $matches[3]) {
79859 $position = 2;
79860 } else {
79861 $position = 3;
79862 }
79863
79864
79865  $stabilitySuffix = '';
79866 if (empty($matches[5]) && empty($matches[7])) {
79867 $stabilitySuffix .= '-dev';
79868 }
79869
79870 $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
79871 $lowerBound = new Constraint('>=', $lowVersion);
79872
79873
79874  
79875  $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
79876 $upperBound = new Constraint('<', $highVersion);
79877
79878 return array(
79879 $lowerBound,
79880 $upperBound,
79881 );
79882 }
79883
79884
79885  
79886  
79887  
79888  if (preg_match('{^v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.[xX*])++$}', $constraint, $matches)) {
79889 if (isset($matches[3]) && '' !== $matches[3]) {
79890 $position = 3;
79891 } elseif (isset($matches[2]) && '' !== $matches[2]) {
79892 $position = 2;
79893 } else {
79894 $position = 1;
79895 }
79896
79897 $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev';
79898 $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
79899
79900 if ($lowVersion === '0.0.0.0-dev') {
79901 return array(new Constraint('<', $highVersion));
79902 }
79903
79904 return array(
79905 new Constraint('>=', $lowVersion),
79906 new Constraint('<', $highVersion),
79907 );
79908 }
79909
79910
79911  
79912  
79913  
79914  
79915  
79916  if (preg_match('{^(?P<from>' . $versionRegex . ') +- +(?P<to>' . $versionRegex . ')($)}i', $constraint, $matches)) {
79917
79918  $lowStabilitySuffix = '';
79919 if (empty($matches[6]) && empty($matches[8])) {
79920 $lowStabilitySuffix = '-dev';
79921 }
79922
79923 $lowVersion = $this->normalize($matches['from']);
79924 $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix);
79925
79926 $empty = function ($x) {
79927 return ($x === 0 || $x === '0') ? false : empty($x);
79928 };
79929
79930 if ((!$empty($matches[11]) && !$empty($matches[12])) || !empty($matches[14]) || !empty($matches[16])) {
79931 $highVersion = $this->normalize($matches['to']);
79932 $upperBound = new Constraint('<=', $highVersion);
79933 } else {
79934 $highMatch = array('', $matches[10], $matches[11], $matches[12], $matches[13]);
79935 $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[11]) ? 1 : 2, 1) . '-dev';
79936 $upperBound = new Constraint('<', $highVersion);
79937 }
79938
79939 return array(
79940 $lowerBound,
79941 $upperBound,
79942 );
79943 }
79944
79945
79946  if (preg_match('{^(<>|!=|>=?|<=?|==?)?\s*(.*)}', $constraint, $matches)) {
79947 try {
79948 $version = $this->normalize($matches[2]);
79949
79950 if (!empty($stabilityModifier) && $this->parseStability($version) === 'stable') {
79951 $version .= '-' . $stabilityModifier;
79952 } elseif ('<' === $matches[1] || '>=' === $matches[1]) {
79953 if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) {
79954 if (substr($matches[2], 0, 4) !== 'dev-') {
79955 $version .= '-dev';
79956 }
79957 }
79958 }
79959
79960 return array(new Constraint($matches[1] ?: '=', $version));
79961 } catch (\Exception $e) {
79962 }
79963 }
79964
79965 $message = 'Could not parse version constraint ' . $constraint;
79966 if (isset($e)) {
79967 $message .= ': ' . $e->getMessage();
79968 }
79969
79970 throw new \UnexpectedValueException($message);
79971 }
79972
79973
79974
79975
79976
79977
79978
79979
79980
79981
79982
79983
79984
79985 private function manipulateVersionString($matches, $position, $increment = 0, $pad = '0')
79986 {
79987 for ($i = 4; $i > 0; --$i) {
79988 if ($i > $position) {
79989 $matches[$i] = $pad;
79990 } elseif ($i === $position && $increment) {
79991 $matches[$i] += $increment;
79992
79993  if ($matches[$i] < 0) {
79994 $matches[$i] = $pad;
79995 --$position;
79996
79997
79998  if ($i === 1) {
79999 return;
80000 }
80001 }
80002 }
80003 }
80004
80005 return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4];
80006 }
80007
80008
80009
80010
80011
80012
80013
80014
80015 private function expandStability($stability)
80016 {
80017 $stability = strtolower($stability);
80018
80019 switch ($stability) {
80020 case 'a':
80021 return 'alpha';
80022 case 'b':
80023 return 'beta';
80024 case 'p':
80025 case 'pl':
80026 return 'patch';
80027 case 'rc':
80028 return 'RC';
80029 default:
80030 return $stability;
80031 }
80032 }
80033 }
80034 Copyright (C) 2016 Composer
80035
80036 Permission is hereby granted, free of charge, to any person obtaining a copy of
80037 this software and associated documentation files (the "Software"), to deal in
80038 the Software without restriction, including without limitation the rights to
80039 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
80040 of the Software, and to permit persons to whom the Software is furnished to do
80041 so, subject to the following conditions:
80042
80043 The above copyright notice and this permission notice shall be included in all
80044 copies or substantial portions of the Software.
80045
80046 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80047 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
80048 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
80049 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
80050 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
80051 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
80052 SOFTWARE.
80053 <?php
80054
80055
80056
80057
80058
80059
80060
80061
80062
80063
80064 namespace Composer\CaBundle;
80065
80066 use Psr\Log\LoggerInterface;
80067 use Symfony\Component\Process\PhpProcess;
80068
80069
80070
80071
80072
80073 class CaBundle
80074 {
80075 private static $caPath;
80076 private static $caFileValidity = array();
80077 private static $useOpensslParse;
80078
80079
80080
80081
80082
80083
80084
80085
80086
80087
80088
80089
80090
80091
80092
80093
80094
80095
80096
80097
80098
80099
80100
80101
80102
80103
80104
80105
80106
80107
80108
80109
80110
80111
80112
80113
80114
80115
80116 public static function getSystemCaRootBundlePath(LoggerInterface $logger = null)
80117 {
80118 if (self::$caPath !== null) {
80119 return self::$caPath;
80120 }
80121
80122
80123  
80124  $envCertFile = getenv('SSL_CERT_FILE');
80125 if ($envCertFile && is_readable($envCertFile) && static::validateCaFile($envCertFile, $logger)) {
80126 return self::$caPath = $envCertFile;
80127 }
80128
80129
80130  
80131  $envCertDir = getenv('SSL_CERT_DIR');
80132 if ($envCertDir && is_dir($envCertDir) && is_readable($envCertDir)) {
80133 return self::$caPath = $envCertDir;
80134 }
80135
80136 $configured = ini_get('openssl.cafile');
80137 if ($configured && strlen($configured) > 0 && is_readable($configured) && static::validateCaFile($configured, $logger)) {
80138 return self::$caPath = $configured;
80139 }
80140
80141 $configured = ini_get('openssl.capath');
80142 if ($configured && is_dir($configured) && is_readable($configured)) {
80143 return self::$caPath = $configured;
80144 }
80145
80146 $caBundlePaths = array(
80147 '/etc/pki/tls/certs/ca-bundle.crt', 
80148  '/etc/ssl/certs/ca-certificates.crt', 
80149  '/etc/ssl/ca-bundle.pem', 
80150  '/usr/local/share/certs/ca-root-nss.crt', 
80151  '/usr/ssl/certs/ca-bundle.crt', 
80152  '/opt/local/share/curl/curl-ca-bundle.crt', 
80153  '/usr/local/share/curl/curl-ca-bundle.crt', 
80154  '/usr/share/ssl/certs/ca-bundle.crt', 
80155  '/etc/ssl/cert.pem', 
80156  '/usr/local/etc/ssl/cert.pem', 
80157  '/usr/local/etc/openssl/cert.pem', 
80158  );
80159
80160 foreach ($caBundlePaths as $caBundle) {
80161 if (@is_readable($caBundle) && static::validateCaFile($caBundle, $logger)) {
80162 return self::$caPath = $caBundle;
80163 }
80164 }
80165
80166 foreach ($caBundlePaths as $caBundle) {
80167 $caBundle = dirname($caBundle);
80168 if (@is_dir($caBundle) && glob($caBundle.'/*')) {
80169 return self::$caPath = $caBundle;
80170 }
80171 }
80172
80173 return self::$caPath = static::getBundledCaBundlePath(); 
80174  }
80175
80176
80177
80178
80179
80180
80181
80182
80183 public static function getBundledCaBundlePath()
80184 {
80185 return __DIR__.'/../res/cacert.pem';
80186 }
80187
80188
80189
80190
80191
80192
80193
80194
80195
80196 public static function validateCaFile($filename, LoggerInterface $logger = null)
80197 {
80198 static $warned = false;
80199
80200 if (isset(self::$caFileValidity[$filename])) {
80201 return self::$caFileValidity[$filename];
80202 }
80203
80204 $contents = file_get_contents($filename);
80205
80206
80207  
80208  if (!static::isOpensslParseSafe()) {
80209 if (!$warned && $logger) {
80210 $logger->warning(sprintf(
80211 'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.',
80212 PHP_VERSION
80213 ));
80214 $warned = true;
80215 }
80216
80217 $isValid = !empty($contents);
80218 } else {
80219 $isValid = (bool) openssl_x509_parse($contents);
80220 }
80221
80222 if ($logger) {
80223 $logger->debug('Checked CA file '.realpath($filename).': '.($isValid ? 'valid' : 'invalid'));
80224 }
80225
80226 return self::$caFileValidity[$filename] = $isValid;
80227 }
80228
80229
80230
80231
80232
80233
80234
80235
80236
80237 public static function isOpensslParseSafe()
80238 {
80239 if (null !== self::$useOpensslParse) {
80240 return self::$useOpensslParse;
80241 }
80242
80243 if (PHP_VERSION_ID >= 50600) {
80244 return self::$useOpensslParse = true;
80245 }
80246
80247
80248  
80249  
80250  
80251  if (
80252 (PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328)
80253 || (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423)
80254 || (PHP_VERSION_ID < 50600 && PHP_VERSION_ID >= 50507)
80255 ) {
80256
80257  return self::$useOpensslParse = true;
80258 }
80259
80260 if (defined('PHP_WINDOWS_VERSION_BUILD')) {
80261
80262  return self::$useOpensslParse = false;
80263 }
80264
80265 $compareDistroVersionPrefix = function ($prefix, $fixedVersion) {
80266 $regex = '{^'.preg_quote($prefix).'([0-9]+)$}';
80267
80268 if (preg_match($regex, PHP_VERSION, $m)) {
80269 return ((int) $m[1]) >= $fixedVersion;
80270 }
80271
80272 return false;
80273 };
80274
80275
80276  if (
80277 $compareDistroVersionPrefix('5.3.3-7+squeeze', 18) 
80278  || $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) 
80279  || $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) 
80280  ) {
80281 return self::$useOpensslParse = true;
80282 }
80283
80284
80285  if (!class_exists('Symfony\Component\Process\PhpProcess')) {
80286 return self::$useOpensslParse = false;
80287 }
80288
80289
80290  
80291  
80292  
80293  
80294  
80295
80296
80297  
80298  $cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K';
80299 $script = <<<'EOT'
80300
80301 error_reporting(-1);
80302 $info = openssl_x509_parse(base64_decode('%s'));
80303 var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']);
80304
80305 EOT;
80306 $script = '<'."?php\n".sprintf($script, $cert);
80307
80308 try {
80309 $process = new PhpProcess($script);
80310 $process->mustRun();
80311 } catch (\Exception $e) {
80312
80313  
80314  return self::$useOpensslParse = false;
80315 }
80316
80317 $output = preg_split('{\r?\n}', trim($process->getOutput()));
80318 $errorOutput = trim($process->getErrorOutput());
80319
80320 if (
80321 count($output) === 3
80322 && $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION)
80323 && $output[1] === 'string(27) "stefan.esser@sektioneins.de"'
80324 && $output[2] === 'int(-1)'
80325 && preg_match('{openssl_x509_parse\(\): illegal (?:ASN1 data type for|length in) timestamp in - on line \d+}', $errorOutput)
80326 ) {
80327
80328  return self::$useOpensslParse = true;
80329 }
80330
80331 return self::$useOpensslParse = false;
80332 }
80333
80334
80335
80336
80337 public static function reset()
80338 {
80339 self::$caFileValidity = array();
80340 self::$caPath = null;
80341 self::$useOpensslParse = null;
80342 }
80343 }
80344 Copyright (c) 2012 PHP Framework Interoperability Group
80345
80346 Permission is hereby granted, free of charge, to any person obtaining a copy 
80347 of this software and associated documentation files (the "Software"), to deal
80348 in the Software without restriction, including without limitation the rights 
80349 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
80350 copies of the Software, and to permit persons to whom the Software is 
80351 furnished to do so, subject to the following conditions:
80352
80353 The above copyright notice and this permission notice shall be included in 
80354 all copies or substantial portions of the Software.
80355
80356 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80357 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
80358 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
80359 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
80360 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
80361 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
80362 THE SOFTWARE.
80363 <?php
80364
80365 namespace Psr\Log;
80366
80367
80368
80369
80370
80371
80372
80373
80374 abstract class AbstractLogger implements LoggerInterface
80375 {
80376
80377
80378
80379
80380
80381
80382
80383
80384 public function emergency($message, array $context = array())
80385 {
80386 $this->log(LogLevel::EMERGENCY, $message, $context);
80387 }
80388
80389
80390
80391
80392
80393
80394
80395
80396
80397
80398
80399
80400 public function alert($message, array $context = array())
80401 {
80402 $this->log(LogLevel::ALERT, $message, $context);
80403 }
80404
80405
80406
80407
80408
80409
80410
80411
80412
80413
80414
80415 public function critical($message, array $context = array())
80416 {
80417 $this->log(LogLevel::CRITICAL, $message, $context);
80418 }
80419
80420
80421
80422
80423
80424
80425
80426
80427
80428
80429 public function error($message, array $context = array())
80430 {
80431 $this->log(LogLevel::ERROR, $message, $context);
80432 }
80433
80434
80435
80436
80437
80438
80439
80440
80441
80442
80443
80444
80445 public function warning($message, array $context = array())
80446 {
80447 $this->log(LogLevel::WARNING, $message, $context);
80448 }
80449
80450
80451
80452
80453
80454
80455
80456
80457
80458 public function notice($message, array $context = array())
80459 {
80460 $this->log(LogLevel::NOTICE, $message, $context);
80461 }
80462
80463
80464
80465
80466
80467
80468
80469
80470
80471
80472
80473 public function info($message, array $context = array())
80474 {
80475 $this->log(LogLevel::INFO, $message, $context);
80476 }
80477
80478
80479
80480
80481
80482
80483
80484
80485
80486 public function debug($message, array $context = array())
80487 {
80488 $this->log(LogLevel::DEBUG, $message, $context);
80489 }
80490 }
80491 <?php
80492
80493 namespace Psr\Log;
80494
80495 class InvalidArgumentException extends \InvalidArgumentException
80496 {
80497 }
80498 <?php
80499
80500 namespace Psr\Log;
80501
80502
80503
80504
80505 class LogLevel
80506 {
80507 const EMERGENCY = 'emergency';
80508 const ALERT = 'alert';
80509 const CRITICAL = 'critical';
80510 const ERROR = 'error';
80511 const WARNING = 'warning';
80512 const NOTICE = 'notice';
80513 const INFO = 'info';
80514 const DEBUG = 'debug';
80515 }
80516 <?php
80517
80518 namespace Psr\Log;
80519
80520
80521
80522
80523 interface LoggerAwareInterface
80524 {
80525
80526
80527
80528
80529
80530
80531
80532 public function setLogger(LoggerInterface $logger);
80533 }
80534 <?php
80535
80536 namespace Psr\Log;
80537
80538
80539
80540
80541 trait LoggerAwareTrait
80542 {
80543
80544
80545
80546
80547
80548 protected $logger;
80549
80550
80551
80552
80553
80554
80555 public function setLogger(LoggerInterface $logger)
80556 {
80557 $this->logger = $logger;
80558 }
80559 }
80560 <?php
80561
80562 namespace Psr\Log;
80563
80564
80565
80566
80567
80568
80569
80570
80571
80572
80573
80574
80575
80576
80577
80578
80579 interface LoggerInterface
80580 {
80581
80582
80583
80584
80585
80586
80587
80588
80589 public function emergency($message, array $context = array());
80590
80591
80592
80593
80594
80595
80596
80597
80598
80599
80600
80601
80602 public function alert($message, array $context = array());
80603
80604
80605
80606
80607
80608
80609
80610
80611
80612
80613
80614 public function critical($message, array $context = array());
80615
80616
80617
80618
80619
80620
80621
80622
80623
80624
80625 public function error($message, array $context = array());
80626
80627
80628
80629
80630
80631
80632
80633
80634
80635
80636
80637
80638 public function warning($message, array $context = array());
80639
80640
80641
80642
80643
80644
80645
80646
80647
80648 public function notice($message, array $context = array());
80649
80650
80651
80652
80653
80654
80655
80656
80657
80658
80659
80660 public function info($message, array $context = array());
80661
80662
80663
80664
80665
80666
80667
80668
80669
80670 public function debug($message, array $context = array());
80671
80672
80673
80674
80675
80676
80677
80678
80679
80680
80681 public function log($level, $message, array $context = array());
80682 }
80683 <?php
80684
80685 namespace Psr\Log;
80686
80687
80688
80689
80690
80691
80692
80693
80694
80695 trait LoggerTrait
80696 {
80697
80698
80699
80700
80701
80702
80703
80704
80705 public function emergency($message, array $context = array())
80706 {
80707 $this->log(LogLevel::EMERGENCY, $message, $context);
80708 }
80709
80710
80711
80712
80713
80714
80715
80716
80717
80718
80719
80720
80721 public function alert($message, array $context = array())
80722 {
80723 $this->log(LogLevel::ALERT, $message, $context);
80724 }
80725
80726
80727
80728
80729
80730
80731
80732
80733
80734
80735
80736 public function critical($message, array $context = array())
80737 {
80738 $this->log(LogLevel::CRITICAL, $message, $context);
80739 }
80740
80741
80742
80743
80744
80745
80746
80747
80748
80749
80750 public function error($message, array $context = array())
80751 {
80752 $this->log(LogLevel::ERROR, $message, $context);
80753 }
80754
80755
80756
80757
80758
80759
80760
80761
80762
80763
80764
80765
80766 public function warning($message, array $context = array())
80767 {
80768 $this->log(LogLevel::WARNING, $message, $context);
80769 }
80770
80771
80772
80773
80774
80775
80776
80777
80778
80779 public function notice($message, array $context = array())
80780 {
80781 $this->log(LogLevel::NOTICE, $message, $context);
80782 }
80783
80784
80785
80786
80787
80788
80789
80790
80791
80792
80793
80794 public function info($message, array $context = array())
80795 {
80796 $this->log(LogLevel::INFO, $message, $context);
80797 }
80798
80799
80800
80801
80802
80803
80804
80805
80806
80807 public function debug($message, array $context = array())
80808 {
80809 $this->log(LogLevel::DEBUG, $message, $context);
80810 }
80811
80812
80813
80814
80815
80816
80817
80818
80819
80820
80821 abstract public function log($level, $message, array $context = array());
80822 }
80823 <?php
80824
80825 namespace Psr\Log;
80826
80827
80828
80829
80830
80831
80832
80833
80834
80835 class NullLogger extends AbstractLogger
80836 {
80837
80838
80839
80840
80841
80842
80843
80844
80845
80846 public function log($level, $message, array $context = array())
80847 {
80848
80849  }
80850 }
80851 <?php
80852
80853 namespace Psr\Log\Test;
80854
80855 use Psr\Log\LoggerInterface;
80856 use Psr\Log\LogLevel;
80857
80858
80859
80860
80861
80862
80863
80864 abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
80865 {
80866
80867
80868
80869 abstract public function getLogger();
80870
80871
80872
80873
80874
80875
80876
80877
80878
80879
80880 abstract public function getLogs();
80881
80882 public function testImplements()
80883 {
80884 $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
80885 }
80886
80887
80888
80889
80890 public function testLogsAtAllLevels($level, $message)
80891 {
80892 $logger = $this->getLogger();
80893 $logger->{$level}($message, array('user' => 'Bob'));
80894 $logger->log($level, $message, array('user' => 'Bob'));
80895
80896 $expected = array(
80897 $level.' message of level '.$level.' with context: Bob',
80898 $level.' message of level '.$level.' with context: Bob',
80899 );
80900 $this->assertEquals($expected, $this->getLogs());
80901 }
80902
80903 public function provideLevelsAndMessages()
80904 {
80905 return array(
80906 LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
80907 LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
80908 LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
80909 LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
80910 LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
80911 LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
80912 LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
80913 LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
80914 );
80915 }
80916
80917
80918
80919
80920 public function testThrowsOnInvalidLevel()
80921 {
80922 $logger = $this->getLogger();
80923 $logger->log('invalid level', 'Foo');
80924 }
80925
80926 public function testContextReplacement()
80927 {
80928 $logger = $this->getLogger();
80929 $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
80930
80931 $expected = array('info {Message {nothing} Bob Bar a}');
80932 $this->assertEquals($expected, $this->getLogs());
80933 }
80934
80935 public function testObjectCastToString()
80936 {
80937 if (method_exists($this, 'createPartialMock')) {
80938 $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString'));
80939 } else {
80940 $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
80941 }
80942 $dummy->expects($this->once())
80943 ->method('__toString')
80944 ->will($this->returnValue('DUMMY'));
80945
80946 $this->getLogger()->warning($dummy);
80947
80948 $expected = array('warning DUMMY');
80949 $this->assertEquals($expected, $this->getLogs());
80950 }
80951
80952 public function testContextCanContainAnything()
80953 {
80954 $context = array(
80955 'bool' => true,
80956 'null' => null,
80957 'string' => 'Foo',
80958 'int' => 0,
80959 'float' => 0.5,
80960 'nested' => array('with object' => new DummyTest),
80961 'object' => new \DateTime,
80962 'resource' => fopen('php://memory', 'r'),
80963 );
80964
80965 $this->getLogger()->warning('Crazy context data', $context);
80966
80967 $expected = array('warning Crazy context data');
80968 $this->assertEquals($expected, $this->getLogs());
80969 }
80970
80971 public function testContextExceptionKeyCanBeExceptionOrOtherValues()
80972 {
80973 $logger = $this->getLogger();
80974 $logger->warning('Random message', array('exception' => 'oops'));
80975 $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
80976
80977 $expected = array(
80978 'warning Random message',
80979 'critical Uncaught Exception!'
80980 );
80981 $this->assertEquals($expected, $this->getLogs());
80982 }
80983 }
80984
80985 class DummyTest
80986 {
80987 public function __toString()
80988 {
80989 }
80990 }
80991 <?php
80992
80993
80994
80995 require_once __DIR__ . '/composer/autoload_real.php';
80996
80997 return ComposerAutoloaderInitComposerPhar1489134585::getLoader();
80998 <?php
80999
81000
81001
81002 $vendorDir = dirname(dirname(__FILE__));
81003 $baseDir = dirname($vendorDir);
81004
81005 return array(
81006 );
81007 <?php
81008
81009
81010
81011 $vendorDir = dirname(dirname(__FILE__));
81012 $baseDir = dirname($vendorDir);
81013
81014 return array(
81015 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
81016 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
81017 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
81018 'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
81019 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
81020 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
81021 'Seld\\PharUtils\\' => array($vendorDir . '/seld/phar-utils/src'),
81022 'Seld\\JsonLint\\' => array($vendorDir . '/seld/jsonlint/src/Seld/JsonLint'),
81023 'Seld\\CliPrompt\\' => array($vendorDir . '/seld/cli-prompt/src'),
81024 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
81025 'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'),
81026 'Composer\\Spdx\\' => array($vendorDir . '/composer/spdx-licenses/src'),
81027 'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
81028 'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),
81029 'Composer\\' => array($baseDir . '/src/Composer'),
81030 );
81031 <?php
81032
81033
81034
81035 $vendorDir = dirname(dirname(__FILE__));
81036 $baseDir = dirname($vendorDir);
81037
81038 return array(
81039 );
81040 <?php
81041
81042
81043
81044 $vendorDir = dirname(dirname(__FILE__));
81045 $baseDir = dirname($vendorDir);
81046
81047 return array(
81048 '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
81049 );
81050 <?php
81051
81052
81053
81054 class ComposerAutoloaderInitComposerPhar1489134585
81055 {
81056 private static $loader;
81057
81058 public static function loadClassLoader($class)
81059 {
81060 if ('Composer\Autoload\ClassLoader' === $class) {
81061 require __DIR__ . '/ClassLoader.php';
81062 }
81063 }
81064
81065 public static function getLoader()
81066 {
81067 if (null !== self::$loader) {
81068 return self::$loader;
81069 }
81070
81071 spl_autoload_register(array('ComposerAutoloaderInitComposerPhar1489134585', 'loadClassLoader'), true, true);
81072 self::$loader = $loader = new \Composer\Autoload\ClassLoader();
81073 spl_autoload_unregister(array('ComposerAutoloaderInitComposerPhar1489134585', 'loadClassLoader'));
81074
81075 $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
81076 if ($useStaticLoader) {
81077 require_once __DIR__ . '/autoload_static.php';
81078
81079 call_user_func(\Composer\Autoload\ComposerStaticInitComposerPhar1489134585::getInitializer($loader));
81080 } else {
81081 $map = require __DIR__ . '/autoload_namespaces.php';
81082 foreach ($map as $namespace => $path) {
81083 $loader->set($namespace, $path);
81084 }
81085
81086 $map = require __DIR__ . '/autoload_psr4.php';
81087 foreach ($map as $namespace => $path) {
81088 $loader->setPsr4($namespace, $path);
81089 }
81090
81091 $classMap = require __DIR__ . '/autoload_classmap.php';
81092 if ($classMap) {
81093 $loader->addClassMap($classMap);
81094 }
81095 }
81096
81097 $loader->register(true);
81098
81099 if ($useStaticLoader) {
81100 $includeFiles = Composer\Autoload\ComposerStaticInitComposerPhar1489134585::$files;
81101 } else {
81102 $includeFiles = require __DIR__ . '/autoload_files.php';
81103 }
81104 foreach ($includeFiles as $fileIdentifier => $file) {
81105 composerRequireComposerPhar1489134585($fileIdentifier, $file);
81106 }
81107
81108 return $loader;
81109 }
81110 }
81111
81112 function composerRequireComposerPhar1489134585($fileIdentifier, $file)
81113 {
81114 if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
81115 require $file;
81116
81117 $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
81118 }
81119 }
81120 <?php
81121
81122
81123
81124 namespace Composer\Autoload;
81125
81126 class ComposerStaticInitComposerPhar1489134585
81127 {
81128 public static $files = array (
81129 '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
81130 );
81131
81132 public static $prefixLengthsPsr4 = array (
81133 'S' => 
81134 array (
81135 'Symfony\\Polyfill\\Mbstring\\' => 26,
81136 'Symfony\\Component\\Process\\' => 26,
81137 'Symfony\\Component\\Finder\\' => 25,
81138 'Symfony\\Component\\Filesystem\\' => 29,
81139 'Symfony\\Component\\Debug\\' => 24,
81140 'Symfony\\Component\\Console\\' => 26,
81141 'Seld\\PharUtils\\' => 15,
81142 'Seld\\JsonLint\\' => 14,
81143 'Seld\\CliPrompt\\' => 15,
81144 ),
81145 'P' => 
81146 array (
81147 'Psr\\Log\\' => 8,
81148 ),
81149 'J' => 
81150 array (
81151 'JsonSchema\\' => 11,
81152 ),
81153 'C' => 
81154 array (
81155 'Composer\\Spdx\\' => 14,
81156 'Composer\\Semver\\' => 16,
81157 'Composer\\CaBundle\\' => 18,
81158 'Composer\\' => 9,
81159 ),
81160 );
81161
81162 public static $prefixDirsPsr4 = array (
81163 'Symfony\\Polyfill\\Mbstring\\' => 
81164 array (
81165 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
81166 ),
81167 'Symfony\\Component\\Process\\' => 
81168 array (
81169 0 => __DIR__ . '/..' . '/symfony/process',
81170 ),
81171 'Symfony\\Component\\Finder\\' => 
81172 array (
81173 0 => __DIR__ . '/..' . '/symfony/finder',
81174 ),
81175 'Symfony\\Component\\Filesystem\\' => 
81176 array (
81177 0 => __DIR__ . '/..' . '/symfony/filesystem',
81178 ),
81179 'Symfony\\Component\\Debug\\' => 
81180 array (
81181 0 => __DIR__ . '/..' . '/symfony/debug',
81182 ),
81183 'Symfony\\Component\\Console\\' => 
81184 array (
81185 0 => __DIR__ . '/..' . '/symfony/console',
81186 ),
81187 'Seld\\PharUtils\\' => 
81188 array (
81189 0 => __DIR__ . '/..' . '/seld/phar-utils/src',
81190 ),
81191 'Seld\\JsonLint\\' => 
81192 array (
81193 0 => __DIR__ . '/..' . '/seld/jsonlint/src/Seld/JsonLint',
81194 ),
81195 'Seld\\CliPrompt\\' => 
81196 array (
81197 0 => __DIR__ . '/..' . '/seld/cli-prompt/src',
81198 ),
81199 'Psr\\Log\\' => 
81200 array (
81201 0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
81202 ),
81203 'JsonSchema\\' => 
81204 array (
81205 0 => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema',
81206 ),
81207 'Composer\\Spdx\\' => 
81208 array (
81209 0 => __DIR__ . '/..' . '/composer/spdx-licenses/src',
81210 ),
81211 'Composer\\Semver\\' => 
81212 array (
81213 0 => __DIR__ . '/..' . '/composer/semver/src',
81214 ),
81215 'Composer\\CaBundle\\' => 
81216 array (
81217 0 => __DIR__ . '/..' . '/composer/ca-bundle/src',
81218 ),
81219 'Composer\\' => 
81220 array (
81221 0 => __DIR__ . '/../..' . '/src/Composer',
81222 ),
81223 );
81224
81225 public static function getInitializer(ClassLoader $loader)
81226 {
81227 return \Closure::bind(function () use ($loader) {
81228 $loader->prefixLengthsPsr4 = ComposerStaticInitComposerPhar1489134585::$prefixLengthsPsr4;
81229 $loader->prefixDirsPsr4 = ComposerStaticInitComposerPhar1489134585::$prefixDirsPsr4;
81230
81231 }, null, ClassLoader::class);
81232 }
81233 }
81234 <?php
81235
81236
81237
81238
81239
81240
81241
81242
81243
81244
81245
81246 namespace Composer\Autoload;
81247
81248
81249
81250
81251
81252
81253
81254
81255
81256
81257
81258
81259
81260
81261
81262
81263
81264
81265
81266
81267
81268
81269
81270
81271
81272
81273
81274
81275
81276 class ClassLoader
81277 {
81278
81279  private $prefixLengthsPsr4 = array();
81280 private $prefixDirsPsr4 = array();
81281 private $fallbackDirsPsr4 = array();
81282
81283
81284  private $prefixesPsr0 = array();
81285 private $fallbackDirsPsr0 = array();
81286
81287 private $useIncludePath = false;
81288 private $classMap = array();
81289 private $classMapAuthoritative = false;
81290 private $missingClasses = array();
81291 private $apcuPrefix;
81292
81293 public function getPrefixes()
81294 {
81295 if (!empty($this->prefixesPsr0)) {
81296 return call_user_func_array('array_merge', $this->prefixesPsr0);
81297 }
81298
81299 return array();
81300 }
81301
81302 public function getPrefixesPsr4()
81303 {
81304 return $this->prefixDirsPsr4;
81305 }
81306
81307 public function getFallbackDirs()
81308 {
81309 return $this->fallbackDirsPsr0;
81310 }
81311
81312 public function getFallbackDirsPsr4()
81313 {
81314 return $this->fallbackDirsPsr4;
81315 }
81316
81317 public function getClassMap()
81318 {
81319 return $this->classMap;
81320 }
81321
81322
81323
81324
81325 public function addClassMap(array $classMap)
81326 {
81327 if ($this->classMap) {
81328 $this->classMap = array_merge($this->classMap, $classMap);
81329 } else {
81330 $this->classMap = $classMap;
81331 }
81332 }
81333
81334
81335
81336
81337
81338
81339
81340
81341
81342 public function add($prefix, $paths, $prepend = false)
81343 {
81344 if (!$prefix) {
81345 if ($prepend) {
81346 $this->fallbackDirsPsr0 = array_merge(
81347 (array) $paths,
81348 $this->fallbackDirsPsr0
81349 );
81350 } else {
81351 $this->fallbackDirsPsr0 = array_merge(
81352 $this->fallbackDirsPsr0,
81353 (array) $paths
81354 );
81355 }
81356
81357 return;
81358 }
81359
81360 $first = $prefix[0];
81361 if (!isset($this->prefixesPsr0[$first][$prefix])) {
81362 $this->prefixesPsr0[$first][$prefix] = (array) $paths;
81363
81364 return;
81365 }
81366 if ($prepend) {
81367 $this->prefixesPsr0[$first][$prefix] = array_merge(
81368 (array) $paths,
81369 $this->prefixesPsr0[$first][$prefix]
81370 );
81371 } else {
81372 $this->prefixesPsr0[$first][$prefix] = array_merge(
81373 $this->prefixesPsr0[$first][$prefix],
81374 (array) $paths
81375 );
81376 }
81377 }
81378
81379
81380
81381
81382
81383
81384
81385
81386
81387
81388
81389 public function addPsr4($prefix, $paths, $prepend = false)
81390 {
81391 if (!$prefix) {
81392
81393  if ($prepend) {
81394 $this->fallbackDirsPsr4 = array_merge(
81395 (array) $paths,
81396 $this->fallbackDirsPsr4
81397 );
81398 } else {
81399 $this->fallbackDirsPsr4 = array_merge(
81400 $this->fallbackDirsPsr4,
81401 (array) $paths
81402 );
81403 }
81404 } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
81405
81406  $length = strlen($prefix);
81407 if ('\\' !== $prefix[$length - 1]) {
81408 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
81409 }
81410 $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
81411 $this->prefixDirsPsr4[$prefix] = (array) $paths;
81412 } elseif ($prepend) {
81413
81414  $this->prefixDirsPsr4[$prefix] = array_merge(
81415 (array) $paths,
81416 $this->prefixDirsPsr4[$prefix]
81417 );
81418 } else {
81419
81420  $this->prefixDirsPsr4[$prefix] = array_merge(
81421 $this->prefixDirsPsr4[$prefix],
81422 (array) $paths
81423 );
81424 }
81425 }
81426
81427
81428
81429
81430
81431
81432
81433
81434 public function set($prefix, $paths)
81435 {
81436 if (!$prefix) {
81437 $this->fallbackDirsPsr0 = (array) $paths;
81438 } else {
81439 $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
81440 }
81441 }
81442
81443
81444
81445
81446
81447
81448
81449
81450
81451
81452 public function setPsr4($prefix, $paths)
81453 {
81454 if (!$prefix) {
81455 $this->fallbackDirsPsr4 = (array) $paths;
81456 } else {
81457 $length = strlen($prefix);
81458 if ('\\' !== $prefix[$length - 1]) {
81459 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
81460 }
81461 $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
81462 $this->prefixDirsPsr4[$prefix] = (array) $paths;
81463 }
81464 }
81465
81466
81467
81468
81469
81470
81471 public function setUseIncludePath($useIncludePath)
81472 {
81473 $this->useIncludePath = $useIncludePath;
81474 }
81475
81476
81477
81478
81479
81480
81481
81482 public function getUseIncludePath()
81483 {
81484 return $this->useIncludePath;
81485 }
81486
81487
81488
81489
81490
81491
81492
81493 public function setClassMapAuthoritative($classMapAuthoritative)
81494 {
81495 $this->classMapAuthoritative = $classMapAuthoritative;
81496 }
81497
81498
81499
81500
81501
81502
81503 public function isClassMapAuthoritative()
81504 {
81505 return $this->classMapAuthoritative;
81506 }
81507
81508
81509
81510
81511
81512
81513 public function setApcuPrefix($apcuPrefix)
81514 {
81515 $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
81516 }
81517
81518
81519
81520
81521
81522
81523 public function getApcuPrefix()
81524 {
81525 return $this->apcuPrefix;
81526 }
81527
81528
81529
81530
81531
81532
81533 public function register($prepend = false)
81534 {
81535 spl_autoload_register(array($this, 'loadClass'), true, $prepend);
81536 }
81537
81538
81539
81540
81541 public function unregister()
81542 {
81543 spl_autoload_unregister(array($this, 'loadClass'));
81544 }
81545
81546
81547
81548
81549
81550
81551
81552 public function loadClass($class)
81553 {
81554 if ($file = $this->findFile($class)) {
81555 includeFile($file);
81556
81557 return true;
81558 }
81559 }
81560
81561
81562
81563
81564
81565
81566
81567
81568 public function findFile($class)
81569 {
81570
81571  if (isset($this->classMap[$class])) {
81572 return $this->classMap[$class];
81573 }
81574 if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
81575 return false;
81576 }
81577 if (null !== $this->apcuPrefix) {
81578 $file = apcu_fetch($this->apcuPrefix.$class, $hit);
81579 if ($hit) {
81580 return $file;
81581 }
81582 }
81583
81584 $file = $this->findFileWithExtension($class, '.php');
81585
81586
81587  if (false === $file && defined('HHVM_VERSION')) {
81588 $file = $this->findFileWithExtension($class, '.hh');
81589 }
81590
81591 if (null !== $this->apcuPrefix) {
81592 apcu_add($this->apcuPrefix.$class, $file);
81593 }
81594
81595 if (false === $file) {
81596
81597  $this->missingClasses[$class] = true;
81598 }
81599
81600 return $file;
81601 }
81602
81603 private function findFileWithExtension($class, $ext)
81604 {
81605
81606  $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
81607
81608 $first = $class[0];
81609 if (isset($this->prefixLengthsPsr4[$first])) {
81610 $subPath = $class;
81611 while (false !== $lastPos = strrpos($subPath, '\\')) {
81612 $subPath = substr($subPath, 0, $lastPos);
81613 $search = $subPath.'\\';
81614 if (isset($this->prefixDirsPsr4[$search])) {
81615 foreach ($this->prefixDirsPsr4[$search] as $dir) {
81616 $length = $this->prefixLengthsPsr4[$first][$search];
81617 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
81618 return $file;
81619 }
81620 }
81621 }
81622 }
81623 }
81624
81625
81626  foreach ($this->fallbackDirsPsr4 as $dir) {
81627 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
81628 return $file;
81629 }
81630 }
81631
81632
81633  if (false !== $pos = strrpos($class, '\\')) {
81634
81635  $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
81636 . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
81637 } else {
81638
81639  $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
81640 }
81641
81642 if (isset($this->prefixesPsr0[$first])) {
81643 foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
81644 if (0 === strpos($class, $prefix)) {
81645 foreach ($dirs as $dir) {
81646 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
81647 return $file;
81648 }
81649 }
81650 }
81651 }
81652 }
81653
81654
81655  foreach ($this->fallbackDirsPsr0 as $dir) {
81656 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
81657 return $file;
81658 }
81659 }
81660
81661
81662  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
81663 return $file;
81664 }
81665
81666 return false;
81667 }
81668 }
81669
81670
81671
81672
81673
81674
81675 function includeFile($file)
81676 {
81677 include $file;
81678 }
81679 ##
81680 ## Bundle of CA Root Certificates
81681 ##
81682 ## Certificate data from Mozilla as of: Wed Jan 18 04:12:05 2017 GMT
81683 ##
81684 ## This is a bundle of X.509 certificates of public Certificate Authorities
81685 ## (CA). These were automatically extracted from Mozilla's root certificates
81686 ## file (certdata.txt).  This file can be found in the mozilla source tree:
81687 ## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
81688 ##
81689 ## It contains the certificates in PEM format and therefore
81690 ## can be directly used with curl / libcurl / php_curl, or with
81691 ## an Apache+mod_ssl webserver for SSL client authentication.
81692 ## Just configure this file as the SSLCACertificateFile.
81693 ##
81694 ## Conversion done with mk-ca-bundle.pl version 1.27.
81695 ## SHA256: dffa79e6aa993f558e82884abf7bb54bf440ab66ee91d82a27a627f6f2a4ace4
81696 ##
81697
81698
81699 GlobalSign Root CA
81700 ==================
81701 -----BEGIN CERTIFICATE-----
81702 MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
81703 GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
81704 b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
81705 BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
81706 VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
81707 DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
81708 THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
81709 Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
81710 c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
81711 gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
81712 HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
81713 AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
81714 Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
81715 j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
81716 hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
81717 X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
81718 -----END CERTIFICATE-----
81719
81720 GlobalSign Root CA - R2
81721 =======================
81722 -----BEGIN CERTIFICATE-----
81723 MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
81724 YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
81725 bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
81726 aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
81727 bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
81728 ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
81729 s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
81730 S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
81731 TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
81732 ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
81733 FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
81734 YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
81735 BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
81736 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
81737 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
81738 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
81739 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
81740 -----END CERTIFICATE-----
81741
81742 Verisign Class 3 Public Primary Certification Authority - G3
81743 ============================================================
81744 -----BEGIN CERTIFICATE-----
81745 MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
81746 UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
81747 cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
81748 IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
81749 dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
81750 CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
81751 dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
81752 cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
81753 Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
81754 ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
81755 EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
81756 cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
81757 EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
81758 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
81759 ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
81760 j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
81761 /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
81762 xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
81763 t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
81764 -----END CERTIFICATE-----
81765
81766 Entrust.net Premium 2048 Secure Server CA
81767 =========================================
81768 -----BEGIN CERTIFICATE-----
81769 MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
81770 ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
81771 bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
81772 BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
81773 NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
81774 d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
81775 MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
81776 ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
81777 MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
81778 Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
81779 hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
81780 nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
81781 VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E
81782 BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ
81783 KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy
81784 T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
81785 zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT
81786 J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e
81787 nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=
81788 -----END CERTIFICATE-----
81789
81790 Baltimore CyberTrust Root
81791 =========================
81792 -----BEGIN CERTIFICATE-----
81793 MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
81794 ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
81795 ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
81796 SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
81797 dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
81798 uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
81799 UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
81800 G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
81801 XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
81802 l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
81803 VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
81804 BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
81805 cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
81806 hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
81807 Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
81808 RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
81809 -----END CERTIFICATE-----
81810
81811 AddTrust Low-Value Services Root
81812 ================================
81813 -----BEGIN CERTIFICATE-----
81814 MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
81815 QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU
81816 cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw
81817 CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO
81818 ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB
81819 AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6
81820 54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr
81821 oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1
81822 Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui
81823 GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w
81824 HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD
81825 AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT
81826 RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw
81827 HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt
81828 ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph
81829 iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
81830 eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr
81831 mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj
81832 ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
81833 -----END CERTIFICATE-----
81834
81835 AddTrust External Root
81836 ======================
81837 -----BEGIN CERTIFICATE-----
81838 MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
81839 QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
81840 VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
81841 NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
81842 cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
81843 Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
81844 +iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
81845 Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
81846 aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
81847 2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
81848 7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
81849 BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
81850 VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
81851 VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
81852 IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
81853 j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
81854 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
81855 e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
81856 G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
81857 -----END CERTIFICATE-----
81858
81859 AddTrust Public Services Root
81860 =============================
81861 -----BEGIN CERTIFICATE-----
81862 MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
81863 QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU
81864 cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ
81865 BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l
81866 dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF
81867 AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu
81868 nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i
81869 d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG
81870 Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw
81871 HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G
81872 A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
81873 /zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux
81874 FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G
81875 A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4
81876 JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL
81877 +YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
81878 GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9
81879 Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H
81880 EufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
81881 -----END CERTIFICATE-----
81882
81883 AddTrust Qualified Certificates Root
81884 ====================================
81885 -----BEGIN CERTIFICATE-----
81886 MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
81887 QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU
81888 cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx
81889 CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ
81890 IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG
81891 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx
81892 64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3
81893 KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o
81894 L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR
81895 wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU
81896 MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/
81897 BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE
81898 BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y
81899 azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD
81900 ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG
81901 GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
81902 dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze
81903 RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB
81904 iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE=
81905 -----END CERTIFICATE-----
81906
81907 Entrust Root Certification Authority
81908 ====================================
81909 -----BEGIN CERTIFICATE-----
81910 MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
81911 BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
81912 b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
81913 A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
81914 MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
81915 MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
81916 Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
81917 dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
81918 ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
81919 A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
81920 Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
81921 j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
81922 rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
81923 DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
81924 MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
81925 hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
81926 A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
81927 Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
81928 v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
81929 W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
81930 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
81931 -----END CERTIFICATE-----
81932
81933 GeoTrust Global CA
81934 ==================
81935 -----BEGIN CERTIFICATE-----
81936 MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
81937 Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
81938 MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
81939 LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
81940 CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
81941 BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
81942 8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
81943 T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
81944 vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
81945 AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
81946 DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
81947 zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
81948 d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
81949 mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
81950 XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
81951 Mw==
81952 -----END CERTIFICATE-----
81953
81954 GeoTrust Global CA 2
81955 ====================
81956 -----BEGIN CERTIFICATE-----
81957 MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
81958 R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw
81959 MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
81960 LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
81961 ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/
81962 NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k
81963 LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA
81964 Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b
81965 HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF
81966 MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH
81967 K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7
81968 srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh
81969 ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL
81970 OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC
81971 x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF
81972 H4z1Ir+rzoPz4iIprn2DQKi6bA==
81973 -----END CERTIFICATE-----
81974
81975 GeoTrust Universal CA
81976 =====================
81977 -----BEGIN CERTIFICATE-----
81978 MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
81979 R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1
81980 MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu
81981 Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
81982 ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t
81983 JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e
81984 RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs
81985 7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d
81986 8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V
81987 qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga
81988 Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB
81989 Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu
81990 KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08
81991 ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0
81992 XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB
81993 hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
81994 aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2
81995 qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL
81996 oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK
81997 xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF
81998 KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2
81999 DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK
82000 xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU
82001 p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI
82002 P/rmMuGNG2+k5o7Y+SlIis5z/iw=
82003 -----END CERTIFICATE-----
82004
82005 GeoTrust Universal CA 2
82006 =======================
82007 -----BEGIN CERTIFICATE-----
82008 MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
82009 R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0
82010 MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg
82011 SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA
82012 A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0
82013 DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17
82014 j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q
82015 JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a
82016 QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2
82017 WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP
82018 20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn
82019 ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC
82020 SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG
82021 8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2
82022 +/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E
82023 BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
82024 dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ
82025 4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+
82026 mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq
82027 A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg
82028 Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP
82029 pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d
82030 FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp
82031 gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
82032 X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
82033 -----END CERTIFICATE-----
82034
82035 Visa eCommerce Root
82036 ===================
82037 -----BEGIN CERTIFICATE-----
82038 MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
82039 EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
82040 QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
82041 WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
82042 VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
82043 bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
82044 F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
82045 RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
82046 TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
82047 /k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
82048 GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
82049 MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
82050 CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
82051 YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
82052 zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
82053 YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
82054 398znM/jra6O1I7mT1GvFpLgXPYHDw==
82055 -----END CERTIFICATE-----
82056
82057 Certum Root CA
82058 ==============
82059 -----BEGIN CERTIFICATE-----
82060 MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK
82061 ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla
82062 Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u
82063 by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x
82064 wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL
82065 kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ
82066 89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K
82067 Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P
82068 NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
82069 hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+
82070 GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg
82071 GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/
82072 0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS
82073 qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw==
82074 -----END CERTIFICATE-----
82075
82076 Comodo AAA Services root
82077 ========================
82078 -----BEGIN CERTIFICATE-----
82079 MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
82080 R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
82081 TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
82082 MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
82083 c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
82084 BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
82085 ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
82086 C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
82087 i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
82088 Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
82089 Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
82090 Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
82091 BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
82092 cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
82093 LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
82094 7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
82095 Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
82096 8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
82097 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
82098 -----END CERTIFICATE-----
82099
82100 Comodo Secure Services root
82101 ===========================
82102 -----BEGIN CERTIFICATE-----
82103 MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
82104 R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
82105 TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw
82106 MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu
82107 Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi
82108 BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
82109 ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP
82110 9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc
82111 rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC
82112 oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V
82113 p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E
82114 FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
82115 gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj
82116 YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm
82117 aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm
82118 4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
82119 Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL
82120 DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw
82121 pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H
82122 RR3B7Hzs/Sk=
82123 -----END CERTIFICATE-----
82124
82125 Comodo Trusted Services root
82126 ============================
82127 -----BEGIN CERTIFICATE-----
82128 MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
82129 R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
82130 TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw
82131 MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h
82132 bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw
82133 IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC
82134 AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7
82135 3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y
82136 /9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6
82137 juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS
82138 ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud
82139 DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
82140 /zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp
82141 ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl
82142 cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw
82143 uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
82144 pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA
82145 BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l
82146 R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O
82147 9y5Xt5hwXsjEeLBi
82148 -----END CERTIFICATE-----
82149
82150 QuoVadis Root CA
82151 ================
82152 -----BEGIN CERTIFICATE-----
82153 MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
82154 ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
82155 eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
82156 MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
82157 cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
82158 EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
82159 AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
82160 J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
82161 F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
82162 YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
82163 AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
82164 PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
82165 ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
82166 MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
82167 YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
82168 ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
82169 Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
82170 Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
82171 BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
82172 FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
82173 aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
82174 tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
82175 fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
82176 LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
82177 gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
82178 5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
82179 5nrQNiOKSnQ2+Q==
82180 -----END CERTIFICATE-----
82181
82182 QuoVadis Root CA 2
82183 ==================
82184 -----BEGIN CERTIFICATE-----
82185 MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
82186 EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx
82187 ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
82188 aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC
82189 DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6
82190 XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk
82191 lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB
82192 lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
82193 lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt
82194 66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn
82195 wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh
82196 D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy
82197 BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie
82198 J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud
82199 DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU
82200 a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
82201 ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv
82202 Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3
82203 UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
82204 VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK
82205 +JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW
82206 IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1
82207 WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X
82208 f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II
82209 4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8
82210 VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
82211 -----END CERTIFICATE-----
82212
82213 QuoVadis Root CA 3
82214 ==================
82215 -----BEGIN CERTIFICATE-----
82216 MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
82217 EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
82218 OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
82219 aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
82220 DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
82221 DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
82222 KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
82223 DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
82224 BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
82225 p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
82226 nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
82227 MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
82228 Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
82229 uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
82230 BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
82231 YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
82232 aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
82233 BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
82234 VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
82235 ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
82236 AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
82237 qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
82238 hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
82239 POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
82240 Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
82241 8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
82242 bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
82243 g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
82244 vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
82245 qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
82246 -----END CERTIFICATE-----
82247
82248 Security Communication Root CA
82249 ==============================
82250 -----BEGIN CERTIFICATE-----
82251 MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
82252 U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
82253 HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
82254 U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
82255 ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
82256 8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
82257 DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
82258 5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
82259 DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
82260 JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
82261 DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
82262 0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
82263 mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
82264 s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
82265 6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
82266 FL39vmwLAw==
82267 -----END CERTIFICATE-----
82268
82269 Sonera Class 2 Root CA
82270 ======================
82271 -----BEGIN CERTIFICATE-----
82272 MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
82273 U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
82274 NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
82275 IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
82276 /Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
82277 dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
82278 f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
82279 tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
82280 nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
82281 XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
82282 0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
82283 cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
82284 Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
82285 EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
82286 llpwrN9M
82287 -----END CERTIFICATE-----
82288
82289 UTN USERFirst Hardware Root CA
82290 ==============================
82291 -----BEGIN CERTIFICATE-----
82292 MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE
82293 BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
82294 IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd
82295 BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx
82296 OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0
82297 eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz
82298 ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3
82299 DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI
82300 wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd
82301 tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8
82302 i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf
82303 Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw
82304 gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF
82305 lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF
82306 UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
82307 BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
82308 //bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW
82309 XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2
82310 lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn
82311 iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67
82312 nfhmqA==
82313 -----END CERTIFICATE-----
82314
82315 Camerfirma Chambers of Commerce Root
82316 ====================================
82317 -----BEGIN CERTIFICATE-----
82318 MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
82319 QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
82320 ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx
82321 NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp
82322 cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn
82323 MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC
82324 AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU
82325 xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH
82326 NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW
82327 DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV
82328 d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud
82329 EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v
82330 cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P
82331 AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh
82332 bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD
82333 VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
82334 aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi
82335 fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD
82336 L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN
82337 UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n
82338 ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1
82339 erfutGWaIZDgqtCYvDi1czyL+Nw=
82340 -----END CERTIFICATE-----
82341
82342 Camerfirma Global Chambersign Root
82343 ==================================
82344 -----BEGIN CERTIFICATE-----
82345 MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
82346 QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
82347 ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx
82348 NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt
82349 YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg
82350 MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw
82351 ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J
82352 1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O
82353 by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl
82354 6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c
82355 8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/
82356 BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j
82357 aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B
82358 Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj
82359 aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y
82360 ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
82361 bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA
82362 PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y
82363 gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ
82364 PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4
82365 IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
82366 t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
82367 -----END CERTIFICATE-----
82368
82369 XRamp Global CA Root
82370 ====================
82371 -----BEGIN CERTIFICATE-----
82372 MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
82373 BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
82374 dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
82375 dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
82376 HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
82377 U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
82378 dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
82379 IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
82380 foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
82381 zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
82382 AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
82383 xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
82384 EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
82385 oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
82386 AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
82387 /Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
82388 qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
82389 nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
82390 8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
82391 -----END CERTIFICATE-----
82392
82393 Go Daddy Class 2 CA
82394 ===================
82395 -----BEGIN CERTIFICATE-----
82396 MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
82397 VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
82398 ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
82399 A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
82400 RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
82401 ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
82402 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
82403 qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
82404 YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
82405 vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
82406 BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
82407 atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
82408 MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
82409 A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
82410 PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
82411 I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
82412 HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
82413 Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
82414 vZ8=
82415 -----END CERTIFICATE-----
82416
82417 Starfield Class 2 CA
82418 ====================
82419 -----BEGIN CERTIFICATE-----
82420 MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
82421 U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
82422 Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
82423 MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
82424 A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
82425 SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
82426 bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
82427 JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
82428 epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
82429 F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
82430 MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
82431 hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
82432 bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
82433 QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
82434 afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
82435 PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
82436 xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
82437 KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
82438 QBFGmh95DmK/D5fs4C8fF5Q=
82439 -----END CERTIFICATE-----
82440
82441 StartCom Certification Authority
82442 ================================
82443 -----BEGIN CERTIFICATE-----
82444 MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
82445 U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
82446 ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
82447 NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
82448 LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
82449 U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
82450 ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
82451 o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
82452 Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
82453 eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
82454 2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
82455 6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
82456 osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
82457 untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
82458 UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
82459 37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
82460 FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0
82461 Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj
82462 YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH
82463 AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw
82464 Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg
82465 U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5
82466 LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl
82467 cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh
82468 cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT
82469 dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC
82470 AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh
82471 3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm
82472 vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk
82473 fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3
82474 fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ
82475 EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
82476 yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl
82477 1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/
82478 lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro
82479 g14=
82480 -----END CERTIFICATE-----
82481
82482 Taiwan GRCA
82483 ===========
82484 -----BEGIN CERTIFICATE-----
82485 MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG
82486 EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X
82487 DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv
82488 dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD
82489 ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN
82490 w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5
82491 BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O
82492 1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO
82493 htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov
82494 J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7
82495 Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t
82496 B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB
82497 O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8
82498 lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV
82499 HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2
82500 09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
82501 TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj
82502 Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2
82503 Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU
82504 D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz
82505 DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk
82506 Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk
82507 7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ
82508 CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
82509 +fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
82510 -----END CERTIFICATE-----
82511
82512 Swisscom Root CA 1
82513 ==================
82514 -----BEGIN CERTIFICATE-----
82515 MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG
82516 EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy
82517 dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4
82518 MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln
82519 aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC
82520 IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM
82521 MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF
82522 NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe
82523 AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC
82524 b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn
82525 7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN
82526 cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp
82527 WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5
82528 haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY
82529 MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw
82530 HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
82531 BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9
82532 MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn
82533 jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ
82534 MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H
82535 VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl
82536 vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl
82537 OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3
82538 1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq
82539 nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy
82540 x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW
82541 NY6E0F/6MBr1mmz0DlP5OlvRHA==
82542 -----END CERTIFICATE-----
82543
82544 DigiCert Assured ID Root CA
82545 ===========================
82546 -----BEGIN CERTIFICATE-----
82547 MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
82548 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
82549 IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
82550 MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
82551 ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
82552 ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
82553 9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
82554 UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
82555 /lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
82556 oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
82557 GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
82558 66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
82559 hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
82560 EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
82561 SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
82562 8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
82563 +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
82564 -----END CERTIFICATE-----
82565
82566 DigiCert Global Root CA
82567 =======================
82568 -----BEGIN CERTIFICATE-----
82569 MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
82570 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
82571 HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
82572 MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
82573 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
82574 hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
82575 TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
82576 BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
82577 4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
82578 7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
82579 o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
82580 8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
82581 BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
82582 EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
82583 tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
82584 UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
82585 CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
82586 -----END CERTIFICATE-----
82587
82588 DigiCert High Assurance EV Root CA
82589 ==================================
82590 -----BEGIN CERTIFICATE-----
82591 MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
82592 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
82593 KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
82594 MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
82595 MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
82596 Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
82597 Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
82598 OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
82599 MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
82600 NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
82601 h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
82602 Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
82603 JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
82604 V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
82605 myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
82606 mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
82607 vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
82608 -----END CERTIFICATE-----
82609
82610 Certplus Class 2 Primary CA
82611 ===========================
82612 -----BEGIN CERTIFICATE-----
82613 MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
82614 BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
82615 OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
82616 dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
82617 ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
82618 5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
82619 Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
82620 YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
82621 e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
82622 CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
82623 YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
82624 L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
82625 P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
82626 TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
82627 7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
82628 //1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
82629 l7+ijrRU
82630 -----END CERTIFICATE-----
82631
82632 DST Root CA X3
82633 ==============
82634 -----BEGIN CERTIFICATE-----
82635 MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
82636 ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
82637 DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
82638 cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
82639 ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
82640 rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
82641 UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
82642 xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
82643 utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
82644 AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
82645 MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
82646 dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
82647 GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
82648 RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
82649 fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
82650 -----END CERTIFICATE-----
82651
82652 DST ACES CA X6
82653 ==============
82654 -----BEGIN CERTIFICATE-----
82655 MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG
82656 EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT
82657 MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha
82658 MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE
82659 CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC
82660 AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI
82661 DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa
82662 pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow
82663 GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy
82664 MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud
82665 EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu
82666 Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy
82667 dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU
82668 CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2
82669 5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t
82670 Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
82671 nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs
82672 vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
82673 oKfN5XozNmr6mis=
82674 -----END CERTIFICATE-----
82675
82676 SwissSign Gold CA - G2
82677 ======================
82678 -----BEGIN CERTIFICATE-----
82679 MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
82680 EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
82681 MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
82682 c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
82683 AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
82684 t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
82685 jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
82686 vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
82687 ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
82688 AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
82689 jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
82690 peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
82691 7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
82692 GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
82693 AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
82694 OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
82695 L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
82696 5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
82697 44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
82698 Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
82699 Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
82700 mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
82701 vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
82702 KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
82703 NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
82704 viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
82705 -----END CERTIFICATE-----
82706
82707 SwissSign Silver CA - G2
82708 ========================
82709 -----BEGIN CERTIFICATE-----
82710 MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
82711 BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
82712 DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
82713 aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
82714 9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
82715 N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
82716 +/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
82717 6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
82718 MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
82719 qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
82720 FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
82721 ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
82722 celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
82723 CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
82724 BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
82725 tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
82726 cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
82727 4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
82728 kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
82729 3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
82730 /uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
82731 DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
82732 e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
82733 WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
82734 DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
82735 DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
82736 -----END CERTIFICATE-----
82737
82738 GeoTrust Primary Certification Authority
82739 ========================================
82740 -----BEGIN CERTIFICATE-----
82741 MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
82742 EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
82743 ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
82744 CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
82745 cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
82746 CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
82747 b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
82748 nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
82749 RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
82750 tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
82751 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
82752 hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
82753 Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
82754 NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
82755 Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
82756 1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
82757 -----END CERTIFICATE-----
82758
82759 thawte Primary Root CA
82760 ======================
82761 -----BEGIN CERTIFICATE-----
82762 MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
82763 BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
82764 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
82765 cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
82766 MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
82767 SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
82768 KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
82769 FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
82770 oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
82771 1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
82772 q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
82773 aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
82774 afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
82775 VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
82776 AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
82777 uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
82778 xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
82779 jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
82780 z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
82781 -----END CERTIFICATE-----
82782
82783 VeriSign Class 3 Public Primary Certification Authority - G5
82784 ============================================================
82785 -----BEGIN CERTIFICATE-----
82786 MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
82787 BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
82788 ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
82789 IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
82790 ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
82791 yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
82792 biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
82793 dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
82794 YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
82795 ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
82796 j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
82797 Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
82798 Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
82799 fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
82800 BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
82801 Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
82802 aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
82803 SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
82804 X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
82805 KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
82806 Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
82807 ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
82808 -----END CERTIFICATE-----
82809
82810 SecureTrust CA
82811 ==============
82812 -----BEGIN CERTIFICATE-----
82813 MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
82814 EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
82815 dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
82816 BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
82817 ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
82818 OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
82819 DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
82820 GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
82821 01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
82822 ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
82823 BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
82824 aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
82825 KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
82826 SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
82827 mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
82828 nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
82829 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
82830 -----END CERTIFICATE-----
82831
82832 Secure Global CA
82833 ================
82834 -----BEGIN CERTIFICATE-----
82835 MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
82836 EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
82837 bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
82838 MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
82839 Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
82840 YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
82841 bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
82842 8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
82843 HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
82844 0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
82845 EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
82846 oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
82847 MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
82848 OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
82849 CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
82850 3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
82851 f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
82852 -----END CERTIFICATE-----
82853
82854 COMODO Certification Authority
82855 ==============================
82856 -----BEGIN CERTIFICATE-----
82857 MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
82858 BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
82859 A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
82860 dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
82861 MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
82862 T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
82863 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
82864 +7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
82865 xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
82866 4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
82867 1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
82868 rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
82869 BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
82870 b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
82871 AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
82872 OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
82873 RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
82874 IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
82875 +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
82876 -----END CERTIFICATE-----
82877
82878 Network Solutions Certificate Authority
82879 =======================================
82880 -----BEGIN CERTIFICATE-----
82881 MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
82882 EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
82883 IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
82884 MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
82885 MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
82886 CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
82887 jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
82888 aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
82889 crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
82890 /Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
82891 AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
82892 BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
82893 bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
82894 A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
82895 4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
82896 GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
82897 wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
82898 ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
82899 -----END CERTIFICATE-----
82900
82901 WellsSecure Public Root Certificate Authority
82902 =============================================
82903 -----BEGIN CERTIFICATE-----
82904 MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM
82905 F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw
82906 NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN
82907 MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl
82908 bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD
82909 VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
82910 CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1
82911 iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13
82912 i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8
82913 bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB
82914 K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB
82915 AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu
82916 cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm
82917 lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB
82918 i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww
82919 GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
82920 Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI
82921 K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0
82922 bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj
82923 qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es
82924 E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ
82925 tylv2G0xffX8oRAHh84vWdw+WNs=
82926 -----END CERTIFICATE-----
82927
82928 COMODO ECC Certification Authority
82929 ==================================
82930 -----BEGIN CERTIFICATE-----
82931 MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
82932 R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
82933 ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
82934 dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
82935 GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
82936 Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
82937 b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
82938 4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
82939 wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
82940 BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
82941 FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
82942 U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
82943 -----END CERTIFICATE-----
82944
82945 Security Communication EV RootCA1
82946 =================================
82947 -----BEGIN CERTIFICATE-----
82948 MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
82949 U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh
82950 dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE
82951 BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl
82952 Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
82953 AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO
82954 /VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX
82955 WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z
82956 ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4
82957 bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK
82958 9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
82959 SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm
82960 iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG
82961 Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW
82962 mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW
82963 T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
82964 -----END CERTIFICATE-----
82965
82966 OISTE WISeKey Global Root GA CA
82967 ===============================
82968 -----BEGIN CERTIFICATE-----
82969 MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
82970 BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
82971 A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
82972 bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
82973 VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
82974 IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
82975 IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
82976 Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
82977 Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
82978 d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
82979 /yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
82980 LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
82981 AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
82982 KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
82983 MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
82984 +vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
82985 hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
82986 okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
82987 -----END CERTIFICATE-----
82988
82989 Microsec e-Szigno Root CA
82990 =========================
82991 -----BEGIN CERTIFICATE-----
82992 MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE
82993 BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL
82994 EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0
82995 MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz
82996 dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT
82997 GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
82998 AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG
82999 d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N
83000 oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc
83001 QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ
83002 PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb
83003 MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG
83004 IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD
83005 VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3
83006 LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A
83007 dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
83008 AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA
83009 4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg
83010 AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA
83011 egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6
83012 Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO
83013 PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv
83014 c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h
83015 cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw
83016 IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT
83017 WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV
83018 MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER
83019 MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp
83020 Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal
83021 HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT
83022 nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE
83023 aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
83024 86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK
83025 yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB
83026 S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
83027 -----END CERTIFICATE-----
83028
83029 Certigna
83030 ========
83031 -----BEGIN CERTIFICATE-----
83032 MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
83033 EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
83034 MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
83035 Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
83036 XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
83037 GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
83038 ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
83039 DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
83040 Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
83041 tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
83042 BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
83043 SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
83044 hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
83045 ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
83046 PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
83047 1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
83048 WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
83049 -----END CERTIFICATE-----
83050
83051 Deutsche Telekom Root CA 2
83052 ==========================
83053 -----BEGIN CERTIFICATE-----
83054 MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
83055 RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
83056 A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
83057 MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
83058 A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
83059 b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
83060 bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
83061 KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
83062 AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
83063 Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
83064 jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
83065 HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
83066 E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
83067 zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
83068 rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
83069 dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
83070 Cm26OWMohpLzGITY+9HPBVZkVw==
83071 -----END CERTIFICATE-----
83072
83073 Cybertrust Global Root
83074 ======================
83075 -----BEGIN CERTIFICATE-----
83076 MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
83077 ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
83078 MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
83079 ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
83080 +Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
83081 0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
83082 AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
83083 89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
83084 8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
83085 BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
83086 MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
83087 A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
83088 lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
83089 5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
83090 hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
83091 X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
83092 WL1WMRJOEcgh4LMRkWXbtKaIOM5V
83093 -----END CERTIFICATE-----
83094
83095 ePKI Root Certification Authority
83096 =================================
83097 -----BEGIN CERTIFICATE-----
83098 MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG
83099 EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg
83100 Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx
83101 MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq
83102 MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B
83103 AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs
83104 IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi
83105 lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv
83106 qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX
83107 12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
83108 WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+
83109 ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
83110 lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/
83111 vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi
83112 Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi
83113 MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
83114 ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0
83115 1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq
83116 KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV
83117 xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
83118 NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r
83119 GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE
83120 xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
83121 gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy
83122 sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD
83123 BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
83124 -----END CERTIFICATE-----
83125
83126 T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3
83127 =============================================================================================================================
83128 -----BEGIN CERTIFICATE-----
83129 MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH
83130 DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q
83131 aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry
83132 b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV
83133 BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg
83134 S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4
83135 MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl
83136 IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF
83137 n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl
83138 IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft
83139 dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl
83140 cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B
83141 AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO
83142 Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1
83143 xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR
83144 6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
83145 hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd
83146 BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
83147 MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4
83148 N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT
83149 y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh
83150 LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M
83151 dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI=
83152 -----END CERTIFICATE-----
83153
83154 certSIGN ROOT CA
83155 ================
83156 -----BEGIN CERTIFICATE-----
83157 MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
83158 VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
83159 Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
83160 CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
83161 JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
83162 rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
83163 ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
83164 0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
83165 AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
83166 Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
83167 AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
83168 SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
83169 x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
83170 vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
83171 TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
83172 -----END CERTIFICATE-----
83173
83174 CNNIC ROOT
83175 ==========
83176 -----BEGIN CERTIFICATE-----
83177 MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE
83178 ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw
83179 OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw
83180 ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD
83181 o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz
83182 VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT
83183 VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or
83184 czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK
83185 y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC
83186 wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S
83187 lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5
83188 Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM
83189 O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8
83190 BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2
83191 G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m
83192 mxE=
83193 -----END CERTIFICATE-----
83194
83195 ApplicationCA - Japanese Government
83196 ===================================
83197 -----BEGIN CERTIFICATE-----
83198 MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT
83199 SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw
83200 MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl
83201 cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
83202 CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4
83203 fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN
83204 wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE
83205 jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu
83206 nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU
83207 WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV
83208 BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD
83209 vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs
83210 o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g
83211 /DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD
83212 io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW
83213 dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
83214 rosot4LKGAfmt1t06SAZf7IbiVQ=
83215 -----END CERTIFICATE-----
83216
83217 GeoTrust Primary Certification Authority - G3
83218 =============================================
83219 -----BEGIN CERTIFICATE-----
83220 MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
83221 BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
83222 IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
83223 eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
83224 NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
83225 YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
83226 LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
83227 hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
83228 K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
83229 c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
83230 IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
83231 dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
83232 MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
83233 2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
83234 cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
83235 Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
83236 AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
83237 t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
83238 -----END CERTIFICATE-----
83239
83240 thawte Primary Root CA - G2
83241 ===========================
83242 -----BEGIN CERTIFICATE-----
83243 MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
83244 VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
83245 IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
83246 Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
83247 MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
83248 b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
83249 IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
83250 LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
83251 8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
83252 mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
83253 G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
83254 rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
83255 -----END CERTIFICATE-----
83256
83257 thawte Primary Root CA - G3
83258 ===========================
83259 -----BEGIN CERTIFICATE-----
83260 MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
83261 BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
83262 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
83263 cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
83264 ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
83265 d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
83266 VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
83267 A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
83268 MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
83269 P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
83270 +BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
83271 7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
83272 vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
83273 BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
83274 KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
83275 A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
83276 t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
83277 8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
83278 er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
83279 -----END CERTIFICATE-----
83280
83281 GeoTrust Primary Certification Authority - G2
83282 =============================================
83283 -----BEGIN CERTIFICATE-----
83284 MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
83285 VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
83286 Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
83287 ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
83288 OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
83289 MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
83290 b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
83291 BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
83292 KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
83293 VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
83294 EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
83295 ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
83296 npaqBA+K
83297 -----END CERTIFICATE-----
83298
83299 VeriSign Universal Root Certification Authority
83300 ===============================================
83301 -----BEGIN CERTIFICATE-----
83302 MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
83303 BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
83304 ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
83305 IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
83306 IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
83307 UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
83308 cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
83309 IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
83310 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
83311 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
83312 MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
83313 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
83314 AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
83315 tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
83316 CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
83317 a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
83318 DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
83319 Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
83320 Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
83321 P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
83322 wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
83323 mJO37M2CYfE45k+XmCpajQ==
83324 -----END CERTIFICATE-----
83325
83326 VeriSign Class 3 Public Primary Certification Authority - G4
83327 ============================================================
83328 -----BEGIN CERTIFICATE-----
83329 MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
83330 VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
83331 b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
83332 ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
83333 YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
83334 MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
83335 cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
83336 b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
83337 IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
83338 Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
83339 rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
83340 /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
83341 HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
83342 Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
83343 A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
83344 AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
83345 -----END CERTIFICATE-----
83346
83347 NetLock Arany (Class Gold) Főtanúsítvány
83348 ========================================
83349 -----BEGIN CERTIFICATE-----
83350 MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
83351 A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
83352 dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
83353 cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
83354 MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
83355 ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
83356 biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
83357 c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
83358 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
83359 /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
83360 H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
83361 fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
83362 neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
83363 BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
83364 qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
83365 YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
83366 bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
83367 NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
83368 dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
83369 -----END CERTIFICATE-----
83370
83371 Staat der Nederlanden Root CA - G2
83372 ==================================
83373 -----BEGIN CERTIFICATE-----
83374 MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
83375 CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
83376 Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC
83377 TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
83378 ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ
83379 5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn
83380 vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj
83381 CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil
83382 e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR
83383 OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI
83384 CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65
83385 48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi
83386 trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737
83387 qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB
83388 AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC
83389 ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
83390 HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA
83391 A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz
83392 +51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj
83393 f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN
83394 kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk
83395 CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF
83396 URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb
83397 CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h
83398 oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV
83399 IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
83400 66+KAQ==
83401 -----END CERTIFICATE-----
83402
83403 Hongkong Post Root CA 1
83404 =======================
83405 -----BEGIN CERTIFICATE-----
83406 MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
83407 DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
83408 NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
83409 IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
83410 AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
83411 ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
83412 auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
83413 qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
83414 V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
83415 HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
83416 h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
83417 l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
83418 IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
83419 T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
83420 c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
83421 -----END CERTIFICATE-----
83422
83423 SecureSign RootCA11
83424 ===================
83425 -----BEGIN CERTIFICATE-----
83426 MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
83427 SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
83428 b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
83429 KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
83430 cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
83431 TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
83432 wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
83433 g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
83434 O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
83435 bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
83436 t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
83437 OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
83438 bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
83439 Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
83440 y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
83441 lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
83442 -----END CERTIFICATE-----
83443
83444 ACEDICOM Root
83445 =============
83446 -----BEGIN CERTIFICATE-----
83447 MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD
83448 T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4
83449 MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG
83450 A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF
83451 AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk
83452 WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD
83453 YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew
83454 MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb
83455 m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk
83456 HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT
83457 xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2
83458 3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9
83459 2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq
83460 TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz
83461 4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU
83462 9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
83463 bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg
83464 aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP
83465 eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk
83466 zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1
83467 ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI
83468 KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq
83469 nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE
83470 I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp
83471 MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o
83472 tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA==
83473 -----END CERTIFICATE-----
83474
83475 Microsec e-Szigno Root CA 2009
83476 ==============================
83477 -----BEGIN CERTIFICATE-----
83478 MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
83479 MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
83480 c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
83481 dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
83482 BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
83483 U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
83484 DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
83485 fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
83486 0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
83487 pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
83488 1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
83489 AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
83490 QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
83491 FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
83492 lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
83493 I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
83494 tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
83495 yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
83496 LXpUq3DDfSJlgnCW
83497 -----END CERTIFICATE-----
83498
83499 GlobalSign Root CA - R3
83500 =======================
83501 -----BEGIN CERTIFICATE-----
83502 MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
83503 YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
83504 bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
83505 aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
83506 bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
83507 iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
83508 0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
83509 rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
83510 OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
83511 xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
83512 FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
83513 lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
83514 EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
83515 bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
83516 YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
83517 kpeDMdmztcpHWD9f
83518 -----END CERTIFICATE-----
83519
83520 Autoridad de Certificacion Firmaprofesional CIF A62634068
83521 =========================================================
83522 -----BEGIN CERTIFICATE-----
83523 MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
83524 BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
83525 MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
83526 QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
83527 NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
83528 Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
83529 B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
83530 7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
83531 ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
83532 plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
83533 MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
83534 LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
83535 bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
83536 vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
83537 EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
83538 DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
83539 cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
83540 bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
83541 ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
83542 51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
83543 R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
83544 T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
83545 Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
83546 osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
83547 crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
83548 saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
83549 KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
83550 6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
83551 -----END CERTIFICATE-----
83552
83553 Izenpe.com
83554 ==========
83555 -----BEGIN CERTIFICATE-----
83556 MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG
83557 EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
83558 MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu
83559 QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ
83560 03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
83561 ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU
83562 +zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC
83563 PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT
83564 OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK
83565 F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
83566 0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+
83567 0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB
83568 leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID
83569 AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+
83570 SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG
83571 NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
83572 MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
83573 BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l
83574 Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
83575 kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q
83576 hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs
83577 g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
83578 aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5
83579 nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC
83580 ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo
83581 Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z
83582 WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
83583 -----END CERTIFICATE-----
83584
83585 Chambers of Commerce Root - 2008
83586 ================================
83587 -----BEGIN CERTIFICATE-----
83588 MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD
83589 MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
83590 bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
83591 QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy
83592 Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl
83593 ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF
83594 EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl
83595 cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
83596 AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA
83597 XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj
83598 h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/
83599 ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk
83600 NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g
83601 D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331
83602 lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ
83603 0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
83604 ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2
83605 EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI
83606 G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ
83607 BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh
83608 bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh
83609 bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC
83610 CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH
83611 AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1
83612 wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH
83613 3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU
83614 RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6
83615 M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1
83616 YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF
83617 9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK
83618 zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG
83619 nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
83620 OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ
83621 -----END CERTIFICATE-----
83622
83623 Global Chambersign Root - 2008
83624 ==============================
83625 -----BEGIN CERTIFICATE-----
83626 MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD
83627 MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
83628 bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
83629 QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx
83630 NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg
83631 Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ
83632 QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
83633 aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf
83634 VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf
83635 XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0
83636 ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB
83637 /gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA
83638 TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M
83639 H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe
83640 Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF
83641 HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
83642 wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB
83643 AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT
83644 BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE
83645 BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm
83646 aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm
83647 aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp
83648 1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0
83649 dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG
83650 /5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6
83651 ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s
83652 dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg
83653 9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH
83654 foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du
83655 qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr
83656 P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq
83657 c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
83658 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
83659 -----END CERTIFICATE-----
83660
83661 Go Daddy Root Certificate Authority - G2
83662 ========================================
83663 -----BEGIN CERTIFICATE-----
83664 MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
83665 B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
83666 MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
83667 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
83668 b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
83669 A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
83670 hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
83671 9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
83672 +qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
83673 fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
83674 NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
83675 MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
83676 BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
83677 vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
83678 5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
83679 N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
83680 LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
83681 -----END CERTIFICATE-----
83682
83683 Starfield Root Certificate Authority - G2
83684 =========================================
83685 -----BEGIN CERTIFICATE-----
83686 MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
83687 B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
83688 b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
83689 eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
83690 DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
83691 VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
83692 dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
83693 W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
83694 bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
83695 N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
83696 ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
83697 JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
83698 AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
83699 TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
83700 4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
83701 F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
83702 pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
83703 c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
83704 -----END CERTIFICATE-----
83705
83706 Starfield Services Root Certificate Authority - G2
83707 ==================================================
83708 -----BEGIN CERTIFICATE-----
83709 MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
83710 B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
83711 b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
83712 IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
83713 BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
83714 dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
83715 Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
83716 AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
83717 h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
83718 hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
83719 LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
83720 rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
83721 AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
83722 SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
83723 E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
83724 xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
83725 iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
83726 YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
83727 -----END CERTIFICATE-----
83728
83729 AffirmTrust Commercial
83730 ======================
83731 -----BEGIN CERTIFICATE-----
83732 MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
83733 BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
83734 MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
83735 bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
83736 AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
83737 DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
83738 C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
83739 BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
83740 MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
83741 HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
83742 AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
83743 hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
83744 qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
83745 0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
83746 sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
83747 -----END CERTIFICATE-----
83748
83749 AffirmTrust Networking
83750 ======================
83751 -----BEGIN CERTIFICATE-----
83752 MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
83753 BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
83754 MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
83755 bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
83756 AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
83757 Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
83758 dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
83759 /PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
83760 h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
83761 HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
83762 AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
83763 UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
83764 12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
83765 WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
83766 /ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
83767 -----END CERTIFICATE-----
83768
83769 AffirmTrust Premium
83770 ===================
83771 -----BEGIN CERTIFICATE-----
83772 MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS
83773 BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy
83774 OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy
83775 dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
83776 MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn
83777 BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV
83778 5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs
83779 +7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd
83780 GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R
83781 p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI
83782 S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04
83783 6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5
83784 /bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo
83785 +Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB
83786 /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv
83787 MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
83788 Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC
83789 6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S
83790 L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK
83791 +4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV
83792 BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg
83793 IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60
83794 g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb
83795 zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==
83796 -----END CERTIFICATE-----
83797
83798 AffirmTrust Premium ECC
83799 =======================
83800 -----BEGIN CERTIFICATE-----
83801 MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
83802 BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
83803 MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
83804 cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
83805 IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
83806 N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
83807 BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
83808 BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
83809 57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
83810 eQ==
83811 -----END CERTIFICATE-----
83812
83813 Certum Trusted Network CA
83814 =========================
83815 -----BEGIN CERTIFICATE-----
83816 MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
83817 ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
83818 biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
83819 MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
83820 ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
83821 MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
83822 AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
83823 l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
83824 J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
83825 fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
83826 cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
83827 Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
83828 DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
83829 jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
83830 mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
83831 Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
83832 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
83833 -----END CERTIFICATE-----
83834
83835 Certinomis - Autorité Racine
83836 ============================
83837 -----BEGIN CERTIFICATE-----
83838 MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
83839 Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg
83840 LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG
83841 A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw
83842 JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD
83843 ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa
83844 wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly
83845 Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw
83846 2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N
83847 jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q
83848 c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC
83849 lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb
83850 xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g
83851 530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna
83852 4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
83853 A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
83854 KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x
83855 WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva
83856 R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40
83857 nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B
83858 CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv
83859 JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE
83860 qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b
83861 WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE
83862 wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/
83863 vgt2Fl43N+bYdJeimUV5
83864 -----END CERTIFICATE-----
83865
83866 TWCA Root Certification Authority
83867 =================================
83868 -----BEGIN CERTIFICATE-----
83869 MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
83870 VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
83871 dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
83872 EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
83873 IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
83874 AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
83875 QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
83876 oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
83877 4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
83878 y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
83879 BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
83880 9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
83881 mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
83882 QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
83883 T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
83884 Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
83885 -----END CERTIFICATE-----
83886
83887 Security Communication RootCA2
83888 ==============================
83889 -----BEGIN CERTIFICATE-----
83890 MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
83891 U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
83892 dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
83893 SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
83894 aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
83895 ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
83896 +T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
83897 3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
83898 spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
83899 EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
83900 QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
83901 CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
83902 u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
83903 3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
83904 tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
83905 mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
83906 -----END CERTIFICATE-----
83907
83908 EC-ACC
83909 ======
83910 -----BEGIN CERTIFICATE-----
83911 MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
83912 BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
83913 ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
83914 VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
83915 CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
83916 BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
83917 MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
83918 SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
83919 Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
83920 cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
83921 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
83922 w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
83923 ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
83924 HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
83925 E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
83926 0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
83927 BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
83928 VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
83929 Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
83930 dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
83931 lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
83932 Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
83933 l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
83934 E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
83935 5EI=
83936 -----END CERTIFICATE-----
83937
83938 Hellenic Academic and Research Institutions RootCA 2011
83939 =======================================================
83940 -----BEGIN CERTIFICATE-----
83941 MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
83942 O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
83943 aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
83944 IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
83945 AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
83946 IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
83947 IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
83948 AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
83949 1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
83950 71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
83951 8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
83952 3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
83953 MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
83954 MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
83955 b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
83956 XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
83957 TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
83958 /md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
83959 7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
83960 -----END CERTIFICATE-----
83961
83962 Actalis Authentication Root CA
83963 ==============================
83964 -----BEGIN CERTIFICATE-----
83965 MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
83966 BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
83967 AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
83968 MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
83969 IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
83970 IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
83971 wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
83972 by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
83973 zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
83974 YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
83975 oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
83976 EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
83977 hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
83978 EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
83979 jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
83980 iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
83981 ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
83982 WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
83983 JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
83984 K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
83985 Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
83986 4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
83987 2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
83988 lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
83989 OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
83990 vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
83991 -----END CERTIFICATE-----
83992
83993 Trustis FPS Root CA
83994 ===================
83995 -----BEGIN CERTIFICATE-----
83996 MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG
83997 EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290
83998 IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV
83999 BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ
84000 KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ
84001 RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk
84002 H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa
84003 cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt
84004 o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA
84005 AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd
84006 BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c
84007 GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC
84008 yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P
84009 8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV
84010 l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl
84011 iB6XzCGcKQENZetX2fNXlrtIzYE=
84012 -----END CERTIFICATE-----
84013
84014 StartCom Certification Authority
84015 ================================
84016 -----BEGIN CERTIFICATE-----
84017 MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
84018 U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
84019 ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
84020 NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
84021 LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
84022 U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
84023 ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
84024 o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
84025 Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
84026 eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
84027 2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
84028 6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
84029 osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
84030 untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
84031 UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
84032 37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
84033 VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ
84034 Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0
84035 dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu
84036 c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv
84037 bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0
84038 aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0
84039 aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
84040 L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG
84041 cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5
84042 fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm
84043 N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN
84044 Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T
84045 tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX
84046 e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA
84047 2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs
84048 HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
84049 JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib
84050 D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8=
84051 -----END CERTIFICATE-----
84052
84053 StartCom Certification Authority G2
84054 ===================================
84055 -----BEGIN CERTIFICATE-----
84056 MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
84057 U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
84058 RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE
84059 ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp
84060 dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O
84061 o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG
84062 4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi
84063 Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul
84064 Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs
84065 O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H
84066 vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L
84067 nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS
84068 FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa
84069 z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E
84070 BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ
84071 KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
84072 2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk
84073 J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+
84074 JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG
84075 /+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc
84076 nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld
84077 blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc
84078 l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm
84079 7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm
84080 obp573PYtlNXLfbQ4ddI
84081 -----END CERTIFICATE-----
84082
84083 Buypass Class 2 Root CA
84084 =======================
84085 -----BEGIN CERTIFICATE-----
84086 MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
84087 QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X
84088 DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
84089 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw
84090 DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1
84091 g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn
84092 9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b
84093 /+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU
84094 CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff
84095 awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI
84096 zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn
84097 Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX
84098 Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs
84099 M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
84100 VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
84101 AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
84102 A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI
84103 osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S
84104 aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd
84105 DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD
84106 LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0
84107 oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC
84108 wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS
84109 CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN
84110 rJgWVqA=
84111 -----END CERTIFICATE-----
84112
84113 Buypass Class 3 Root CA
84114 =======================
84115 -----BEGIN CERTIFICATE-----
84116 MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
84117 QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X
84118 DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
84119 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw
84120 DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH
84121 sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR
84122 5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh
84123 7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ
84124 ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH
84125 2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV
84126 /afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ
84127 RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA
84128 Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq
84129 j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
84130 VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
84131 AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
84132 cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G
84133 uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG
84134 Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8
84135 ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2
84136 KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz
84137 6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug
84138 UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe
84139 eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi
84140 Cp/HuZc=
84141 -----END CERTIFICATE-----
84142
84143 T-TeleSec GlobalRoot Class 3
84144 ============================
84145 -----BEGIN CERTIFICATE-----
84146 MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
84147 IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
84148 cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx
84149 MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
84150 dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
84151 ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3
84152 DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK
84153 9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU
84154 NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF
84155 iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W
84156 0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA
84157 MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr
84158 AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb
84159 fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT
84160 ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h
84161 P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
84162 e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==
84163 -----END CERTIFICATE-----
84164
84165 EE Certification Centre Root CA
84166 ===============================
84167 -----BEGIN CERTIFICATE-----
84168 MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
84169 EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy
84170 dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw
84171 MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB
84172 UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy
84173 ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
84174 DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM
84175 TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2
84176 rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw
84177 93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN
84178 P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T
84179 AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ
84180 MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF
84181 BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj
84182 xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM
84183 lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
84184 uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU
84185 3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM
84186 dcGWxZ0=
84187 -----END CERTIFICATE-----
84188
84189 TURKTRUST Certificate Services Provider Root 2007
84190 =================================================
84191 -----BEGIN CERTIFICATE-----
84192 MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
84193 bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
84194 MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
84195 QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X
84196 DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl
84197 a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN
84198 BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
84199 bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw
84200 DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N
84201 YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv
84202 KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya
84203 KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT
84204 rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC
84205 AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP
84206 BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s
84207 Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
84208 aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO
84209 Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb
84210 BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK
84211 poRq0Tl9
84212 -----END CERTIFICATE-----
84213
84214 D-TRUST Root Class 3 CA 2 2009
84215 ==============================
84216 -----BEGIN CERTIFICATE-----
84217 MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK
84218 DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe
84219 Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE
84220 LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw
84221 DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD
84222 ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA
84223 BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv
84224 KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z
84225 p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC
84226 AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ
84227 4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y
84228 eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw
84229 MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G
84230 PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw
84231 OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm
84232 2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
84233 o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV
84234 dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph
84235 X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I=
84236 -----END CERTIFICATE-----
84237
84238 D-TRUST Root Class 3 CA 2 EV 2009
84239 =================================
84240 -----BEGIN CERTIFICATE-----
84241 MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
84242 DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
84243 OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
84244 DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
84245 OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS
84246 egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh
84247 zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T
84248 7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60
84249 sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35
84250 11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv
84251 cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v
84252 ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El
84253 MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp
84254 b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh
84255 c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+
84256 PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
84257 nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX
84258 ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA
84259 NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv
84260 w9y4AyHqnxbxLFS1
84261 -----END CERTIFICATE-----
84262
84263 PSCProcert
84264 ==========
84265 -----BEGIN CERTIFICATE-----
84266 MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk
84267 ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ
84268 MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz
84269 dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl
84270 cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw
84271 IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw
84272 MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w
84273 DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD
84274 ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp
84275 Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw
84276 DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC
84277 wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA
84278 3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh
84279 RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO
84280 EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2
84281 0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH
84282 0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU
84283 td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw
84284 Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp
84285 r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/
84286 AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz
84287 Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId
84288 xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp
84289 ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH
84290 EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h
84291 Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k
84292 ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG
84293 9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG
84294 MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG
84295 LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52
84296 ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy
84297 YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v
84298 Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o
84299 dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq
84300 T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN
84301 g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q
84302 uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1
84303 n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn
84304 FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo
84305 5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq
84306 3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5
84307 poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y
84308 eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
84309 -----END CERTIFICATE-----
84310
84311 China Internet Network Information Center EV Certificates Root
84312 ==============================================================
84313 -----BEGIN CERTIFICATE-----
84314 MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV
84315 BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D
84316 aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg
84317 Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG
84318 A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM
84319 PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl
84320 cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y
84321 jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV
84322 98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H
84323 klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23
84324 KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC
84325 7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV
84326 HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD
84327 glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5
84328 0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM
84329 7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
84330 ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0
84331 5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8=
84332 -----END CERTIFICATE-----
84333
84334 Swisscom Root CA 2
84335 ==================
84336 -----BEGIN CERTIFICATE-----
84337 MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG
84338 EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy
84339 dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2
84340 MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln
84341 aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC
84342 IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM
84343 LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo
84344 ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ
84345 wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH
84346 Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a
84347 SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS
84348 NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab
84349 mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY
84350 Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3
84351 qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw
84352 HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
84353 BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu
84354 MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO
84355 v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ
84356 82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz
84357 o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs
84358 a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx
84359 OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW
84360 mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o
84361 +sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC
84362 rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX
84363 5OfNeOI5wSsSnqaeG8XmDtkx2Q==
84364 -----END CERTIFICATE-----
84365
84366 Swisscom Root EV CA 2
84367 =====================
84368 -----BEGIN CERTIFICATE-----
84369 MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE
84370 BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl
84371 cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN
84372 MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT
84373 HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg
84374 Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz
84375 o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy
84376 Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti
84377 GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li
84378 qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH
84379 Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG
84380 alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa
84381 m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox
84382 bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi
84383 xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/
84384 BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
84385 MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB
84386 bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL
84387 j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU
84388 wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7
84389 XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH
84390 59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/
84391 23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq
84392 J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA
84393 HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi
84394 uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW
84395 l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc=
84396 -----END CERTIFICATE-----
84397
84398 CA Disig Root R1
84399 ================
84400 -----BEGIN CERTIFICATE-----
84401 MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw
84402 EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp
84403 ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx
84404 EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp
84405 c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy
84406 3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8
84407 u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2
84408 m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk
84409 CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa
84410 YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6
84411 vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL
84412 LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX
84413 ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is
84414 XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV
84415 HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ
84416 04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
84417 xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B
84418 LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM
84419 CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb
84420 VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85
84421 YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS
84422 ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix
84423 lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N
84424 UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ
84425 a7+h89n07eLw4+1knj0vllJPgFOL
84426 -----END CERTIFICATE-----
84427
84428 CA Disig Root R2
84429 ================
84430 -----BEGIN CERTIFICATE-----
84431 MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw
84432 EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp
84433 ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx
84434 EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp
84435 c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC
84436 w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia
84437 xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7
84438 A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S
84439 GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV
84440 g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa
84441 5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE
84442 koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A
84443 Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i
84444 Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV
84445 HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u
84446 Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
84447 tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV
84448 sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je
84449 dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8
84450 1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx
84451 mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01
84452 utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0
84453 sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg
84454 UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV
84455 7+ZtsH8tZ/3zbBt1RqPlShfppNcL
84456 -----END CERTIFICATE-----
84457
84458 ACCVRAIZ1
84459 =========
84460 -----BEGIN CERTIFICATE-----
84461 MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB
84462 SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1
84463 MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH
84464 UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
84465 DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM
84466 jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0
84467 RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD
84468 aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ
84469 0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG
84470 WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7
84471 8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR
84472 5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J
84473 9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK
84474 Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw
84475 Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu
84476 Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
84477 VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM
84478 Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA
84479 QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh
84480 AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA
84481 YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj
84482 AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA
84483 IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk
84484 aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0
84485 dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2
84486 MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI
84487 hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E
84488 R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN
84489 YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49
84490 nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ
84491 TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3
84492 sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
84493 I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg
84494 Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd
84495 3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p
84496 EfbRD0tVNEYqi4Y7
84497 -----END CERTIFICATE-----
84498
84499 TWCA Global Root CA
84500 ===================
84501 -----BEGIN CERTIFICATE-----
84502 MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT
84503 CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD
84504 QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK
84505 EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg
84506 Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C
84507 nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV
84508 r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR
84509 Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV
84510 tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W
84511 KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99
84512 sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p
84513 yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn
84514 kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI
84515 zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC
84516 AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g
84517 cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
84518 LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M
84519 8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg
84520 /eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg
84521 lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP
84522 A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m
84523 i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8
84524 EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3
84525 zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=
84526 -----END CERTIFICATE-----
84527
84528 TeliaSonera Root CA v1
84529 ======================
84530 -----BEGIN CERTIFICATE-----
84531 MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE
84532 CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4
84533 MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW
84534 VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+
84535 6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA
84536 3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k
84537 B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn
84538 Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH
84539 oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3
84540 F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ
84541 oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7
84542 gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc
84543 TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB
84544 AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW
84545 DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm
84546 zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
84547 0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW
84548 pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV
84549 G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc
84550 c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT
84551 JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2
84552 qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6
84553 Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems
84554 WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
84555 -----END CERTIFICATE-----
84556
84557 E-Tugra Certification Authority
84558 ===============================
84559 -----BEGIN CERTIFICATE-----
84560 MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w
84561 DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls
84562 ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
84563 ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw
84564 NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx
84565 QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl
84566 cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD
84567 DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
84568 MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd
84569 hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K
84570 CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g
84571 ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ
84572 BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0
84573 E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz
84574 rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq
84575 jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
84576 rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5
84577 dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB
84578 /wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG
84579 MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK
84580 kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO
84581 XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807
84582 VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo
84583 a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc
84584 dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV
84585 KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT
84586 Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0
84587 8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G
84588 C7TbO6Orb1wdtn7os4I07QZcJA==
84589 -----END CERTIFICATE-----
84590
84591 T-TeleSec GlobalRoot Class 2
84592 ============================
84593 -----BEGIN CERTIFICATE-----
84594 MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
84595 IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
84596 cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx
84597 MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
84598 dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
84599 ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3
84600 DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ
84601 SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F
84602 vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970
84603 2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV
84604 WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA
84605 MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy
84606 YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4
84607 r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf
84608 vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR
84609 3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
84610 9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==
84611 -----END CERTIFICATE-----
84612
84613 Atos TrustedRoot 2011
84614 =====================
84615 -----BEGIN CERTIFICATE-----
84616 MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU
84617 cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4
84618 MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG
84619 A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
84620 hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr
84621 54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+
84622 DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320
84623 HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR
84624 z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R
84625 l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ
84626 bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
84627 CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h
84628 k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh
84629 TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9
84630 61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G
84631 3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
84632 -----END CERTIFICATE-----
84633
84634 QuoVadis Root CA 1 G3
84635 =====================
84636 -----BEGIN CERTIFICATE-----
84637 MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG
84638 A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
84639 b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN
84640 MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg
84641 RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE
84642 PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm
84643 PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6
84644 Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN
84645 ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l
84646 g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV
84647 7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX
84648 9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f
84649 iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg
84650 t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
84651 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI
84652 hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
84653 MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3
84654 GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct
84655 Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP
84656 +V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh
84657 3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa
84658 wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6
84659 O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0
84660 FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV
84661 hMJKzRwuJIczYOXD
84662 -----END CERTIFICATE-----
84663
84664 QuoVadis Root CA 2 G3
84665 =====================
84666 -----BEGIN CERTIFICATE-----
84667 MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG
84668 A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
84669 b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN
84670 MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg
84671 RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh
84672 ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY
84673 NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t
84674 oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o
84675 MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l
84676 V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo
84677 L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ
84678 sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD
84679 6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh
84680 lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
84681 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI
84682 hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
84683 AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K
84684 pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9
84685 x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz
84686 dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X
84687 U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw
84688 mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD
84689 zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN
84690 JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr
84691 O3jtZsSOeWmD3n+M
84692 -----END CERTIFICATE-----
84693
84694 QuoVadis Root CA 3 G3
84695 =====================
84696 -----BEGIN CERTIFICATE-----
84697 MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG
84698 A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
84699 b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN
84700 MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg
84701 RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286
84702 IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL
84703 Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe
84704 6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3
84705 I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U
84706 VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7
84707 5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi
84708 Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM
84709 dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt
84710 rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
84711 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI
84712 hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
84713 KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS
84714 t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ
84715 TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du
84716 DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib
84717 Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD
84718 hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX
84719 0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW
84720 dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2
84721 PpxxVJkES/1Y+Zj0
84722 -----END CERTIFICATE-----
84723
84724 DigiCert Assured ID Root G2
84725 ===========================
84726 -----BEGIN CERTIFICATE-----
84727 MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG
84728 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
84729 IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw
84730 MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
84731 ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw
84732 ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH
84733 35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq
84734 bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw
84735 VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP
84736 YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn
84737 lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO
84738 w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv
84739 0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz
84740 d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW
84741 hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M
84742 jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
84743 IhNzbM8m9Yop5w==
84744 -----END CERTIFICATE-----
84745
84746 DigiCert Assured ID Root G3
84747 ===========================
84748 -----BEGIN CERTIFICATE-----
84749 MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
84750 UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD
84751 VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
84752 MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
84753 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ
84754 BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb
84755 RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs
84756 KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF
84757 UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy
84758 YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy
84759 1vUhZscv6pZjamVFkpUBtA==
84760 -----END CERTIFICATE-----
84761
84762 DigiCert Global Root G2
84763 =======================
84764 -----BEGIN CERTIFICATE-----
84765 MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG
84766 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
84767 HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx
84768 MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
84769 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq
84770 hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ
84771 kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO
84772 3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV
84773 BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM
84774 UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB
84775 o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu
84776 5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr
84777 F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U
84778 WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH
84779 QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/
84780 iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
84781 MrY=
84782 -----END CERTIFICATE-----
84783
84784 DigiCert Global Root G3
84785 =======================
84786 -----BEGIN CERTIFICATE-----
84787 MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV
84788 UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD
84789 VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw
84790 MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
84791 aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C
84792 AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O
84793 YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP
84794 BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp
84795 Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y
84796 3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34
84797 VOKa5Vt8sycX
84798 -----END CERTIFICATE-----
84799
84800 DigiCert Trusted Root G4
84801 ========================
84802 -----BEGIN CERTIFICATE-----
84803 MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG
84804 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw
84805 HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
84806 MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
84807 d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G
84808 CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp
84809 pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o
84810 k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa
84811 vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
84812 QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6
84813 MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm
84814 mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7
84815 f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH
84816 dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8
84817 oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
84818 DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
84819 ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY
84820 ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr
84821 yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy
84822 7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah
84823 ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN
84824 5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb
84825 /UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa
84826 5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK
84827 G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP
84828 82Z+
84829 -----END CERTIFICATE-----
84830
84831 WoSign
84832 ======
84833 -----BEGIN CERTIFICATE-----
84834 MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG
84835 EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g
84836 QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ
84837 BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh
84838 dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
84839 vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO
84840 CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX
84841 2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5
84842 KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR
84843 +ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez
84844 EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk
84845 lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2
84846 8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY
84847 yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C
84848 AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R
84849 8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
84850 LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq
84851 T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj
84852 y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC
84853 2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes
84854 5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/
84855 EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh
84856 mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx
84857 kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi
84858 kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w==
84859 -----END CERTIFICATE-----
84860
84861 WoSign China
84862 ============
84863 -----BEGIN CERTIFICATE-----
84864 MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG
84865 EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv
84866 geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD
84867 VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN
84868 BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k
84869 8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5
84870 uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85
84871 dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5
84872 Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy
84873 b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc
84874 76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m
84875 +Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6
84876 yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX
84877 GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
84878 EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA
84879 A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
84880 yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY
84881 r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115
84882 j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A
84883 kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97
84884 qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y
84885 jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB
84886 ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv
84887 T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO
84888 kI26oQ==
84889 -----END CERTIFICATE-----
84890
84891 COMODO RSA Certification Authority
84892 ==================================
84893 -----BEGIN CERTIFICATE-----
84894 MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE
84895 BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
84896 A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv
84897 biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC
84898 R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
84899 ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB
84900 dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn
84901 dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ
84902 FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+
84903 5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG
84904 x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX
84905 2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL
84906 OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3
84907 sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C
84908 GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5
84909 WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
84910 FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
84911 DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt
84912 rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+
84913 nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg
84914 tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW
84915 sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp
84916 pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA
84917 zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq
84918 ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52
84919 7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I
84920 LaZRfyHBNVOFBkpdn627G190
84921 -----END CERTIFICATE-----
84922
84923 USERTrust RSA Certification Authority
84924 =====================================
84925 -----BEGIN CERTIFICATE-----
84926 MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE
84927 BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
84928 ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
84929 dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE
84930 BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
84931 ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
84932 dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz
84933 0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j
84934 Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn
84935 RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O
84936 +T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq
84937 /nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE
84938 Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM
84939 lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8
84940 yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+
84941 eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
84942 BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
84943 MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW
84944 FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ
84945 7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ
84946 Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM
84947 8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi
84948 FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi
84949 yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c
84950 J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw
84951 sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx
84952 Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
84953 -----END CERTIFICATE-----
84954
84955 USERTrust ECC Certification Authority
84956 =====================================
84957 -----BEGIN CERTIFICATE-----
84958 MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC
84959 VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
84960 aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
84961 biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC
84962 VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
84963 aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
84964 biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2
84965 0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez
84966 nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV
84967 HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB
84968 HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu
84969 9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
84970 -----END CERTIFICATE-----
84971
84972 GlobalSign ECC Root CA - R4
84973 ===========================
84974 -----BEGIN CERTIFICATE-----
84975 MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb
84976 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
84977 EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
84978 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
84979 EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl
84980 OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P
84981 AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV
84982 MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF
84983 JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=
84984 -----END CERTIFICATE-----
84985
84986 GlobalSign ECC Root CA - R5
84987 ===========================
84988 -----BEGIN CERTIFICATE-----
84989 MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb
84990 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
84991 EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
84992 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
84993 EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6
84994 SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS
84995 h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
84996 BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx
84997 uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7
84998 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3
84999 -----END CERTIFICATE-----
85000
85001 Staat der Nederlanden Root CA - G3
85002 ==================================
85003 -----BEGIN CERTIFICATE-----
85004 MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
85005 CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
85006 Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC
85007 TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
85008 ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y
85009 olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t
85010 x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy
85011 EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K
85012 Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur
85013 mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5
85014 1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp
85015 07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo
85016 FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE
85017 41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB
85018 AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu
85019 yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
85020 U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq
85021 KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1
85022 v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA
85023 8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b
85024 8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r
85025 mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq
85026 1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI
85027 JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV
85028 tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk=
85029 -----END CERTIFICATE-----
85030
85031 Staat der Nederlanden EV Root CA
85032 ================================
85033 -----BEGIN CERTIFICATE-----
85034 MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE
85035 CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
85036 RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M
85037 MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl
85038 cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk
85039 SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW
85040 O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r
85041 0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8
85042 Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV
85043 XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr
85044 08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV
85045 0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd
85046 74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx
85047 fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC
85048 MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa
85049 ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
85050 eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu
85051 c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq
85052 5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN
85053 b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN
85054 f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi
85055 5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4
85056 WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK
85057 DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy
85058 eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==
85059 -----END CERTIFICATE-----
85060
85061 IdenTrust Commercial Root CA 1
85062 ==============================
85063 -----BEGIN CERTIFICATE-----
85064 MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG
85065 EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS
85066 b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES
85067 MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB
85068 IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld
85069 hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/
85070 mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi
85071 1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C
85072 XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl
85073 3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy
85074 NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV
85075 WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg
85076 xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix
85077 uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
85078 AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI
85079 hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
85080 6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg
85081 ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt
85082 ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV
85083 YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX
85084 feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro
85085 kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe
85086 2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz
85087 Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R
85088 cGzM7vRX+Bi6hG6H
85089 -----END CERTIFICATE-----
85090
85091 IdenTrust Public Sector Root CA 1
85092 =================================
85093 -----BEGIN CERTIFICATE-----
85094 MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG
85095 EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv
85096 ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV
85097 UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS
85098 b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy
85099 P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6
85100 Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI
85101 rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf
85102 qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS
85103 mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn
85104 ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh
85105 LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v
85106 iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL
85107 4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B
85108 Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw
85109 DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
85110 t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A
85111 mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt
85112 GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt
85113 m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx
85114 NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4
85115 Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI
85116 ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC
85117 ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ
85118 3Wl9af0AVqW3rLatt8o+Ae+c
85119 -----END CERTIFICATE-----
85120
85121 Entrust Root Certification Authority - G2
85122 =========================================
85123 -----BEGIN CERTIFICATE-----
85124 MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV
85125 BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy
85126 bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug
85127 b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw
85128 HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT
85129 DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx
85130 OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s
85131 eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi
85132 MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP
85133 /vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz
85134 HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU
85135 s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y
85136 TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx
85137 AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6
85138 0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z
85139 iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
85140 Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi
85141 nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+
85142 vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO
85143 e4pIb4tF9g==
85144 -----END CERTIFICATE-----
85145
85146 Entrust Root Certification Authority - EC1
85147 ==========================================
85148 -----BEGIN CERTIFICATE-----
85149 MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx
85150 FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn
85151 YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl
85152 ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
85153 IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw
85154 FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs
85155 LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg
85156 dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
85157 IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy
85158 AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef
85159 9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
85160 FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h
85161 vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8
85162 kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
85163 -----END CERTIFICATE-----
85164
85165 CFCA EV ROOT
85166 ============
85167 -----BEGIN CERTIFICATE-----
85168 MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE
85169 CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB
85170 IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw
85171 MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD
85172 DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV
85173 BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD
85174 7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN
85175 uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW
85176 ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7
85177 xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f
85178 py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K
85179 gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol
85180 hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ
85181 tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf
85182 BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
85183 /wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
85184 ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q
85185 ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua
85186 4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG
85187 E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX
85188 BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn
85189 aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy
85190 PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
85191 kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
85192 ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
85193 -----END CERTIFICATE-----
85194
85195 TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5
85196 ====================================================
85197 -----BEGIN CERTIFICATE-----
85198 MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN
85199 BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
85200 bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg
85201 RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw
85202 ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w
85203 SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE
85204 n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp
85205 ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
85206 CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537
85207 jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m
85208 ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP
85209 9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV
85210 4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH
85211 HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
85212 hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo
85213 BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
85214 URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl
85215 lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8
85216 B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU=
85217 -----END CERTIFICATE-----
85218
85219 TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6
85220 ====================================================
85221 -----BEGIN CERTIFICATE-----
85222 MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G
85223 A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
85224 acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
85225 bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5
85226 MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL
85227 BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf
85228 aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm
85229 aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
85230 AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a
85231 2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED
85232 wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb
85233 HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV
85234 +DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT
85235 9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
85236 9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R
85237 fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy
85238 o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW
85239 hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1
85240 O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw==
85241 -----END CERTIFICATE-----
85242
85243 Certinomis - Root CA
85244 ====================
85245 -----BEGIN CERTIFICATE-----
85246 MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
85247 Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg
85248 LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx
85249 EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD
85250 ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos
85251 P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo
85252 d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap
85253 z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00
85254 8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x
85255 RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE
85256 6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t
85257 FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV
85258 PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH
85259 i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj
85260 YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I
85261 6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
85262 AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV
85263 WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw
85264 Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX
85265 lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ
85266 y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9
85267 Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng
85268 DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi
85269 I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM
85270 cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr
85271 hkIGuUE=
85272 -----END CERTIFICATE-----
85273
85274 OISTE WISeKey Global Root GB CA
85275 ===============================
85276 -----BEGIN CERTIFICATE-----
85277 MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG
85278 EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
85279 ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw
85280 MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD
85281 VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds
85282 b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX
85283 scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP
85284 rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk
85285 9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o
85286 Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg
85287 GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
85288 /zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI
85289 hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD
85290 dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0
85291 VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui
85292 HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
85293 Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
85294 -----END CERTIFICATE-----
85295
85296 Certification Authority of WoSign G2
85297 ====================================
85298 -----BEGIN CERTIFICATE-----
85299 MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG
85300 EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g
85301 QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx
85302 CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm
85303 aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
85304 CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai
85305 XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du
85306 W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9
85307 5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK
85308 v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
85309 AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI
85310 hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY
85311 P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3
85312 TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu
85313 +sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+
85314 7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg=
85315 -----END CERTIFICATE-----
85316
85317 CA WoSign ECC Root
85318 ==================
85319 -----BEGIN CERTIFICATE-----
85320 MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD
85321 TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v
85322 dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK
85323 ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI
85324 zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU
85325 t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw
85326 QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R
85327 MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0
85328 Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu
85329 a/GRspBl9JrmkO5K
85330 -----END CERTIFICATE-----
85331
85332 SZAFIR ROOT CA2
85333 ===============
85334 -----BEGIN CERTIFICATE-----
85335 MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG
85336 A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV
85337 BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ
85338 BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD
85339 VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q
85340 qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK
85341 DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE
85342 2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ
85343 ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi
85344 ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
85345 AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC
85346 AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5
85347 O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67
85348 oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul
85349 4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6
85350 +/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
85351 -----END CERTIFICATE-----
85352
85353 Certum Trusted Network CA 2
85354 ===========================
85355 -----BEGIN CERTIFICATE-----
85356 MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE
85357 BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1
85358 bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y
85359 ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ
85360 TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl
85361 cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB
85362 IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9
85363 7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o
85364 CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b
85365 Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p
85366 uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130
85367 GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ
85368 9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB
85369 Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye
85370 hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM
85371 BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
85372 AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
85373 hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW
85374 Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA
85375 L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo
85376 clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM
85377 pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb
85378 w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo
85379 J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm
85380 ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX
85381 is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7
85382 zAYspsbiDrW5viSP
85383 -----END CERTIFICATE-----
85384
85385 Hellenic Academic and Research Institutions RootCA 2015
85386 =======================================================
85387 -----BEGIN CERTIFICATE-----
85388 MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT
85389 BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0
85390 aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
85391 YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx
85392 MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg
85393 QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV
85394 BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw
85395 MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv
85396 bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh
85397 iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+
85398 6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd
85399 FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr
85400 i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F
85401 GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2
85402 fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu
85403 iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
85404 Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
85405 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI
85406 hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+
85407 D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM
85408 d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y
85409 d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn
85410 82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb
85411 davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F
85412 Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt
85413 J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa
85414 JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q
85415 p/UsQu0yrbYhnr68
85416 -----END CERTIFICATE-----
85417
85418 Hellenic Academic and Research Institutions ECC RootCA 2015
85419 ===========================================================
85420 -----BEGIN CERTIFICATE-----
85421 MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0
85422 aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u
85423 cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
85424 aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw
85425 MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj
85426 IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD
85427 VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290
85428 Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP
85429 dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK
85430 Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
85431 BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA
85432 GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn
85433 dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
85434 -----END CERTIFICATE-----
85435
85436 Certplus Root CA G1
85437 ===================
85438 -----BEGIN CERTIFICATE-----
85439 MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV
85440 BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe
85441 Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD
85442 ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD
85443 ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN
85444 r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx
85445 Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj
85446 BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv
85447 LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2
85448 z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc
85449 4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd
85450 4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj
85451 jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+
85452 ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G
85453 A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY
85454 lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh
85455 66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG
85456 YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/
85457 2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F
85458 6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX
85459 CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe
85460 tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC
85461 VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/
85462 +mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+
85463 qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
85464 -----END CERTIFICATE-----
85465
85466 Certplus Root CA G2
85467 ===================
85468 -----BEGIN CERTIFICATE-----
85469 MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT
85470 AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x
85471 NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0
85472 cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA
85473 BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN
85474 Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD
85475 AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud
85476 IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV
85477 HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl
85478 vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw==
85479 -----END CERTIFICATE-----
85480
85481 OpenTrust Root CA G1
85482 ====================
85483 -----BEGIN CERTIFICATE-----
85484 MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV
85485 BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx
85486 MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
85487 CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB
85488 AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa
85489 Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87
85490 ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO
85491 YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9
85492 xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO
85493 9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq
85494 3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi
85495 n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9
85496 URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr
85497 TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
85498 /zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px
85499 N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
85500 PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv
85501 uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK
85502 n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh
85503 X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80
85504 nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm
85505 GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/
85506 bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o
85507 4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA
85508 OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx
85509 -----END CERTIFICATE-----
85510
85511 OpenTrust Root CA G2
85512 ====================
85513 -----BEGIN CERTIFICATE-----
85514 MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV
85515 BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy
85516 MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
85517 CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB
85518 AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+
85519 Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz
85520 4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV
85521 eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt
85522 UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz
85523 3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj
85524 3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz
85525 9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0
85526 0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT
85527 y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
85528 /zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59
85529 M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz
85530 Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI
85531 mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG
85532 S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp
85533 EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ
85534 6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr
85535 gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo
85536 SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0
85537 YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm
85538 u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK
85539 -----END CERTIFICATE-----
85540
85541 OpenTrust Root CA G3
85542 ====================
85543 -----BEGIN CERTIFICATE-----
85544 MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT
85545 AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X
85546 DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w
85547 ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA
85548 IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B
85549 ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB
85550 /wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf
85551 BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM
85552 BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta
85553 3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB
85554 -----END CERTIFICATE-----
85555
85556 ISRG Root X1
85557 ============
85558 -----BEGIN CERTIFICATE-----
85559 MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE
85560 BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD
85561 EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG
85562 EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT
85563 DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r
85564 Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1
85565 3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K
85566 b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN
85567 Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ
85568 4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf
85569 1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu
85570 hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH
85571 usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r
85572 OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G
85573 A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY
85574 9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
85575 ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV
85576 0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt
85577 hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw
85578 TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx
85579 e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA
85580 JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD
85581 YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n
85582 JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ
85583 m+kXQ99b21/+jh5Xos1AnX5iItreGCc=
85584 -----END CERTIFICATE-----
85585
85586 AC RAIZ FNMT-RCM
85587 ================
85588 -----BEGIN CERTIFICATE-----
85589 MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT
85590 AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw
85591 MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD
85592 TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
85593 ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf
85594 qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr
85595 btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL
85596 j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou
85597 08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw
85598 WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT
85599 tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ
85600 47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC
85601 ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa
85602 i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
85603 FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o
85604 dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
85605 nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s
85606 D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ
85607 j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT
85608 Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW
85609 +YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7
85610 Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d
85611 8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm
85612 5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG
85613 rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
85614 -----END CERTIFICATE-----
85615
85616 Amazon Root CA 1
85617 ================
85618 -----BEGIN CERTIFICATE-----
85619 MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD
85620 VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1
85621 MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
85622 bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
85623 ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH
85624 FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ
85625 gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t
85626 dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce
85627 VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
85628 /zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3
85629 DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM
85630 CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy
85631 8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa
85632 2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2
85633 xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5
85634 -----END CERTIFICATE-----
85635
85636 Amazon Root CA 2
85637 ================
85638 -----BEGIN CERTIFICATE-----
85639 MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD
85640 VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1
85641 MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
85642 bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
85643 ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4
85644 kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp
85645 N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9
85646 AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd
85647 fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx
85648 kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS
85649 btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0
85650 Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN
85651 c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+
85652 3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw
85653 DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA
85654 A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
85655 +gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE
85656 YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW
85657 xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ
85658 gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW
85659 aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV
85660 Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3
85661 KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi
85662 JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=
85663 -----END CERTIFICATE-----
85664
85665 Amazon Root CA 3
85666 ================
85667 -----BEGIN CERTIFICATE-----
85668 MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG
85669 EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy
85670 NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
85671 MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB
85672 f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr
85673 Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43
85674 rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc
85675 eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==
85676 -----END CERTIFICATE-----
85677
85678 Amazon Root CA 4
85679 ================
85680 -----BEGIN CERTIFICATE-----
85681 MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG
85682 EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy
85683 NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
85684 MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN
85685 /sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri
85686 83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
85687 HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA
85688 MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1
85689 AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==
85690 -----END CERTIFICATE-----
85691
85692 LuxTrust Global Root 2
85693 ======================
85694 -----BEGIN CERTIFICATE-----
85695 MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG
85696 A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh
85697 bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW
85698 MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC
85699 AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm
85700 Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2
85701 xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC
85702 wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm
85703 1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm
85704 FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF
85705 wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/
85706 a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U
85707 ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ
85708 MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB
85709 /zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5
85710 Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
85711 +Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ
85712 FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN
85713 H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW
85714 7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu
85715 ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA
85716 VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR
85717 TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt
85718 /f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc
85719 7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I
85720 iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
85721 -----END CERTIFICATE-----
85722 <?php
85723
85724 if (PHP_SAPI !== 'cli') {
85725     echo 'Warning: Composer should be invoked via the CLI version of PHP, not the '.PHP_SAPI.' SAPI'.PHP_EOL;
85726 }
85727
85728 require __DIR__.'/../src/bootstrap.php';
85729
85730 use Composer\Factory;
85731 use Composer\XdebugHandler;
85732 use Composer\Console\Application;
85733
85734 error_reporting(-1);
85735
85736 // Create output for XdebugHandler and Application
85737 $output = Factory::createOutput();
85738
85739 $xdebug = new XdebugHandler($output);
85740 $xdebug->check();
85741 unset($xdebug);
85742
85743 if (function_exists('ini_set')) {
85744     @ini_set('display_errors', 1);
85745
85746     $memoryInBytes = function ($value) {
85747         $unit = strtolower(substr($value, -1, 1));
85748         $value = (int) $value;
85749         switch($unit) {
85750             case 'g':
85751                 $value *= 1024;
85752                 // no break (cumulative multiplier)
85753             case 'm':
85754                 $value *= 1024;
85755                 // no break (cumulative multiplier)
85756             case 'k':
85757                 $value *= 1024;
85758         }
85759
85760         return $value;
85761     };
85762
85763     $memoryLimit = trim(ini_get('memory_limit'));
85764     // Increase memory_limit if it is lower than 1.5GB
85765     if ($memoryLimit != -1 && $memoryInBytes($memoryLimit) < 1024 * 1024 * 1536) {
85766         @ini_set('memory_limit', '1536M');
85767     }
85768     unset($memoryInBytes, $memoryLimit);
85769 }
85770
85771 putenv('COMPOSER_BINARY='.realpath($_SERVER['argv'][0]));
85772
85773 // run the command application
85774 $application = new Application();
85775 $application->run(null, $output);
85776
85777 Copyright (c) Nils Adermann, Jordi Boggiano
85778
85779 Permission is hereby granted, free of charge, to any person obtaining a copy
85780 of this software and associated documentation files (the "Software"), to deal
85781 in the Software without restriction, including without limitation the rights
85782 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
85783 copies of the Software, and to permit persons to whom the Software is furnished
85784 to do so, subject to the following conditions:
85785
85786 The above copyright notice and this permission notice shall be included in all
85787 copies or substantial portions of the Software.
85788
85789 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
85790 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
85791 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
85792 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
85793 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
85794 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
85795 THE SOFTWARE.
85796
85797 ó\ 2\8deO¯½¯\95êõÌ\9ajïÀÜ,Cl\ 2\0\0\0GBMB