From 4069de89595f188b9931454ba6753662e66a10d3 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 20 Oct 2023 06:31:52 +0000 Subject: [PATCH] release PHP 7.2 downgraded --- .editorconfig | 12 - .../workflows/auto_closer.yaml | 0 .github/workflows/bare_run.yaml | 48 +- .gitignore | 3 - README.md | 111 +- bin/monorepo-builder | 3 +- bin/monorepo-builder.php | 40 +- .../bootstrap.php => bootstrap.php | 0 build/rector-downgrade-php-72.php | 21 - build/target-repository/.github/FUNDING.yml | 3 - .../.github/workflows/bare_run.yaml | 23 - build/target-repository/README.md | 245 - build/target-repository/composer.json | 27 - composer.json | 65 +- composer.lock | 3712 +++++++++++++ config/config.php | 95 +- ecs.php | 21 - full-tool-build.sh | 18 - .../ComposerJsonFactoryTest.php | 56 - .../Source/full_composer.json | 45 - .../Source/some_composer.json | 19 - .../ComposerJsonSchemaValidationTest.php | 46 - .../symfony-website_skeleton-composer.json | 90 - .../Sorter/ComposerPackageSorterTest.php | 52 - .../ValueObject/ComposerJsonTest.php | 47 - ...gedAndDecoratedComposerJsonFactoryTest.php | 44 - .../Application/Source/expected_composer.json | 62 - .../Source/packages/one_package.json | 33 - .../Source/packages/src/some_file.txt | 1 - .../Source/packages/tests/some_file.txt | 1 - .../Source/packages/two_package.json | 35 - .../Application/Source/root_composer.json | 29 - .../AbstractComposerJsonDecoratorTest.php | 73 - .../AppenderComposerJsonDecoratorTest.php | 31 - .../Source/appending_config.php | 23 - .../Source/expected.json | 14 - .../Source/input.json | 10 - .../Source/to-append.json | 12 - .../RemoverComposerJsonDecoratorTest.php | 108 - ...epositoryPathComposerJsonDecoratorTest.php | 93 - .../RootRemoveComposerJsonDecoratorTest.php | 42 - .../Source/composer.json | 5 - .../Source/expected-composer.json | 7 - .../Source/packages/composer.json | 7 - .../SortComposerJsonDecoratorTest.php | 59 - .../ComposerJsonMergerTest.php | 42 - .../Fixture/require_priority.test | 17 - .../Fixture/require_priority_inversed.test | 17 - .../Fixture/with_authors.test | 41 - .../Fixture/with_existing_authors.test | 85 - .../Fixture/with_extra.test | 32 - .../Fixture/with_provide.test | 25 - .../MinimalStability/keep_stability.test | 5 - .../main_has_minimum_stability.test | 5 - .../new_has_minimum_stability.test | 5 - .../no_minimum_stability.test | 5 - .../MinimalStability/widen_stability.test | 5 - .../MinimalStabilityKeyMergerTest.php | 36 - .../Merge/Package/AbstractMergeTestCase.php | 51 - .../CombineStringsToArrayJsonMergerTest.php | 21 - .../Source/expected.json | 57 - .../expected-with-composer-patches.json | 16 - .../expected-with-relative-paths.json | 13 - .../expected.json | 11 - .../Package/PackageComposerJsonMergerTest.php | 35 - .../Merge/Package/Source/package-one.json | 13 - .../Merge/Package/Source/package-two.json | 12 - .../Merge/Package/Source/src/some_file.txt | 1 - .../SourceComposerPatches/package-one.json | 9 - .../SourceComposerPatches/package-three.json | 9 - .../SourceComposerPatches/package-two.json | 13 - .../PackageA/Something.php | 1 - .../PackageA/composer.json | 21 - .../PackageA/lib/some_file.txt | 1 - .../PackageA/src/array/some_file.txt | 1 - .../PackageA/src/collection/some_file.txt | 1 - .../PackageA/src/core/some_file.txt | 1 - .../PackageA/src/list/some_file.txt | 1 - .../PackageA/src/shared/some_file.txt | 1 - .../PackageB/composer.json | 11 - .../PackageB/src/collection/some_file.txt | 1 - .../PackageB/src/core-extension/some_file.txt | 1 - .../PackageB/src/core/some_file.txt | 1 - .../PackageB/src/interfaces/some_file.txt | 1 - .../PackageB/src/list/some_file.txt | 1 - .../PackageB/src/shared/some_file.txt | 1 - .../SubA/PackageC/composer.json | 8 - .../SubA/PackageC/src/models/some_file.txt | 1 - .../SubA/PackageC/src/package-c/some_file.txt | 1 - .../SubB/PackageD/composer.json | 7 - .../SubB/PackageD/src/package-d/some_file.txt | 1 - .../SourceUniqueRepositories/package-one.json | 8 - .../package-three.json | 11 - .../SourceUniqueRepositories/package-two.json | 8 - .../autoload.json | 7 - .../expected-autoload.json | 7 - .../AutoloadPathNormalizerTest.php | 37 - .../ComposerPatchesPathNormalizerTest.php | 23 - .../Fixture/propagate-require-dev.test | 22 - .../VersionPropagator/Fixture/propagate.test | 19 - .../VersionPropagaterTest.php | 41 - .../ReleaseWorkerProviderTest.php | 27 - .../config/all_release_workers.php | 23 - .../ComposerJsonSymlinkerTest.php | 87 - .../expected_deeper_path_repository.test | 19 - .../Fixture/expected_path_repository.test | 19 - .../Fixture/expected_repository.test | 12 - .../expected_reuse_existing_repository.test | 12 - .../Fixture/expected_symlink_true.test | 12 - .../Testing/ComposerJson/composer.json | 3 - .../ComposerJson/config/test_config.php | 11 - .../packages/package-one/composer.json | 12 - .../packages/package-three/composer.json | 12 - .../packages/package-two/composer.json | 3 - .../package-four/composer.json | 12 - .../PathResolver/PackagePathResolverTest.php | 44 - .../some_root/composer.json | 1 - .../nested_packages/nested/composer.json | 1 - .../ComposerJsonFactory.php | 65 +- .../FileSystem/JsonFileManager.php | 65 +- .../Json/JsonCleaner.php | 9 +- .../Json/JsonInliner.php | 36 +- .../Printer/ComposerJsonPrinter.php | 28 +- .../Sorter/ComposerPackageSorter.php | 67 +- .../ValueObject/ComposerJson.php | 498 +- .../ValueObject/ComposerJsonSection.php | 26 +- .../ValueObject/Option.php | 3 +- packages/Init/Command/InitCommand.php | 28 +- .../MergedAndDecoratedComposerJsonFactory.php | 34 +- packages/Merge/Arrays/ArraySorter.php | 21 +- .../Merge/Arrays/SortedParameterMerger.php | 30 +- .../RequireRequireDevDuplicateCleaner.php | 10 +- packages/Merge/Command/MergeCommand.php | 73 +- .../AppenderComposerJsonDecorator.php | 26 +- ...catedRequireAndRequireDevJsonDecorator.php | 15 +- .../RemoverComposerJsonDecorator.php | 66 +- .../ReplaceSectionJsonDecorator.php | 19 +- .../RepositoryPathComposerJsonDecorator.php | 24 +- .../RootRemoveComposerJsonDecorator.php | 27 +- .../SortComposerJsonDecorator.php | 29 +- packages/Merge/ComposerJsonMerger.php | 59 +- .../AuthorComposerKeyMerger.php | 17 +- .../AutoloadComposerKeyMerger.php | 23 +- .../AutoloadDevComposerKeyMerger.php | 24 +- .../ExtraComposerKeyMerger.php | 26 +- .../MinimalStabilityKeyMerger.php | 14 +- .../PreferStableKeyMerger.php | 7 +- .../ProvideComposerKeyMerger.php | 42 +- .../ReplaceComposerKeyMerger.php | 9 +- .../RepositoriesComposerKeyMerger.php | 29 +- .../RequireComposerKeyMerger.php | 36 +- .../RequireDevComposerKeyMerger.php | 31 +- .../Configuration/MergedPackagesCollector.php | 17 +- .../ModifyingComposerJsonProvider.php | 30 +- .../ComposerJsonDecoratorInterface.php | 6 +- .../Contract/ComposerKeyMergerInterface.php | 6 +- .../ComposerPathNormalizerInterface.php | 8 +- .../Merge/Guard/ConflictingVersionsGuard.php | 38 +- .../PathResolver/AutoloadPathNormalizer.php | 41 +- .../ComposerPatchesPathNormalizer.php | 40 +- .../Propagate/Command/PropagateCommand.php | 62 +- packages/Propagate/VersionPropagator.php | 12 +- packages/Release/Command/ReleaseCommand.php | 104 +- .../Release/Configuration/StageResolver.php | 21 +- .../Release/Configuration/VersionResolver.php | 19 +- .../ReleaseWorker/ReleaseWorkerInterface.php | 9 +- .../ReleaseWorker/StageAwareInterface.php | 7 +- .../Exception/ConfigurationException.php | 4 +- .../MissingComposerJsonException.php | 4 +- packages/Release/Guard/ReleaseGuard.php | 95 +- .../Release/Output/ReleaseWorkerReporter.php | 25 +- packages/Release/Process/ProcessRunner.php | 45 +- .../AddTagToChangelogReleaseWorker.php | 48 +- .../PushNextDevReleaseWorker.php | 49 +- .../ReleaseWorker/PushTagReleaseWorker.php | 22 +- ...CurrentMutualDependenciesReleaseWorker.php | 51 +- ...SetNextMutualDependenciesReleaseWorker.php | 48 +- .../ReleaseWorker/TagVersionReleaseWorker.php | 64 +- .../UpdateBranchAliasReleaseWorker.php | 41 +- .../UpdateReplaceReleaseWorker.php | 42 +- packages/Release/ReleaseWorkerProvider.php | 23 +- packages/Release/ValueObject/SemVersion.php | 6 +- packages/Release/ValueObject/Stage.php | 3 +- packages/Release/Version/VersionFactory.php | 57 +- .../Command/LocalizeComposerPathsCommand.php | 56 +- .../ComposerJson/ComposerJsonSymlinker.php | 97 +- .../ComposerVersionManipulator.php | 24 +- .../ComposerJsonRepositoriesUpdater.php | 85 +- .../Testing/ComposerJsonRequireUpdater.php | 71 +- .../UsedPackagesResolver.php | 27 +- .../PathResolver/PackagePathResolver.php | 32 +- packages/Testing/ValueObject/Option.php | 3 +- phpstan.neon | 7 - phpunit.xml | 7 - prefix-code.sh | 49 - rector.php | 46 - scoper.php | 91 - src/Command/BumpInterdependencyCommand.php | 63 +- src/Command/PackageAliasCommand.php | 44 +- src/Command/ValidateCommand.php | 53 +- src/Config/MBConfig.php | 56 +- src/Console/MonorepoBuilderApplication.php | 8 +- src/Contract/Git/TagResolverInterface.php | 5 +- src/DependencyUpdater.php | 77 +- src/DevMasterAliasUpdater.php | 46 +- src/Exception/ConfigurationException.php | 4 +- .../Git/InvalidGitVersionException.php | 4 +- .../MissingComposerJsonException.php | 4 +- .../InvalidComposerJsonSetupException.php | 4 +- src/FileSystem/ComposerJsonProvider.php | 63 +- src/Finder/PackageComposerFinder.php | 75 +- src/Git/ExpectedAliasResolver.php | 21 +- src/Git/MostRecentTagResolver.php | 34 +- src/Kernel/MonorepoBuilderKernel.php | 16 +- src/Package/PackageNamesProvider.php | 34 +- src/Utils/RelativeFilePathHelper.php | 8 +- src/Utils/VersionUtils.php | 64 +- .../ConflictingPackageVersionsReporter.php | 28 +- src/Validator/SourcesPresenceValidator.php | 33 +- src/ValueObject/File.php | 3 +- src/ValueObject/Option.php | 19 +- src/VersionValidator.php | 71 +- .../Fixture/expected_composer.test | 8 - .../Fixture/input_composer_backup.test | 5 - .../DependencyUpdaterTest.php | 40 - .../Source/backup-first.json | 12 - .../Source/expected-first.json | 12 - tests/DependencyUpdater/Source/first.json | 12 - .../DevMasterAliasUpdaterTest.php | 40 - .../Source/backup-first.json | 7 - .../Source/expected-first.json | 7 - tests/DevMasterAliasUpdater/Source/first.json | 7 - .../JsonFileManager/JsonFileManagerTest.php | 101 - .../JsonFileManager/Source/dynamic.json | 3 - .../Source/expected-inlined.json | 8 - .../Source/expected-second.json | 3 - .../JsonFileManager/Source/first.json | 3 - .../config/inlined_section_config.php | 11 - .../PackageComposerFinderTest.php | 25 - .../Source/First/ExcludeThis/composer.json | 3 - .../Source/First/composer.json | 3 - .../Source/Second/composer.json | 3 - .../Source/source_config.php | 17 - .../InterdependencyUpdaterTest.php | 53 - .../Source/backup-first.json | 6 - .../Source/expected-first-packages.json | 6 - .../Source/expected-first-vendor.json | 6 - .../InterdependencyUpdater/Source/first.json | 6 - tests/Utils/VersionUtilsTest.php | 67 - tests/VersionValidator/Source/first.json | 5 - tests/VersionValidator/Source/second.json | 5 - .../VersionValidator/VersionValidatorTest.php | 52 - vendor/autoload.php | 25 + vendor/bin/easy-testing | 94 + vendor/composer/ClassLoader.php | 579 +++ vendor/composer/InstalledVersions.php | 313 ++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 709 +++ vendor/composer/autoload_files.php | 15 + vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 29 + vendor/composer/autoload_real.php | 49 + vendor/composer/autoload_static.php | 843 +++ vendor/composer/installed.json | 1729 ++++++ vendor/composer/installed.php | 5 + vendor/nette/utils/composer.json | 72 + vendor/nette/utils/license.md | 60 + vendor/nette/utils/readme.md | 54 + vendor/nette/utils/src/HtmlStringable.php | 17 + .../utils/src/Iterators/CachingIterator.php | 133 + vendor/nette/utils/src/Iterators/Mapper.php | 27 + vendor/nette/utils/src/SmartObject.php | 120 + vendor/nette/utils/src/StaticClass.php | 32 + vendor/nette/utils/src/Translator.php | 22 + vendor/nette/utils/src/Utils/ArrayHash.php | 86 + vendor/nette/utils/src/Utils/ArrayList.php | 111 + vendor/nette/utils/src/Utils/Arrays.php | 394 ++ vendor/nette/utils/src/Utils/Callback.php | 151 + vendor/nette/utils/src/Utils/DateTime.php | 105 + vendor/nette/utils/src/Utils/FileSystem.php | 186 + vendor/nette/utils/src/Utils/Floats.php | 83 + vendor/nette/utils/src/Utils/Helpers.php | 78 + vendor/nette/utils/src/Utils/Html.php | 744 +++ vendor/nette/utils/src/Utils/Image.php | 611 +++ vendor/nette/utils/src/Utils/Json.php | 49 + .../nette/utils/src/Utils/ObjectHelpers.php | 175 + vendor/nette/utils/src/Utils/ObjectMixin.php | 32 + vendor/nette/utils/src/Utils/Paginator.php | 191 + vendor/nette/utils/src/Utils/Random.php | 38 + vendor/nette/utils/src/Utils/Reflection.php | 326 ++ vendor/nette/utils/src/Utils/Strings.php | 488 ++ vendor/nette/utils/src/Utils/Type.php | 212 + vendor/nette/utils/src/Utils/Validators.php | 341 ++ vendor/nette/utils/src/Utils/exceptions.php | 40 + vendor/nette/utils/src/compatibility.php | 28 + vendor/nette/utils/src/exceptions.php | 84 + vendor/phar-io/version/CHANGELOG.md | 142 + vendor/phar-io/version/LICENSE | 29 + vendor/phar-io/version/README.md | 61 + vendor/phar-io/version/composer.json | 33 + vendor/phar-io/version/src/BuildMetaData.php | 30 + .../phar-io/version/src/PreReleaseSuffix.php | 64 + vendor/phar-io/version/src/Version.php | 178 + .../version/src/VersionConstraintParser.php | 73 + .../version/src/VersionConstraintValue.php | 82 + vendor/phar-io/version/src/VersionNumber.php | 30 + .../constraints/AbstractVersionConstraint.php | 26 + .../constraints/AndVersionConstraintGroup.php | 35 + .../src/constraints/AnyVersionConstraint.php | 24 + .../constraints/ExactVersionConstraint.php | 24 + .../GreaterThanOrEqualToVersionConstraint.php | 27 + .../constraints/OrVersionConstraintGroup.php | 36 + ...SpecificMajorAndMinorVersionConstraint.php | 33 + .../SpecificMajorVersionConstraint.php | 27 + .../src/constraints/VersionConstraint.php | 18 + .../version/src/exceptions/Exception.php | 17 + .../InvalidPreReleaseSuffixException.php | 8 + .../exceptions/InvalidVersionException.php | 8 + .../exceptions/NoBuildMetaDataException.php | 8 + .../NoPreReleaseSuffixException.php | 8 + .../UnsupportedVersionConstraintException.php | 16 + vendor/psr/container/LICENSE | 21 + vendor/psr/container/README.md | 13 + vendor/psr/container/composer.json | 33 + .../src/ContainerExceptionInterface.php | 11 + .../psr/container/src/ContainerInterface.php | 34 + .../src/NotFoundExceptionInterface.php | 10 + vendor/scoper-autoload.php | 13 + vendor/sebastian/diff/ChangeLog.md | 120 + vendor/sebastian/diff/LICENSE | 29 + vendor/sebastian/diff/README.md | 206 + vendor/sebastian/diff/SECURITY.md | 30 + vendor/sebastian/diff/composer.json | 56 + vendor/sebastian/diff/src/Chunk.php | 79 + vendor/sebastian/diff/src/Diff.php | 60 + vendor/sebastian/diff/src/Differ.php | 206 + .../src/Exception/ConfigurationException.php | 24 + .../diff/src/Exception/Exception.php | 17 + .../Exception/InvalidArgumentException.php | 16 + vendor/sebastian/diff/src/Line.php | 40 + .../LongestCommonSubsequenceCalculator.php | 20 + ...ientLongestCommonSubsequenceCalculator.php | 79 + .../src/Output/AbstractChunkOutputBuilder.php | 49 + .../diff/src/Output/DiffOnlyOutputBuilder.php | 68 + .../src/Output/DiffOutputBuilderInterface.php | 21 + .../Output/StrictUnifiedDiffOutputBuilder.php | 252 + .../src/Output/UnifiedDiffOutputBuilder.php | 198 + vendor/sebastian/diff/src/Parser.php | 84 + ...ientLongestCommonSubsequenceCalculator.php | 74 + .../symfony/config/Builder/ClassBuilder.php | 165 + .../config/Builder/ConfigBuilderGenerator.php | 506 ++ .../ConfigBuilderGeneratorInterface.php | 25 + .../config/Builder/ConfigBuilderInterface.php | 28 + vendor/symfony/config/Builder/Method.php | 34 + vendor/symfony/config/Builder/Property.php | 92 + vendor/symfony/config/CHANGELOG.md | 153 + vendor/symfony/config/ConfigCache.php | 56 + vendor/symfony/config/ConfigCacheFactory.php | 43 + .../config/ConfigCacheFactoryInterface.php | 29 + .../symfony/config/ConfigCacheInterface.php | 43 + .../symfony/config/Definition/ArrayNode.php | 359 ++ vendor/symfony/config/Definition/BaseNode.php | 501 ++ .../symfony/config/Definition/BooleanNode.php | 48 + .../Builder/ArrayNodeDefinition.php | 421 ++ .../Builder/BooleanNodeDefinition.php | 42 + .../Builder/BuilderAwareInterface.php | 26 + .../Definition/Builder/EnumNodeDefinition.php | 48 + .../config/Definition/Builder/ExprBuilder.php | 239 + .../Builder/FloatNodeDefinition.php | 28 + .../Builder/IntegerNodeDefinition.php | 28 + .../Definition/Builder/MergeBuilder.php | 55 + .../config/Definition/Builder/NodeBuilder.php | 170 + .../Definition/Builder/NodeDefinition.php | 296 ++ .../Builder/NodeParentInterface.php | 20 + .../Builder/NormalizationBuilder.php | 54 + .../Builder/NumericNodeDefinition.php | 63 + .../Builder/ParentNodeDefinitionInterface.php | 46 + .../Builder/ScalarNodeDefinition.php | 28 + .../config/Definition/Builder/TreeBuilder.php | 56 + .../Definition/Builder/ValidationBuilder.php | 39 + .../Builder/VariableNodeDefinition.php | 54 + .../Definition/ConfigurableInterface.php | 23 + .../config/Definition/Configuration.php | 52 + .../Definition/ConfigurationInterface.php | 27 + .../Configurator/DefinitionConfigurator.php | 61 + .../Definition/Dumper/XmlReferenceDumper.php | 262 + .../Definition/Dumper/YamlReferenceDumper.php | 232 + vendor/symfony/config/Definition/EnumNode.php | 88 + .../Exception/DuplicateKeyException.php | 21 + .../config/Definition/Exception/Exception.php | 20 + .../Exception/ForbiddenOverwriteException.php | 21 + .../InvalidConfigurationException.php | 54 + .../Exception/InvalidDefinitionException.php | 20 + .../Exception/InvalidTypeException.php | 20 + .../Exception/UnsetKeyException.php | 21 + .../symfony/config/Definition/FloatNode.php | 44 + .../symfony/config/Definition/IntegerNode.php | 40 + .../Loader/DefinitionFileLoader.php | 106 + .../config/Definition/NodeInterface.php | 76 + .../symfony/config/Definition/NumericNode.php | 62 + .../symfony/config/Definition/Processor.php | 81 + .../Definition/PrototypeNodeInterface.php | 26 + .../config/Definition/PrototypedArrayNode.php | 348 ++ .../symfony/config/Definition/ScalarNode.php | 59 + .../config/Definition/VariableNode.php | 130 + ...LoaderImportCircularReferenceException.php | 25 + .../FileLocatorFileNotFoundException.php | 36 + .../config/Exception/LoaderLoadException.php | 101 + vendor/symfony/config/FileLocator.php | 74 + .../symfony/config/FileLocatorInterface.php | 32 + vendor/symfony/config/LICENSE | 19 + .../config/Loader/DelegatingLoader.php | 46 + .../Loader/DirectoryAwareLoaderInterface.php | 24 + vendor/symfony/config/Loader/FileLoader.php | 171 + .../symfony/config/Loader/GlobFileLoader.php | 35 + vendor/symfony/config/Loader/Loader.php | 65 + .../symfony/config/Loader/LoaderInterface.php | 49 + .../symfony/config/Loader/LoaderResolver.php | 66 + .../config/Loader/LoaderResolverInterface.php | 28 + .../config/Loader/ParamConfigurator.php | 32 + vendor/symfony/config/README.md | 15 + .../Resource/ClassExistenceResource.php | 206 + .../config/Resource/ComposerResource.php | 61 + .../config/Resource/DirectoryResource.php | 88 + .../config/Resource/FileExistenceResource.php | 53 + .../symfony/config/Resource/FileResource.php | 56 + .../symfony/config/Resource/GlobResource.php | 227 + .../Resource/ReflectionClassResource.php | 191 + .../config/Resource/ResourceInterface.php | 30 + .../Resource/SelfCheckingResourceChecker.php | 44 + .../SelfCheckingResourceInterface.php | 27 + .../config/ResourceCheckerConfigCache.php | 166 + .../ResourceCheckerConfigCacheFactory.php | 40 + .../config/ResourceCheckerInterface.php | 42 + .../Util/Exception/InvalidXmlException.php | 21 + .../Util/Exception/XmlParsingException.php | 20 + vendor/symfony/config/Util/XmlUtils.php | 235 + vendor/symfony/config/composer.json | 44 + vendor/symfony/console/Application.php | 1147 ++++ .../symfony/console/Attribute/AsCommand.php | 41 + vendor/symfony/console/CHANGELOG.md | 252 + .../console/CI/GithubActionReporter.php | 79 + vendor/symfony/console/Color.php | 99 + vendor/symfony/console/Command/Command.php | 677 +++ .../console/Command/CompleteCommand.php | 158 + .../console/Command/DumpCompletionCommand.php | 143 + .../symfony/console/Command/HelpCommand.php | 68 + .../symfony/console/Command/LazyCommand.php | 188 + .../symfony/console/Command/ListCommand.php | 60 + .../symfony/console/Command/LockableTrait.php | 62 + .../Command/SignalableCommandInterface.php | 31 + .../CommandLoader/CommandLoaderInterface.php | 34 + .../CommandLoader/ContainerCommandLoader.php | 54 + .../CommandLoader/FactoryCommandLoader.php | 49 + .../console/Completion/CompletionInput.php | 210 + .../Completion/CompletionSuggestions.php | 86 + .../Output/BashCompletionOutput.php | 31 + .../Output/CompletionOutputInterface.php | 23 + .../Output/FishCompletionOutput.php | 31 + .../Completion/Output/ZshCompletionOutput.php | 34 + .../symfony/console/Completion/Suggestion.php | 47 + vendor/symfony/console/ConsoleEvents.php | 61 + vendor/symfony/console/Cursor.php | 167 + .../AddConsoleCommandPass.php | 107 + .../Descriptor/ApplicationDescription.php | 129 + .../symfony/console/Descriptor/Descriptor.php | 78 + .../Descriptor/DescriptorInterface.php | 25 + .../console/Descriptor/JsonDescriptor.php | 112 + .../console/Descriptor/MarkdownDescriptor.php | 128 + .../Descriptor/ReStructuredTextDescriptor.php | 234 + .../console/Descriptor/TextDescriptor.php | 274 + .../console/Descriptor/XmlDescriptor.php | 191 + .../console/Event/ConsoleCommandEvent.php | 47 + .../console/Event/ConsoleErrorEvent.php | 55 + vendor/symfony/console/Event/ConsoleEvent.php | 60 + .../console/Event/ConsoleSignalEvent.php | 60 + .../console/Event/ConsoleTerminateEvent.php | 40 + .../console/EventListener/ErrorListener.php | 82 + .../Exception/CommandNotFoundException.php | 42 + .../console/Exception/ExceptionInterface.php | 20 + .../Exception/InvalidArgumentException.php | 18 + .../Exception/InvalidOptionException.php | 20 + .../console/Exception/LogicException.php | 18 + .../Exception/MissingInputException.php | 20 + .../Exception/NamespaceNotFoundException.php | 20 + .../console/Exception/RuntimeException.php | 18 + .../console/Formatter/NullOutputFormatter.php | 47 + .../Formatter/NullOutputFormatterStyle.php | 48 + .../console/Formatter/OutputFormatter.php | 241 + .../Formatter/OutputFormatterInterface.php | 50 + .../Formatter/OutputFormatterStyle.php | 113 + .../OutputFormatterStyleInterface.php | 54 + .../Formatter/OutputFormatterStyleStack.php | 94 + .../WrappableOutputFormatterInterface.php | 26 + .../console/Helper/DebugFormatterHelper.php | 89 + .../console/Helper/DescriptorHelper.php | 74 + vendor/symfony/console/Helper/Dumper.php | 73 + .../console/Helper/FormatterHelper.php | 71 + vendor/symfony/console/Helper/Helper.php | 128 + .../console/Helper/HelperInterface.php | 36 + vendor/symfony/console/Helper/HelperSet.php | 68 + .../console/Helper/InputAwareHelper.php | 30 + .../symfony/console/Helper/OutputWrapper.php | 75 + .../symfony/console/Helper/ProcessHelper.php | 116 + vendor/symfony/console/Helper/ProgressBar.php | 591 +++ .../console/Helper/ProgressIndicator.php | 225 + .../symfony/console/Helper/QuestionHelper.php | 517 ++ .../console/Helper/SymfonyQuestionHelper.php | 85 + vendor/symfony/console/Helper/Table.php | 801 +++ vendor/symfony/console/Helper/TableCell.php | 64 + .../symfony/console/Helper/TableCellStyle.php | 59 + vendor/symfony/console/Helper/TableRows.php | 30 + .../symfony/console/Helper/TableSeparator.php | 24 + vendor/symfony/console/Helper/TableStyle.php | 378 ++ vendor/symfony/console/Input/ArgvInput.php | 336 ++ vendor/symfony/console/Input/ArrayInput.php | 181 + vendor/symfony/console/Input/Input.php | 173 + .../symfony/console/Input/InputArgument.php | 155 + .../console/Input/InputAwareInterface.php | 27 + .../symfony/console/Input/InputDefinition.php | 384 ++ .../symfony/console/Input/InputInterface.php | 136 + vendor/symfony/console/Input/InputOption.php | 237 + .../Input/StreamableInputInterface.php | 37 + vendor/symfony/console/Input/StringInput.php | 78 + vendor/symfony/console/LICENSE | 19 + .../symfony/console/Logger/ConsoleLogger.php | 101 + .../symfony/console/Output/AnsiColorMode.php | 76 + .../symfony/console/Output/BufferedOutput.php | 41 + .../symfony/console/Output/ConsoleOutput.php | 146 + .../console/Output/ConsoleOutputInterface.php | 30 + .../console/Output/ConsoleSectionOutput.php | 222 + vendor/symfony/console/Output/NullOutput.php | 95 + vendor/symfony/console/Output/Output.php | 142 + .../console/Output/OutputInterface.php | 94 + .../symfony/console/Output/StreamOutput.php | 95 + .../console/Output/TrimmedBufferOutput.php | 58 + .../console/Question/ChoiceQuestion.php | 163 + .../console/Question/ConfirmationQuestion.php | 53 + vendor/symfony/console/Question/Question.php | 285 + vendor/symfony/console/README.md | 36 + .../console/Resources/bin/hiddeninput.exe | Bin 0 -> 9216 bytes .../symfony/console/Resources/completion.bash | 94 + .../symfony/console/Resources/completion.fish | 29 + .../symfony/console/Resources/completion.zsh | 82 + .../console/SignalRegistry/SignalRegistry.php | 51 + .../console/SingleCommandApplication.php | 71 + vendor/symfony/console/Style/OutputStyle.php | 118 + .../symfony/console/Style/StyleInterface.php | 130 + vendor/symfony/console/Style/SymfonyStyle.php | 462 ++ vendor/symfony/console/Terminal.php | 209 + .../console/Tester/ApplicationTester.php | 79 + .../Tester/CommandCompletionTester.php | 48 + .../symfony/console/Tester/CommandTester.php | 66 + .../Tester/Constraint/CommandIsSuccessful.php | 34 + vendor/symfony/console/Tester/TesterTrait.php | 167 + vendor/symfony/console/composer.json | 58 + vendor/symfony/dependency-injection/Alias.php | 98 + .../Argument/AbstractArgument.php | 42 + .../Argument/ArgumentInterface.php | 22 + .../Argument/BoundArgument.php | 77 + .../Argument/IteratorArgument.php | 36 + .../Argument/ReferenceSetArgumentTrait.php | 54 + .../Argument/RewindableGenerator.php | 46 + .../Argument/ServiceClosureArgument.php | 49 + .../Argument/ServiceLocator.php | 64 + .../Argument/ServiceLocatorArgument.php | 51 + .../Argument/TaggedIteratorArgument.php | 89 + .../Attribute/AsDecorator.php | 35 + .../Attribute/AsTaggedItem.php | 34 + .../Attribute/Autoconfigure.php | 73 + .../Attribute/AutoconfigureTag.php | 25 + .../Attribute/Autowire.php | 69 + .../Attribute/MapDecorated.php | 16 + .../Attribute/TaggedIterator.php | 47 + .../Attribute/TaggedLocator.php | 47 + .../dependency-injection/Attribute/Target.php | 46 + .../dependency-injection/Attribute/When.php | 29 + .../symfony/dependency-injection/CHANGELOG.md | 325 ++ .../dependency-injection/ChildDefinition.php | 92 + .../Compiler/AbstractRecursivePass.php | 226 + .../AliasDeprecatedPublicServicesPass.php | 56 + .../Compiler/AnalyzeServiceReferencesPass.php | 188 + .../AttributeAutoconfigurationPass.php | 146 + .../Compiler/AutoAliasServicePass.php | 39 + .../Compiler/AutowireAsDecoratorPass.php | 44 + .../Compiler/AutowirePass.php | 588 +++ .../Compiler/AutowireRequiredMethodsPass.php | 98 + .../AutowireRequiredPropertiesPass.php | 55 + .../Compiler/CheckArgumentsValidityPass.php | 107 + .../Compiler/CheckCircularReferencesPass.php | 74 + .../Compiler/CheckDefinitionValidityPass.php | 82 + ...xceptionOnInvalidReferenceBehaviorPass.php | 98 + .../Compiler/CheckReferenceValidityPass.php | 43 + .../Compiler/CheckTypeDeclarationsPass.php | 270 + .../Compiler/Compiler.php | 93 + .../Compiler/CompilerPassInterface.php | 25 + .../Compiler/DecoratorServicePass.php | 106 + .../Compiler/DefinitionErrorExceptionPass.php | 53 + .../Compiler/ExtensionCompilerPass.php | 34 + .../Compiler/InlineServiceDefinitionsPass.php | 214 + .../MergeExtensionConfigurationPass.php | 197 + .../Compiler/PassConfig.php | 203 + .../Compiler/PriorityTaggedServiceTrait.php | 151 + .../RegisterAutoconfigureAttributesPass.php | 65 + .../Compiler/RegisterEnvVarProcessorsPass.php | 65 + .../Compiler/RegisterReverseContainerPass.php | 58 + .../RegisterServiceSubscribersPass.php | 119 + .../RemoveAbstractDefinitionsPass.php | 31 + .../Compiler/RemovePrivateAliasesPass.php | 36 + .../Compiler/RemoveUnusedDefinitionsPass.php | 85 + .../ReplaceAliasByActualDefinitionPass.php | 97 + .../Compiler/ResolveBindingsPass.php | 222 + .../Compiler/ResolveChildDefinitionsPass.php | 185 + .../Compiler/ResolveClassPass.php | 38 + .../Compiler/ResolveDecoratorStackPass.php | 99 + .../Compiler/ResolveEnvPlaceholdersPass.php | 43 + .../Compiler/ResolveFactoryClassPass.php | 36 + .../Compiler/ResolveHotPathPass.php | 72 + .../ResolveInstanceofConditionalsPass.php | 145 + .../Compiler/ResolveInvalidReferencesPass.php | 129 + .../Compiler/ResolveNamedArgumentsPass.php | 134 + .../Compiler/ResolveNoPreloadPass.php | 85 + .../ResolveParameterPlaceHoldersPass.php | 103 + .../ResolveReferencesToAliasesPass.php | 73 + .../ResolveServiceSubscribersPass.php | 52 + .../ResolveTaggedIteratorArgumentPass.php | 35 + .../Compiler/ServiceLocatorTagPass.php | 107 + .../Compiler/ServiceReferenceGraph.php | 92 + .../Compiler/ServiceReferenceGraphEdge.php | 101 + .../Compiler/ServiceReferenceGraphNode.php | 110 + .../Compiler/ValidateEnvPlaceholdersPass.php | 90 + .../Config/ContainerParametersResource.php | 42 + .../ContainerParametersResourceChecker.php | 48 + .../dependency-injection/Container.php | 362 ++ .../ContainerAwareInterface.php | 24 + .../ContainerAwareTrait.php | 28 + .../dependency-injection/ContainerBuilder.php | 1426 +++++ .../ContainerInterface.php | 54 + .../dependency-injection/Definition.php | 762 +++ .../dependency-injection/Dumper/Dumper.php | 26 + .../Dumper/DumperInterface.php | 25 + .../Dumper/GraphvizDumper.php | 202 + .../dependency-injection/Dumper/PhpDumper.php | 1995 +++++++ .../dependency-injection/Dumper/Preloader.php | 106 + .../dependency-injection/Dumper/XmlDumper.php | 366 ++ .../Dumper/YamlDumper.php | 313 ++ .../EnvVarLoaderInterface.php | 24 + .../dependency-injection/EnvVarProcessor.php | 237 + .../EnvVarProcessorInterface.php | 36 + .../Exception/AutowiringFailedException.php | 76 + .../Exception/BadMethodCallException.php | 18 + .../Exception/EnvNotFoundException.php | 20 + .../Exception/EnvParameterException.php | 24 + .../Exception/ExceptionInterface.php | 22 + .../Exception/InvalidArgumentException.php | 20 + .../InvalidParameterTypeException.php | 30 + .../Exception/LogicException.php | 18 + .../Exception/OutOfBoundsException.php | 18 + .../ParameterCircularReferenceException.php | 33 + .../Exception/ParameterNotFoundException.php | 101 + .../Exception/RuntimeException.php | 20 + .../ServiceCircularReferenceException.php | 42 + .../Exception/ServiceNotFoundException.php | 67 + .../ExpressionLanguage.php | 36 + .../ExpressionLanguageProvider.php | 63 + .../Extension/AbstractExtension.php | 54 + .../ConfigurableExtensionInterface.php | 29 + .../ConfigurationExtensionInterface.php | 28 + .../Extension/Extension.php | 121 + .../Extension/ExtensionInterface.php | 47 + .../Extension/ExtensionTrait.php | 58 + .../Extension/PrependExtensionInterface.php | 20 + vendor/symfony/dependency-injection/LICENSE | 19 + .../Instantiator/InstantiatorInterface.php | 32 + .../Instantiator/RealServiceInstantiator.php | 31 + .../LazyProxy/PhpDumper/DumperInterface.php | 33 + .../LazyProxy/PhpDumper/NullDumper.php | 44 + .../LazyProxy/ProxyHelper.php | 82 + .../Loader/ClosureLoader.php | 50 + .../Configurator/AbstractConfigurator.php | 98 + .../AbstractServiceConfigurator.php | 100 + .../Loader/Configurator/AliasConfigurator.php | 27 + .../ClosureReferenceConfigurator.php | 15 + .../Configurator/ContainerConfigurator.php | 205 + .../Configurator/DefaultsConfigurator.php | 61 + .../Loader/Configurator/EnvConfigurator.php | 181 + .../InlineServiceConfigurator.php | 47 + .../Configurator/InstanceofConfigurator.php | 45 + .../Configurator/ParametersConfigurator.php | 50 + .../Configurator/PrototypeConfigurator.php | 88 + .../Configurator/ReferenceConfigurator.php | 57 + .../Configurator/ServiceConfigurator.php | 78 + .../Configurator/ServicesConfigurator.php | 182 + .../Configurator/Traits/AbstractTrait.php | 26 + .../Configurator/Traits/ArgumentTrait.php | 37 + .../Traits/AutoconfigureTrait.php | 28 + .../Configurator/Traits/AutowireTrait.php | 25 + .../Loader/Configurator/Traits/BindTrait.php | 39 + .../Loader/Configurator/Traits/CallTrait.php | 32 + .../Loader/Configurator/Traits/ClassTrait.php | 25 + .../Configurator/Traits/ConfiguratorTrait.php | 27 + .../Configurator/Traits/DecorateTrait.php | 31 + .../Configurator/Traits/DeprecateTrait.php | 32 + .../Configurator/Traits/FactoryTrait.php | 36 + .../Loader/Configurator/Traits/FileTrait.php | 25 + .../Loader/Configurator/Traits/LazyTrait.php | 30 + .../Configurator/Traits/ParentTrait.php | 41 + .../Configurator/Traits/PropertyTrait.php | 26 + .../Configurator/Traits/PublicTrait.php | 31 + .../Loader/Configurator/Traits/ShareTrait.php | 25 + .../Configurator/Traits/SyntheticTrait.php | 26 + .../Loader/Configurator/Traits/TagTrait.php | 34 + .../Loader/DirectoryLoader.php | 53 + .../Loader/FileLoader.php | 215 + .../Loader/GlobFileLoader.php | 41 + .../Loader/IniFileLoader.php | 93 + .../Loader/PhpFileLoader.php | 188 + .../Loader/XmlFileLoader.php | 667 +++ .../Loader/YamlFileLoader.php | 741 +++ .../schema/dic/services/services-1.0.xsd | 364 ++ .../symfony/dependency-injection/PATCHES.txt | 7 + .../dependency-injection/Parameter.php | 32 + .../ParameterBag/ContainerBag.php | 49 + .../ParameterBag/ContainerBagInterface.php | 45 + .../EnvPlaceholderParameterBag.php | 153 + .../ParameterBag/FrozenParameterBag.php | 63 + .../ParameterBag/ParameterBag.php | 238 + .../ParameterBag/ParameterBagInterface.php | 83 + vendor/symfony/dependency-injection/README.md | 14 + .../dependency-injection/Reference.php | 44 + .../dependency-injection/ReverseContainer.php | 78 + .../dependency-injection/ServiceLocator.php | 137 + .../TaggedContainerInterface.php | 26 + .../dependency-injection/TypedReference.php | 48 + .../symfony/dependency-injection/Variable.php | 40 + .../dependency-injection/composer.json | 56 + .../deprecation-contracts/CHANGELOG.md | 5 + vendor/symfony/deprecation-contracts/LICENSE | 19 + .../symfony/deprecation-contracts/README.md | 26 + .../deprecation-contracts/composer.json | 35 + .../deprecation-contracts/function.php | 27 + vendor/symfony/filesystem/CHANGELOG.md | 82 + .../Exception/ExceptionInterface.php | 20 + .../Exception/FileNotFoundException.php | 32 + .../filesystem/Exception/IOException.php | 35 + .../Exception/IOExceptionInterface.php | 24 + .../Exception/InvalidArgumentException.php | 18 + .../filesystem/Exception/RuntimeException.php | 18 + vendor/symfony/filesystem/Filesystem.php | 667 +++ vendor/symfony/filesystem/LICENSE | 19 + vendor/symfony/filesystem/Path.php | 708 +++ vendor/symfony/filesystem/README.md | 13 + vendor/symfony/filesystem/composer.json | 32 + vendor/symfony/finder/CHANGELOG.md | 98 + .../symfony/finder/Comparator/Comparator.php | 69 + .../finder/Comparator/DateComparator.php | 45 + .../finder/Comparator/NumberComparator.php | 75 + .../Exception/AccessDeniedException.php | 18 + .../Exception/DirectoryNotFoundException.php | 18 + vendor/symfony/finder/Finder.php | 804 +++ vendor/symfony/finder/Gitignore.php | 81 + vendor/symfony/finder/Glob.php | 100 + .../finder/Iterator/CustomFilterIterator.php | 58 + .../Iterator/DateRangeFilterIterator.php | 53 + .../Iterator/DepthRangeFilterIterator.php | 47 + .../ExcludeDirectoryFilterIterator.php | 87 + .../Iterator/FileTypeFilterIterator.php | 50 + .../Iterator/FilecontentFilterIterator.php | 51 + .../Iterator/FilenameFilterIterator.php | 42 + .../symfony/finder/Iterator/LazyIterator.php | 32 + .../Iterator/MultiplePcreFilterIterator.php | 96 + .../finder/Iterator/PathFilterIterator.php | 51 + .../Iterator/RecursiveDirectoryIterator.php | 126 + .../Iterator/SizeRangeFilterIterator.php | 53 + .../finder/Iterator/SortableIterator.php | 117 + .../Iterator/VcsIgnoredFilterIterator.php | 134 + vendor/symfony/finder/LICENSE | 19 + vendor/symfony/finder/README.md | 14 + vendor/symfony/finder/SplFileInfo.php | 82 + vendor/symfony/finder/composer.json | 33 + vendor/symfony/polyfill-ctype/Ctype.php | 205 + vendor/symfony/polyfill-ctype/LICENSE | 19 + vendor/symfony/polyfill-ctype/README.md | 12 + vendor/symfony/polyfill-ctype/bootstrap.php | 50 + vendor/symfony/polyfill-ctype/bootstrap80.php | 79 + vendor/symfony/polyfill-ctype/composer.json | 50 + .../polyfill-intl-grapheme/Grapheme.php | 210 + vendor/symfony/polyfill-intl-grapheme/LICENSE | 19 + .../symfony/polyfill-intl-grapheme/README.md | 31 + .../polyfill-intl-grapheme/bootstrap.php | 58 + .../polyfill-intl-grapheme/bootstrap80.php | 77 + .../polyfill-intl-grapheme/composer.json | 49 + .../symfony/polyfill-intl-normalizer/LICENSE | 19 + .../polyfill-intl-normalizer/Normalizer.php | 258 + .../polyfill-intl-normalizer/README.md | 14 + .../Resources/stubs/Normalizer.php | 17 + .../unidata/canonicalComposition.php | 5 + .../unidata/canonicalDecomposition.php | 5 + .../Resources/unidata/combiningClass.php | 5 + .../unidata/compatibilityDecomposition.php | 5 + .../polyfill-intl-normalizer/bootstrap.php | 23 + .../polyfill-intl-normalizer/bootstrap80.php | 22 + .../polyfill-intl-normalizer/composer.json | 52 + vendor/symfony/polyfill-mbstring/LICENSE | 19 + vendor/symfony/polyfill-mbstring/Mbstring.php | 753 +++ vendor/symfony/polyfill-mbstring/README.md | 13 + .../Resources/unidata/caseFolding.php | 5 + .../Resources/unidata/lowerCase.php | 5 + .../Resources/unidata/titleCaseRegexp.php | 6 + .../Resources/unidata/upperCase.php | 5 + .../symfony/polyfill-mbstring/bootstrap.php | 151 + .../symfony/polyfill-mbstring/bootstrap80.php | 218 + .../symfony/polyfill-mbstring/composer.json | 51 + vendor/symfony/process/CHANGELOG.md | 116 + .../process/Exception/ExceptionInterface.php | 20 + .../Exception/InvalidArgumentException.php | 20 + .../process/Exception/LogicException.php | 20 + .../Exception/ProcessFailedException.php | 41 + .../Exception/ProcessSignaledException.php | 35 + .../Exception/ProcessTimedOutException.php | 63 + .../process/Exception/RuntimeException.php | 20 + vendor/symfony/process/ExecutableFinder.php | 79 + vendor/symfony/process/InputStream.php | 91 + vendor/symfony/process/LICENSE | 19 + .../symfony/process/PhpExecutableFinder.php | 85 + vendor/symfony/process/PhpProcess.php | 67 + .../symfony/process/Pipes/AbstractPipes.php | 160 + .../symfony/process/Pipes/PipesInterface.php | 54 + vendor/symfony/process/Pipes/UnixPipes.php | 116 + vendor/symfony/process/Pipes/WindowsPipes.php | 156 + vendor/symfony/process/Process.php | 1382 +++++ vendor/symfony/process/ProcessUtils.php | 63 + vendor/symfony/process/README.md | 13 + vendor/symfony/process/composer.json | 30 + .../service-contracts/Attribute/Required.php | 24 + .../Attribute/SubscribedService.php | 55 + vendor/symfony/service-contracts/CHANGELOG.md | 5 + vendor/symfony/service-contracts/LICENSE | 19 + vendor/symfony/service-contracts/README.md | 9 + .../service-contracts/ResetInterface.php | 32 + .../service-contracts/ServiceLocatorTrait.php | 112 + .../ServiceProviderInterface.php | 41 + .../ServiceSubscriberInterface.php | 60 + .../ServiceSubscriberTrait.php | 67 + .../Test/ServiceLocatorTest.php | 21 + .../Test/ServiceLocatorTestCase.php | 83 + .../symfony/service-contracts/composer.json | 50 + vendor/symfony/string/AbstractString.php | 646 +++ .../symfony/string/AbstractUnicodeString.php | 523 ++ vendor/symfony/string/ByteString.php | 459 ++ vendor/symfony/string/CHANGELOG.md | 40 + vendor/symfony/string/CodePointString.php | 234 + .../string/Exception/ExceptionInterface.php | 15 + .../Exception/InvalidArgumentException.php | 15 + .../string/Exception/RuntimeException.php | 15 + .../string/Inflector/EnglishInflector.php | 382 ++ .../string/Inflector/FrenchInflector.php | 122 + .../string/Inflector/InflectorInterface.php | 31 + vendor/symfony/string/LICENSE | 19 + vendor/symfony/string/LazyString.php | 132 + vendor/symfony/string/README.md | 14 + .../Resources/data/wcswidth_table_wide.php | 11 + .../Resources/data/wcswidth_table_zero.php | 11 + vendor/symfony/string/Resources/functions.php | 34 + .../symfony/string/Slugger/AsciiSlugger.php | 164 + .../string/Slugger/SluggerInterface.php | 25 + vendor/symfony/string/UnicodeString.php | 323 ++ vendor/symfony/string/composer.json | 54 + .../symplify/autowire-array-parameter/LICENSE | 25 + .../autowire-array-parameter/composer.json | 54 + .../autowire-array-parameter/easy-ci.php | 10 + .../symplify/autowire-array-parameter/ecs.php | 11 + .../autowire-array-parameter/phpstan.neon | 15 + .../autowire-array-parameter/rector.php | 26 + .../AutowireArrayParameterCompilerPass.php | 155 + .../DependencyInjection/DefinitionFinder.php | 64 + .../DocBlock/ParamTypeDocBlockResolver.php | 48 + .../DefinitionForTypeNotFoundException.php | 9 + .../src/Skipper/ParameterSkipper.php | 73 + .../TypeResolver/ParameterTypeResolver.php | 47 + vendor/symplify/easy-testing/LICENSE | 25 + vendor/symplify/easy-testing/bin/easy-testing | 5 + .../easy-testing/bin/easy-testing.php | 23 + vendor/symplify/easy-testing/composer.json | 53 + .../symplify/easy-testing/config/config.php | 16 + .../ValidateFixtureSkipNamingCommand.php | 58 + .../src/DataProvider/StaticFixtureFinder.php | 112 + .../src/DataProvider/StaticFixtureUpdater.php | 50 + .../easy-testing/src/Finder/FixtureFinder.php | 29 + .../FixtureSplitter/TrioFixtureSplitter.php | 33 + .../src/Kernel/EasyTestingKernel.php | 19 + .../src/MissplacedSkipPrefixResolver.php | 41 + .../Behavior/DirectoryAssertableTrait.php | 76 + .../src/PHPUnit/StaticPHPUnitEnvironment.php | 18 + .../src/StaticFixtureSplitter.php | 104 + .../src/ValueObject/EasyTestingConfig.php | 15 + .../ExpectedAndOutputFileInfoPair.php | 41 + .../ValueObject/FixtureSplit/TrioContent.php | 41 + .../ValueObject/IncorrectAndMissingSkips.php | 44 + .../src/ValueObject/InputAndExpected.php | 35 + .../ValueObject/InputFileInfoAndExpected.php | 47 + .../InputFileInfoAndExpectedFileInfo.php | 41 + .../easy-testing/src/ValueObject/Option.php | 12 + .../easy-testing/src/ValueObject/Prefix.php | 13 + .../src/ValueObject/SplitLine.php | 13 + vendor/symplify/package-builder/composer.json | 57 + .../package-builder/config/config.php | 21 + .../package-builder/phpstan-baseline.neon | 46 + .../src/Composer/VendorDirProvider.php | 31 + .../Command/AbstractSymplifyCommand.php | 47 + .../Formatter/ColorConsoleDiffFormatter.php | 85 + .../src/Console/Input/StaticInputDetector.php | 17 + .../src/Console/Output/ConsoleDiffer.php | 33 + .../src/Console/Style/SymfonyStyleFactory.php | 53 + .../AutowireInterfacesCompilerPass.php | 35 + .../ParameterMergingPhpFileLoader.php | 51 + .../src/Diff/DifferFactory.php | 20 + ...ompleteUnifiedDiffOutputBuilderFactory.php | 32 + .../HttpKernel/MissingInterfaceException.php | 9 + .../InvalidPrivatePropertyTypeException.php | 9 + .../MissingPrivatePropertyException.php | 9 + .../src/Exception/MissingServiceException.php | 9 + .../src/Parameter/ParameterProvider.php | 94 + .../package-builder/src/Php/TypeChecker.php | 24 + .../Reflection/ClassLikeExistenceChecker.php | 53 + .../src/Reflection/PrivatesAccessor.php | 75 + .../src/Reflection/PrivatesCaller.php | 50 + .../src/Strings/StringFormatConverter.php | 61 + .../Strings/StringFormatConverter.phpqIy1Ap | 0 .../src/Testing/AbstractKernelTestCase.php | 228 + .../ValueObject/ConsoleColorDiffConfig.php | 15 + .../src/ValueObject/MethodName.php | 23 + .../src/ValueObject/Option.php | 18 + .../src/Yaml/ParametersMerger.php | 77 + vendor/symplify/smart-file-system/LICENSE | 25 + .../symplify/smart-file-system/composer.json | 55 + .../Exception/DirectoryNotFoundException.php | 9 + .../src/Exception/FileNotFoundException.php | 9 + .../src/FileSystemFilter.php | 33 + .../smart-file-system/src/FileSystemGuard.php | 31 + .../src/Finder/FinderSanitizer.php | 31 + .../src/Finder/SmartFinder.php | 68 + .../src/Json/JsonFileSystem.php | 57 + .../src/Normalizer/PathNormalizer.php | 77 + .../smart-file-system/src/SmartFileInfo.php | 127 + .../smart-file-system/src/SmartFileSystem.php | 49 + vendor/symplify/symplify-kernel/README.md | 71 + vendor/symplify/symplify-kernel/composer.json | 48 + .../symplify-kernel/config/common-config.php | 31 + vendor/symplify/symplify-kernel/phpunit.xml | 9 + .../Loader/ParameterMergingLoaderFactory.php | 22 + .../src/ContainerBuilderFactory.php | 74 + .../Config/LoaderFactoryInterface.php | 11 + .../src/Contract/LightKernelInterface.php | 17 + .../LoadExtensionConfigsCompilerPass.php | 22 + .../src/Exception/BootException.php | 9 + .../Exception/ShouldNotHappenException.php | 12 + .../src/HttpKernel/AbstractSymplifyKernel.php | 47 + .../KernelBootAndApplicationRun.php | 98 + .../src/ValueObject/SymplifyKernelConfig.php | 15 + .../ContainerBuilderFactoryTest.php | 19 + .../config/some_services.php | 11 + vendor/webmozart/assert/CHANGELOG.md | 207 + vendor/webmozart/assert/LICENSE | 20 + vendor/webmozart/assert/README.md | 287 + vendor/webmozart/assert/composer.json | 43 + vendor/webmozart/assert/src/Assert.php | 1606 ++++++ .../assert/src/InvalidArgumentException.php | 15 + vendor/webmozart/assert/src/Mixin.php | 4630 +++++++++++++++++ 969 files changed, 84514 insertions(+), 5746 deletions(-) delete mode 100644 .editorconfig rename {build/target-repository/.github => .github}/workflows/auto_closer.yaml (100%) delete mode 100644 .gitignore rename build/target-repository/bootstrap.php => bootstrap.php (100%) delete mode 100644 build/rector-downgrade-php-72.php delete mode 100644 build/target-repository/.github/FUNDING.yml delete mode 100644 build/target-repository/.github/workflows/bare_run.yaml delete mode 100644 build/target-repository/README.md delete mode 100644 build/target-repository/composer.json create mode 100644 composer.lock delete mode 100644 ecs.php delete mode 100644 full-tool-build.sh delete mode 100644 packages-tests/ComposerJsonManipulator/ComposerJsonFactory/ComposerJsonFactoryTest.php delete mode 100644 packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/full_composer.json delete mode 100644 packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/some_composer.json delete mode 100644 packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/ComposerJsonSchemaValidationTest.php delete mode 100644 packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/Source/symfony-website_skeleton-composer.json delete mode 100644 packages-tests/ComposerJsonManipulator/Sorter/ComposerPackageSorterTest.php delete mode 100644 packages-tests/ComposerJsonManipulator/ValueObject/ComposerJsonTest.php delete mode 100644 packages-tests/Merge/Application/MergedAndDecoratedComposerJsonFactoryTest.php delete mode 100644 packages-tests/Merge/Application/Source/expected_composer.json delete mode 100644 packages-tests/Merge/Application/Source/packages/one_package.json delete mode 100644 packages-tests/Merge/Application/Source/packages/src/some_file.txt delete mode 100644 packages-tests/Merge/Application/Source/packages/tests/some_file.txt delete mode 100644 packages-tests/Merge/Application/Source/packages/two_package.json delete mode 100644 packages-tests/Merge/Application/Source/root_composer.json delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/AbstractComposerJsonDecoratorTest.php delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/AppenderComposerJsonDecoratorTest.php delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/appending_config.php delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/expected.json delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/input.json delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/to-append.json delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator/RemoverComposerJsonDecoratorTest.php delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator/RepositoryPathComposerJsonDecoratorTest.php delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/RootRemoveComposerJsonDecoratorTest.php delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/composer.json delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/expected-composer.json delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/packages/composer.json delete mode 100644 packages-tests/Merge/ComposerJsonDecorator/SortComposerJsonDecorator/SortComposerJsonDecoratorTest.php delete mode 100644 packages-tests/Merge/ComposerJsonMerger/ComposerJsonMergerTest.php delete mode 100644 packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority.test delete mode 100644 packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority_inversed.test delete mode 100644 packages-tests/Merge/ComposerJsonMerger/Fixture/with_authors.test delete mode 100644 packages-tests/Merge/ComposerJsonMerger/Fixture/with_existing_authors.test delete mode 100644 packages-tests/Merge/ComposerJsonMerger/Fixture/with_extra.test delete mode 100644 packages-tests/Merge/ComposerJsonMerger/Fixture/with_provide.test delete mode 100644 packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/keep_stability.test delete mode 100644 packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/main_has_minimum_stability.test delete mode 100644 packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/new_has_minimum_stability.test delete mode 100644 packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/no_minimum_stability.test delete mode 100644 packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/widen_stability.test delete mode 100644 packages-tests/Merge/ComposerKeyMerger/MinimalStabilityKeyMergerTest.php delete mode 100644 packages-tests/Merge/Package/AbstractMergeTestCase.php delete mode 100644 packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/CombineStringsToArrayJsonMergerTest.php delete mode 100644 packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/Source/expected.json delete mode 100644 packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-composer-patches.json delete mode 100644 packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-relative-paths.json delete mode 100644 packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected.json delete mode 100644 packages-tests/Merge/Package/PackageComposerJsonMergerTest.php delete mode 100644 packages-tests/Merge/Package/Source/package-one.json delete mode 100644 packages-tests/Merge/Package/Source/package-two.json delete mode 100644 packages-tests/Merge/Package/Source/src/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceComposerPatches/package-one.json delete mode 100644 packages-tests/Merge/Package/SourceComposerPatches/package-three.json delete mode 100644 packages-tests/Merge/Package/SourceComposerPatches/package-two.json delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/Something.php delete mode 100755 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/composer.json delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/lib/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/array/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/collection/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/core/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/list/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/shared/some_file.txt delete mode 100755 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/composer.json delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/collection/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core-extension/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/interfaces/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/list/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/shared/some_file.txt delete mode 100755 packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/composer.json delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/models/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/package-c/some_file.txt delete mode 100755 packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/composer.json delete mode 100644 packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/src/package-d/some_file.txt delete mode 100644 packages-tests/Merge/Package/SourceUniqueRepositories/package-one.json delete mode 100644 packages-tests/Merge/Package/SourceUniqueRepositories/package-three.json delete mode 100644 packages-tests/Merge/Package/SourceUniqueRepositories/package-two.json delete mode 100644 packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/autoload.json delete mode 100644 packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/expected-autoload.json delete mode 100644 packages-tests/Merge/PathResolver/AutoloadPathNormalizerTest.php delete mode 100644 packages-tests/Merge/PathResolver/ComposerPatchesPathNormalizerTest.php delete mode 100644 packages-tests/Propagate/VersionPropagator/Fixture/propagate-require-dev.test delete mode 100644 packages-tests/Propagate/VersionPropagator/Fixture/propagate.test delete mode 100644 packages-tests/Propagate/VersionPropagator/VersionPropagaterTest.php delete mode 100644 packages-tests/Release/ReleaseWorkerProvider/ReleaseWorkerProviderTest.php delete mode 100644 packages-tests/Release/ReleaseWorkerProvider/config/all_release_workers.php delete mode 100644 packages-tests/Testing/ComposerJson/ComposerJsonSymlinkerTest.php delete mode 100644 packages-tests/Testing/ComposerJson/Fixture/expected_deeper_path_repository.test delete mode 100644 packages-tests/Testing/ComposerJson/Fixture/expected_path_repository.test delete mode 100644 packages-tests/Testing/ComposerJson/Fixture/expected_repository.test delete mode 100644 packages-tests/Testing/ComposerJson/Fixture/expected_reuse_existing_repository.test delete mode 100644 packages-tests/Testing/ComposerJson/Fixture/expected_symlink_true.test delete mode 100644 packages-tests/Testing/ComposerJson/composer.json delete mode 100644 packages-tests/Testing/ComposerJson/config/test_config.php delete mode 100644 packages-tests/Testing/ComposerJson/packages/package-one/composer.json delete mode 100644 packages-tests/Testing/ComposerJson/packages/package-three/composer.json delete mode 100644 packages-tests/Testing/ComposerJson/packages/package-two/composer.json delete mode 100644 packages-tests/Testing/ComposerJson/packages/with-more-depth/package-four/composer.json delete mode 100644 packages-tests/Testing/PathResolver/PackagePathResolverTest.php delete mode 100644 packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/composer.json delete mode 100644 packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/nested_packages/nested/composer.json delete mode 100644 phpstan.neon delete mode 100644 phpunit.xml delete mode 100644 prefix-code.sh delete mode 100644 rector.php delete mode 100644 scoper.php delete mode 100644 tests/ConflictingUpdater/Fixture/expected_composer.test delete mode 100644 tests/ConflictingUpdater/Fixture/input_composer_backup.test delete mode 100644 tests/DependencyUpdater/DependencyUpdaterTest.php delete mode 100644 tests/DependencyUpdater/Source/backup-first.json delete mode 100644 tests/DependencyUpdater/Source/expected-first.json delete mode 100644 tests/DependencyUpdater/Source/first.json delete mode 100644 tests/DevMasterAliasUpdater/DevMasterAliasUpdaterTest.php delete mode 100644 tests/DevMasterAliasUpdater/Source/backup-first.json delete mode 100644 tests/DevMasterAliasUpdater/Source/expected-first.json delete mode 100644 tests/DevMasterAliasUpdater/Source/first.json delete mode 100644 tests/FileSystem/JsonFileManager/JsonFileManagerTest.php delete mode 100644 tests/FileSystem/JsonFileManager/Source/dynamic.json delete mode 100644 tests/FileSystem/JsonFileManager/Source/expected-inlined.json delete mode 100644 tests/FileSystem/JsonFileManager/Source/expected-second.json delete mode 100644 tests/FileSystem/JsonFileManager/Source/first.json delete mode 100644 tests/FileSystem/JsonFileManager/config/inlined_section_config.php delete mode 100644 tests/Finder/PackageComposerFinder/PackageComposerFinderTest.php delete mode 100644 tests/Finder/PackageComposerFinder/Source/First/ExcludeThis/composer.json delete mode 100644 tests/Finder/PackageComposerFinder/Source/First/composer.json delete mode 100644 tests/Finder/PackageComposerFinder/Source/Second/composer.json delete mode 100644 tests/Finder/PackageComposerFinder/Source/source_config.php delete mode 100644 tests/InterdependencyUpdater/InterdependencyUpdaterTest.php delete mode 100644 tests/InterdependencyUpdater/Source/backup-first.json delete mode 100644 tests/InterdependencyUpdater/Source/expected-first-packages.json delete mode 100644 tests/InterdependencyUpdater/Source/expected-first-vendor.json delete mode 100644 tests/InterdependencyUpdater/Source/first.json delete mode 100644 tests/Utils/VersionUtilsTest.php delete mode 100644 tests/VersionValidator/Source/first.json delete mode 100644 tests/VersionValidator/Source/second.json delete mode 100644 tests/VersionValidator/VersionValidatorTest.php create mode 100644 vendor/autoload.php create mode 100644 vendor/bin/easy-testing create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/composer/installed.php create mode 100644 vendor/nette/utils/composer.json create mode 100644 vendor/nette/utils/license.md create mode 100644 vendor/nette/utils/readme.md create mode 100644 vendor/nette/utils/src/HtmlStringable.php create mode 100644 vendor/nette/utils/src/Iterators/CachingIterator.php create mode 100644 vendor/nette/utils/src/Iterators/Mapper.php create mode 100644 vendor/nette/utils/src/SmartObject.php create mode 100644 vendor/nette/utils/src/StaticClass.php create mode 100644 vendor/nette/utils/src/Translator.php create mode 100644 vendor/nette/utils/src/Utils/ArrayHash.php create mode 100644 vendor/nette/utils/src/Utils/ArrayList.php create mode 100644 vendor/nette/utils/src/Utils/Arrays.php create mode 100644 vendor/nette/utils/src/Utils/Callback.php create mode 100644 vendor/nette/utils/src/Utils/DateTime.php create mode 100644 vendor/nette/utils/src/Utils/FileSystem.php create mode 100644 vendor/nette/utils/src/Utils/Floats.php create mode 100644 vendor/nette/utils/src/Utils/Helpers.php create mode 100644 vendor/nette/utils/src/Utils/Html.php create mode 100644 vendor/nette/utils/src/Utils/Image.php create mode 100644 vendor/nette/utils/src/Utils/Json.php create mode 100644 vendor/nette/utils/src/Utils/ObjectHelpers.php create mode 100644 vendor/nette/utils/src/Utils/ObjectMixin.php create mode 100644 vendor/nette/utils/src/Utils/Paginator.php create mode 100644 vendor/nette/utils/src/Utils/Random.php create mode 100644 vendor/nette/utils/src/Utils/Reflection.php create mode 100644 vendor/nette/utils/src/Utils/Strings.php create mode 100644 vendor/nette/utils/src/Utils/Type.php create mode 100644 vendor/nette/utils/src/Utils/Validators.php create mode 100644 vendor/nette/utils/src/Utils/exceptions.php create mode 100644 vendor/nette/utils/src/compatibility.php create mode 100644 vendor/nette/utils/src/exceptions.php create mode 100644 vendor/phar-io/version/CHANGELOG.md create mode 100644 vendor/phar-io/version/LICENSE create mode 100644 vendor/phar-io/version/README.md create mode 100644 vendor/phar-io/version/composer.json create mode 100644 vendor/phar-io/version/src/BuildMetaData.php create mode 100644 vendor/phar-io/version/src/PreReleaseSuffix.php create mode 100644 vendor/phar-io/version/src/Version.php create mode 100644 vendor/phar-io/version/src/VersionConstraintParser.php create mode 100644 vendor/phar-io/version/src/VersionConstraintValue.php create mode 100644 vendor/phar-io/version/src/VersionNumber.php create mode 100644 vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php create mode 100644 vendor/phar-io/version/src/constraints/AnyVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/ExactVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php create mode 100644 vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/VersionConstraint.php create mode 100644 vendor/phar-io/version/src/exceptions/Exception.php create mode 100644 vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php create mode 100644 vendor/phar-io/version/src/exceptions/InvalidVersionException.php create mode 100644 vendor/phar-io/version/src/exceptions/NoBuildMetaDataException.php create mode 100644 vendor/phar-io/version/src/exceptions/NoPreReleaseSuffixException.php create mode 100644 vendor/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php create mode 100644 vendor/psr/container/LICENSE create mode 100644 vendor/psr/container/README.md create mode 100644 vendor/psr/container/composer.json create mode 100644 vendor/psr/container/src/ContainerExceptionInterface.php create mode 100644 vendor/psr/container/src/ContainerInterface.php create mode 100644 vendor/psr/container/src/NotFoundExceptionInterface.php create mode 100644 vendor/scoper-autoload.php create mode 100644 vendor/sebastian/diff/ChangeLog.md create mode 100644 vendor/sebastian/diff/LICENSE create mode 100644 vendor/sebastian/diff/README.md create mode 100644 vendor/sebastian/diff/SECURITY.md create mode 100644 vendor/sebastian/diff/composer.json create mode 100644 vendor/sebastian/diff/src/Chunk.php create mode 100644 vendor/sebastian/diff/src/Diff.php create mode 100644 vendor/sebastian/diff/src/Differ.php create mode 100644 vendor/sebastian/diff/src/Exception/ConfigurationException.php create mode 100644 vendor/sebastian/diff/src/Exception/Exception.php create mode 100644 vendor/sebastian/diff/src/Exception/InvalidArgumentException.php create mode 100644 vendor/sebastian/diff/src/Line.php create mode 100644 vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php create mode 100644 vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php create mode 100644 vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php create mode 100644 vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Parser.php create mode 100644 vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php create mode 100644 vendor/symfony/config/Builder/ClassBuilder.php create mode 100644 vendor/symfony/config/Builder/ConfigBuilderGenerator.php create mode 100644 vendor/symfony/config/Builder/ConfigBuilderGeneratorInterface.php create mode 100644 vendor/symfony/config/Builder/ConfigBuilderInterface.php create mode 100644 vendor/symfony/config/Builder/Method.php create mode 100644 vendor/symfony/config/Builder/Property.php create mode 100644 vendor/symfony/config/CHANGELOG.md create mode 100644 vendor/symfony/config/ConfigCache.php create mode 100644 vendor/symfony/config/ConfigCacheFactory.php create mode 100644 vendor/symfony/config/ConfigCacheFactoryInterface.php create mode 100644 vendor/symfony/config/ConfigCacheInterface.php create mode 100644 vendor/symfony/config/Definition/ArrayNode.php create mode 100644 vendor/symfony/config/Definition/BaseNode.php create mode 100644 vendor/symfony/config/Definition/BooleanNode.php create mode 100644 vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/BuilderAwareInterface.php create mode 100644 vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/ExprBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/MergeBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/NodeBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/NodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/NodeParentInterface.php create mode 100644 vendor/symfony/config/Definition/Builder/NormalizationBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php create mode 100644 vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/Builder/TreeBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/ValidationBuilder.php create mode 100644 vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php create mode 100644 vendor/symfony/config/Definition/ConfigurableInterface.php create mode 100644 vendor/symfony/config/Definition/Configuration.php create mode 100644 vendor/symfony/config/Definition/ConfigurationInterface.php create mode 100644 vendor/symfony/config/Definition/Configurator/DefinitionConfigurator.php create mode 100644 vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php create mode 100644 vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php create mode 100644 vendor/symfony/config/Definition/EnumNode.php create mode 100644 vendor/symfony/config/Definition/Exception/DuplicateKeyException.php create mode 100644 vendor/symfony/config/Definition/Exception/Exception.php create mode 100644 vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php create mode 100644 vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php create mode 100644 vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php create mode 100644 vendor/symfony/config/Definition/Exception/InvalidTypeException.php create mode 100644 vendor/symfony/config/Definition/Exception/UnsetKeyException.php create mode 100644 vendor/symfony/config/Definition/FloatNode.php create mode 100644 vendor/symfony/config/Definition/IntegerNode.php create mode 100644 vendor/symfony/config/Definition/Loader/DefinitionFileLoader.php create mode 100644 vendor/symfony/config/Definition/NodeInterface.php create mode 100644 vendor/symfony/config/Definition/NumericNode.php create mode 100644 vendor/symfony/config/Definition/Processor.php create mode 100644 vendor/symfony/config/Definition/PrototypeNodeInterface.php create mode 100644 vendor/symfony/config/Definition/PrototypedArrayNode.php create mode 100644 vendor/symfony/config/Definition/ScalarNode.php create mode 100644 vendor/symfony/config/Definition/VariableNode.php create mode 100644 vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php create mode 100644 vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php create mode 100644 vendor/symfony/config/Exception/LoaderLoadException.php create mode 100644 vendor/symfony/config/FileLocator.php create mode 100644 vendor/symfony/config/FileLocatorInterface.php create mode 100644 vendor/symfony/config/LICENSE create mode 100644 vendor/symfony/config/Loader/DelegatingLoader.php create mode 100644 vendor/symfony/config/Loader/DirectoryAwareLoaderInterface.php create mode 100644 vendor/symfony/config/Loader/FileLoader.php create mode 100644 vendor/symfony/config/Loader/GlobFileLoader.php create mode 100644 vendor/symfony/config/Loader/Loader.php create mode 100644 vendor/symfony/config/Loader/LoaderInterface.php create mode 100644 vendor/symfony/config/Loader/LoaderResolver.php create mode 100644 vendor/symfony/config/Loader/LoaderResolverInterface.php create mode 100644 vendor/symfony/config/Loader/ParamConfigurator.php create mode 100644 vendor/symfony/config/README.md create mode 100644 vendor/symfony/config/Resource/ClassExistenceResource.php create mode 100644 vendor/symfony/config/Resource/ComposerResource.php create mode 100644 vendor/symfony/config/Resource/DirectoryResource.php create mode 100644 vendor/symfony/config/Resource/FileExistenceResource.php create mode 100644 vendor/symfony/config/Resource/FileResource.php create mode 100644 vendor/symfony/config/Resource/GlobResource.php create mode 100644 vendor/symfony/config/Resource/ReflectionClassResource.php create mode 100644 vendor/symfony/config/Resource/ResourceInterface.php create mode 100644 vendor/symfony/config/Resource/SelfCheckingResourceChecker.php create mode 100644 vendor/symfony/config/Resource/SelfCheckingResourceInterface.php create mode 100644 vendor/symfony/config/ResourceCheckerConfigCache.php create mode 100644 vendor/symfony/config/ResourceCheckerConfigCacheFactory.php create mode 100644 vendor/symfony/config/ResourceCheckerInterface.php create mode 100644 vendor/symfony/config/Util/Exception/InvalidXmlException.php create mode 100644 vendor/symfony/config/Util/Exception/XmlParsingException.php create mode 100644 vendor/symfony/config/Util/XmlUtils.php create mode 100644 vendor/symfony/config/composer.json create mode 100644 vendor/symfony/console/Application.php create mode 100644 vendor/symfony/console/Attribute/AsCommand.php create mode 100644 vendor/symfony/console/CHANGELOG.md create mode 100644 vendor/symfony/console/CI/GithubActionReporter.php create mode 100644 vendor/symfony/console/Color.php create mode 100644 vendor/symfony/console/Command/Command.php create mode 100644 vendor/symfony/console/Command/CompleteCommand.php create mode 100644 vendor/symfony/console/Command/DumpCompletionCommand.php create mode 100644 vendor/symfony/console/Command/HelpCommand.php create mode 100644 vendor/symfony/console/Command/LazyCommand.php create mode 100644 vendor/symfony/console/Command/ListCommand.php create mode 100644 vendor/symfony/console/Command/LockableTrait.php create mode 100644 vendor/symfony/console/Command/SignalableCommandInterface.php create mode 100644 vendor/symfony/console/CommandLoader/CommandLoaderInterface.php create mode 100644 vendor/symfony/console/CommandLoader/ContainerCommandLoader.php create mode 100644 vendor/symfony/console/CommandLoader/FactoryCommandLoader.php create mode 100644 vendor/symfony/console/Completion/CompletionInput.php create mode 100644 vendor/symfony/console/Completion/CompletionSuggestions.php create mode 100644 vendor/symfony/console/Completion/Output/BashCompletionOutput.php create mode 100644 vendor/symfony/console/Completion/Output/CompletionOutputInterface.php create mode 100644 vendor/symfony/console/Completion/Output/FishCompletionOutput.php create mode 100644 vendor/symfony/console/Completion/Output/ZshCompletionOutput.php create mode 100644 vendor/symfony/console/Completion/Suggestion.php create mode 100644 vendor/symfony/console/ConsoleEvents.php create mode 100644 vendor/symfony/console/Cursor.php create mode 100644 vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php create mode 100644 vendor/symfony/console/Descriptor/ApplicationDescription.php create mode 100644 vendor/symfony/console/Descriptor/Descriptor.php create mode 100644 vendor/symfony/console/Descriptor/DescriptorInterface.php create mode 100644 vendor/symfony/console/Descriptor/JsonDescriptor.php create mode 100644 vendor/symfony/console/Descriptor/MarkdownDescriptor.php create mode 100644 vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php create mode 100644 vendor/symfony/console/Descriptor/TextDescriptor.php create mode 100644 vendor/symfony/console/Descriptor/XmlDescriptor.php create mode 100644 vendor/symfony/console/Event/ConsoleCommandEvent.php create mode 100644 vendor/symfony/console/Event/ConsoleErrorEvent.php create mode 100644 vendor/symfony/console/Event/ConsoleEvent.php create mode 100644 vendor/symfony/console/Event/ConsoleSignalEvent.php create mode 100644 vendor/symfony/console/Event/ConsoleTerminateEvent.php create mode 100644 vendor/symfony/console/EventListener/ErrorListener.php create mode 100644 vendor/symfony/console/Exception/CommandNotFoundException.php create mode 100644 vendor/symfony/console/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/console/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/console/Exception/InvalidOptionException.php create mode 100644 vendor/symfony/console/Exception/LogicException.php create mode 100644 vendor/symfony/console/Exception/MissingInputException.php create mode 100644 vendor/symfony/console/Exception/NamespaceNotFoundException.php create mode 100644 vendor/symfony/console/Exception/RuntimeException.php create mode 100644 vendor/symfony/console/Formatter/NullOutputFormatter.php create mode 100644 vendor/symfony/console/Formatter/NullOutputFormatterStyle.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatter.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterInterface.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyle.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php create mode 100644 vendor/symfony/console/Formatter/OutputFormatterStyleStack.php create mode 100644 vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php create mode 100644 vendor/symfony/console/Helper/DebugFormatterHelper.php create mode 100644 vendor/symfony/console/Helper/DescriptorHelper.php create mode 100644 vendor/symfony/console/Helper/Dumper.php create mode 100644 vendor/symfony/console/Helper/FormatterHelper.php create mode 100644 vendor/symfony/console/Helper/Helper.php create mode 100644 vendor/symfony/console/Helper/HelperInterface.php create mode 100644 vendor/symfony/console/Helper/HelperSet.php create mode 100644 vendor/symfony/console/Helper/InputAwareHelper.php create mode 100644 vendor/symfony/console/Helper/OutputWrapper.php create mode 100644 vendor/symfony/console/Helper/ProcessHelper.php create mode 100644 vendor/symfony/console/Helper/ProgressBar.php create mode 100644 vendor/symfony/console/Helper/ProgressIndicator.php create mode 100644 vendor/symfony/console/Helper/QuestionHelper.php create mode 100644 vendor/symfony/console/Helper/SymfonyQuestionHelper.php create mode 100644 vendor/symfony/console/Helper/Table.php create mode 100644 vendor/symfony/console/Helper/TableCell.php create mode 100644 vendor/symfony/console/Helper/TableCellStyle.php create mode 100644 vendor/symfony/console/Helper/TableRows.php create mode 100644 vendor/symfony/console/Helper/TableSeparator.php create mode 100644 vendor/symfony/console/Helper/TableStyle.php create mode 100644 vendor/symfony/console/Input/ArgvInput.php create mode 100644 vendor/symfony/console/Input/ArrayInput.php create mode 100644 vendor/symfony/console/Input/Input.php create mode 100644 vendor/symfony/console/Input/InputArgument.php create mode 100644 vendor/symfony/console/Input/InputAwareInterface.php create mode 100644 vendor/symfony/console/Input/InputDefinition.php create mode 100644 vendor/symfony/console/Input/InputInterface.php create mode 100644 vendor/symfony/console/Input/InputOption.php create mode 100644 vendor/symfony/console/Input/StreamableInputInterface.php create mode 100644 vendor/symfony/console/Input/StringInput.php create mode 100644 vendor/symfony/console/LICENSE create mode 100644 vendor/symfony/console/Logger/ConsoleLogger.php create mode 100644 vendor/symfony/console/Output/AnsiColorMode.php create mode 100644 vendor/symfony/console/Output/BufferedOutput.php create mode 100644 vendor/symfony/console/Output/ConsoleOutput.php create mode 100644 vendor/symfony/console/Output/ConsoleOutputInterface.php create mode 100644 vendor/symfony/console/Output/ConsoleSectionOutput.php create mode 100644 vendor/symfony/console/Output/NullOutput.php create mode 100644 vendor/symfony/console/Output/Output.php create mode 100644 vendor/symfony/console/Output/OutputInterface.php create mode 100644 vendor/symfony/console/Output/StreamOutput.php create mode 100644 vendor/symfony/console/Output/TrimmedBufferOutput.php create mode 100644 vendor/symfony/console/Question/ChoiceQuestion.php create mode 100644 vendor/symfony/console/Question/ConfirmationQuestion.php create mode 100644 vendor/symfony/console/Question/Question.php create mode 100644 vendor/symfony/console/README.md create mode 100644 vendor/symfony/console/Resources/bin/hiddeninput.exe create mode 100644 vendor/symfony/console/Resources/completion.bash create mode 100644 vendor/symfony/console/Resources/completion.fish create mode 100644 vendor/symfony/console/Resources/completion.zsh create mode 100644 vendor/symfony/console/SignalRegistry/SignalRegistry.php create mode 100644 vendor/symfony/console/SingleCommandApplication.php create mode 100644 vendor/symfony/console/Style/OutputStyle.php create mode 100644 vendor/symfony/console/Style/StyleInterface.php create mode 100644 vendor/symfony/console/Style/SymfonyStyle.php create mode 100644 vendor/symfony/console/Terminal.php create mode 100644 vendor/symfony/console/Tester/ApplicationTester.php create mode 100644 vendor/symfony/console/Tester/CommandCompletionTester.php create mode 100644 vendor/symfony/console/Tester/CommandTester.php create mode 100644 vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php create mode 100644 vendor/symfony/console/Tester/TesterTrait.php create mode 100644 vendor/symfony/console/composer.json create mode 100644 vendor/symfony/dependency-injection/Alias.php create mode 100644 vendor/symfony/dependency-injection/Argument/AbstractArgument.php create mode 100644 vendor/symfony/dependency-injection/Argument/ArgumentInterface.php create mode 100644 vendor/symfony/dependency-injection/Argument/BoundArgument.php create mode 100644 vendor/symfony/dependency-injection/Argument/IteratorArgument.php create mode 100644 vendor/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php create mode 100644 vendor/symfony/dependency-injection/Argument/RewindableGenerator.php create mode 100644 vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php create mode 100644 vendor/symfony/dependency-injection/Argument/ServiceLocator.php create mode 100644 vendor/symfony/dependency-injection/Argument/ServiceLocatorArgument.php create mode 100644 vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php create mode 100644 vendor/symfony/dependency-injection/Attribute/AsDecorator.php create mode 100644 vendor/symfony/dependency-injection/Attribute/AsTaggedItem.php create mode 100644 vendor/symfony/dependency-injection/Attribute/Autoconfigure.php create mode 100644 vendor/symfony/dependency-injection/Attribute/AutoconfigureTag.php create mode 100644 vendor/symfony/dependency-injection/Attribute/Autowire.php create mode 100644 vendor/symfony/dependency-injection/Attribute/MapDecorated.php create mode 100644 vendor/symfony/dependency-injection/Attribute/TaggedIterator.php create mode 100644 vendor/symfony/dependency-injection/Attribute/TaggedLocator.php create mode 100644 vendor/symfony/dependency-injection/Attribute/Target.php create mode 100644 vendor/symfony/dependency-injection/Attribute/When.php create mode 100644 vendor/symfony/dependency-injection/CHANGELOG.md create mode 100644 vendor/symfony/dependency-injection/ChildDefinition.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AliasDeprecatedPublicServicesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AutowireAsDecoratorPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AutowirePass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/AutowireRequiredPropertiesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/Compiler.php create mode 100644 vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php create mode 100644 vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/PassConfig.php create mode 100644 vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php create mode 100644 vendor/symfony/dependency-injection/Compiler/RegisterAutoconfigureAttributesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveDecoratorStackPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveNoPreloadPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php create mode 100644 vendor/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php create mode 100644 vendor/symfony/dependency-injection/Config/ContainerParametersResource.php create mode 100644 vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php create mode 100644 vendor/symfony/dependency-injection/Container.php create mode 100644 vendor/symfony/dependency-injection/ContainerAwareInterface.php create mode 100644 vendor/symfony/dependency-injection/ContainerAwareTrait.php create mode 100644 vendor/symfony/dependency-injection/ContainerBuilder.php create mode 100644 vendor/symfony/dependency-injection/ContainerInterface.php create mode 100644 vendor/symfony/dependency-injection/Definition.php create mode 100644 vendor/symfony/dependency-injection/Dumper/Dumper.php create mode 100644 vendor/symfony/dependency-injection/Dumper/DumperInterface.php create mode 100644 vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php create mode 100644 vendor/symfony/dependency-injection/Dumper/PhpDumper.php create mode 100644 vendor/symfony/dependency-injection/Dumper/Preloader.php create mode 100644 vendor/symfony/dependency-injection/Dumper/XmlDumper.php create mode 100644 vendor/symfony/dependency-injection/Dumper/YamlDumper.php create mode 100644 vendor/symfony/dependency-injection/EnvVarLoaderInterface.php create mode 100644 vendor/symfony/dependency-injection/EnvVarProcessor.php create mode 100644 vendor/symfony/dependency-injection/EnvVarProcessorInterface.php create mode 100644 vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php create mode 100644 vendor/symfony/dependency-injection/Exception/BadMethodCallException.php create mode 100644 vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php create mode 100644 vendor/symfony/dependency-injection/Exception/EnvParameterException.php create mode 100644 vendor/symfony/dependency-injection/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/dependency-injection/Exception/InvalidParameterTypeException.php create mode 100644 vendor/symfony/dependency-injection/Exception/LogicException.php create mode 100644 vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php create mode 100644 vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php create mode 100644 vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php create mode 100644 vendor/symfony/dependency-injection/Exception/RuntimeException.php create mode 100644 vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php create mode 100644 vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php create mode 100644 vendor/symfony/dependency-injection/ExpressionLanguage.php create mode 100644 vendor/symfony/dependency-injection/ExpressionLanguageProvider.php create mode 100644 vendor/symfony/dependency-injection/Extension/AbstractExtension.php create mode 100644 vendor/symfony/dependency-injection/Extension/ConfigurableExtensionInterface.php create mode 100644 vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php create mode 100644 vendor/symfony/dependency-injection/Extension/Extension.php create mode 100644 vendor/symfony/dependency-injection/Extension/ExtensionInterface.php create mode 100644 vendor/symfony/dependency-injection/Extension/ExtensionTrait.php create mode 100644 vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php create mode 100644 vendor/symfony/dependency-injection/LICENSE create mode 100644 vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php create mode 100644 vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php create mode 100644 vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php create mode 100644 vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php create mode 100644 vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php create mode 100644 vendor/symfony/dependency-injection/Loader/ClosureLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/ClosureReferenceConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/EnvConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php create mode 100644 vendor/symfony/dependency-injection/Loader/DirectoryLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/FileLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/GlobFileLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/IniFileLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/PhpFileLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/XmlFileLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/YamlFileLoader.php create mode 100644 vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd create mode 100644 vendor/symfony/dependency-injection/PATCHES.txt create mode 100644 vendor/symfony/dependency-injection/Parameter.php create mode 100644 vendor/symfony/dependency-injection/ParameterBag/ContainerBag.php create mode 100644 vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php create mode 100644 vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php create mode 100644 vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php create mode 100644 vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php create mode 100644 vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php create mode 100644 vendor/symfony/dependency-injection/README.md create mode 100644 vendor/symfony/dependency-injection/Reference.php create mode 100644 vendor/symfony/dependency-injection/ReverseContainer.php create mode 100644 vendor/symfony/dependency-injection/ServiceLocator.php create mode 100644 vendor/symfony/dependency-injection/TaggedContainerInterface.php create mode 100644 vendor/symfony/dependency-injection/TypedReference.php create mode 100644 vendor/symfony/dependency-injection/Variable.php create mode 100644 vendor/symfony/dependency-injection/composer.json create mode 100644 vendor/symfony/deprecation-contracts/CHANGELOG.md create mode 100644 vendor/symfony/deprecation-contracts/LICENSE create mode 100644 vendor/symfony/deprecation-contracts/README.md create mode 100644 vendor/symfony/deprecation-contracts/composer.json create mode 100644 vendor/symfony/deprecation-contracts/function.php create mode 100644 vendor/symfony/filesystem/CHANGELOG.md create mode 100644 vendor/symfony/filesystem/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/filesystem/Exception/FileNotFoundException.php create mode 100644 vendor/symfony/filesystem/Exception/IOException.php create mode 100644 vendor/symfony/filesystem/Exception/IOExceptionInterface.php create mode 100644 vendor/symfony/filesystem/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/filesystem/Exception/RuntimeException.php create mode 100644 vendor/symfony/filesystem/Filesystem.php create mode 100644 vendor/symfony/filesystem/LICENSE create mode 100644 vendor/symfony/filesystem/Path.php create mode 100644 vendor/symfony/filesystem/README.md create mode 100644 vendor/symfony/filesystem/composer.json create mode 100644 vendor/symfony/finder/CHANGELOG.md create mode 100644 vendor/symfony/finder/Comparator/Comparator.php create mode 100644 vendor/symfony/finder/Comparator/DateComparator.php create mode 100644 vendor/symfony/finder/Comparator/NumberComparator.php create mode 100644 vendor/symfony/finder/Exception/AccessDeniedException.php create mode 100644 vendor/symfony/finder/Exception/DirectoryNotFoundException.php create mode 100644 vendor/symfony/finder/Finder.php create mode 100644 vendor/symfony/finder/Gitignore.php create mode 100644 vendor/symfony/finder/Glob.php create mode 100644 vendor/symfony/finder/Iterator/CustomFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/DateRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/FileTypeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/FilecontentFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/FilenameFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/LazyIterator.php create mode 100644 vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/PathFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php create mode 100644 vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php create mode 100644 vendor/symfony/finder/Iterator/SortableIterator.php create mode 100644 vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php create mode 100644 vendor/symfony/finder/LICENSE create mode 100644 vendor/symfony/finder/README.md create mode 100644 vendor/symfony/finder/SplFileInfo.php create mode 100644 vendor/symfony/finder/composer.json create mode 100644 vendor/symfony/polyfill-ctype/Ctype.php create mode 100644 vendor/symfony/polyfill-ctype/LICENSE create mode 100644 vendor/symfony/polyfill-ctype/README.md create mode 100644 vendor/symfony/polyfill-ctype/bootstrap.php create mode 100644 vendor/symfony/polyfill-ctype/bootstrap80.php create mode 100644 vendor/symfony/polyfill-ctype/composer.json create mode 100644 vendor/symfony/polyfill-intl-grapheme/Grapheme.php create mode 100644 vendor/symfony/polyfill-intl-grapheme/LICENSE create mode 100644 vendor/symfony/polyfill-intl-grapheme/README.md create mode 100644 vendor/symfony/polyfill-intl-grapheme/bootstrap.php create mode 100644 vendor/symfony/polyfill-intl-grapheme/bootstrap80.php create mode 100644 vendor/symfony/polyfill-intl-grapheme/composer.json create mode 100644 vendor/symfony/polyfill-intl-normalizer/LICENSE create mode 100644 vendor/symfony/polyfill-intl-normalizer/Normalizer.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/README.md create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/bootstrap.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/bootstrap80.php create mode 100644 vendor/symfony/polyfill-intl-normalizer/composer.json create mode 100644 vendor/symfony/polyfill-mbstring/LICENSE create mode 100644 vendor/symfony/polyfill-mbstring/Mbstring.php create mode 100644 vendor/symfony/polyfill-mbstring/README.md create mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php create mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php create mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php create mode 100644 vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php create mode 100644 vendor/symfony/polyfill-mbstring/bootstrap.php create mode 100644 vendor/symfony/polyfill-mbstring/bootstrap80.php create mode 100644 vendor/symfony/polyfill-mbstring/composer.json create mode 100644 vendor/symfony/process/CHANGELOG.md create mode 100644 vendor/symfony/process/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/process/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/process/Exception/LogicException.php create mode 100644 vendor/symfony/process/Exception/ProcessFailedException.php create mode 100644 vendor/symfony/process/Exception/ProcessSignaledException.php create mode 100644 vendor/symfony/process/Exception/ProcessTimedOutException.php create mode 100644 vendor/symfony/process/Exception/RuntimeException.php create mode 100644 vendor/symfony/process/ExecutableFinder.php create mode 100644 vendor/symfony/process/InputStream.php create mode 100644 vendor/symfony/process/LICENSE create mode 100644 vendor/symfony/process/PhpExecutableFinder.php create mode 100644 vendor/symfony/process/PhpProcess.php create mode 100644 vendor/symfony/process/Pipes/AbstractPipes.php create mode 100644 vendor/symfony/process/Pipes/PipesInterface.php create mode 100644 vendor/symfony/process/Pipes/UnixPipes.php create mode 100644 vendor/symfony/process/Pipes/WindowsPipes.php create mode 100644 vendor/symfony/process/Process.php create mode 100644 vendor/symfony/process/ProcessUtils.php create mode 100644 vendor/symfony/process/README.md create mode 100644 vendor/symfony/process/composer.json create mode 100644 vendor/symfony/service-contracts/Attribute/Required.php create mode 100644 vendor/symfony/service-contracts/Attribute/SubscribedService.php create mode 100644 vendor/symfony/service-contracts/CHANGELOG.md create mode 100644 vendor/symfony/service-contracts/LICENSE create mode 100644 vendor/symfony/service-contracts/README.md create mode 100644 vendor/symfony/service-contracts/ResetInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceLocatorTrait.php create mode 100644 vendor/symfony/service-contracts/ServiceProviderInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceSubscriberInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceSubscriberTrait.php create mode 100644 vendor/symfony/service-contracts/Test/ServiceLocatorTest.php create mode 100644 vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php create mode 100644 vendor/symfony/service-contracts/composer.json create mode 100644 vendor/symfony/string/AbstractString.php create mode 100644 vendor/symfony/string/AbstractUnicodeString.php create mode 100644 vendor/symfony/string/ByteString.php create mode 100644 vendor/symfony/string/CHANGELOG.md create mode 100644 vendor/symfony/string/CodePointString.php create mode 100644 vendor/symfony/string/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/string/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/string/Exception/RuntimeException.php create mode 100644 vendor/symfony/string/Inflector/EnglishInflector.php create mode 100644 vendor/symfony/string/Inflector/FrenchInflector.php create mode 100644 vendor/symfony/string/Inflector/InflectorInterface.php create mode 100644 vendor/symfony/string/LICENSE create mode 100644 vendor/symfony/string/LazyString.php create mode 100644 vendor/symfony/string/README.md create mode 100644 vendor/symfony/string/Resources/data/wcswidth_table_wide.php create mode 100644 vendor/symfony/string/Resources/data/wcswidth_table_zero.php create mode 100644 vendor/symfony/string/Resources/functions.php create mode 100644 vendor/symfony/string/Slugger/AsciiSlugger.php create mode 100644 vendor/symfony/string/Slugger/SluggerInterface.php create mode 100644 vendor/symfony/string/UnicodeString.php create mode 100644 vendor/symfony/string/composer.json create mode 100644 vendor/symplify/autowire-array-parameter/LICENSE create mode 100644 vendor/symplify/autowire-array-parameter/composer.json create mode 100644 vendor/symplify/autowire-array-parameter/easy-ci.php create mode 100644 vendor/symplify/autowire-array-parameter/ecs.php create mode 100644 vendor/symplify/autowire-array-parameter/phpstan.neon create mode 100644 vendor/symplify/autowire-array-parameter/rector.php create mode 100644 vendor/symplify/autowire-array-parameter/src/DependencyInjection/CompilerPass/AutowireArrayParameterCompilerPass.php create mode 100644 vendor/symplify/autowire-array-parameter/src/DependencyInjection/DefinitionFinder.php create mode 100644 vendor/symplify/autowire-array-parameter/src/DocBlock/ParamTypeDocBlockResolver.php create mode 100644 vendor/symplify/autowire-array-parameter/src/Exception/DependencyInjection/DefinitionForTypeNotFoundException.php create mode 100644 vendor/symplify/autowire-array-parameter/src/Skipper/ParameterSkipper.php create mode 100644 vendor/symplify/autowire-array-parameter/src/TypeResolver/ParameterTypeResolver.php create mode 100644 vendor/symplify/easy-testing/LICENSE create mode 100644 vendor/symplify/easy-testing/bin/easy-testing create mode 100644 vendor/symplify/easy-testing/bin/easy-testing.php create mode 100644 vendor/symplify/easy-testing/composer.json create mode 100644 vendor/symplify/easy-testing/config/config.php create mode 100644 vendor/symplify/easy-testing/src/Command/ValidateFixtureSkipNamingCommand.php create mode 100644 vendor/symplify/easy-testing/src/DataProvider/StaticFixtureFinder.php create mode 100644 vendor/symplify/easy-testing/src/DataProvider/StaticFixtureUpdater.php create mode 100644 vendor/symplify/easy-testing/src/Finder/FixtureFinder.php create mode 100644 vendor/symplify/easy-testing/src/FixtureSplitter/TrioFixtureSplitter.php create mode 100644 vendor/symplify/easy-testing/src/Kernel/EasyTestingKernel.php create mode 100644 vendor/symplify/easy-testing/src/MissplacedSkipPrefixResolver.php create mode 100644 vendor/symplify/easy-testing/src/PHPUnit/Behavior/DirectoryAssertableTrait.php create mode 100644 vendor/symplify/easy-testing/src/PHPUnit/StaticPHPUnitEnvironment.php create mode 100644 vendor/symplify/easy-testing/src/StaticFixtureSplitter.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/EasyTestingConfig.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/ExpectedAndOutputFileInfoPair.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/FixtureSplit/TrioContent.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/IncorrectAndMissingSkips.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/InputAndExpected.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpected.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpectedFileInfo.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/Option.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/Prefix.php create mode 100644 vendor/symplify/easy-testing/src/ValueObject/SplitLine.php create mode 100644 vendor/symplify/package-builder/composer.json create mode 100644 vendor/symplify/package-builder/config/config.php create mode 100644 vendor/symplify/package-builder/phpstan-baseline.neon create mode 100644 vendor/symplify/package-builder/src/Composer/VendorDirProvider.php create mode 100644 vendor/symplify/package-builder/src/Console/Command/AbstractSymplifyCommand.php create mode 100644 vendor/symplify/package-builder/src/Console/Formatter/ColorConsoleDiffFormatter.php create mode 100644 vendor/symplify/package-builder/src/Console/Input/StaticInputDetector.php create mode 100644 vendor/symplify/package-builder/src/Console/Output/ConsoleDiffer.php create mode 100644 vendor/symplify/package-builder/src/Console/Style/SymfonyStyleFactory.php create mode 100644 vendor/symplify/package-builder/src/DependencyInjection/CompilerPass/AutowireInterfacesCompilerPass.php create mode 100644 vendor/symplify/package-builder/src/DependencyInjection/FileLoader/ParameterMergingPhpFileLoader.php create mode 100644 vendor/symplify/package-builder/src/Diff/DifferFactory.php create mode 100644 vendor/symplify/package-builder/src/Diff/Output/CompleteUnifiedDiffOutputBuilderFactory.php create mode 100644 vendor/symplify/package-builder/src/Exception/HttpKernel/MissingInterfaceException.php create mode 100644 vendor/symplify/package-builder/src/Exception/InvalidPrivatePropertyTypeException.php create mode 100644 vendor/symplify/package-builder/src/Exception/MissingPrivatePropertyException.php create mode 100644 vendor/symplify/package-builder/src/Exception/MissingServiceException.php create mode 100644 vendor/symplify/package-builder/src/Parameter/ParameterProvider.php create mode 100644 vendor/symplify/package-builder/src/Php/TypeChecker.php create mode 100644 vendor/symplify/package-builder/src/Reflection/ClassLikeExistenceChecker.php create mode 100644 vendor/symplify/package-builder/src/Reflection/PrivatesAccessor.php create mode 100644 vendor/symplify/package-builder/src/Reflection/PrivatesCaller.php create mode 100644 vendor/symplify/package-builder/src/Strings/StringFormatConverter.php create mode 100644 vendor/symplify/package-builder/src/Strings/StringFormatConverter.phpqIy1Ap create mode 100644 vendor/symplify/package-builder/src/Testing/AbstractKernelTestCase.php create mode 100644 vendor/symplify/package-builder/src/ValueObject/ConsoleColorDiffConfig.php create mode 100644 vendor/symplify/package-builder/src/ValueObject/MethodName.php create mode 100644 vendor/symplify/package-builder/src/ValueObject/Option.php create mode 100644 vendor/symplify/package-builder/src/Yaml/ParametersMerger.php create mode 100644 vendor/symplify/smart-file-system/LICENSE create mode 100644 vendor/symplify/smart-file-system/composer.json create mode 100644 vendor/symplify/smart-file-system/src/Exception/DirectoryNotFoundException.php create mode 100644 vendor/symplify/smart-file-system/src/Exception/FileNotFoundException.php create mode 100644 vendor/symplify/smart-file-system/src/FileSystemFilter.php create mode 100644 vendor/symplify/smart-file-system/src/FileSystemGuard.php create mode 100644 vendor/symplify/smart-file-system/src/Finder/FinderSanitizer.php create mode 100644 vendor/symplify/smart-file-system/src/Finder/SmartFinder.php create mode 100644 vendor/symplify/smart-file-system/src/Json/JsonFileSystem.php create mode 100644 vendor/symplify/smart-file-system/src/Normalizer/PathNormalizer.php create mode 100644 vendor/symplify/smart-file-system/src/SmartFileInfo.php create mode 100644 vendor/symplify/smart-file-system/src/SmartFileSystem.php create mode 100644 vendor/symplify/symplify-kernel/README.md create mode 100644 vendor/symplify/symplify-kernel/composer.json create mode 100644 vendor/symplify/symplify-kernel/config/common-config.php create mode 100644 vendor/symplify/symplify-kernel/phpunit.xml create mode 100644 vendor/symplify/symplify-kernel/src/Config/Loader/ParameterMergingLoaderFactory.php create mode 100644 vendor/symplify/symplify-kernel/src/ContainerBuilderFactory.php create mode 100644 vendor/symplify/symplify-kernel/src/Contract/Config/LoaderFactoryInterface.php create mode 100644 vendor/symplify/symplify-kernel/src/Contract/LightKernelInterface.php create mode 100644 vendor/symplify/symplify-kernel/src/DependencyInjection/LoadExtensionConfigsCompilerPass.php create mode 100644 vendor/symplify/symplify-kernel/src/Exception/BootException.php create mode 100644 vendor/symplify/symplify-kernel/src/Exception/ShouldNotHappenException.php create mode 100644 vendor/symplify/symplify-kernel/src/HttpKernel/AbstractSymplifyKernel.php create mode 100644 vendor/symplify/symplify-kernel/src/ValueObject/KernelBootAndApplicationRun.php create mode 100644 vendor/symplify/symplify-kernel/src/ValueObject/SymplifyKernelConfig.php create mode 100644 vendor/symplify/symplify-kernel/tests/ContainerBuilderFactory/ContainerBuilderFactoryTest.php create mode 100644 vendor/symplify/symplify-kernel/tests/ContainerBuilderFactory/config/some_services.php create mode 100644 vendor/webmozart/assert/CHANGELOG.md create mode 100644 vendor/webmozart/assert/LICENSE create mode 100644 vendor/webmozart/assert/README.md create mode 100644 vendor/webmozart/assert/composer.json create mode 100644 vendor/webmozart/assert/src/Assert.php create mode 100644 vendor/webmozart/assert/src/InvalidArgumentException.php create mode 100644 vendor/webmozart/assert/src/Mixin.php diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index f73a7bb1ce..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true -indent_style = space -indent_size = 4 - -[*.{yml,yaml}] -indent_size = 2 diff --git a/build/target-repository/.github/workflows/auto_closer.yaml b/.github/workflows/auto_closer.yaml similarity index 100% rename from build/target-repository/.github/workflows/auto_closer.yaml rename to .github/workflows/auto_closer.yaml diff --git a/.github/workflows/bare_run.yaml b/.github/workflows/bare_run.yaml index 99cf2ab6af..90a1728f9f 100644 --- a/.github/workflows/bare_run.yaml +++ b/.github/workflows/bare_run.yaml @@ -1,39 +1,23 @@ -name: Bare Run on various PHP versions +name: Bare Run -on: - push: - tags: - - '*' +on: [pull_request, push] jobs: - bare_run: - runs-on: ubuntu-latest + bare_run: + runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - php_version: ['7.2', '7.3', '7.4', '8.0'] + strategy: + fail-fast: false + matrix: + php_version: ['7.2', '7.3', '7.4', '8.0'] - steps: - - uses: actions/checkout@v3 + steps: + - uses: actions/checkout@v2 - - - id: check_tag - run: | - MESSAGE=$(git tag -l --format='%(contents)' $(git describe --tags $(git rev-list --tags --max-count=1))) - if echo $MESSAGE | grep -q "PHP 7.2 downgraded"; then - echo "NEEDED_DOWNGRADE=1" >> $GITHUB_ENV - else - echo "NEEDED_DOWNGRADE=0" >> $GITHUB_ENV - fi + - + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php_version }} + coverage: none - - - name: Setup PHP And Run Monorepo - if: env.NEEDED_DOWNGRADE == '1' - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php_version }} - coverage: none - - - if: env.NEEDED_DOWNGRADE == '1' - run: php bin/monorepo-builder list --ansi \ No newline at end of file + - run: php bin/monorepo-builder list --ansi diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 782a18ad21..0000000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -composer.lock -/vendor -/.phpunit.cache diff --git a/README.md b/README.md index 96867b996b..5aba7b8c72 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ composer require symplify/monorepo-builder --dev ## Usage -### 1. Are you New to Monorepo? +### 0. Are you New to Monorepo? The best to lean-in fast is to read basic intro at blog post [All You Always Wanted to Know About Monorepo](https://www.tomasvotruba.com/blog/2019/10/28/all-you-always-wanted-to-know-about-monorepo-but-were-afraid-to-ask/#what-is-monorepo). We also made a simple command to make that easy for you: @@ -25,7 +25,7 @@ vendor/bin/monorepo-builder init And the basic setup is done! -### 2. Merge local `composer.json` to the Root One +### 1. Merge local `composer.json` to the Root One Merges configured sections to the root `composer.json`, so you can only edit `composer.json` of particular packages and let script to synchronize it. @@ -49,9 +49,9 @@ vendor/bin/monorepo-builder merge Typical location for packages is `/packages`. But what if you have different naming or extra `/projects` directory? ```php -use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection; +// monorepo-builder.php +use Symplify\ComposerJsonManipulator\ValueObject\ComposerJsonSection; use Symplify\MonorepoBuilder\Config\MBConfig; -use Symplify\MonorepoBuilder\ValueObject\Option; return static function (MBConfig $mbConfig): void { // where are the packages located? @@ -62,7 +62,7 @@ return static function (MBConfig $mbConfig): void { __DIR__ . '/projects', ]); - // how to skip packages in loaded directories? + // how skip packages in loaded direectories? $mbConfig->packageDirectoriesExcludes([__DIR__ . '/packages/secret-package']); // "merge" command related @@ -84,15 +84,11 @@ return static function (MBConfig $mbConfig): void { // the line is removed by key, so version is irrelevant, thus * 'phpunit/phpunit' => '*', ], - ComposerJsonSection::REPOSITORIES => [ - // this will remove all repositories - Option::REMOVE_COMPLETELY, - ], ]); }; ``` -### 3. Bump Package Inter-dependencies +### 2. Bump Package Inter-dependencies Let's say you release `symplify/symplify` 4.0 and you need package to depend on version `^4.0` for each other: @@ -100,7 +96,7 @@ Let's say you release `symplify/symplify` 4.0 and you need package to depend on vendor/bin/monorepo-builder bump-interdependency "^4.0" ``` -### 4. Keep Synchronized Package Version +### 3. Keep Synchronized Package Version In synchronized monorepo, it's common to use same package version to prevent bugs and WTFs. So if one of your package uses `symfony/console` 3.4 and the other `symfony/console` 4.1, this will tell you: @@ -108,7 +104,7 @@ In synchronized monorepo, it's common to use same package version to prevent bug vendor/bin/monorepo-builder validate ``` -### 5. Keep Package Alias Up-To-Date +### 4. Keep Package Alias Up-To-Date You can see this even if there is already version 3.0 out: @@ -133,21 +129,23 @@ This will add alias `3.1-dev` to `composer.json` in each package. If you prefer [`3.1.x-dev`](https://getcomposer.org/doc/articles/aliases.md#branch-alias) over default `3.1-dev`, you can configure it: ```php -use Symplify\MonorepoBuilder\Config\MBConfig; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use Symplify\MonorepoBuilder\ValueObject\Option; -return static function (MBConfig $mbConfig): void { +return static function (ContainerConfigurator $containerConfigurator): void { + $parameters = $containerConfigurator->parameters(); // default: ".-dev" - $mbConfig->packageAliasFormat('..x-dev'); + $parameters->set(Option::PACKAGE_ALIAS_FORMAT, '..x-dev'); }; ``` -### 6. Split Directories to Git Repositories +### 5. Split Directories to Git Repositories Thanks to GitHub Actions, this was never simpler to set up. Use [symplify/github-action-monorepo-split](https://github.com/symplify/github-action-monorepo-split). -How to configure it? See our local setup at [.github/workflows/split_monorepo.yaml](https://github.com/danharrin/monorepo-split-github-action/blob/main/.github/workflows/split.yaml) +How to configure it? See our local setup at [.github/workflows/split_monorepo.yaml](https://github.com/symplify/symplify/blob/main/.github/workflows/split_monorepo.yaml) -### 7. Release Flow +### 6. Release Flow When a new version of your package is released, you have to do many manual steps: @@ -168,7 +166,9 @@ vendor/bin/monorepo-builder release v7.0 And add the following release workers to your `monorepo-builder.php`: ```php -use Symplify\MonorepoBuilder\Config\MBConfig; +// File: monorepo-builder.php + +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker; @@ -178,35 +178,25 @@ use Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker; use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateReplaceReleaseWorker; -return static function (MBConfig $mbConfig): void { - // release workers - in order to execute - $mbConfig->workers([ - UpdateReplaceReleaseWorker::class, - SetCurrentMutualDependenciesReleaseWorker::class, - AddTagToChangelogReleaseWorker::class, - TagVersionReleaseWorker::class, - PushTagReleaseWorker::class, - SetNextMutualDependenciesReleaseWorker::class, - UpdateBranchAliasReleaseWorker::class, - PushNextDevReleaseWorker::class, - ]); -}; -``` - -These `TagVersionReleaseWorker` and `PushTagReleaseWorker` are enabled by default. -If you want to disable these default workers, you can use the following code. - -```php -return static function (MBConfig $mbConfig): void { - $mbConfig->disableDefaultWorkers(); +return static function (ContainerConfigurator $containerConfigurator): void { + $services = $containerConfigurator->services(); + + # release workers - in order to execute + $services->set(UpdateReplaceReleaseWorker::class); + $services->set(SetCurrentMutualDependenciesReleaseWorker::class); + $services->set(AddTagToChangelogReleaseWorker::class); + $services->set(TagVersionReleaseWorker::class); + $services->set(PushTagReleaseWorker::class); + $services->set(SetNextMutualDependenciesReleaseWorker::class); + $services->set(UpdateBranchAliasReleaseWorker::class); + $services->set(PushNextDevReleaseWorker::class); }; ``` -You can also include your own workers. Just add services that implements `ReleaseWorkerInterface`. Are you afraid to tag and push? Use `--dry-run` to see only descriptions: ```bash -vendor/bin/monorepo-builder release 7.0 --dry-run +vendor/bin/monorepo-builder release v7.0 --dry-run ``` Do you want to release next [patch version](https://semver.org/), e.g. current `v0.7.1` → next `v0.7.2`? @@ -216,3 +206,40 @@ vendor/bin/monorepo-builder release patch ``` You can use `minor` and `major` too. + +### 7. Set Your Own Release Flow + +There is set of few default release workers - classes that implement `Symplify\MonorepoBuilder\Release\Contract\ReleaseWorker\ReleaseWorkerInterface`. + +You need to register them as services. Feel free to start with default ones: + +```php +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; + +return static function (ContainerConfigurator $containerConfigurator): void { + $services = $containerConfigurator->services(); + + // release workers - in order to execute + $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\SetCurrentMutualDependenciesReleaseWorker::class); + $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker::class); + + // you can extend with your own + $services->set(App\SendPigeonToTwitterReleaseWorker::class); + + $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker::class); + $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker::class); + $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\SetNextMutualDependenciesReleaseWorker::class); + $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker::class); + $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker::class); +}; +``` + +
+ +## Report Issues + +In case you are experiencing a bug or want to request a new feature head over to the [Symplify monorepo issue tracker](https://github.com/symplify/symplify/issues) + +## Contribute + +The sources of this package are contained in the Symplify monorepo. We welcome contributions for this package on [symplify/symplify](https://github.com/symplify/symplify). diff --git a/bin/monorepo-builder b/bin/monorepo-builder index 34ad36e03d..2a4deb21b5 100755 --- a/bin/monorepo-builder +++ b/bin/monorepo-builder @@ -1,4 +1,5 @@ #!/usr/bin/env php -run(); - - - -function resolveConfigFile(ArgvInput $argvInput): ?string +function resolveConfigFile(ArgvInput $argvInput) : ?string { if ($argvInput->hasParameterOption(['-c', '--config'])) { $configOption = $argvInput->getParameterOption(['-c', '--config']); - if (is_string($configOption) && file_exists($configOption)) { - return realpath($configOption); + if (\is_string($configOption) && \file_exists($configOption)) { + return \realpath($configOption); } } - - $defaultConfigFilePath = getcwd() . '/' . File::CONFIG; - if (file_exists($defaultConfigFilePath)) { + $defaultConfigFilePath = \getcwd() . '/' . File::CONFIG; + if (\file_exists($defaultConfigFilePath)) { return $defaultConfigFilePath; } - return null; } diff --git a/build/target-repository/bootstrap.php b/bootstrap.php similarity index 100% rename from build/target-repository/bootstrap.php rename to bootstrap.php diff --git a/build/rector-downgrade-php-72.php b/build/rector-downgrade-php-72.php deleted file mode 100644 index a284a9aa81..0000000000 --- a/build/rector-downgrade-php-72.php +++ /dev/null @@ -1,21 +0,0 @@ -parallel(240, 8, 1); - - $rectorConfig->sets([DowngradeLevelSetList::DOWN_TO_PHP_72]); - - $rectorConfig->skip([ - '*/Tests/*', - '*/tests/*', - __DIR__ . '/../../tests', - # missing "optional" dependency and never used here - '*/symfony/framework-bundle/KernelBrowser.php', - '*/symfony/http-kernel/HttpKernelBrowser.php', - ]); -}; \ No newline at end of file diff --git a/build/target-repository/.github/FUNDING.yml b/build/target-repository/.github/FUNDING.yml deleted file mode 100644 index f797866a90..0000000000 --- a/build/target-repository/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -# These are supported funding model platforms -github: tomasvotruba -custom: https://www.paypal.me/rectorphp diff --git a/build/target-repository/.github/workflows/bare_run.yaml b/build/target-repository/.github/workflows/bare_run.yaml deleted file mode 100644 index 90a1728f9f..0000000000 --- a/build/target-repository/.github/workflows/bare_run.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Bare Run - -on: [pull_request, push] - -jobs: - bare_run: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - php_version: ['7.2', '7.3', '7.4', '8.0'] - - steps: - - uses: actions/checkout@v2 - - - - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php_version }} - coverage: none - - - run: php bin/monorepo-builder list --ansi diff --git a/build/target-repository/README.md b/build/target-repository/README.md deleted file mode 100644 index 5aba7b8c72..0000000000 --- a/build/target-repository/README.md +++ /dev/null @@ -1,245 +0,0 @@ -# Not only Composer tools to build a Monorepo - -[![Downloads total](https://img.shields.io/packagist/dt/symplify/monorepo-builder.svg?style=flat-square)](https://packagist.org/packages/symplify/monorepo-builder/stats) - -Do you maintain [a monorepo](https://tomasvotruba.com/blog/2019/10/28/all-you-always-wanted-to-know-about-monorepo-but-were-afraid-to-ask/) with more packages? - -**This package has few useful tools, that will make that easier**. - -## Install - -```bash -composer require symplify/monorepo-builder --dev -``` - -## Usage - -### 0. Are you New to Monorepo? - -The best to lean-in fast is to read basic intro at blog post [All You Always Wanted to Know About Monorepo](https://www.tomasvotruba.com/blog/2019/10/28/all-you-always-wanted-to-know-about-monorepo-but-were-afraid-to-ask/#what-is-monorepo). -We also made a simple command to make that easy for you: - -```bash -vendor/bin/monorepo-builder init -``` - -And the basic setup is done! - -### 1. Merge local `composer.json` to the Root One - -Merges configured sections to the root `composer.json`, so you can only edit `composer.json` of particular packages and let script to synchronize it. - -Sections that are needed for monorepo to work will be merged: - -- 'require' -- 'require-dev' -- 'autoload' -- 'autoload-dev' -- 'repositories' -- 'extra' - -To merge run: - -```bash -vendor/bin/monorepo-builder merge -``` - -
- -Typical location for packages is `/packages`. But what if you have different naming or extra `/projects` directory? - -```php -// monorepo-builder.php -use Symplify\ComposerJsonManipulator\ValueObject\ComposerJsonSection; -use Symplify\MonorepoBuilder\Config\MBConfig; - -return static function (MBConfig $mbConfig): void { - // where are the packages located? - $mbConfig->packageDirectories([ - // default value - __DIR__ . '/packages', - // custom - __DIR__ . '/projects', - ]); - - // how skip packages in loaded direectories? - $mbConfig->packageDirectoriesExcludes([__DIR__ . '/packages/secret-package']); - - // "merge" command related - - // what extra parts to add after merge? - $mbConfig->dataToAppend([ - ComposerJsonSection::AUTOLOAD_DEV => [ - 'psr-4' => [ - 'Symplify\Tests\\' => 'tests', - ], - ], - ComposerJsonSection::REQUIRE_DEV => [ - 'phpstan/phpstan' => '^0.12', - ], - ]); - - $mbConfig->dataToRemove([ - ComposerJsonSection::REQUIRE => [ - // the line is removed by key, so version is irrelevant, thus * - 'phpunit/phpunit' => '*', - ], - ]); -}; -``` - -### 2. Bump Package Inter-dependencies - -Let's say you release `symplify/symplify` 4.0 and you need package to depend on version `^4.0` for each other: - -```bash -vendor/bin/monorepo-builder bump-interdependency "^4.0" -``` - -### 3. Keep Synchronized Package Version - -In synchronized monorepo, it's common to use same package version to prevent bugs and WTFs. So if one of your package uses `symfony/console` 3.4 and the other `symfony/console` 4.1, this will tell you: - -```bash -vendor/bin/monorepo-builder validate -``` - -### 4. Keep Package Alias Up-To-Date - -You can see this even if there is already version 3.0 out: - -```json -{ - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - } -} -``` - -**Not good.** Get rid of this manual work and add this command to your release workflow: - -```bash -vendor/bin/monorepo-builder package-alias -``` - -This will add alias `3.1-dev` to `composer.json` in each package. - -If you prefer [`3.1.x-dev`](https://getcomposer.org/doc/articles/aliases.md#branch-alias) over default `3.1-dev`, you can configure it: - -```php -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -use Symplify\MonorepoBuilder\ValueObject\Option; - -return static function (ContainerConfigurator $containerConfigurator): void { - $parameters = $containerConfigurator->parameters(); - // default: ".-dev" - $parameters->set(Option::PACKAGE_ALIAS_FORMAT, '..x-dev'); -}; -``` - -### 5. Split Directories to Git Repositories - -Thanks to GitHub Actions, this was never simpler to set up. Use [symplify/github-action-monorepo-split](https://github.com/symplify/github-action-monorepo-split). - -How to configure it? See our local setup at [.github/workflows/split_monorepo.yaml](https://github.com/symplify/symplify/blob/main/.github/workflows/split_monorepo.yaml) - -### 6. Release Flow - -When a new version of your package is released, you have to do many manual steps: - -- bump mutual dependencies, -- tag this version, -- `git push` with tag, -- change `CHANGELOG.md` title *Unreleased* to `v - Y-m-d` format -- bump alias and mutual dependencies to next version alias - -But what if **you forget one or do it in wrong order**? Everything will crash! - -The `release` command will make you safe: - -```bash -vendor/bin/monorepo-builder release v7.0 -``` - -And add the following release workers to your `monorepo-builder.php`: - -```php -// File: monorepo-builder.php - -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\SetCurrentMutualDependenciesReleaseWorker; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\SetNextMutualDependenciesReleaseWorker; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker; -use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateReplaceReleaseWorker; - -return static function (ContainerConfigurator $containerConfigurator): void { - $services = $containerConfigurator->services(); - - # release workers - in order to execute - $services->set(UpdateReplaceReleaseWorker::class); - $services->set(SetCurrentMutualDependenciesReleaseWorker::class); - $services->set(AddTagToChangelogReleaseWorker::class); - $services->set(TagVersionReleaseWorker::class); - $services->set(PushTagReleaseWorker::class); - $services->set(SetNextMutualDependenciesReleaseWorker::class); - $services->set(UpdateBranchAliasReleaseWorker::class); - $services->set(PushNextDevReleaseWorker::class); -}; -``` - -Are you afraid to tag and push? Use `--dry-run` to see only descriptions: - -```bash -vendor/bin/monorepo-builder release v7.0 --dry-run -``` - -Do you want to release next [patch version](https://semver.org/), e.g. current `v0.7.1` → next `v0.7.2`? - -```bash -vendor/bin/monorepo-builder release patch -``` - -You can use `minor` and `major` too. - -### 7. Set Your Own Release Flow - -There is set of few default release workers - classes that implement `Symplify\MonorepoBuilder\Release\Contract\ReleaseWorker\ReleaseWorkerInterface`. - -You need to register them as services. Feel free to start with default ones: - -```php -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; - -return static function (ContainerConfigurator $containerConfigurator): void { - $services = $containerConfigurator->services(); - - // release workers - in order to execute - $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\SetCurrentMutualDependenciesReleaseWorker::class); - $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker::class); - - // you can extend with your own - $services->set(App\SendPigeonToTwitterReleaseWorker::class); - - $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker::class); - $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker::class); - $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\SetNextMutualDependenciesReleaseWorker::class); - $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker::class); - $services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker::class); -}; -``` - -
- -## Report Issues - -In case you are experiencing a bug or want to request a new feature head over to the [Symplify monorepo issue tracker](https://github.com/symplify/symplify/issues) - -## Contribute - -The sources of this package are contained in the Symplify monorepo. We welcome contributions for this package on [symplify/symplify](https://github.com/symplify/symplify). diff --git a/build/target-repository/composer.json b/build/target-repository/composer.json deleted file mode 100644 index 3d1e1c5885..0000000000 --- a/build/target-repository/composer.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "symplify/monorepo-builder", - "description": "Prefixed version of Not only Composer tools to build a Monorepo.", - "license": "MIT", - "require": { - "php": ">=7.2" - }, - "bin": [ - "bin/monorepo-builder" - ], - "extra": { - "branch-alias": { - "dev-main": "10.3-dev" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "config": { - "allow-plugins": { - "cweagans/composer-patches": true, - "phpstan/extension-installer": true - } - } -} diff --git a/composer.json b/composer.json index fe0ac20d5f..3d1e1c5885 100644 --- a/composer.json +++ b/composer.json @@ -1,70 +1,27 @@ { "name": "symplify/monorepo-builder", - "description": "Not only Composer tools to build a Monorepo.", + "description": "Prefixed version of Not only Composer tools to build a Monorepo.", "license": "MIT", + "require": { + "php": ">=7.2" + }, "bin": [ "bin/monorepo-builder" ], - "require": { - "php": ">=8.1", - "nette/utils": "^3.2", - "phar-io/version": "^3.2", - "symfony/finder": "^6.2", - "symfony/dependency-injection": "6.1.*", - "symfony/console": "^6.2", - "symfony/process": "^6.2", - "symplify/package-builder": "^11.1", - "symplify/symplify-kernel": "^11.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.3.1", - "cweagans/composer-patches": "^1.7", - "rector/rector": "^0.17", - "phpstan/phpstan": "^1.10", - "symplify/easy-coding-standard": "^12.0", - "symplify/easy-ci": "^11.3", - "symplify/phpstan-extensions": "^11.1", - "phpstan/extension-installer": "^1.2", - "php-parallel-lint/php-parallel-lint": "^1.3", - "tracy/tracy": "^2.9", - "tomasvotruba/class-leak": "0.1.1.72" - }, - "autoload": { - "psr-4": { - "Symplify\\MonorepoBuilder\\": [ - "src", - "packages" - ] - } - }, - "autoload-dev": { - "psr-4": { - "Symplify\\MonorepoBuilder\\Tests\\": [ - "tests", - "packages-tests" - ] - } - }, "extra": { - "enable-patching": true, - "patches": { - "symfony/dependency-injection": [ - "https://raw.githubusercontent.com/symplify/vendor-patch-files/main/patches/generic-php-config-loader.patch" - ] + "branch-alias": { + "dev-main": "10.3-dev" } }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, "config": { - "platform-check": false, "allow-plugins": { "cweagans/composer-patches": true, "phpstan/extension-installer": true } - }, - "scripts": { - "check-cs": "vendor/bin/ecs check --ansi", - "fix-cs": "vendor/bin/ecs check --fix --ansi", - "phpstan": "vendor/bin/phpstan analyse --ansi --error-format symplify", - "rector": "vendor/bin/rector process --dry-run --ansi", - "release": "bin/monorepo-builder release patch --ansi" } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..24325a08c3 --- /dev/null +++ b/composer.lock @@ -0,0 +1,3712 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "40522c779707518f5fc82043e1269113", + "packages": [ + { + "name": "nette/utils", + "version": "v3.2.10", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "a4175c62652f2300c8017fb7e640f9ccb11648d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/a4175c62652f2300c8017fb7e640f9ccb11648d2", + "reference": "a4175c62652f2300c8017fb7e640f9ccb11648d2", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.4" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "~2.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.10" + }, + "time": "2023-07-30T15:38:18+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-01T07:48:21+00:00" + }, + { + "name": "symfony/config", + "version": "v6.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-19T20:22:16+00:00" + }, + { + "name": "symfony/console", + "version": "v6.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6", + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-08-16T10:10:12+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v6.1.12", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "360c9d0948e1fe675336346d5862e8e55b378d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/360c9d0948e1fe675336346d5862e8e55b378d90", + "reference": "360c9d0948e1fe675336346d5862e8e55b378d90", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/service-contracts": "^1.1.6|^2.0|^3.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.1", + "symfony/finder": "<5.4", + "symfony/proxy-manager-bridge": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.1", + "symfony/expression-language": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v6.1.12" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-30T15:43:30+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.3.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.3.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-06-01T08:30:39+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.3.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.3.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-09-26T12:56:25+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "875e90aeea2777b6f135677f618529449334a612" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-28T09:04:16+00:00" + }, + { + "name": "symfony/process", + "version": "v6.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-08-07T10:39:22+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/string", + "version": "v6.3.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/13d76d0fb049051ed12a04bef4f9de8715bea339", + "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.3.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-09-18T10:38:32+00:00" + }, + { + "name": "symplify/autowire-array-parameter", + "version": "11.1.26", + "source": { + "type": "git", + "url": "https://github.com/symplify/autowire-array-parameter.git", + "reference": "ca9094e65223fbff7bb18d162df19312f9802a81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/autowire-array-parameter/zipball/ca9094e65223fbff7bb18d162df19312f9802a81", + "reference": "ca9094e65223fbff7bb18d162df19312f9802a81", + "shasum": "" + }, + "require": { + "nette/utils": "^3.2", + "php": ">=8.1", + "symfony/dependency-injection": "6.1.*" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpstan/extension-installer": "^1.2", + "phpunit/phpunit": "^9.5.26", + "rector/rector": "^0.15.10", + "symplify/easy-ci": "^11.1", + "symplify/easy-coding-standard": "^11.1", + "symplify/package-builder": "^11.2", + "symplify/phpstan-extensions": "^11.1", + "symplify/symplify-kernel": "^11.2", + "tomasvotruba/unused-public": "^0.0.34" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symplify\\AutowireArrayParameter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Autowire array parameters for your Symfony applications", + "support": { + "source": "https://github.com/symplify/autowire-array-parameter/tree/11.1.26" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "abandoned": "symfony/dependency-injection", + "time": "2023-02-03T09:12:23+00:00" + }, + { + "name": "symplify/easy-testing", + "version": "11.1.25", + "source": { + "type": "git", + "url": "https://github.com/symplify/easy-testing.git", + "reference": "a9fd0eed1b33847f175f085d9803f5bf299cba4b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/easy-testing/zipball/a9fd0eed1b33847f175f085d9803f5bf299cba4b", + "reference": "a9fd0eed1b33847f175f085d9803f5bf299cba4b", + "shasum": "" + }, + "require": { + "nette/utils": "^3.2", + "php": ">=8.1", + "symfony/console": "^6.2", + "symfony/dependency-injection": "6.1.*", + "symfony/finder": "^6.2", + "symplify/package-builder": "^11.1.25", + "symplify/smart-file-system": "^11.1.25", + "symplify/symplify-kernel": "^11.1.25" + }, + "conflict": { + "symplify/autowire-array-parameter": "<11.1.25", + "symplify/coding-standard": "<11.1.24", + "symplify/config-transformer": "<11.1.24", + "symplify/easy-ci": "<11.1.24", + "symplify/easy-parallel": "<11.1.25", + "symplify/monorepo-builder": "<11.1.24", + "symplify/php-config-printer": "<11.1.25", + "symplify/phpstan-extensions": "<11.1.25", + "symplify/phpstan-rules": "<11.1.24", + "symplify/rule-doc-generator": "<11.1.25", + "symplify/rule-doc-generator-contracts": "<11.1.25", + "symplify/symfony-static-dumper": "<11.1.25" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.26" + }, + "bin": [ + "bin/easy-testing" + ], + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symplify\\EasyTesting\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Testing made easy", + "support": { + "source": "https://github.com/symplify/easy-testing/tree/11.1.25" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-01-28T10:13:33+00:00" + }, + { + "name": "symplify/package-builder", + "version": "11.3.0", + "source": { + "type": "git", + "url": "https://github.com/symplify/package-builder.git", + "reference": "99d055542e9ab631297b6765e2a3257261f9d667" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/package-builder/zipball/99d055542e9ab631297b6765e2a3257261f9d667", + "reference": "99d055542e9ab631297b6765e2a3257261f9d667", + "shasum": "" + }, + "require": { + "nette/utils": "^3.2", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "symfony/config": "^6.2", + "symfony/console": "^6.2", + "symfony/dependency-injection": "6.1.*", + "symfony/finder": "^6.2" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpstan/extension-installer": "^1.2", + "phpunit/phpunit": "^10.0", + "rector/rector": "^0.15.10", + "symplify/easy-ci": "^11.2.0", + "symplify/easy-coding-standard": "^11.2", + "symplify/phpstan-extensions": "^11.1", + "symplify/phpstan-rules": "^11.2", + "symplify/symplify-kernel": "^11.1", + "tomasvotruba/unused-public": "^0.0.34" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symplify\\PackageBuilder\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Dependency Injection, Console and Kernel toolkit for Symplify packages.", + "support": { + "source": "https://github.com/symplify/package-builder/tree/11.3.0" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-02-05T14:53:28+00:00" + }, + { + "name": "symplify/smart-file-system", + "version": "11.1.26", + "source": { + "type": "git", + "url": "https://github.com/symplify/smart-file-system.git", + "reference": "f3b006424d08359cccaf4e2e38cf3f9ef2effca6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/smart-file-system/zipball/f3b006424d08359cccaf4e2e38cf3f9ef2effca6", + "reference": "f3b006424d08359cccaf4e2e38cf3f9ef2effca6", + "shasum": "" + }, + "require": { + "nette/utils": "^3.2", + "php": ">=8.1", + "symfony/filesystem": "^6.2", + "symfony/finder": "^6.2", + "symplify/easy-testing": "^11.1" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpstan/extension-installer": "^1.2", + "phpunit/phpunit": "^9.5.26", + "rector/rector": "^0.15.10", + "symplify/easy-ci": "^11.1", + "symplify/easy-coding-standard": "^11.1", + "symplify/phpstan-extensions": "^11.1", + "symplify/phpstan-rules": "11.2.3.72", + "symplify/symplify-kernel": "^11.1", + "tomasvotruba/unused-public": "^0.0.34" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symplify\\SmartFileSystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Sanitized FileInfo with safe getRealPath() and other handy methods", + "support": { + "source": "https://github.com/symplify/smart-file-system/tree/11.1.26" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-02-05T13:38:33+00:00" + }, + { + "name": "symplify/symplify-kernel", + "version": "11.1.25", + "source": { + "type": "git", + "url": "https://github.com/symplify/symplify-kernel.git", + "reference": "15b29ac9aedea76dc7b1a3524614e881594fccf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/symplify-kernel/zipball/15b29ac9aedea76dc7b1a3524614e881594fccf5", + "reference": "15b29ac9aedea76dc7b1a3524614e881594fccf5", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/console": "^6.2", + "symfony/dependency-injection": "6.1.*", + "symplify/autowire-array-parameter": "^11.1.25", + "symplify/package-builder": "^11.1.25", + "symplify/smart-file-system": "^11.1.25", + "webmozart/assert": "^1.11" + }, + "conflict": { + "symplify/coding-standard": "<11.1.24", + "symplify/config-transformer": "<11.1.24", + "symplify/easy-ci": "<11.1.24", + "symplify/easy-parallel": "<11.1.25", + "symplify/easy-testing": "<11.1.25", + "symplify/monorepo-builder": "<11.1.24", + "symplify/php-config-printer": "<11.1.25", + "symplify/phpstan-extensions": "<11.1.25", + "symplify/phpstan-rules": "<11.1.24", + "symplify/rule-doc-generator": "<11.1.25", + "symplify/rule-doc-generator-contracts": "<11.1.25", + "symplify/symfony-static-dumper": "<11.1.25" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symplify\\SymplifyKernel\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Internal Kernel for Symplify packages", + "support": { + "source": "https://github.com/symplify/symplify-kernel/tree/11.1.25" + }, + "time": "2023-01-28T10:13:47+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "cweagans/composer-patches", + "version": "1.7.3", + "source": { + "type": "git", + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "e190d4466fe2b103a55467dfa83fc2fecfcaf2db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/e190d4466fe2b103a55467dfa83fc2fecfcaf2db", + "reference": "e190d4466fe2b103a55467dfa83fc2fecfcaf2db", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3.0" + }, + "require-dev": { + "composer/composer": "~1.0 || ~2.0", + "phpunit/phpunit": "~4.6" + }, + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "description": "Provides a way to patch Composer packages.", + "support": { + "issues": "https://github.com/cweagans/composer-patches/issues", + "source": "https://github.com/cweagans/composer-patches/tree/1.7.3" + }, + "time": "2022-12-20T22:53:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.17.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + }, + "time": "2023-08-13T19:53:39+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "php-parallel-lint/php-parallel-lint", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git", + "reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/6483c9832e71973ed29cf71bd6b3f4fde438a9de", + "reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.3.0" + }, + "replace": { + "grogy/php-parallel-lint": "*", + "jakub-onderka/php-parallel-lint": "*" + }, + "require-dev": { + "nette/tester": "^1.3 || ^2.0", + "php-parallel-lint/php-console-highlighter": "0.* || ^1.0", + "squizlabs/php_codesniffer": "^3.6" + }, + "suggest": { + "php-parallel-lint/php-console-highlighter": "Highlight syntax in code snippet" + }, + "bin": [ + "parallel-lint" + ], + "type": "library", + "autoload": { + "classmap": [ + "./src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "ahoj@jakubonderka.cz" + } + ], + "description": "This tool check syntax of PHP files about 20x faster than serial check.", + "homepage": "https://github.com/php-parallel-lint/PHP-Parallel-Lint", + "support": { + "issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues", + "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.3.2" + }, + "time": "2022-02-21T12:50:22+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.3.1" + }, + "time": "2023-05-24T08:59:17+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.39", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d9dedb0413f678b4d03cbc2279a48f91592c97c4", + "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2023-10-17T15:46:26+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "355324ca4980b8916c18b9db29f3ef484078f26e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/355324ca4980b8916c18b9db29f3ef484078f26e", + "reference": "355324ca4980b8916c18b9db29f3ef484078f26e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-10-04T15:34:17+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "62bd7af13d282deeb95650077d28ba3600ca321c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/62bd7af13d282deeb95650077d28ba3600ca321c", + "reference": "62bd7af13d282deeb95650077d28ba3600ca321c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.4-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.1" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2023-10-08T05:01:11+00:00" + }, + { + "name": "rector/rector", + "version": "0.17.13", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "e2003ba7c5bda06d7bb419cf4be8dae5f8672132" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/e2003ba7c5bda06d7bb419cf4be8dae5f8672132", + "reference": "e2003ba7c5bda06d7bb419cf4be8dae5f8672132", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.26" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.17.13" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-08-14T16:33:29+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:15+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-14T13:18:12+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", + "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-28T11:50:59+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-04-11T05:39:26+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-24T13:22:09+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-07-19T07:19:23+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T09:25:50+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "symplify/easy-ci", + "version": "11.3.1.72", + "source": { + "type": "git", + "url": "https://github.com/symplify/easy-ci.git", + "reference": "d1c396af82582f66f71cf779fc37ea267307d188" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/easy-ci/zipball/d1c396af82582f66f71cf779fc37ea267307d188", + "reference": "d1c396af82582f66f71cf779fc37ea267307d188", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "bin": [ + "bin/easy-ci" + ], + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Toolkit of commands that should not be missed in you CI", + "support": { + "issues": "https://github.com/symplify/easy-ci/issues", + "source": "https://github.com/symplify/easy-ci/tree/11.3.1.72" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-07-18T15:20:09+00:00" + }, + { + "name": "symplify/easy-coding-standard", + "version": "12.0.8", + "source": { + "type": "git", + "url": "https://github.com/easy-coding-standard/easy-coding-standard.git", + "reference": "99d87d188acc712dd6655ee946569f823cfeff69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/99d87d188acc712dd6655ee946569f823cfeff69", + "reference": "99d87d188acc712dd6655ee946569f823cfeff69", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "conflict": { + "friendsofphp/php-cs-fixer": "<3.0", + "squizlabs/php_codesniffer": "<3.6", + "symplify/coding-standard": "<11.3" + }, + "bin": [ + "bin/ecs" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer", + "keywords": [ + "Code style", + "automation", + "fixer", + "static analysis" + ], + "support": { + "issues": "https://github.com/easy-coding-standard/easy-coding-standard/issues", + "source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/12.0.8" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-09-08T10:17:14+00:00" + }, + { + "name": "symplify/phpstan-extensions", + "version": "11.4.2", + "source": { + "type": "git", + "url": "https://github.com/symplify/phpstan-extensions.git", + "reference": "efd509f6a748aa933fb02628dc6f8583301f965b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/phpstan-extensions/zipball/efd509f6a748aa933fb02628dc6f8583301f965b", + "reference": "efd509f6a748aa933fb02628dc6f8583301f965b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "config/config.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Symplify\\PHPStanExtensions\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Pre-escaped error messages in 'symplify' error format, container aware test case and other useful extensions for PHPStan", + "keywords": [ + "phpstan-extension", + "static analysis" + ], + "support": { + "issues": "https://github.com/symplify/phpstan-extensions/issues", + "source": "https://github.com/symplify/phpstan-extensions/tree/11.4.2" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-09-17T18:30:45+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "tomasvotruba/class-leak", + "version": "0.1.1.72", + "source": { + "type": "git", + "url": "https://github.com/TomasVotruba/class-leak.git", + "reference": "f78d151d787c7edee8b33a6969a671d0944429ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TomasVotruba/class-leak/zipball/f78d151d787c7edee8b33a6969a671d0944429ee", + "reference": "f78d151d787c7edee8b33a6969a671d0944429ee", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "bin": [ + "bin/class-leak", + "bin/class-leak.php" + ], + "type": "library", + "autoload": { + "psr-4": { + "TomasVotruba\\ClassLeak\\": "app" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Detect leaking classes", + "support": { + "issues": "https://github.com/TomasVotruba/class-leak/issues", + "source": "https://github.com/TomasVotruba/class-leak/tree/0.1.1.72" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-07-26T09:53:21+00:00" + }, + { + "name": "tracy/tracy", + "version": "v2.10.5", + "source": { + "type": "git", + "url": "https://github.com/nette/tracy.git", + "reference": "86bdba4aa0f707d3f125933931d3df6e5c7aad79" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tracy/zipball/86bdba4aa0f707d3f125933931d3df6e5c7aad79", + "reference": "86bdba4aa0f707d3f125933931d3df6e5c7aad79", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-session": "*", + "php": ">=8.0 <8.4" + }, + "conflict": { + "nette/di": "<3.0" + }, + "require-dev": { + "latte/latte": "^2.5", + "nette/di": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0", + "nette/tester": "^2.2", + "nette/utils": "^3.0", + "phpstan/phpstan": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10-dev" + } + }, + "autoload": { + "files": [ + "src/Tracy/functions.php" + ], + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.", + "homepage": "https://tracy.nette.org", + "keywords": [ + "Xdebug", + "debug", + "debugger", + "nette", + "profiler" + ], + "support": { + "issues": "https://github.com/nette/tracy/issues", + "source": "https://github.com/nette/tracy/tree/v2.10.5" + }, + "time": "2023-10-16T21:54:18+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.1" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/config/config.php b/config/config.php index f5ae006ec1..167a0a911c 100644 --- a/config/config.php +++ b/config/config.php @@ -1,107 +1,54 @@ parameters(); - $parameters->set('env(GITHUB_TOKEN)', null); $parameters->set(Option::GITHUB_TOKEN, '%env(GITHUB_TOKEN)%'); - $mbConfig->packageDirectories([]); $mbConfig->packageDirectoriesExcludes([]); $mbConfig->dataToAppend([]); $mbConfig->dataToRemove([]); - $parameters->set(Option::EXCLUDE_PACKAGE_VERSION_CONFLICTS, []); - - $parameters->set(Option::IS_STAGE_REQUIRED, false); + $parameters->set(Option::IS_STAGE_REQUIRED, \false); $parameters->set(Option::STAGES_TO_ALLOW_EXISTING_TAG, []); - // for back compatibility, better switch to "main" $mbConfig->defaultBranch('master'); - $mbConfig->packageAliasFormat('.-dev'); - - $mbConfig->composerSectionOrder([ - ComposerJsonSection::NAME, - ComposerJsonSection::TYPE, - ComposerJsonSection::DESCRIPTION, - ComposerJsonSection::KEYWORDS, - ComposerJsonSection::HOMEPAGE, - ComposerJsonSection::LICENSE, - ComposerJsonSection::AUTHORS, - ComposerJsonSection::BIN, - ComposerJsonSection::REQUIRE, - ComposerJsonSection::REQUIRE_DEV, - ComposerJsonSection::AUTOLOAD, - ComposerJsonSection::AUTOLOAD_DEV, - ComposerJsonSection::REPOSITORIES, - ComposerJsonSection::PROVIDE, - ComposerJsonSection::CONFLICT, - ComposerJsonSection::REPLACE, - ComposerJsonSection::SCRIPTS, - ComposerJsonSection::SCRIPTS_DESCRIPTIONS, - ComposerJsonSection::SUGGEST, - ComposerJsonSection::CONFIG, - ComposerJsonSection::MINIMUM_STABILITY, - ComposerJsonSection::PREFER_STABLE, - ComposerJsonSection::EXTRA, - ]); - + $mbConfig->composerSectionOrder([ComposerJsonSection::NAME, ComposerJsonSection::TYPE, ComposerJsonSection::DESCRIPTION, ComposerJsonSection::KEYWORDS, ComposerJsonSection::HOMEPAGE, ComposerJsonSection::LICENSE, ComposerJsonSection::AUTHORS, ComposerJsonSection::BIN, ComposerJsonSection::REQUIRE, ComposerJsonSection::REQUIRE_DEV, ComposerJsonSection::AUTOLOAD, ComposerJsonSection::AUTOLOAD_DEV, ComposerJsonSection::REPOSITORIES, ComposerJsonSection::PROVIDE, ComposerJsonSection::CONFLICT, ComposerJsonSection::REPLACE, ComposerJsonSection::SCRIPTS, ComposerJsonSection::SCRIPTS_DESCRIPTIONS, ComposerJsonSection::SUGGEST, ComposerJsonSection::CONFIG, ComposerJsonSection::MINIMUM_STABILITY, ComposerJsonSection::PREFER_STABLE, ComposerJsonSection::EXTRA]); $services = $mbConfig->services(); - - $services->defaults() - ->public() - ->autowire(); - - $services->load('Symplify\MonorepoBuilder\\', __DIR__ . '/../packages') - ->exclude([ - // register manually - __DIR__ . '/../packages/Release/ReleaseWorker', - ]); - - if (! $mbConfig->isDisableDefaultWorkers()) { + $services->defaults()->public()->autowire(); + $services->load('Symplify\MonorepoBuilder\\', __DIR__ . '/../packages')->exclude([ + // register manually + __DIR__ . '/../packages/Release/ReleaseWorker', + ]); + if (!$mbConfig->isDisableDefaultWorkers()) { // add default for easy tag and push without need to make configs $services->set(TagVersionReleaseWorker::class); $services->set(PushTagReleaseWorker::class); } - - $services->load('Symplify\MonorepoBuilder\\', __DIR__ . '/../src') - ->exclude([ - __DIR__ . '/../src/Config/MBConfig.php', - __DIR__ . '/../src/Exception', - __DIR__ . '/../src/Kernel', - __DIR__ . '/../src/ValueObject', - ]); - + $services->load('Symplify\MonorepoBuilder\\', __DIR__ . '/../src')->exclude([__DIR__ . '/../src/Config/MBConfig.php', __DIR__ . '/../src/Exception', __DIR__ . '/../src/Kernel', __DIR__ . '/../src/ValueObject']); // for autowired commands $services->alias(Application::class, MonorepoBuilderApplication::class); - $services->set(PrivatesCaller::class); $services->set(ParametersMerger::class); - $services->set(PrivatesCaller::class); - - $services->set(ParameterProvider::class) - ->args([service('service_container')]); - + $services->set(ParameterProvider::class)->args([service('service_container')]); $services->set(SymfonyStyleFactory::class); - $services->set(SymfonyStyle::class) - ->factory([service(SymfonyStyleFactory::class), 'create']); + $services->set(SymfonyStyle::class)->factory([service(SymfonyStyleFactory::class), 'create']); }; diff --git a/ecs.php b/ecs.php deleted file mode 100644 index a66f62e83b..0000000000 --- a/ecs.php +++ /dev/null @@ -1,21 +0,0 @@ -paths([ - __DIR__ . '/ecs.php', - __DIR__ . '/rector.php', - __DIR__ . '/config', - __DIR__ . '/src', - __DIR__ . '/tests', - ]); - - $ecsConfig->sets([ - SetList::COMMON, - SetList::PSR_12, - ]); -}; diff --git a/full-tool-build.sh b/full-tool-build.sh deleted file mode 100644 index 374612fb84..0000000000 --- a/full-tool-build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -# add patches -composer install --ansi - -# but skip dev dependencies -composer update --no-dev --ansi - -# remove tests and useless files, to make downgraded, scoped and deployed codebase as small as possible -rm -rf tests - -# downgrade with rector -mkdir rector-local -composer require rector/rector ^0.17 --working-dir rector-local -rector-local/vendor/bin/rector process bin src packages vendor --config build/rector-downgrade-php-72.php --ansi - -# prefix -sh prefix-code.sh diff --git a/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/ComposerJsonFactoryTest.php b/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/ComposerJsonFactoryTest.php deleted file mode 100644 index 19c9fa41c2..0000000000 --- a/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/ComposerJsonFactoryTest.php +++ /dev/null @@ -1,56 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - $this->composerJsonFactory = $this->getService(ComposerJsonFactory::class); - $this->jsonFileManager = $this->getService(JsonFileManager::class); - } - - public function test(): void - { - $composerJson = $this->composerJsonFactory->createFromFilePath(__DIR__ . '/Source/some_composer.json'); - - $fileInfo = $composerJson->getFileInfo(); - $this->assertInstanceOf(SmartFileInfo::class, $fileInfo); - - $this->assertCount(2, $composerJson->getAllClassmaps()); - - $this->assertSame(['directory', 'src'], $composerJson->getPsr4AndClassmapDirectories()); - - $this->assertSame([ - 'symplify/between' => '^8.3.45', - ], $composerJson->getReplace()); - - $this->assertSame('project', $composerJson->getType()); - } - - public function testReprint(): void - { - $composerJson = $this->composerJsonFactory->createFromFilePath(self::FULL_COMPOSER_JSON_FILE_PATH); - $actualJson = $this->jsonFileManager->encodeJsonToFileContent($composerJson->getJsonArray()); - - $this->assertJsonStringEqualsJsonFile(self::FULL_COMPOSER_JSON_FILE_PATH, $actualJson); - } -} diff --git a/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/full_composer.json b/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/full_composer.json deleted file mode 100644 index f560214b37..0000000000 --- a/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/full_composer.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "test-package", - "description": "Package to load, merge and save composer.json file(s)", - "license": "MIT", - "type": "symfony-bundle", - "version": "1.0.0", - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^8.5|^9.4" - }, - "autoload": { - "psr-4": { - "Symplify\\ComposerJsonManipulator\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "Symplify\\ComposerJsonManipulator\\Tests\\": "tests" - } - }, - "extra": { - "branch-alias": { - "dev-master": "9.1-dev" - } - }, - "minimum-stability": "dev", - "prefer-stable": true, - "provide": { - "psr/log-implementation": "3.0.0" - }, - "replace": { - "symplify/package-builder": "self.version" - }, - "scripts": { - "check-cs": "packages/easy-coding-standard/bin/ecs check --ansi" - }, - "scripts-descriptions": { - "check-cs": "some-description" - }, - "config": { - "sort-packages": true - } -} diff --git a/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/some_composer.json b/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/some_composer.json deleted file mode 100644 index 8ff71f5cb1..0000000000 --- a/packages-tests/ComposerJsonManipulator/ComposerJsonFactory/Source/some_composer.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "project", - "autoload": { - "classmap": ["src"], - "psr-4": { - "App\\": "directory" - } - }, - "autoload-dev": { - "classmap": ["tests"] - }, - "require": { - "php": "^7.4", - "symfony/console": "^5.2" - }, - "replace": { - "symplify/between": "^8.3.45" - } -} diff --git a/packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/ComposerJsonSchemaValidationTest.php b/packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/ComposerJsonSchemaValidationTest.php deleted file mode 100644 index a15e7c6e34..0000000000 --- a/packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/ComposerJsonSchemaValidationTest.php +++ /dev/null @@ -1,46 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - - $this->jsonFileManager = $this->getService(JsonFileManager::class); - $this->smartFileSystem = new SmartFileSystem(); - } - - public function testCheckEmptyKeysAreRemoved(): void - { - $sourceJsonPath = __DIR__ . '/Source/symfony-website_skeleton-composer.json'; - $targetJsonPath = sys_get_temp_dir() . '/composer_json_manipulator_test_schema_validation.json'; - - $sourceJson = $this->jsonFileManager->loadFromFilePath($sourceJsonPath); - $this->smartFileSystem->dumpFile($targetJsonPath, $this->jsonFileManager->encodeJsonToFileContent($sourceJson)); - - $sourceJson = $this->jsonFileManager->loadFromFilePath($sourceJsonPath); - $targetJson = $this->jsonFileManager->loadFromFilePath($targetJsonPath); - - /* - * Check empty keys are present in "source" but not in "target" - */ - $this->assertArrayHasKey(ComposerJsonSection::REQUIRE_DEV, $sourceJson); - $this->assertArrayHasKey('auto-scripts', $sourceJson['scripts']); - $this->assertArrayNotHasKey(ComposerJsonSection::REQUIRE_DEV, $targetJson); - $this->assertArrayNotHasKey('auto-scripts', $targetJson['scripts']); - } -} diff --git a/packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/Source/symfony-website_skeleton-composer.json b/packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/Source/symfony-website_skeleton-composer.json deleted file mode 100644 index 68b79b6e61..0000000000 --- a/packages-tests/ComposerJsonManipulator/ComposerJsonSchemaValidation/Source/symfony-website_skeleton-composer.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "name": "symfony/website-skeleton", - "type": "project", - "license": "MIT", - "description": "A skeleton to start a new Symfony website", - "require": { - "php": "^7.2.5", - "ext-ctype": "*", - "ext-iconv": "*", - "symfony/flex": "^1.3.1" - }, - "flex-require": { - "sensio/framework-extra-bundle": "^5.1", - "symfony/asset": "*", - "symfony/console": "*", - "symfony/dotenv": "*", - "symfony/expression-language": "*", - "symfony/form": "*", - "symfony/framework-bundle": "*", - "symfony/http-client": "*", - "symfony/intl": "*", - "symfony/mailer": "*", - "symfony/mime": "*", - "symfony/monolog-bundle": "^3.1", - "symfony/notifier": "*", - "symfony/orm-pack": "*", - "symfony/process": "*", - "symfony/security-bundle": "*", - "symfony/serializer-pack": "*", - "symfony/string": "*", - "symfony/translation": "*", - "symfony/twig-pack": "*", - "symfony/validator": "*", - "symfony/web-link": "*", - "symfony/yaml": "*" - }, - "require-dev": { - }, - "flex-require-dev": { - "symfony/debug-pack": "*", - "symfony/maker-bundle": "^1.0", - "symfony/profiler-pack": "*", - "symfony/test-pack": "*" - }, - "config": { - "optimize-autoloader": true, - "preferred-install": { - "*": "dist" - }, - "sort-packages": true - }, - "autoload": { - "psr-4": { - "App\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "App\\Tests\\": "tests/" - } - }, - "replace": { - "paragonie/random_compat": "2.*", - "symfony/polyfill-ctype": "*", - "symfony/polyfill-iconv": "*", - "symfony/polyfill-php72": "*", - "symfony/polyfill-php71": "*", - "symfony/polyfill-php70": "*", - "symfony/polyfill-php56": "*" - }, - "scripts": { - "auto-scripts": [ - ], - "post-install-cmd": [ - "@auto-scripts" - ], - "post-update-cmd": [ - "@auto-scripts" - ] - }, - "conflict": { - "symfony/symfony": "*" - }, - "extra": { - "symfony": { - "allow-contrib": false, - "require": "5.1.*" - } - } -} diff --git a/packages-tests/ComposerJsonManipulator/Sorter/ComposerPackageSorterTest.php b/packages-tests/ComposerJsonManipulator/Sorter/ComposerPackageSorterTest.php deleted file mode 100644 index 3119f9ad10..0000000000 --- a/packages-tests/ComposerJsonManipulator/Sorter/ComposerPackageSorterTest.php +++ /dev/null @@ -1,52 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - $this->composerPackageSorter = $this->getService(ComposerPackageSorter::class); - } - - /** - * @param array $packages - * @param array $expectedSortedPackages - */ - #[DataProvider('provideData')] - public function test(array $packages, array $expectedSortedPackages): void - { - $sortedPackages = $this->composerPackageSorter->sortPackages($packages); - $this->assertSame($expectedSortedPackages, $sortedPackages); - } - - /** - * @return Iterator>> - */ - public static function provideData(): Iterator - { - yield [ - [ - 'symfony/console' => '^5.2', - 'php' => '^8.0', - 'ext-json' => '*', - ], - [ - 'php' => '^8.0', - 'ext-json' => '*', - 'symfony/console' => '^5.2', - ], - ]; - } -} diff --git a/packages-tests/ComposerJsonManipulator/ValueObject/ComposerJsonTest.php b/packages-tests/ComposerJsonManipulator/ValueObject/ComposerJsonTest.php deleted file mode 100644 index e7fbe39555..0000000000 --- a/packages-tests/ComposerJsonManipulator/ValueObject/ComposerJsonTest.php +++ /dev/null @@ -1,47 +0,0 @@ -addRequiredPackage('symfony/console', '^5.5'); - $composerJson->addRequiredPackage('nette/utils', '^3.2'); - - $this->assertSame([ - 'symfony/console' => '^5.5', - 'nette/utils' => '^3.2', - ], $composerJson->getRequire()); - } - - public function testMovePackageToRequireDev(): void - { - $composerJson = new ComposerJson(); - $composerJson->addRequiredPackage('symfony/console', '^5.5'); - $composerJson->addRequiredDevPackage('symfony/http-kernel', '^5.5'); - $composerJson->movePackageToRequireDev('symfony/console'); - - $this->assertSame([ - 'symfony/http-kernel' => '^5.5', - 'symfony/console' => '^5.5', - ], $composerJson->getRequireDev()); - } - - public function testReplacePacage(): void - { - $composerJson = new ComposerJson(); - $composerJson->addRequiredPackage('symfony/console', '^5.5'); - $composerJson->replacePackage('symfony/console', 'symfony/http-kernel', '^5.0'); - - $this->assertSame([ - 'symfony/http-kernel' => '^5.0', - ], $composerJson->getRequire()); - } -} diff --git a/packages-tests/Merge/Application/MergedAndDecoratedComposerJsonFactoryTest.php b/packages-tests/Merge/Application/MergedAndDecoratedComposerJsonFactoryTest.php deleted file mode 100644 index 8b2c201f7b..0000000000 --- a/packages-tests/Merge/Application/MergedAndDecoratedComposerJsonFactoryTest.php +++ /dev/null @@ -1,44 +0,0 @@ -mergedAndDecoratedComposerJsonFactory = $this->getService( - MergedAndDecoratedComposerJsonFactory::class - ); - } - - public function test(): void - { - if (! defined('SYMPLIFY_MONOREPO')) { - $this->markTestSkipped('Already tested on monorepo'); - } - - $mainComposerJson = $this->createComposerJson(__DIR__ . '/Source/root_composer.json'); - - $packagesFileInfos = [ - new SmartFileInfo(__DIR__ . '/Source/packages/one_package.json'), - new SmartFileInfo(__DIR__ . '/Source/packages/two_package.json'), - ]; - - $this->mergedAndDecoratedComposerJsonFactory->createFromRootConfigAndPackageFileInfos( - $mainComposerJson, - $packagesFileInfos - ); - - $this->assertComposerJsonEquals(__DIR__ . '/Source/expected_composer.json', $mainComposerJson); - } -} diff --git a/packages-tests/Merge/Application/Source/expected_composer.json b/packages-tests/Merge/Application/Source/expected_composer.json deleted file mode 100644 index 53d0a0a63e..0000000000 --- a/packages-tests/Merge/Application/Source/expected_composer.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "symplify/symplify", - "description": "Repository for Symplify packages development.", - "license": "MIT", - "require": { - "php": "^7.2", - "friendsofphp/php-cs-fixer": "^2.16", - "nette/di": "^3.0", - "nette/utils": "^3.0", - "phpstan/phpstan": "^0.12.7", - "symfony/console": "^4.4|^5.1", - "symfony/filesystem": "^4.4|^5.1", - "symfony/finder": "^4.4|^5.1", - "symplify/package-builder": "^7.3", - "symplify/smart-file-system": "^7.3" - }, - "require-dev": { - "nikic/php-parser": "^4.3", - "phpunit/phpunit": "^8.5" - }, - "autoload": { - "psr-4": { - "Symplify\\OnePackage\\": "packages/monorepo-builder/packages-tests/Merge/Application/Source/packages/src", - "Symplify\\PHPStanExtensions\\": "packages/monorepo-builder/packages-tests/Merge/Application/Source/packages/src" - } - }, - "autoload-dev": { - "psr-4": { - "Symplify\\OnePackage\\Tests\\": "packages/monorepo-builder/packages-tests/Merge/Application/Source/packages/tests", - "Symplify\\PHPStanExtensions\\Tests\\": "packages/monorepo-builder/packages-tests/Merge/Application/Source/packages/tests" - - } - }, - "scripts": { - "complete-check": [ - "phpunit", - "@fix-cs", - "@phpstan" - ], - "check-cs": "packages/easy-coding-standard/bin/ecs check --ansi", - "fix-cs": [ - "packages/easy-coding-standard/bin/ecs check --fix --ansi", - "bin/clear_readmes.sh" - ], - "phpstan": "phpstan analyse packages --error-format symplify --ansi", - "changelog": [ - "packages/changelog-linker/bin/changelog-linker dump-merges --ansi", - "packages/changelog-linker/bin/changelog-linker link --ansi", - "packages/changelog-linker/bin/changelog-linker cleanup --ansi" - ], - "merge": "packages/monorepo-builder/bin/monorepo-builder merge --ansi", - "propagate": "packages/monorepo-builder/bin/monorepo-builder propagate --ansi", - "rector": "rector process packages --config rector-ci.yaml --dry-run --ansi" - }, - "replace": { - "symplify/phpstan-extensions": "self.version", - "symplify/set-config-resolver": "self.version" - }, - "config": { - "sort-packages": true - } -} diff --git a/packages-tests/Merge/Application/Source/packages/one_package.json b/packages-tests/Merge/Application/Source/packages/one_package.json deleted file mode 100644 index 4f2954321f..0000000000 --- a/packages-tests/Merge/Application/Source/packages/one_package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "symplify/set-config-resolver", - "description": "Resolve config and sets from configs and cli opptions for CLI applications", - "license": "MIT", - "require": { - "php": "^7.2", - "nette/utils": "^3.0", - "symfony/console": "^4.4|^5.1", - "symfony/finder": "^4.4|^5.1", - "symfony/filesystem": "^4.4|^5.1", - "symplify/smart-file-system": "^7.3" - }, - "require-dev": { - "phpunit/phpunit": "^8.5" - }, - "autoload": { - "psr-4": { - "Symplify\\OnePackage\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "Symplify\\OnePackage\\Tests\\": "tests" - } - }, - "extra": { - "branch-alias": { - "dev-master": "7.3-dev" - } - }, - "minimum-stability": "dev", - "prefer-stable": true -} diff --git a/packages-tests/Merge/Application/Source/packages/src/some_file.txt b/packages-tests/Merge/Application/Source/packages/src/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Application/Source/packages/src/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Application/Source/packages/tests/some_file.txt b/packages-tests/Merge/Application/Source/packages/tests/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Application/Source/packages/tests/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Application/Source/packages/two_package.json b/packages-tests/Merge/Application/Source/packages/two_package.json deleted file mode 100644 index 7086cced7c..0000000000 --- a/packages-tests/Merge/Application/Source/packages/two_package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "symplify/phpstan-extensions", - "description": "'stats' and 'ignore' error format, solid Symfony SplFileInfo and other useful extensions for PHPStan.", - "license": "MIT", - "require": { - "php": "^7.2", - "friendsofphp/php-cs-fixer": "^2.16", - "nette/di": "^3.0", - "nette/utils": "^3.0", - "phpstan/phpstan": "^0.12.7", - "symplify/package-builder": "^7.3", - "symplify/smart-file-system": "^7.3" - }, - "require-dev": { - "phpunit/phpunit": "^8.5", - "nikic/php-parser": "^4.3" - }, - "autoload": { - "psr-4": { - "Symplify\\PHPStanExtensions\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "Symplify\\PHPStanExtensions\\Tests\\": "tests" - } - }, - "extra": { - "branch-alias": { - "dev-master": "7.3-dev" - } - }, - "minimum-stability": "dev", - "prefer-stable": true -} diff --git a/packages-tests/Merge/Application/Source/root_composer.json b/packages-tests/Merge/Application/Source/root_composer.json deleted file mode 100644 index 272341db71..0000000000 --- a/packages-tests/Merge/Application/Source/root_composer.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "symplify/symplify", - "description": "Repository for Symplify packages development.", - "license": "MIT", - "scripts": { - "complete-check": [ - "phpunit", - "@fix-cs", - "@phpstan" - ], - "check-cs": "packages/easy-coding-standard/bin/ecs check --ansi", - "fix-cs": [ - "packages/easy-coding-standard/bin/ecs check --fix --ansi", - "bin/clear_readmes.sh" - ], - "phpstan": "phpstan analyse packages --error-format symplify --ansi", - "changelog": [ - "packages/changelog-linker/bin/changelog-linker dump-merges --ansi", - "packages/changelog-linker/bin/changelog-linker link --ansi", - "packages/changelog-linker/bin/changelog-linker cleanup --ansi" - ], - "merge": "packages/monorepo-builder/bin/monorepo-builder merge --ansi", - "propagate": "packages/monorepo-builder/bin/monorepo-builder propagate --ansi", - "rector": "rector process packages --config rector-ci.yaml --dry-run --ansi" - }, - "config": { - "sort-packages": true - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/AbstractComposerJsonDecoratorTest.php b/packages-tests/Merge/ComposerJsonDecorator/AbstractComposerJsonDecoratorTest.php deleted file mode 100644 index d3b44d9c1d..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/AbstractComposerJsonDecoratorTest.php +++ /dev/null @@ -1,73 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - - $this->composerJsonFactory = $this->getService(ComposerJsonFactory::class); - $this->trioFixtureSplitter = new TrioFixtureSplitter(); - } - - /** - * @param array|SmartFileInfo|string $source - */ - protected function createComposerJson(array | SmartFileInfo | string $source): ComposerJson - { - if (is_string($source) && ! file_exists($source)) { - return $this->composerJsonFactory->createFromString($source); - } - - if (is_array($source)) { - return $this->composerJsonFactory->createFromArray($source); - } - - if ($source instanceof SmartFileInfo) { - return $this->composerJsonFactory->createFromFileInfo($source); - } - - return $this->composerJsonFactory->createFromFilePath($source); - } - - protected function assertComposerJsonEquals( - string | ComposerJson $firstComposerJson, - ComposerJson $secondComposerJson - ): void { - if (is_string($firstComposerJson)) { - $firstComposerJson = $this->createComposerJson($firstComposerJson); - } - - $this->assertSame($firstComposerJson->getAutoload(), $secondComposerJson->getAutoload()); - $this->assertSame($firstComposerJson->getAutoloadDev(), $secondComposerJson->getAutoloadDev()); - - $this->assertSame($firstComposerJson->getRequire(), $secondComposerJson->getRequire()); - $this->assertSame($firstComposerJson->getRequireDev(), $secondComposerJson->getRequireDev()); - $this->assertSame($firstComposerJson->getRepositories(), $secondComposerJson->getRepositories()); - - $this->assertSame($firstComposerJson->getReplace(), $secondComposerJson->getReplace()); - $this->assertSame($firstComposerJson->getProvide(), $secondComposerJson->getProvide()); - $this->assertSame($firstComposerJson->getExtra(), $secondComposerJson->getExtra()); - $this->assertSame($firstComposerJson->getConfig(), $secondComposerJson->getConfig()); - - $this->assertSame($firstComposerJson->getName(), $secondComposerJson->getName()); - $this->assertSame($firstComposerJson->getLicense(), $secondComposerJson->getLicense()); - $this->assertSame($firstComposerJson->getDescription(), $secondComposerJson->getDescription()); - $this->assertSame($firstComposerJson->getAuthors(), $secondComposerJson->getAuthors()); - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/AppenderComposerJsonDecoratorTest.php b/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/AppenderComposerJsonDecoratorTest.php deleted file mode 100644 index 6ae3e00f52..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/AppenderComposerJsonDecoratorTest.php +++ /dev/null @@ -1,31 +0,0 @@ -bootKernelWithConfigs(MonorepoBuilderKernel::class, [__DIR__ . '/Source/appending_config.php']); - - $this->composerJsonFactory = $this->getService(ComposerJsonFactory::class); - $this->appenderComposerJsonDecorator = $this->getService(AppenderComposerJsonDecorator::class); - } - - public function test(): void - { - $composerJson = $this->createComposerJson(__DIR__ . '/Source/input.json'); - $this->appenderComposerJsonDecorator->decorate($composerJson); - - $this->assertComposerJsonEquals(__DIR__ . '/Source/expected.json', $composerJson); - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/appending_config.php b/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/appending_config.php deleted file mode 100644 index 271498a0b9..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/appending_config.php +++ /dev/null @@ -1,23 +0,0 @@ -dataToAppend([ - ComposerJsonSection::REQUIRE_DEV => [ - 'phpstan/phpstan' => '^0.9', - 'tracy/tracy' => '^2.4', - 'slam/php-cs-fixer-extensions' => '^1.15', - ], - ComposerJsonSection::AUTOLOAD => [ - 'psr-4' => [ - 'Symplify\Tests\\' => 'tests' - ], - ], - ]); -}; diff --git a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/expected.json b/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/expected.json deleted file mode 100644 index 787713ab85..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/expected.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "require-dev": { - "phpstan/phpstan": "^0.9", - "rector/rector": "v1.0.0", - "slam/php-cs-fixer-extensions": "^1.15", - "tracy/tracy": "^2.4" - }, - "autoload": { - "psr-4": { - "App\\": "src", - "Symplify\\Tests\\": "tests" - } - } -} \ No newline at end of file diff --git a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/input.json b/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/input.json deleted file mode 100644 index 5accce4ee6..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/input.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "require-dev": { - "rector/rector": "v1.0.0" - }, - "autoload": { - "psr-4": { - "App\\": "src" - } - } -} \ No newline at end of file diff --git a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/to-append.json b/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/to-append.json deleted file mode 100644 index d74379ac25..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator/Source/to-append.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "require-dev": { - "phpstan/phpstan": "^0.9", - "tracy/tracy": "^2.4", - "slam/php-cs-fixer-extensions": "^1.15" - }, - "autoload": { - "psr-4": { - "Symplify\\Tests\\": "tests" - } - } -} \ No newline at end of file diff --git a/packages-tests/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator/RemoverComposerJsonDecoratorTest.php b/packages-tests/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator/RemoverComposerJsonDecoratorTest.php deleted file mode 100644 index fa50f4cdc8..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator/RemoverComposerJsonDecoratorTest.php +++ /dev/null @@ -1,108 +0,0 @@ - [ - 'phpunit/phpunit' => 'v1.0.0', - 'rector/rector' => 'v1.0.0', - ], - ComposerJsonSection::AUTOLOAD_DEV => [ - 'psr-4' => [ - 'Symplify\Tests\\' => 'tests', - 'Symplify\SuperTests\\' => 'super-tests', - ], - 'files' => ['src/SomeFile.php', 'src/KeepFile.php'], - ], - ComposerJsonSection::REPOSITORIES => [ - [ - 'type' => 'git', - 'url' => '', - ], - ], - ]; - - private ComposerJson $composerJson; - - private ComposerJson $expectedComposerJson; - - private RemoverComposerJsonDecorator $removerComposerJsonDecorator; - - protected function setUp(): void - { - $this->bootKernel(MonorepoBuilderKernel::class); - - /** @var ParameterProvider $parameterProvider */ - $parameterProvider = $this->getService(ParameterProvider::class); - $parameterProvider->changeParameter(Option::DATA_TO_REMOVE, [ - ComposerJsonSection::REQUIRE => [ - 'phpunit/phpunit' => '*', - ], - ComposerJsonSection::AUTOLOAD_DEV => [ - 'psr-4' => [ - 'Symplify\\Tests\\' => 'tests', - ], - 'files' => ['src/SomeFile.php'], - ], - ComposerJsonSection::REPOSITORIES => [Option::REMOVE_COMPLETELY], - ]); - - $this->removerComposerJsonDecorator = $this->getService(RemoverComposerJsonDecorator::class); - - $this->composerJson = $this->createMainComposerJson(); - $this->expectedComposerJson = $this->createExpectedComposerJson(); - } - - public function test(): void - { - $this->removerComposerJsonDecorator->decorate($this->composerJson); - - $this->assertComposerJsonEquals($this->expectedComposerJson, $this->composerJson); - } - - private function createMainComposerJson(): ComposerJson - { - /** @var ComposerJsonFactory $composerJsonFactory */ - $composerJsonFactory = $this->getService(ComposerJsonFactory::class); - - return $composerJsonFactory->createFromArray(self::COMPOSER_JSON_DATA); - } - - private function createExpectedComposerJson(): ComposerJson - { - /** @var ComposerJsonFactory $composerJsonFactory */ - $composerJsonFactory = $this->getService(ComposerJsonFactory::class); - - $expectedComposerJson = [ - ComposerJsonSection::REQUIRE => [ - 'rector/rector' => 'v1.0.0', - ], - ComposerJsonSection::AUTOLOAD_DEV => [ - 'psr-4' => [ - 'Symplify\SuperTests\\' => 'super-tests', - ], - 'files' => [ - 1 => 'src/KeepFile.php', - ], - ], - ]; - - return $composerJsonFactory->createFromArray($expectedComposerJson); - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator/RepositoryPathComposerJsonDecoratorTest.php b/packages-tests/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator/RepositoryPathComposerJsonDecoratorTest.php deleted file mode 100644 index e566cb62e1..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator/RepositoryPathComposerJsonDecoratorTest.php +++ /dev/null @@ -1,93 +0,0 @@ - [ - [ - 'type' => 'artifact', - 'url' => 'path/to/directory/with/zips/', - - ], - [ - 'type' => 'path', - 'url' => '../../libs/*/', - ], - [ - 'type' => 'path', - 'url' => 'libs/*/', - ], - [ - 'packagist.org' => false, - ], - ], - ]; - - private ComposerJson $composerJson; - - private ComposerJson $expectedComposerJson; - - private RepositoryPathComposerJsonDecorator $repositoryPathComposerJsonDecorator; - - protected function setUp(): void - { - $this->bootKernel(MonorepoBuilderKernel::class); - - $this->repositoryPathComposerJsonDecorator = $this->getService(RepositoryPathComposerJsonDecorator::class); - $this->composerJson = $this->createMainComposerJson(); - $this->expectedComposerJson = $this->createExpectedComposerJson(); - } - - public function test(): void - { - $this->repositoryPathComposerJsonDecorator->decorate($this->composerJson); - - $this->assertComposerJsonEquals($this->expectedComposerJson, $this->composerJson); - } - - private function createMainComposerJson(): ComposerJson - { - /** @var ComposerJsonFactory $composerJsonFactory */ - $composerJsonFactory = $this->getService(ComposerJsonFactory::class); - - return $composerJsonFactory->createFromArray(self::COMPOSER_JSON_DATA); - } - - private function createExpectedComposerJson(): ComposerJson - { - /** @var ComposerJsonFactory $composerJsonFactory */ - $composerJsonFactory = $this->getService(ComposerJsonFactory::class); - - $expectedComposerJson = [ - ComposerJsonSection::REPOSITORIES => [ - 0 => [ - 'type' => 'artifact', - 'url' => 'path/to/directory/with/zips/', - ], - 1 => [ - 'type' => 'path', - 'url' => 'libs/*/', - ], - 3 => [ - 'packagist.org' => false, - ], - ], - ]; - - return $composerJsonFactory->createFromArray($expectedComposerJson); - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/RootRemoveComposerJsonDecoratorTest.php b/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/RootRemoveComposerJsonDecoratorTest.php deleted file mode 100644 index 3078253696..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/RootRemoveComposerJsonDecoratorTest.php +++ /dev/null @@ -1,42 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - $this->composerJsonMerger = $this->getService(ComposerJsonMerger::class); - } - - /** - * Only packages collected from /packages directory should be removed - */ - public function test(): void - { - $composerJson = $this->composerJsonFactory->createFromFilePath(__DIR__ . '/Source/composer.json'); - $extraComposerJson = $this->composerJsonFactory->createFromFilePath(__DIR__ . '/Source/packages/composer.json'); - - $this->composerJsonMerger->mergeJsonToRoot($composerJson, $extraComposerJson); - - $expectedComposerJson = $this->composerJsonFactory->createFromFilePath( - __DIR__ . '/Source/expected-composer.json' - ); - - $this->assertComposerJsonEquals($expectedComposerJson, $composerJson); - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/composer.json b/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/composer.json deleted file mode 100644 index bbe38d1fdc..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "symfony/symfony", - "require": { - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/expected-composer.json b/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/expected-composer.json deleted file mode 100644 index c08293d9ca..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/expected-composer.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "symfony/symfony", - "require": { - "rector/rector": "v1.0.0", - "symfony/dependency-injection": "v1.0.0" - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/packages/composer.json b/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/packages/composer.json deleted file mode 100644 index fe709043cd..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator/Source/packages/composer.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "symfony/console", - "require": { - "symfony/dependency-injection": "v1.0.0", - "rector/rector": "v1.0.0" - } -} diff --git a/packages-tests/Merge/ComposerJsonDecorator/SortComposerJsonDecorator/SortComposerJsonDecoratorTest.php b/packages-tests/Merge/ComposerJsonDecorator/SortComposerJsonDecorator/SortComposerJsonDecoratorTest.php deleted file mode 100644 index ff31f58edb..0000000000 --- a/packages-tests/Merge/ComposerJsonDecorator/SortComposerJsonDecorator/SortComposerJsonDecoratorTest.php +++ /dev/null @@ -1,59 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - - $this->composerJson = $this->createComposerJson(); - $this->sortComposerJsonDecorator = $this->getService(SortComposerJsonDecorator::class); - } - - public function test(): void - { - $this->sortComposerJsonDecorator->decorate($this->composerJson); - - $this->assertSame( - [ - 'random-this', - 'random-that', - ComposerJsonSection::REQUIRE, - ComposerJsonSection::REQUIRE_DEV, - ComposerJsonSection::AUTOLOAD, - ComposerJsonSection::AUTOLOAD_DEV, - ], - $this->composerJson->getOrderedKeys() - ); - } - - private function createComposerJson(): ComposerJson - { - /** @var ComposerJsonFactory $composerJsonFactory */ - $composerJsonFactory = $this->getService(ComposerJsonFactory::class); - - return $composerJsonFactory->createFromArray([ - 'random-this' => [], - ComposerJsonSection::AUTOLOAD_DEV => [], - ComposerJsonSection::AUTOLOAD => [], - 'random-that' => [], - ComposerJsonSection::REQUIRE_DEV => [], - ComposerJsonSection::REQUIRE => [], - ]); - } -} diff --git a/packages-tests/Merge/ComposerJsonMerger/ComposerJsonMergerTest.php b/packages-tests/Merge/ComposerJsonMerger/ComposerJsonMergerTest.php deleted file mode 100644 index afc1df5fdc..0000000000 --- a/packages-tests/Merge/ComposerJsonMerger/ComposerJsonMergerTest.php +++ /dev/null @@ -1,42 +0,0 @@ -composerJsonMerger = $this->getService(ComposerJsonMerger::class); - } - - #[DataProvider('provideData')] - public function testFixture(SmartFileInfo $fixtureFileInfo): void - { - $trioContent = $this->trioFixtureSplitter->splitFileInfo($fixtureFileInfo); - - $mainComposerJson = $this->createComposerJson($trioContent->getFirstValue()); - $packageComposerJson = $this->createComposerJson($trioContent->getSecondValue()); - - $this->composerJsonMerger->mergeJsonToRoot($mainComposerJson, $packageComposerJson); - - $this->assertComposerJsonEquals($trioContent->getExpectedResult(), $mainComposerJson); - } - - public static function provideData(): Iterator - { - return StaticFixtureFinder::yieldDirectoryExclusively(__DIR__ . '/Fixture', '*.test'); - } -} diff --git a/packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority.test b/packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority.test deleted file mode 100644 index 74b8e54452..0000000000 --- a/packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority.test +++ /dev/null @@ -1,17 +0,0 @@ -{ - "require": { - "phpstan/phpstan": "^0.13" - } -} ------ -{ - "require-dev": { - "phpstan/phpstan": "^0.13" - } -} ------ -{ - "require": { - "phpstan/phpstan": "^0.13" - } -} diff --git a/packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority_inversed.test b/packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority_inversed.test deleted file mode 100644 index 3134010416..0000000000 --- a/packages-tests/Merge/ComposerJsonMerger/Fixture/require_priority_inversed.test +++ /dev/null @@ -1,17 +0,0 @@ -{ - "require-dev": { - "phpstan/phpstan": "^0.13" - } -} ------ -{ - "require": { - "phpstan/phpstan": "^0.13" - } -} ------ -{ - "require": { - "phpstan/phpstan": "^0.13" - } -} diff --git a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_authors.test b/packages-tests/Merge/ComposerJsonMerger/Fixture/with_authors.test deleted file mode 100644 index c286b1d134..0000000000 --- a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_authors.test +++ /dev/null @@ -1,41 +0,0 @@ -{ - "require": { - "php": "^7.1", - "symfony/dependency-injection": "^4.1" - }, - "authors": [ - { - "name": "Original Author", - "email": "original@example.com" - } - ] -} ------ -{ - "require": { - "php": "^7.1" - }, - "authors": [ - { - "name": "New Author", - "email": "new@example.com" - } - ] -} ------ -{ - "require": { - "php": "^7.1", - "symfony/dependency-injection": "^4.1" - }, - "authors": [ - { - "name": "Original Author", - "email": "original@example.com" - }, - { - "name": "New Author", - "email": "new@example.com" - } - ] -} diff --git a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_existing_authors.test b/packages-tests/Merge/ComposerJsonMerger/Fixture/with_existing_authors.test deleted file mode 100644 index a63aed32b3..0000000000 --- a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_existing_authors.test +++ /dev/null @@ -1,85 +0,0 @@ -{ - "require": { - "php": "^7.1", - "symfony/dependency-injection": "^4.1" - }, - "authors": [ - { - "name": "Original Author", - "email": "original@example.com" - } - ], - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/molaux/PostgreSearchBundle.git", - "options": { - "symlink": false - } - }, - { - "type": "path", - "url": "../../packages/*" - } - ] -} ------ -{ - "require": { - "php": "^7.1" - }, - "authors": [ - { - "name": "Package 2 Author", - "email": "package2@example.com" - }, - { - "name": "New Author", - "email": "new@example.com" - } - ], - "autoload": { - "psr-4": { - "Some\\": "some" - } - } -} ------ -{ - "require": { - "php": "^7.1", - "symfony/dependency-injection": "^4.1" - }, - "autoload": { - "psr-4": { - "Some\\": "some" - } - }, - "authors": [ - { - "name": "Original Author", - "email": "original@example.com" - }, - { - "name": "Package 2 Author", - "email": "package2@example.com" - }, - { - "name": "New Author", - "email": "new@example.com" - } - ], - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/molaux/PostgreSearchBundle.git", - "options": { - "symlink": false - } - }, - { - "type": "path", - "url": "../../packages/*" - } - ] -} diff --git a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_extra.test b/packages-tests/Merge/ComposerJsonMerger/Fixture/with_extra.test deleted file mode 100644 index 196c7a8e58..0000000000 --- a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_extra.test +++ /dev/null @@ -1,32 +0,0 @@ -{ - "extra": { - "laravel": { - "providers": [ - "Illuminate\\Database\\ArtisanServiceProvider" - ] - } - } -} ------ -{ - "extra": { - "laravel": { - "providers": [ - "ComposerEventDispatcher\\ComposerEventDispatcherServiceProvide", - "Aws\\AwsServiceProvice" - ] - } - } -} ------ -{ - "extra": { - "laravel": { - "providers": [ - "Aws\\AwsServiceProvice", - "ComposerEventDispatcher\\ComposerEventDispatcherServiceProvide", - "Illuminate\\Database\\ArtisanServiceProvider" - ] - } - } -} \ No newline at end of file diff --git a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_provide.test b/packages-tests/Merge/ComposerJsonMerger/Fixture/with_provide.test deleted file mode 100644 index ac9133b00e..0000000000 --- a/packages-tests/Merge/ComposerJsonMerger/Fixture/with_provide.test +++ /dev/null @@ -1,25 +0,0 @@ -{ - "provide": { - "my/simple-merge": "1.0", - "my/merge-with-star": "1.0", - "my/merge-duplicates-and-spaces": "1.0 | 2.0", - "my/no-merge": "1.0" - } -} ------ -{ - "provide": { - "my/simple-merge": "2.0", - "my/merge-with-star": "*", - "my/merge-duplicates-and-spaces": "1.0 | 2.0 | 3.0" - } -} ------ -{ - "provide": { - "my/simple-merge": "1.0|2.0", - "my/merge-with-star": "*", - "my/merge-duplicates-and-spaces": "1.0|2.0|3.0", - "my/no-merge": "1.0" - } -} diff --git a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/keep_stability.test b/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/keep_stability.test deleted file mode 100644 index 874ef7392e..0000000000 --- a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/keep_stability.test +++ /dev/null @@ -1,5 +0,0 @@ -{"minimum_stability": "alpha"} ------ -{"minimum_stability": "beta"} ------ -{"minimum_stability": "alpha"} diff --git a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/main_has_minimum_stability.test b/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/main_has_minimum_stability.test deleted file mode 100644 index f9d985b326..0000000000 --- a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/main_has_minimum_stability.test +++ /dev/null @@ -1,5 +0,0 @@ -{"minimum_stability": "rc"} ------ -{} ------ -{"minimum_stability": "rc"} diff --git a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/new_has_minimum_stability.test b/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/new_has_minimum_stability.test deleted file mode 100644 index 60a0c11e95..0000000000 --- a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/new_has_minimum_stability.test +++ /dev/null @@ -1,5 +0,0 @@ -{} ------ -{"minimum_stability": "rc"} ------ -{"minimum_stability": "rc"} diff --git a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/no_minimum_stability.test b/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/no_minimum_stability.test deleted file mode 100644 index fa8955313a..0000000000 --- a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/no_minimum_stability.test +++ /dev/null @@ -1,5 +0,0 @@ -{} ------ -{} ------ -{} diff --git a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/widen_stability.test b/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/widen_stability.test deleted file mode 100644 index ad63c5967a..0000000000 --- a/packages-tests/Merge/ComposerKeyMerger/Fixture/MinimalStability/widen_stability.test +++ /dev/null @@ -1,5 +0,0 @@ -{"minimum_stability": "beta"} ------ -{"minimum_stability": "alpha"} ------ -{"minimum_stability": "alpha"} diff --git a/packages-tests/Merge/ComposerKeyMerger/MinimalStabilityKeyMergerTest.php b/packages-tests/Merge/ComposerKeyMerger/MinimalStabilityKeyMergerTest.php deleted file mode 100644 index 7189128bd7..0000000000 --- a/packages-tests/Merge/ComposerKeyMerger/MinimalStabilityKeyMergerTest.php +++ /dev/null @@ -1,36 +0,0 @@ -trioFixtureSplitter->splitFileInfo($fixtureFileInfo); - $mainComposerJson = $this->createComposerJson($trioContent->getFirstValue()); - $packageComposerJson = $this->createComposerJson($trioContent->getSecondValue()); - - $minimalStabilityKeyMerger = new MinimalStabilityKeyMerger(); - $minimalStabilityKeyMerger->merge($mainComposerJson, $packageComposerJson); - - $this->assertComposerJsonEquals($trioContent->getExpectedResult(), $mainComposerJson); - } - - public static function provideData(): Iterator - { - return StaticFixtureFinder::yieldDirectoryExclusively(__DIR__ . '/Fixture/MinimalStability', '*.test'); - } -} diff --git a/packages-tests/Merge/Package/AbstractMergeTestCase.php b/packages-tests/Merge/Package/AbstractMergeTestCase.php deleted file mode 100644 index 1915b9bc28..0000000000 --- a/packages-tests/Merge/Package/AbstractMergeTestCase.php +++ /dev/null @@ -1,51 +0,0 @@ -composerJsonMerger = $this->getService(ComposerJsonMerger::class); - $this->finderSanitizer = $this->getService(FinderSanitizer::class); - } - - protected function doTestDirectoryMergeToFile( - string $directoryWithJsonFiles, - ComposerJson $expectedComposerJson - ): void { - $fileInfos = $this->getFileInfosFromDirectory($directoryWithJsonFiles); - $mergedComposerJson = $this->composerJsonMerger->mergeFileInfos($fileInfos); - - $this->assertComposerJsonEquals($expectedComposerJson, $mergedComposerJson); - } - - /** - * @return SmartFileInfo[] - */ - private function getFileInfosFromDirectory(string $directory): array - { - $finder = Finder::create() - ->files() - ->in($directory) - ->name('*.json') - ->sortByName(); - - return $this->finderSanitizer->sanitize($finder); - } -} diff --git a/packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/CombineStringsToArrayJsonMergerTest.php b/packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/CombineStringsToArrayJsonMergerTest.php deleted file mode 100644 index cacfbbdb7b..0000000000 --- a/packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/CombineStringsToArrayJsonMergerTest.php +++ /dev/null @@ -1,21 +0,0 @@ -markTestSkipped('Already tested on monorepo'); - } - - $expectedComposerJson = $this->createComposerJson(__DIR__ . '/Source/expected.json'); - - $this->doTestDirectoryMergeToFile(__DIR__ . '/../SourceIdenticalNamespaces', $expectedComposerJson); - } -} diff --git a/packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/Source/expected.json b/packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/Source/expected.json deleted file mode 100644 index cd7891a332..0000000000 --- a/packages-tests/Merge/Package/CombineStringsToArrayJsonMerger/Source/expected.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "autoload": { - "classmap": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/Something.php", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/lib/", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/" - ], - "exclude-from-classmap": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/Tests/", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/test/", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/tests/" - ], - "files": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/MyLibrary/functions.php" - ], - "psr-0": { - "": "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/", - "Monolog\\": "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/", - "UniqueGlobalClass": "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/", - "Vendor\\Namespace\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/lib/", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/" - ], - "Vendor_Namespace_": "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/" - }, - "psr-4": { - "App\\Collection\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/collection", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/collection" - ], - "App\\Core\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/core", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core-extension" - ], - "App\\FixedArray\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/array", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/list" - ], - "App\\Model\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/interfaces", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/models" - ], - "App\\Shared\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/shared", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/shared" - ], - "App\\Sub\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/package-c", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/src/package-d" - ], - "App\\YetAnother\\": [ - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src", - "packages/monorepo-builder/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src" - ] - } - } -} diff --git a/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-composer-patches.json b/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-composer-patches.json deleted file mode 100644 index 3e6aa5d3b8..0000000000 --- a/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-composer-patches.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extra": { - "patches": { - "example/package-one": [ - "packages-tests/Merge/Package/SourceComposerPatches/patch-files/example.patch" - ], - "example/package-two": { - "Patch description": "packages-tests/Merge/Package/SourceComposerPatches/patch-files/example.patch", - "Patch two description": "packages-tests/Merge/Package/SourceComposerPatches/patch-files/example.patch" - }, - "symfony/dependency-injection": [ - "https://raw.githubusercontent.com/symplify/vendor-patch-files/main/patches/generic-php-config-loader.patch" - ] - } - } -} diff --git a/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-relative-paths.json b/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-relative-paths.json deleted file mode 100644 index 4949e22b3d..0000000000 --- a/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected-with-relative-paths.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "require": { - "phpunit/phpunit": "^2.0", - "rector/rector": "^2.0", - "symplify/symplify": "^2.0" - }, - "autoload": { - "psr-4": { - "Symplify\\MonorepoBuilder\\": "packages/monorepo-builder/packages-tests/Merge/Package/Source/src", - "Symplify\\Statie\\": "packages/monorepo-builder/packages-tests/Merge/Package/Source/src" - } - } -} diff --git a/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected.json b/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected.json deleted file mode 100644 index 2b9b23803c..0000000000 --- a/packages-tests/Merge/Package/PackageComposerJsonMergerSource/expected.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "repositories": [ - { - "type": "composer", - "url": "https://packages.example.org/" - } - ], - "require": { - "php": "^7.1" - } -} \ No newline at end of file diff --git a/packages-tests/Merge/Package/PackageComposerJsonMergerTest.php b/packages-tests/Merge/Package/PackageComposerJsonMergerTest.php deleted file mode 100644 index 2969d2edc2..0000000000 --- a/packages-tests/Merge/Package/PackageComposerJsonMergerTest.php +++ /dev/null @@ -1,35 +0,0 @@ -markTestSkipped('Already tested on monorepo'); - } - - $expectedComposerJson = $this->createComposerJson( - __DIR__ . '/PackageComposerJsonMergerSource/expected-with-relative-paths.json' - ); - - $this->doTestDirectoryMergeToFile(__DIR__ . '/Source', $expectedComposerJson); - } - - public function testUniqueRepositories(): void - { - $expectedComposerJson = $this->createComposerJson(__DIR__ . '/PackageComposerJsonMergerSource/expected.json'); - - $this->doTestDirectoryMergeToFile(__DIR__ . '/SourceUniqueRepositories', $expectedComposerJson); - } - - public function testComposerPatches(): void - { - $expectedComposerJson = $this->createComposerJson(__DIR__ . '/PackageComposerJsonMergerSource/expected-with-composer-patches.json'); - - $this->doTestDirectoryMergeToFile(__DIR__ . '/SourceComposerPatches', $expectedComposerJson); - } -} diff --git a/packages-tests/Merge/Package/Source/package-one.json b/packages-tests/Merge/Package/Source/package-one.json deleted file mode 100644 index 15c63b65ba..0000000000 --- a/packages-tests/Merge/Package/Source/package-one.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "require": { - "symplify/symplify": "^2.0" - }, - "require-dev": { - "phpunit/phpunit": "^2.0" - }, - "autoload": { - "psr-4": { - "Symplify\\MonorepoBuilder\\": "src" - } - } -} \ No newline at end of file diff --git a/packages-tests/Merge/Package/Source/package-two.json b/packages-tests/Merge/Package/Source/package-two.json deleted file mode 100644 index 10a60db662..0000000000 --- a/packages-tests/Merge/Package/Source/package-two.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "require": { - "rector/rector": "^2.0", - "phpunit/phpunit": "^2.0" - }, - "autoload": { - "psr-4": { - "Symplify\\Statie\\": "src" - } - }, - "minimum-stability": "dev" -} diff --git a/packages-tests/Merge/Package/Source/src/some_file.txt b/packages-tests/Merge/Package/Source/src/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/Source/src/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceComposerPatches/package-one.json b/packages-tests/Merge/Package/SourceComposerPatches/package-one.json deleted file mode 100644 index 3c5c22a6ab..0000000000 --- a/packages-tests/Merge/Package/SourceComposerPatches/package-one.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extra": { - "patches": { - "symfony/dependency-injection": [ - "https://raw.githubusercontent.com/symplify/vendor-patch-files/main/patches/generic-php-config-loader.patch" - ] - } - } -} diff --git a/packages-tests/Merge/Package/SourceComposerPatches/package-three.json b/packages-tests/Merge/Package/SourceComposerPatches/package-three.json deleted file mode 100644 index 3c5c22a6ab..0000000000 --- a/packages-tests/Merge/Package/SourceComposerPatches/package-three.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extra": { - "patches": { - "symfony/dependency-injection": [ - "https://raw.githubusercontent.com/symplify/vendor-patch-files/main/patches/generic-php-config-loader.patch" - ] - } - } -} diff --git a/packages-tests/Merge/Package/SourceComposerPatches/package-two.json b/packages-tests/Merge/Package/SourceComposerPatches/package-two.json deleted file mode 100644 index 3fd2ca79e8..0000000000 --- a/packages-tests/Merge/Package/SourceComposerPatches/package-two.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extra": { - "patches": { - "example/package-one": [ - "vendor/symplify/monorepo-builder/patch-files/example.patch" - ], - "example/package-two": { - "Patch description": "vendor/symplify/monorepo-builder/patch-files/example.patch", - "Patch two description": "./vendor/symplify/monorepo-builder/patch-files/example.patch" - } - } - } -} diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/Something.php b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/Something.php deleted file mode 100644 index deba01fc8d..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/Something.php +++ /dev/null @@ -1 +0,0 @@ -something diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/composer.json b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/composer.json deleted file mode 100755 index ab32b9c9ba..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/composer.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "autoload": { - "psr-4": { - "App\\Collection\\": ["src/collection"], - "App\\Core\\": "src/core", - "App\\FixedArray\\": ["src/array", "src/list"], - "App\\Shared\\": "src/shared", - "App\\YetAnother\\": ["src"] - }, - "psr-0": { - "Monolog\\": "src/", - "Vendor\\Namespace\\": ["src/", "lib/"], - "Vendor_Namespace_": "src/", - "UniqueGlobalClass": "", - "": "src/" - }, - "classmap": ["src/", "lib/", "Something.php"], - "files": ["src/MyLibrary/functions.php"], - "exclude-from-classmap": ["/Tests/", "/test/", "/tests/"] - } -} diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/lib/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/lib/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/lib/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/array/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/array/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/array/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/collection/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/collection/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/collection/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/core/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/core/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/core/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/list/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/list/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/list/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/shared/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/shared/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageA/src/shared/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/composer.json b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/composer.json deleted file mode 100755 index e1d7192a73..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/composer.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "autoload": { - "psr-4": { - "App\\Collection\\": ["src/collection"], - "App\\Core\\": "src/core-extension", - "App\\Model\\": "src/interfaces", - "App\\Shared\\": "src/shared", - "App\\YetAnother\\": "src" - } - } -} diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/collection/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/collection/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/collection/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core-extension/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core-extension/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core-extension/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/core/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/interfaces/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/interfaces/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/interfaces/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/list/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/list/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/list/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/shared/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/shared/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/PackageB/src/shared/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/composer.json b/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/composer.json deleted file mode 100755 index 8b3cace711..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/composer.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "autoload": { - "psr-4": { - "App\\Model\\": "src/models", - "App\\Sub\\": "src/package-c" - } - } -} diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/models/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/models/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/models/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/package-c/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/package-c/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubA/PackageC/src/package-c/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/composer.json b/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/composer.json deleted file mode 100755 index 8d3d383e90..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/composer.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "autoload": { - "psr-4": { - "App\\Sub\\": "src/package-d" - } - } -} diff --git a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/src/package-d/some_file.txt b/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/src/package-d/some_file.txt deleted file mode 100644 index 2ef267e25b..0000000000 --- a/packages-tests/Merge/Package/SourceIdenticalNamespaces/SubB/PackageD/src/package-d/some_file.txt +++ /dev/null @@ -1 +0,0 @@ -some content diff --git a/packages-tests/Merge/Package/SourceUniqueRepositories/package-one.json b/packages-tests/Merge/Package/SourceUniqueRepositories/package-one.json deleted file mode 100644 index 62f210cc4e..0000000000 --- a/packages-tests/Merge/Package/SourceUniqueRepositories/package-one.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "repositories": [ - { - "type": "composer", - "url": "https://packages.example.org/" - } - ] -} diff --git a/packages-tests/Merge/Package/SourceUniqueRepositories/package-three.json b/packages-tests/Merge/Package/SourceUniqueRepositories/package-three.json deleted file mode 100644 index 4b364da6e7..0000000000 --- a/packages-tests/Merge/Package/SourceUniqueRepositories/package-three.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "require": { - "php": "^7.1" - }, - "repositories": [ - { - "type": "composer", - "url": "https://packages.example.org/" - } - ] -} diff --git a/packages-tests/Merge/Package/SourceUniqueRepositories/package-two.json b/packages-tests/Merge/Package/SourceUniqueRepositories/package-two.json deleted file mode 100644 index 62f210cc4e..0000000000 --- a/packages-tests/Merge/Package/SourceUniqueRepositories/package-two.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "repositories": [ - { - "type": "composer", - "url": "https://packages.example.org/" - } - ] -} diff --git a/packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/autoload.json b/packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/autoload.json deleted file mode 100644 index c94579132b..0000000000 --- a/packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/autoload.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "autoload": { - "psr-4": { - "App\\": "src" - } - } -} diff --git a/packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/expected-autoload.json b/packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/expected-autoload.json deleted file mode 100644 index 9f6b8dbbc4..0000000000 --- a/packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/expected-autoload.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "autoload": { - "psr-4": { - "App\\": "packages/monorepo-builder/packages-tests/Merge/PathResolver/AutoloadPathNormalizerSource/src" - } - } -} diff --git a/packages-tests/Merge/PathResolver/AutoloadPathNormalizerTest.php b/packages-tests/Merge/PathResolver/AutoloadPathNormalizerTest.php deleted file mode 100644 index c6a71422fa..0000000000 --- a/packages-tests/Merge/PathResolver/AutoloadPathNormalizerTest.php +++ /dev/null @@ -1,37 +0,0 @@ -autoloadPathNormalizer = $this->getService(AutoloadPathNormalizer::class); - } - - public function test(): void - { - if (! defined('SYMPLIFY_MONOREPO')) { - $this->markTestSkipped('Already tested on monorepo'); - } - - $autoloadFileInfo = new SmartFileInfo(__DIR__ . '/AutoloadPathNormalizerSource/autoload.json'); - $composerJson = $this->createComposerJson($autoloadFileInfo); - - $this->autoloadPathNormalizer->normalizePaths($composerJson, $autoloadFileInfo); - $this->assertComposerJsonEquals( - __DIR__ . '/AutoloadPathNormalizerSource/expected-autoload.json', - $composerJson - ); - } -} diff --git a/packages-tests/Merge/PathResolver/ComposerPatchesPathNormalizerTest.php b/packages-tests/Merge/PathResolver/ComposerPatchesPathNormalizerTest.php deleted file mode 100644 index 28d1d4c2cd..0000000000 --- a/packages-tests/Merge/PathResolver/ComposerPatchesPathNormalizerTest.php +++ /dev/null @@ -1,23 +0,0 @@ -markTestSkipped('Already tested on monorepo'); - } - } -} diff --git a/packages-tests/Propagate/VersionPropagator/Fixture/propagate-require-dev.test b/packages-tests/Propagate/VersionPropagator/Fixture/propagate-require-dev.test deleted file mode 100644 index 1f3e2c092e..0000000000 --- a/packages-tests/Propagate/VersionPropagator/Fixture/propagate-require-dev.test +++ /dev/null @@ -1,22 +0,0 @@ -{ - "require": { - "symfony/console": "^5.2" - }, - "require-dev": { - "symfony/event-dispatcher": "^4.4" - } -} ------ -{ - "name": "another-package", - "require-dev": { - "symfony/event-dispatcher": "^4.1" - } -} ------ -{ - "name": "another-package", - "require-dev": { - "symfony/event-dispatcher": "^4.4" - } -} diff --git a/packages-tests/Propagate/VersionPropagator/Fixture/propagate.test b/packages-tests/Propagate/VersionPropagator/Fixture/propagate.test deleted file mode 100644 index 5e10e032b5..0000000000 --- a/packages-tests/Propagate/VersionPropagator/Fixture/propagate.test +++ /dev/null @@ -1,19 +0,0 @@ -{ - "require": { - "symfony/console": "^5.2" - } -} ------ -{ - "name": "another-package", - "require": { - "symfony/console": "^4.2" - } -} ------ -{ - "name": "another-package", - "require": { - "symfony/console": "^5.2" - } -} diff --git a/packages-tests/Propagate/VersionPropagator/VersionPropagaterTest.php b/packages-tests/Propagate/VersionPropagator/VersionPropagaterTest.php deleted file mode 100644 index a807e0989d..0000000000 --- a/packages-tests/Propagate/VersionPropagator/VersionPropagaterTest.php +++ /dev/null @@ -1,41 +0,0 @@ -versionPropagator = $this->getService(VersionPropagator::class); - } - - #[DataProvider('provideData')] - public function test(SmartFileInfo $fixtureFileInfo): void - { - $trioContent = $this->trioFixtureSplitter->splitFileInfo($fixtureFileInfo); - - $mainComposerJson = $this->composerJsonFactory->createFromString($trioContent->getFirstValue()); - $packageComposerJson = $this->createComposerJson($trioContent->getSecondValue()); - - $this->versionPropagator->propagate($mainComposerJson, $packageComposerJson); - - $this->assertComposerJsonEquals($trioContent->getExpectedResult(), $packageComposerJson); - } - - public static function provideData(): Iterator - { - return StaticFixtureFinder::yieldDirectoryExclusively(__DIR__ . '/Fixture', '*.test'); - } -} diff --git a/packages-tests/Release/ReleaseWorkerProvider/ReleaseWorkerProviderTest.php b/packages-tests/Release/ReleaseWorkerProvider/ReleaseWorkerProviderTest.php deleted file mode 100644 index 0931566add..0000000000 --- a/packages-tests/Release/ReleaseWorkerProvider/ReleaseWorkerProviderTest.php +++ /dev/null @@ -1,27 +0,0 @@ -bootKernelWithConfigs(MonorepoBuilderKernel::class, [__DIR__ . '/config/all_release_workers.php']); - $this->releaseWorkerProvider = $this->getService(ReleaseWorkerProvider::class); - } - - public function test(): void - { - $releaseWorkers = $this->releaseWorkerProvider->provideByStage(Stage::MAIN); - $this->assertCount(7, $releaseWorkers); - } -} diff --git a/packages-tests/Release/ReleaseWorkerProvider/config/all_release_workers.php b/packages-tests/Release/ReleaseWorkerProvider/config/all_release_workers.php deleted file mode 100644 index ee93cc193d..0000000000 --- a/packages-tests/Release/ReleaseWorkerProvider/config/all_release_workers.php +++ /dev/null @@ -1,23 +0,0 @@ -services(); - $services->set(SetCurrentMutualDependenciesReleaseWorker::class); - $services->set(AddTagToChangelogReleaseWorker::class); - $services->set(TagVersionReleaseWorker::class); - $services->set(PushTagReleaseWorker::class); - $services->set(SetNextMutualDependenciesReleaseWorker::class); - $services->set(UpdateBranchAliasReleaseWorker::class); - $services->set(PushNextDevReleaseWorker::class); -}; diff --git a/packages-tests/Testing/ComposerJson/ComposerJsonSymlinkerTest.php b/packages-tests/Testing/ComposerJson/ComposerJsonSymlinkerTest.php deleted file mode 100644 index eb8ffc09f0..0000000000 --- a/packages-tests/Testing/ComposerJson/ComposerJsonSymlinkerTest.php +++ /dev/null @@ -1,87 +0,0 @@ -bootKernelWithConfigs(MonorepoBuilderKernel::class, [__DIR__ . '/config/test_config.php']); - - $this->composerJsonSymlinker = $this->getService(ComposerJsonSymlinker::class); - } - - #[DataProvider('provideData')] - public function testItCanAppendPathRepository( - string $packagePath, - string $packageName, - bool $symlink, - string $expectedJsonFile - ): void { - $mainComposerJson = new SmartFileInfo(__DIR__ . '/composer.json'); - $packageFileInfo = new SmartFileInfo($packagePath); - - $packageComposerJson = $this->composerJsonSymlinker->decoratePackageComposerJsonWithPackageSymlinks( - $packageFileInfo, - [$packageName], - $mainComposerJson, - $symlink - ); - - $jsonString = Json::encode($packageComposerJson, Json::PRETTY); - $this->assertJsonStringEqualsJsonFile($expectedJsonFile, $jsonString); - } - - /** - * @return Iterator - */ - public static function provideData(): Iterator - { - yield [ - __DIR__ . '/packages/package-one/composer.json', - 'example/package-two', - false, - __DIR__ . '/Fixture/expected_path_repository.test', - ]; - - yield [ - __DIR__ . '/packages/package-two/composer.json', - 'example/package-one', - false, - __DIR__ . '/Fixture/expected_repository.test', - ]; - - yield [ - __DIR__ . '/packages/package-two/composer.json', - 'example/package-one', - true, - __DIR__ . '/Fixture/expected_symlink_true.test', - ]; - - yield [ - __DIR__ . '/packages/package-three/composer.json', - 'example/package-one', - false, - __DIR__ . '/Fixture/expected_reuse_existing_repository.test', - ]; - - yield [ - __DIR__ . '/packages/with-more-depth/package-four/composer.json', - 'example/package-two', - false, - __DIR__ . '/Fixture/expected_deeper_path_repository.test', - ]; - } -} diff --git a/packages-tests/Testing/ComposerJson/Fixture/expected_deeper_path_repository.test b/packages-tests/Testing/ComposerJson/Fixture/expected_deeper_path_repository.test deleted file mode 100644 index 9ead4c24c6..0000000000 --- a/packages-tests/Testing/ComposerJson/Fixture/expected_deeper_path_repository.test +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "example/package-four", - "repositories": [ - { - "type": "path", - "url": "../../../packages/package-two", - "options": { - "symlink": false - } - }, - { - "type": "composer", - "url": "https://repo.packagist.com/acme-companies/" - }, - { - "packagist.org": false - } - ] -} diff --git a/packages-tests/Testing/ComposerJson/Fixture/expected_path_repository.test b/packages-tests/Testing/ComposerJson/Fixture/expected_path_repository.test deleted file mode 100644 index 81224691db..0000000000 --- a/packages-tests/Testing/ComposerJson/Fixture/expected_path_repository.test +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "example/package-one", - "repositories": [ - { - "type": "path", - "url": "../../packages/package-two", - "options": { - "symlink": false - } - }, - { - "type": "composer", - "url": "https://repo.packagist.com/acme-companies/" - }, - { - "packagist.org": false - } - ] -} diff --git a/packages-tests/Testing/ComposerJson/Fixture/expected_repository.test b/packages-tests/Testing/ComposerJson/Fixture/expected_repository.test deleted file mode 100644 index 8ba92aff8f..0000000000 --- a/packages-tests/Testing/ComposerJson/Fixture/expected_repository.test +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "example/package-two", - "repositories": [ - { - "type": "path", - "url": "../../packages/package-one", - "options": { - "symlink": false - } - } - ] -} diff --git a/packages-tests/Testing/ComposerJson/Fixture/expected_reuse_existing_repository.test b/packages-tests/Testing/ComposerJson/Fixture/expected_reuse_existing_repository.test deleted file mode 100644 index 7160ec8e0f..0000000000 --- a/packages-tests/Testing/ComposerJson/Fixture/expected_reuse_existing_repository.test +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "example/package-three", - "repositories": [ - { - "type": "path", - "url": "../../packages/package-one", - "options": { - "symlink": false - } - } - ] -} diff --git a/packages-tests/Testing/ComposerJson/Fixture/expected_symlink_true.test b/packages-tests/Testing/ComposerJson/Fixture/expected_symlink_true.test deleted file mode 100644 index 873759f8f0..0000000000 --- a/packages-tests/Testing/ComposerJson/Fixture/expected_symlink_true.test +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "example/package-two", - "repositories": [ - { - "type": "path", - "url": "../../packages/package-one", - "options": { - "symlink": true - } - } - ] -} diff --git a/packages-tests/Testing/ComposerJson/composer.json b/packages-tests/Testing/ComposerJson/composer.json deleted file mode 100644 index 0db3279e44..0000000000 --- a/packages-tests/Testing/ComposerJson/composer.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} diff --git a/packages-tests/Testing/ComposerJson/config/test_config.php b/packages-tests/Testing/ComposerJson/config/test_config.php deleted file mode 100644 index 165bfd2f03..0000000000 --- a/packages-tests/Testing/ComposerJson/config/test_config.php +++ /dev/null @@ -1,11 +0,0 @@ -parameters(); - $parameters->set(Option::PACKAGE_DIRECTORIES, [__DIR__ . '/../packages']); -}; diff --git a/packages-tests/Testing/ComposerJson/packages/package-one/composer.json b/packages-tests/Testing/ComposerJson/packages/package-one/composer.json deleted file mode 100644 index bc101a3088..0000000000 --- a/packages-tests/Testing/ComposerJson/packages/package-one/composer.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "example/package-one", - "repositories": [ - { - "type": "composer", - "url": "https://repo.packagist.com/acme-companies/" - }, - { - "packagist.org": false - } - ] -} diff --git a/packages-tests/Testing/ComposerJson/packages/package-three/composer.json b/packages-tests/Testing/ComposerJson/packages/package-three/composer.json deleted file mode 100644 index 5be02ba504..0000000000 --- a/packages-tests/Testing/ComposerJson/packages/package-three/composer.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "example/package-three", - "repositories": [ - { - "type": "path", - "url": "../../packages/package-one", - "options": { - "symlink": true - } - } - ] -} diff --git a/packages-tests/Testing/ComposerJson/packages/package-two/composer.json b/packages-tests/Testing/ComposerJson/packages/package-two/composer.json deleted file mode 100644 index 34426ad455..0000000000 --- a/packages-tests/Testing/ComposerJson/packages/package-two/composer.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "example/package-two" -} diff --git a/packages-tests/Testing/ComposerJson/packages/with-more-depth/package-four/composer.json b/packages-tests/Testing/ComposerJson/packages/with-more-depth/package-four/composer.json deleted file mode 100644 index 4a3c6457fd..0000000000 --- a/packages-tests/Testing/ComposerJson/packages/with-more-depth/package-four/composer.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "example/package-four", - "repositories": [ - { - "type": "composer", - "url": "https://repo.packagist.com/acme-companies/" - }, - { - "packagist.org": false - } - ] -} diff --git a/packages-tests/Testing/PathResolver/PackagePathResolverTest.php b/packages-tests/Testing/PathResolver/PackagePathResolverTest.php deleted file mode 100644 index ecbbbbea7a..0000000000 --- a/packages-tests/Testing/PathResolver/PackagePathResolverTest.php +++ /dev/null @@ -1,44 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - $this->packagePathResolver = $this->getService(PackagePathResolver::class); - } - - public function test(): void - { - $mainComposerJson = new SmartFileInfo(__DIR__ . '/PackagePathResolverTestSource/some_root/composer.json'); - - $packageComposerJson = new SmartFileInfo( - __DIR__ . '/PackagePathResolverTestSource/some_root/nested_packages/nested/composer.json' - ); - - $relativeFolderPathToLocalPackage = $this->packagePathResolver->resolveRelativeFolderPathToLocalPackage( - $mainComposerJson, - $packageComposerJson - ); - - $this->assertSame('../../', $relativeFolderPathToLocalPackage); - - $relativeDirectoryToRoot = $this->packagePathResolver->resolveRelativeDirectoryToRoot( - $mainComposerJson, - $packageComposerJson - ); - - $this->assertSame('nested_packages/nested', $relativeDirectoryToRoot); - } -} diff --git a/packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/composer.json b/packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/composer.json deleted file mode 100644 index 0967ef424b..0000000000 --- a/packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/composer.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/nested_packages/nested/composer.json b/packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/nested_packages/nested/composer.json deleted file mode 100644 index 0967ef424b..0000000000 --- a/packages-tests/Testing/PathResolver/PackagePathResolverTestSource/some_root/nested_packages/nested/composer.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/packages/ComposerJsonManipulator/ComposerJsonFactory.php b/packages/ComposerJsonManipulator/ComposerJsonFactory.php index 3e9fc26166..ae510bf74b 100644 --- a/packages/ComposerJsonManipulator/ComposerJsonFactory.php +++ b/packages/ComposerJsonManipulator/ComposerJsonFactory.php @@ -1,164 +1,131 @@ jsonFileManager = $jsonFileManager; } - - public function createFromString(string $jsonString): ComposerJson + public function createFromString(string $jsonString) : ComposerJson { $jsonArray = Json::decode($jsonString, Json::FORCE_ARRAY); return $this->createFromArray($jsonArray); } - - public function createFromFileInfo(SmartFileInfo $smartFileInfo): ComposerJson + public function createFromFileInfo(SmartFileInfo $smartFileInfo) : ComposerJson { $jsonArray = $this->jsonFileManager->loadFromFilePath($smartFileInfo->getRealPath()); - $composerJson = $this->createFromArray($jsonArray); $composerJson->setOriginalFileInfo($smartFileInfo); - return $composerJson; } - - public function createFromFilePath(string $filePath): ComposerJson + public function createFromFilePath(string $filePath) : ComposerJson { $jsonArray = $this->jsonFileManager->loadFromFilePath($filePath); - $composerJson = $this->createFromArray($jsonArray); $fileInfo = new SmartFileInfo($filePath); $composerJson->setOriginalFileInfo($fileInfo); - return $composerJson; } - - public function createEmpty(): ComposerJson + public function createEmpty() : ComposerJson { return new ComposerJson(); } - /** * @param mixed[] $jsonArray */ - public function createFromArray(array $jsonArray): ComposerJson + public function createFromArray(array $jsonArray) : ComposerJson { $composerJson = new ComposerJson(); - if (isset($jsonArray[ComposerJsonSection::CONFIG])) { $composerJson->setConfig($jsonArray[ComposerJsonSection::CONFIG]); } - if (isset($jsonArray[ComposerJsonSection::NAME])) { $composerJson->setName($jsonArray[ComposerJsonSection::NAME]); } - if (isset($jsonArray[ComposerJsonSection::TYPE])) { $composerJson->setType($jsonArray[ComposerJsonSection::TYPE]); } - if (isset($jsonArray[ComposerJsonSection::AUTHORS])) { $composerJson->setAuthors($jsonArray[ComposerJsonSection::AUTHORS]); } - if (isset($jsonArray[ComposerJsonSection::DESCRIPTION])) { $composerJson->setDescription($jsonArray[ComposerJsonSection::DESCRIPTION]); } - if (isset($jsonArray[ComposerJsonSection::KEYWORDS])) { $composerJson->setKeywords($jsonArray[ComposerJsonSection::KEYWORDS]); } - if (isset($jsonArray[ComposerJsonSection::HOMEPAGE])) { $composerJson->setHomepage($jsonArray[ComposerJsonSection::HOMEPAGE]); } - if (isset($jsonArray[ComposerJsonSection::LICENSE])) { $composerJson->setLicense($jsonArray[ComposerJsonSection::LICENSE]); } - if (isset($jsonArray[ComposerJsonSection::BIN])) { $composerJson->setBin($jsonArray[ComposerJsonSection::BIN]); } - if (isset($jsonArray[ComposerJsonSection::REQUIRE])) { $composerJson->setRequire($jsonArray[ComposerJsonSection::REQUIRE]); } - if (isset($jsonArray[ComposerJsonSection::REQUIRE_DEV])) { $composerJson->setRequireDev($jsonArray[ComposerJsonSection::REQUIRE_DEV]); } - if (isset($jsonArray[ComposerJsonSection::AUTOLOAD])) { $composerJson->setAutoload($jsonArray[ComposerJsonSection::AUTOLOAD]); } - if (isset($jsonArray[ComposerJsonSection::AUTOLOAD_DEV])) { $composerJson->setAutoloadDev($jsonArray[ComposerJsonSection::AUTOLOAD_DEV]); } - if (isset($jsonArray[ComposerJsonSection::REPLACE])) { $composerJson->setReplace($jsonArray[ComposerJsonSection::REPLACE]); } - if (isset($jsonArray[ComposerJsonSection::EXTRA])) { $composerJson->setExtra($jsonArray[ComposerJsonSection::EXTRA]); } - if (isset($jsonArray[ComposerJsonSection::SCRIPTS])) { $composerJson->setScripts($jsonArray[ComposerJsonSection::SCRIPTS]); } - if (isset($jsonArray[ComposerJsonSection::SCRIPTS_DESCRIPTIONS])) { $composerJson->setScriptsDescriptions($jsonArray[ComposerJsonSection::SCRIPTS_DESCRIPTIONS]); } - if (isset($jsonArray[ComposerJsonSection::SUGGEST])) { $composerJson->setSuggest($jsonArray[ComposerJsonSection::SUGGEST]); } - if (isset($jsonArray[ComposerJsonSection::MINIMUM_STABILITY])) { $composerJson->setMinimumStability($jsonArray[ComposerJsonSection::MINIMUM_STABILITY]); } - if (isset($jsonArray[ComposerJsonSection::PREFER_STABLE])) { $composerJson->setPreferStable($jsonArray[ComposerJsonSection::PREFER_STABLE]); } - if (isset($jsonArray[ComposerJsonSection::CONFLICT])) { $composerJson->setConflicts($jsonArray[ComposerJsonSection::CONFLICT]); } - if (isset($jsonArray[ComposerJsonSection::REPOSITORIES])) { $composerJson->setRepositories($jsonArray[ComposerJsonSection::REPOSITORIES]); } - if (isset($jsonArray[ComposerJsonSection::VERSION])) { $composerJson->setVersion($jsonArray[ComposerJsonSection::VERSION]); } - if (isset($jsonArray[ComposerJsonSection::PROVIDE])) { $composerJson->setProvide($jsonArray[ComposerJsonSection::PROVIDE]); } - - $orderedKeys = array_keys($jsonArray); + $orderedKeys = \array_keys($jsonArray); $composerJson->setOrderedKeys($orderedKeys); - return $composerJson; } } diff --git a/packages/ComposerJsonManipulator/FileSystem/JsonFileManager.php b/packages/ComposerJsonManipulator/FileSystem/JsonFileManager.php index 022bfcad7f..3fbb81682a 100644 --- a/packages/ComposerJsonManipulator/FileSystem/JsonFileManager.php +++ b/packages/ComposerJsonManipulator/FileSystem/JsonFileManager.php @@ -1,98 +1,95 @@ */ - private array $cachedJSONFiles = []; - - public function __construct( - private SmartFileSystem $smartFileSystem, - private JsonCleaner $jsonCleaner, - private JsonInliner $jsonInliner - ) { + private $cachedJSONFiles = []; + public function __construct(SmartFileSystem $smartFileSystem, JsonCleaner $jsonCleaner, JsonInliner $jsonInliner) + { + $this->smartFileSystem = $smartFileSystem; + $this->jsonCleaner = $jsonCleaner; + $this->jsonInliner = $jsonInliner; } - /** * @return mixed[] */ - public function loadFromFileInfo(SmartFileInfo $smartFileInfo): array + public function loadFromFileInfo(SmartFileInfo $smartFileInfo) : array { $realPath = $smartFileInfo->getRealPath(); - if (! isset($this->cachedJSONFiles[$realPath])) { + if (!isset($this->cachedJSONFiles[$realPath])) { $this->cachedJSONFiles[$realPath] = Json::decode($smartFileInfo->getContents(), Json::FORCE_ARRAY); } - return $this->cachedJSONFiles[$realPath]; } - /** * @return array */ - public function loadFromFilePath(string $filePath): array + public function loadFromFilePath(string $filePath) : array { $fileContent = $this->smartFileSystem->readFile($filePath); - return Json::decode($fileContent, Json::FORCE_ARRAY); } - /** * @param mixed[] $json */ - public function printJsonToFileInfoAndReturn(array $json, SmartFileInfo $smartFileInfo): string + public function printJsonToFileInfoAndReturn(array $json, SmartFileInfo $smartFileInfo) : string { $jsonString = $this->encodeJsonToFileContent($json); $this->printJsonStringToSmartFileInfo($smartFileInfo, $jsonString); - return $jsonString; } - /** * @param mixed[] $json */ - public function printJsonToFileInfo(array $json, SmartFileInfo $smartFileInfo): void + public function printJsonToFileInfo(array $json, SmartFileInfo $smartFileInfo) : void { $jsonString = $this->encodeJsonToFileContent($json); $this->printJsonStringToSmartFileInfo($smartFileInfo, $jsonString); } - - public function printComposerJsonToFilePath(ComposerJson $composerJson, string $filePath): void + public function printComposerJsonToFilePath(ComposerJson $composerJson, string $filePath) : void { $jsonString = $this->encodeJsonToFileContent($composerJson->getJsonArray()); $this->smartFileSystem->dumpFile($filePath, $jsonString); } - /** * @param mixed[] $json */ - public function encodeJsonToFileContent(array $json): string + public function encodeJsonToFileContent(array $json) : string { // Empty arrays may lead to bad encoding since we can't be sure whether they need to be arrays or objects. $json = $this->jsonCleaner->removeEmptyKeysFromJsonArray($json); - $jsonContent = Json::encode($json, Json::PRETTY) . PHP_EOL; - + $jsonContent = Json::encode($json, Json::PRETTY) . \PHP_EOL; return $this->jsonInliner->inlineSections($jsonContent); } - - private function printJsonStringToSmartFileInfo(SmartFileInfo $smartFileInfo, string $jsonString): void + private function printJsonStringToSmartFileInfo(SmartFileInfo $smartFileInfo, string $jsonString) : void { $this->smartFileSystem->dumpFile($smartFileInfo->getPathname(), $jsonString); - $realPath = $smartFileInfo->getRealPath(); unset($this->cachedJSONFiles[$realPath]); } diff --git a/packages/ComposerJsonManipulator/Json/JsonCleaner.php b/packages/ComposerJsonManipulator/Json/JsonCleaner.php index 935eab8ec0..2c4304bf88 100644 --- a/packages/ComposerJsonManipulator/Json/JsonCleaner.php +++ b/packages/ComposerJsonManipulator/Json/JsonCleaner.php @@ -1,7 +1,6 @@ $data * @return array */ - public function removeEmptyKeysFromJsonArray(array $data): array + public function removeEmptyKeysFromJsonArray(array $data) : array { foreach ($data as $key => $value) { - if (! is_array($value)) { + if (!\is_array($value)) { continue; } - if ($value === []) { unset($data[$key]); } else { $data[$key] = $this->removeEmptyKeysFromJsonArray($value); } } - return $data; } } diff --git a/packages/ComposerJsonManipulator/Json/JsonInliner.php b/packages/ComposerJsonManipulator/Json/JsonInliner.php index 2c868aa379..e27c0ac0d9 100644 --- a/packages/ComposerJsonManipulator/Json/JsonInliner.php +++ b/packages/ComposerJsonManipulator/Json/JsonInliner.php @@ -1,45 +1,41 @@ parameterProvider = $parameterProvider; } - - public function inlineSections(string $jsonContent): string + public function inlineSections(string $jsonContent) : string { - if (! $this->parameterProvider->hasParameter(Option::INLINE_SECTIONS)) { + if (!$this->parameterProvider->hasParameter(Option::INLINE_SECTIONS)) { return $jsonContent; } - $inlineSections = $this->parameterProvider->provideArrayParameter(Option::INLINE_SECTIONS); - foreach ($inlineSections as $inlineSection) { - $pattern = '#("' . preg_quote($inlineSection, '#') . '": )\[(.*?)\](,)#ms'; - - $jsonContent = Strings::replace($jsonContent, $pattern, static function (array $match): string { + $pattern = '#("' . \preg_quote($inlineSection, '#') . '": )\\[(.*?)\\](,)#ms'; + $jsonContent = Strings::replace($jsonContent, $pattern, static function (array $match) : string { $inlined = Strings::replace($match[2], self::SPACE_REGEX, ' '); - $inlined = trim($inlined); + $inlined = \trim($inlined); $inlined = '[' . $inlined . ']'; return $match[1] . $inlined . $match[3]; }); } - return $jsonContent; } } diff --git a/packages/ComposerJsonManipulator/Printer/ComposerJsonPrinter.php b/packages/ComposerJsonManipulator/Printer/ComposerJsonPrinter.php index d1cc9cc605..3663d11511 100644 --- a/packages/ComposerJsonManipulator/Printer/ComposerJsonPrinter.php +++ b/packages/ComposerJsonManipulator/Printer/ComposerJsonPrinter.php @@ -1,35 +1,37 @@ jsonFileManager = $jsonFileManager; } - - public function printToString(ComposerJson $composerJson): string + public function printToString(ComposerJson $composerJson) : string { return $this->jsonFileManager->encodeJsonToFileContent($composerJson->getJsonArray()); } - - public function print(ComposerJson $composerJson, string | SmartFileInfo $targetFile): void + /** + * @param string|\Symplify\SmartFileSystem\SmartFileInfo $targetFile + */ + public function print(ComposerJson $composerJson, $targetFile) : void { - if (is_string($targetFile)) { + if (\is_string($targetFile)) { $this->jsonFileManager->printComposerJsonToFilePath($composerJson, $targetFile); return; } - $this->jsonFileManager->printJsonToFileInfo($composerJson->getJsonArray(), $targetFile); } } diff --git a/packages/ComposerJsonManipulator/Sorter/ComposerPackageSorter.php b/packages/ComposerJsonManipulator/Sorter/ComposerPackageSorter.php index 21de701443..a328ba9a84 100644 --- a/packages/ComposerJsonManipulator/Sorter/ComposerPackageSorter.php +++ b/packages/ComposerJsonManipulator/Sorter/ComposerPackageSorter.php @@ -1,11 +1,9 @@ php|hhvm|ext|lib|\D)#'; - + private const REQUIREMENT_TYPE_REGEX = '#^(?php|hhvm|ext|lib|\\D)#'; /** * Sorts packages by importance (platform packages first, then PHP dependencies) and alphabetically. * @@ -33,51 +29,36 @@ final class ComposerPackageSorter * @param array $packages * @return array */ - public function sortPackages(array $packages): array + public function sortPackages(array $packages) : array { - uksort( - $packages, - fn (string $firstPackageName, string $secondPackageName): int => $this->createNameWithPriority( - $firstPackageName - ) <=> $this->createNameWithPriority($secondPackageName) - ); - + \uksort($packages, function (string $firstPackageName, string $secondPackageName) : int { + return $this->createNameWithPriority($firstPackageName) <=> $this->createNameWithPriority($secondPackageName); + }); return $packages; } - - private function createNameWithPriority(string $requirementName): string + private function createNameWithPriority(string $requirementName) : string { if ($this->isPlatformPackage($requirementName)) { - return Strings::replace( - $requirementName, - self::REQUIREMENT_TYPE_REGEX, - static function (array $match): string { - $name = $match['name']; - if ($name === 'php') { - return '0-' . $name; - } - - if ($name === 'hhvm') { - return '0-' . $name; - } - - if ($name === 'ext') { - return '1-' . $name; - } - - if ($name === 'lib') { - return '2-' . $name; - } - - return '3-' . $name; + return Strings::replace($requirementName, self::REQUIREMENT_TYPE_REGEX, static function (array $match) : string { + $name = $match['name']; + if ($name === 'php') { + return '0-' . $name; + } + if ($name === 'hhvm') { + return '0-' . $name; + } + if ($name === 'ext') { + return '1-' . $name; } - ); + if ($name === 'lib') { + return '2-' . $name; + } + return '3-' . $name; + }); } - return '4-' . $requirementName; } - - private function isPlatformPackage(string $name): bool + private function isPlatformPackage(string $name) : bool { return (bool) Strings::match($name, self::PLATFORM_PACKAGE_REGEX); } diff --git a/packages/ComposerJsonManipulator/ValueObject/ComposerJson.php b/packages/ComposerJsonManipulator/ValueObject/ComposerJson.php index e87a3e684f..8d1610fad0 100644 --- a/packages/ComposerJsonManipulator/ValueObject/ComposerJson.php +++ b/packages/ComposerJsonManipulator/ValueObject/ComposerJson.php @@ -1,15 +1,13 @@ */ - private array $require = []; - + private $require = []; /** * @var mixed[] */ - private array $autoload = []; - + private $autoload = []; /** * @var mixed[] */ - private array $extra = []; - + private $extra = []; /** * @var array */ - private array $requireDev = []; - + private $requireDev = []; /** * @var mixed[] */ - private array $autoloadDev = []; - + private $autoloadDev = []; /** * @var string[] */ - private array $orderedKeys = []; - + private $orderedKeys = []; /** * @var array */ - private array $replace = []; - + private $replace = []; /** * @var array */ - private array $scripts = []; - + private $scripts = []; /** * @var mixed[] */ - private array $config = []; - - private ?SmartFileInfo $fileInfo = null; - - private ComposerPackageSorter $composerPackageSorter; - + private $config = []; + /** + * @var \Symplify\SmartFileSystem\SmartFileInfo|null + */ + private $fileInfo; + /** + * @var \Symplify\MonorepoBuilder\ComposerJsonManipulator\Sorter\ComposerPackageSorter + */ + private $composerPackageSorter; /** * @var array */ - private array $conflicts = []; - + private $conflicts = []; /** * @var mixed[] */ - private array $bin = []; - - private ?string $type = null; - + private $bin = []; + /** + * @var string|null + */ + private $type; /** * @var mixed[] */ - private array $authors = []; - + private $authors = []; /** * @var array */ - private array $scriptsDescriptions = []; - + private $scriptsDescriptions = []; /** * @var array */ - private array $suggest = []; - - private ?string $version = null; - + private $suggest = []; + /** + * @var string|null + */ + private $version; /** * @var array */ - private array $provide = []; - + private $provide = []; public function __construct() { $this->composerPackageSorter = new ComposerPackageSorter(); } - - public function setOriginalFileInfo(SmartFileInfo $fileInfo): void + public function setOriginalFileInfo(SmartFileInfo $fileInfo) : void { $this->fileInfo = $fileInfo; } - - public function setName(string $name): void + public function setName(string $name) : void { $this->name = $name; } - - public function setType(string $type): void + public function setType(string $type) : void { $this->type = $type; } - /** * @param array $require */ - public function setRequire(array $require): void + public function setRequire(array $require) : void { $this->require = $this->sortPackagesIfNeeded($require); } - - public function getVersion(): ?string + public function getVersion() : ?string { return $this->version; } - - public function setVersion(string $version): void + public function setVersion(string $version) : void { $this->version = $version; } - /** * @return mixed[] */ - public function getRequire(): array + public function getRequire() : array { return $this->require; } - - public function getRequirePhpVersion(): ?string + public function getRequirePhpVersion() : ?string { return $this->require[self::PHP] ?? null; } - /** * @return array */ - public function getRequireDev(): array + public function getRequireDev() : array { return $this->requireDev; } - /** * @param array $requireDev */ - public function setRequireDev(array $requireDev): void + public function setRequireDev(array $requireDev) : void { $this->requireDev = $this->sortPackagesIfNeeded($requireDev); } - /** * @param string[] $orderedKeys */ - public function setOrderedKeys(array $orderedKeys): void + public function setOrderedKeys(array $orderedKeys) : void { $this->orderedKeys = $orderedKeys; } - /** * @return string[] */ - public function getOrderedKeys(): array + public function getOrderedKeys() : array { return $this->orderedKeys; } - /** * @return mixed[] */ - public function getAutoload(): array + public function getAutoload() : array { return $this->autoload; } - /** * @return string[] */ - public function getAbsoluteAutoloadDirectories(): array + public function getAbsoluteAutoloadDirectories() : array { if (!$this->fileInfo instanceof SmartFileInfo) { throw new ShouldNotHappenException(); } - $autoloadDirectories = $this->getAutoloadDirectories(); - $absoluteAutoloadDirectories = []; - foreach ($autoloadDirectories as $autoloadDirectory) { - if (is_file($autoloadDirectory)) { + if (\is_file($autoloadDirectory)) { // skip files continue; } - $absoluteAutoloadDirectories[] = $this->resolveExistingAutoloadDirectory($autoloadDirectory); } - return $absoluteAutoloadDirectories; } - /** * @param mixed[] $autoload */ - public function setAutoload(array $autoload): void + public function setAutoload(array $autoload) : void { $this->autoload = $autoload; } - /** * @return mixed[] */ - public function getAutoloadDev(): array + public function getAutoloadDev() : array { return $this->autoloadDev; } - /** * @param mixed[] $autoloadDev */ - public function setAutoloadDev(array $autoloadDev): void + public function setAutoloadDev(array $autoloadDev) : void { $this->autoloadDev = $autoloadDev; } - /** * @return mixed[] */ - public function getRepositories(): array + public function getRepositories() : array { return $this->repositories; } - /** * @param mixed[] $repositories */ - public function setRepositories(array $repositories): void + public function setRepositories(array $repositories) : void { $this->repositories = $repositories; } - - public function setMinimumStability(string $minimumStability): void + public function setMinimumStability(string $minimumStability) : void { $this->minimumStability = $minimumStability; } - - public function removeMinimumStability(): void + public function removeMinimumStability() : void { $this->minimumStability = null; } - - public function getMinimumStability(): ?string + public function getMinimumStability() : ?string { return $this->minimumStability; } - - public function getPreferStable(): ?bool + public function getPreferStable() : ?bool { return $this->preferStable; } - - public function setPreferStable(bool $preferStable): void + public function setPreferStable(bool $preferStable) : void { $this->preferStable = $preferStable; } - - public function removePreferStable(): void + public function removePreferStable() : void { $this->preferStable = null; } - /** * @return mixed[] */ - public function getExtra(): array + public function getExtra() : array { return $this->extra; } - /** * @param mixed[] $extra */ - public function setExtra(array $extra): void + public function setExtra(array $extra) : void { $this->extra = $extra; } - - public function getName(): ?string + public function getName() : ?string { return $this->name; } - - public function getVendorName(): ?string + public function getVendorName() : ?string { if ($this->name === null) { return null; } - - [$vendor] = explode('/', $this->name); + [$vendor] = \explode('/', $this->name); return $vendor; } - - public function getShortName(): ?string + public function getShortName() : ?string { if ($this->name === null) { return null; } - return Strings::after($this->name, '/', -1); } - /** * @return array */ - public function getReplace(): array + public function getReplace() : array { return $this->replace; } - - public function isReplacePackageSet(string $packageName): bool + public function isReplacePackageSet(string $packageName) : bool { return isset($this->replace[$packageName]); } - /** * @param array $replace */ - public function setReplace(array $replace): void + public function setReplace(array $replace) : void { - ksort($replace); - + \ksort($replace); $this->replace = $replace; } - - public function setReplacePackage(string $packageName, string $version): void + public function setReplacePackage(string $packageName, string $version) : void { $this->replace[$packageName] = $version; } - /** * @return mixed[] */ - public function getJsonArray(): array - { - $array = array_filter([ - ComposerJsonSection::NAME => $this->name, - ComposerJsonSection::DESCRIPTION => $this->description, - ComposerJsonSection::KEYWORDS => $this->keywords, - ComposerJsonSection::HOMEPAGE => $this->homepage, - ComposerJsonSection::LICENSE => $this->license, - ComposerJsonSection::AUTHORS => $this->authors, - ComposerJsonSection::TYPE => $this->type, - ComposerJsonSection::REQUIRE => $this->require, - ComposerJsonSection::REQUIRE_DEV => $this->requireDev, - ComposerJsonSection::AUTOLOAD => $this->autoload, - ComposerJsonSection::AUTOLOAD_DEV => $this->autoloadDev, - ComposerJsonSection::REPOSITORIES => $this->repositories, - ComposerJsonSection::EXTRA => $this->extra, - ComposerJsonSection::BIN => $this->bin, - ComposerJsonSection::SCRIPTS => $this->scripts, - ComposerJsonSection::SCRIPTS_DESCRIPTIONS => $this->scriptsDescriptions, - ComposerJsonSection::SUGGEST => $this->suggest, - ComposerJsonSection::CONFIG => $this->config, - ComposerJsonSection::REPLACE => $this->replace, - ComposerJsonSection::CONFLICT => $this->conflicts, - ComposerJsonSection::PROVIDE => $this->provide, - ComposerJsonSection::VERSION => $this->version, - ]); - + public function getJsonArray() : array + { + $array = \array_filter([\Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::NAME => $this->name, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::DESCRIPTION => $this->description, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::KEYWORDS => $this->keywords, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::HOMEPAGE => $this->homepage, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::LICENSE => $this->license, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::AUTHORS => $this->authors, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::TYPE => $this->type, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::REQUIRE => $this->require, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::REQUIRE_DEV => $this->requireDev, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::AUTOLOAD => $this->autoload, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::AUTOLOAD_DEV => $this->autoloadDev, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::REPOSITORIES => $this->repositories, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::EXTRA => $this->extra, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::BIN => $this->bin, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::SCRIPTS => $this->scripts, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::SCRIPTS_DESCRIPTIONS => $this->scriptsDescriptions, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::SUGGEST => $this->suggest, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::CONFIG => $this->config, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::REPLACE => $this->replace, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::CONFLICT => $this->conflicts, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::PROVIDE => $this->provide, \Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::VERSION => $this->version]); if ($this->minimumStability !== null) { - $array[ComposerJsonSection::MINIMUM_STABILITY] = $this->minimumStability; - $this->moveValueToBack(ComposerJsonSection::MINIMUM_STABILITY); + $array[\Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::MINIMUM_STABILITY] = $this->minimumStability; + $this->moveValueToBack(\Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::MINIMUM_STABILITY); } - if ($this->preferStable !== null) { - $array[ComposerJsonSection::PREFER_STABLE] = $this->preferStable; - $this->moveValueToBack(ComposerJsonSection::PREFER_STABLE); + $array[\Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::PREFER_STABLE] = $this->preferStable; + $this->moveValueToBack(\Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection::PREFER_STABLE); } - return $this->sortItemsByOrderedListOfKeys($array, $this->orderedKeys); } - /** * @param array $scripts */ - public function setScripts(array $scripts): void + public function setScripts(array $scripts) : void { $this->scripts = $scripts; } - /** * @param mixed[] $config */ - public function setConfig(array $config): void + public function setConfig(array $config) : void { $this->config = $config; } - /** * @return mixed[] */ - public function getConfig(): array + public function getConfig() : array { return $this->config; } - - public function setDescription(string $description): void + public function setDescription(string $description) : void { $this->description = $description; } - - public function getDescription(): ?string + public function getDescription() : ?string { return $this->description; } - /** * @param string[] $keywords */ - public function setKeywords(array $keywords): void + public function setKeywords(array $keywords) : void { $this->keywords = $keywords; } - /** * @return string[] */ - public function getKeywords(): array + public function getKeywords() : array { return $this->keywords; } - - public function setHomepage(string $homepage): void + public function setHomepage(string $homepage) : void { $this->homepage = $homepage; } - - public function getHomepage(): ?string + public function getHomepage() : ?string { return $this->homepage; } - /** * @param string|string[]|null $license */ - public function setLicense(string | array | null $license): void + public function setLicense($license) : void { $this->license = $license; } - /** * @return string|string[]|null */ - public function getLicense(): string|array|null + public function getLicense() { return $this->license; } - /** * @param mixed[] $authors */ - public function setAuthors(array $authors): void + public function setAuthors(array $authors) : void { $this->authors = $authors; } - /** * @return mixed[] */ - public function getAuthors(): array + public function getAuthors() : array { return $this->authors; } - - public function hasPackage(string $packageName): bool + public function hasPackage(string $packageName) : bool { if ($this->hasRequiredPackage($packageName)) { - return true; + return \true; } - return $this->hasRequiredDevPackage($packageName); } - - public function hasRequiredPackage(string $packageName): bool + public function hasRequiredPackage(string $packageName) : bool { return isset($this->require[$packageName]); } - - public function hasRequiredDevPackage(string $packageName): bool + public function hasRequiredDevPackage(string $packageName) : bool { return isset($this->requireDev[$packageName]); } - - public function addRequiredPackage(string $packageName, string $version): void + public function addRequiredPackage(string $packageName, string $version) : void { - if (! $this->hasPackage($packageName)) { + if (!$this->hasPackage($packageName)) { $this->require[$packageName] = $version; $this->require = $this->sortPackagesIfNeeded($this->require); } } - - public function addRequiredDevPackage(string $packageName, string $version): void + public function addRequiredDevPackage(string $packageName, string $version) : void { - if (! $this->hasPackage($packageName)) { + if (!$this->hasPackage($packageName)) { $this->requireDev[$packageName] = $version; $this->requireDev = $this->sortPackagesIfNeeded($this->requireDev); } } - - public function changePackageVersion(string $packageName, string $version): void + public function changePackageVersion(string $packageName, string $version) : void { if ($this->hasRequiredPackage($packageName)) { $this->require[$packageName] = $version; } - if ($this->hasRequiredDevPackage($packageName)) { $this->requireDev[$packageName] = $version; } } - - public function movePackageToRequire(string $packageName): void + public function movePackageToRequire(string $packageName) : void { - if (! $this->hasRequiredDevPackage($packageName)) { + if (!$this->hasRequiredDevPackage($packageName)) { return; } - $version = $this->requireDev[$packageName]; $this->removePackage($packageName); $this->addRequiredPackage($packageName, $version); } - - public function movePackageToRequireDev(string $packageName): void + public function movePackageToRequireDev(string $packageName) : void { - if (! $this->hasRequiredPackage($packageName)) { + if (!$this->hasRequiredPackage($packageName)) { return; } - $version = $this->require[$packageName]; $this->removePackage($packageName); $this->addRequiredDevPackage($packageName, $version); } - - public function removePackage(string $packageName): void + public function removePackage(string $packageName) : void { unset($this->require[$packageName], $this->requireDev[$packageName]); } - - public function replacePackage(string $oldPackageName, string $newPackageName, string $targetVersion): void + public function replacePackage(string $oldPackageName, string $newPackageName, string $targetVersion) : void { if ($this->hasRequiredPackage($oldPackageName)) { unset($this->require[$oldPackageName]); $this->addRequiredPackage($newPackageName, $targetVersion); } - if ($this->hasRequiredDevPackage($oldPackageName)) { unset($this->requireDev[$oldPackageName]); $this->addRequiredDevPackage($newPackageName, $targetVersion); } } - - public function getFileInfo(): ?SmartFileInfo + public function getFileInfo() : ?SmartFileInfo { return $this->fileInfo; } - /** * @param array $conflicts */ - public function setConflicts(array $conflicts): void + public function setConflicts(array $conflicts) : void { $this->conflicts = $conflicts; } - /** * @param mixed[] $bin */ - public function setBin(array $bin): void + public function setBin(array $bin) : void { $this->bin = $bin; } - /** * @return mixed[] */ - public function getBin(): array + public function getBin() : array { return $this->bin; } - /** * @return string[] */ - public function getPsr4AndClassmapDirectories(): array + public function getPsr4AndClassmapDirectories() : array { - $psr4Directories = array_values($this->autoload['psr-4'] ?? []); + $psr4Directories = \array_values($this->autoload['psr-4'] ?? []); $classmapDirectories = $this->autoload['classmap'] ?? []; - - return array_merge($psr4Directories, $classmapDirectories); + return \array_merge($psr4Directories, $classmapDirectories); } - /** * @return array */ - public function getScripts(): array + public function getScripts() : array { return $this->scripts; } - /** * @return array */ - public function getScriptsDescriptions(): array + public function getScriptsDescriptions() : array { return $this->scriptsDescriptions; } - /** * @return array */ - public function getSuggest(): array + public function getSuggest() : array { return $this->suggest; } - /** * @return string[] */ - public function getAllClassmaps(): array + public function getAllClassmaps() : array { $autoloadClassmaps = $this->autoload[self::CLASSMAP_KEY] ?? []; $autoloadDevClassmaps = $this->autoloadDev[self::CLASSMAP_KEY] ?? []; - - return array_merge($autoloadClassmaps, $autoloadDevClassmaps); + return \array_merge($autoloadClassmaps, $autoloadDevClassmaps); } - /** * @return array */ - public function getConflicts(): array + public function getConflicts() : array { return $this->conflicts; } - /** * @api */ - public function getType(): ?string + public function getType() : ?string { return $this->type; } - /** * @return string[] */ - public function getAutoloadDirectories(): array + public function getAutoloadDirectories() : array { - $autoloadDirectories = array_merge( - $this->getPsr4AndClassmapDirectories(), - $this->getPsr4AndClassmapDevDirectories() - ); - + $autoloadDirectories = \array_merge($this->getPsr4AndClassmapDirectories(), $this->getPsr4AndClassmapDevDirectories()); return Arrays::flatten($autoloadDirectories); } - /** * @return string[] */ - public function getPsr4AndClassmapDevDirectories(): array + public function getPsr4AndClassmapDevDirectories() : array { - $psr4Directories = array_values($this->autoloadDev['psr-4'] ?? []); + $psr4Directories = \array_values($this->autoloadDev['psr-4'] ?? []); $classmapDirectories = $this->autoloadDev['classmap'] ?? []; - - return array_merge($psr4Directories, $classmapDirectories); + return \array_merge($psr4Directories, $classmapDirectories); } - /** * @param array $scriptsDescriptions */ - public function setScriptsDescriptions(array $scriptsDescriptions): void + public function setScriptsDescriptions(array $scriptsDescriptions) : void { $this->scriptsDescriptions = $scriptsDescriptions; } - /** * @param array $suggest */ - public function setSuggest(array $suggest): void + public function setSuggest(array $suggest) : void { $this->suggest = $suggest; } - /** * @return string[] */ - public function getDuplicatedRequirePackages(): array + public function getDuplicatedRequirePackages() : array { $requiredPackageNames = $this->require; $requiredDevPackageNames = $this->requireDev; - - return array_intersect($requiredPackageNames, $requiredDevPackageNames); + return \array_intersect($requiredPackageNames, $requiredDevPackageNames); } - /** * @return string[] */ - public function getRequirePackageNames(): array + public function getRequirePackageNames() : array { - return array_keys($this->require); + return \array_keys($this->require); } - /** * @return array */ - public function getProvide(): array + public function getProvide() : array { return $this->provide; } - - public function isProvidePackageSet(string $packageName): bool + public function isProvidePackageSet(string $packageName) : bool { return isset($this->provide[$packageName]); } - /** * @param array $provide */ - public function setProvide(array $provide): void + public function setProvide(array $provide) : void { - ksort($provide); - + \ksort($provide); $this->provide = $provide; } - - public function setProvidePackage(string $packageName, string $version): void + public function setProvidePackage(string $packageName, string $version) : void { $this->provide[$packageName] = $version; } - /** * @param ComposerJsonSection::* $valueName */ - private function moveValueToBack(string $valueName): void + private function moveValueToBack(string $valueName) : void { - $key = array_search($valueName, $this->orderedKeys, true); - if ($key !== false) { + $key = \array_search($valueName, $this->orderedKeys, \true); + if ($key !== \false) { unset($this->orderedKeys[$key]); } - $this->orderedKeys[] = $valueName; } - /** * 2. sort item by prescribed key order * @@ -808,68 +674,58 @@ private function moveValueToBack(string $valueName): void * @param string[] $orderedVisibleItems * @return mixed[] */ - private function sortItemsByOrderedListOfKeys(array $contentItems, array $orderedVisibleItems): array + private function sortItemsByOrderedListOfKeys(array $contentItems, array $orderedVisibleItems) : array { - uksort($contentItems, function ($firstContentItem, $secondContentItem) use ($orderedVisibleItems): int { + \uksort($contentItems, function ($firstContentItem, $secondContentItem) use($orderedVisibleItems) : int { $firstItemPosition = $this->findPosition($firstContentItem, $orderedVisibleItems); $secondItemPosition = $this->findPosition($secondContentItem, $orderedVisibleItems); - - if ($firstItemPosition === false) { + if ($firstItemPosition === \false) { // new item, put in the back return -1; } - - if ($secondItemPosition === false) { + if ($secondItemPosition === \false) { // new item, put in the back return -1; } - return $firstItemPosition <=> $secondItemPosition; }); - return $contentItems; } - - private function resolveExistingAutoloadDirectory(string $autoloadDirectory): string + private function resolveExistingAutoloadDirectory(string $autoloadDirectory) : string { if (!$this->fileInfo instanceof SmartFileInfo) { throw new ShouldNotHappenException(); } - $filePathCandidates = [ - $this->fileInfo->getPath() . DIRECTORY_SEPARATOR . $autoloadDirectory, + $this->fileInfo->getPath() . \DIRECTORY_SEPARATOR . $autoloadDirectory, // mostly tests - getcwd() . DIRECTORY_SEPARATOR . $autoloadDirectory, + \getcwd() . \DIRECTORY_SEPARATOR . $autoloadDirectory, ]; - foreach ($filePathCandidates as $filePathCandidate) { - if (file_exists($filePathCandidate)) { + if (\file_exists($filePathCandidate)) { return $filePathCandidate; } } - return $autoloadDirectory; } - /** * @param array $packages * @return array */ - private function sortPackagesIfNeeded(array $packages): array + private function sortPackagesIfNeeded(array $packages) : array { - $sortPackages = $this->config['sort-packages'] ?? false; + $sortPackages = $this->config['sort-packages'] ?? \false; if ($sortPackages) { return $this->composerPackageSorter->sortPackages($packages); } - return $packages; } - /** * @param string[] $items + * @return int|string|bool */ - private function findPosition(string $key, array $items): int | string | bool + private function findPosition(string $key, array $items) { - return array_search($key, $items, true); + return \array_search($key, $items, \true); } } diff --git a/packages/ComposerJsonManipulator/ValueObject/ComposerJsonSection.php b/packages/ComposerJsonManipulator/ValueObject/ComposerJsonSection.php index fc05d17576..a9fa17082c 100644 --- a/packages/ComposerJsonManipulator/ValueObject/ComposerJsonSection.php +++ b/packages/ComposerJsonManipulator/ValueObject/ComposerJsonSection.php @@ -1,7 +1,6 @@ setName('init'); $this->setDescription('Creates empty monorepo directory and composer.json structure.'); - $this->addArgument(self::OUTPUT, InputArgument::OPTIONAL, 'Directory to generate monorepo into.', getcwd()); + $this->addArgument(self::OUTPUT, InputArgument::OPTIONAL, 'Directory to generate monorepo into.', \getcwd()); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { /** @var string $output */ $output = $input->getArgument(self::OUTPUT); - $this->smartFileSystem->mirror(__DIR__ . '/../../../templates/monorepo', $output); - $this->symfonyStyle->success('Congrats! Your first monorepo is here.'); - $message = sprintf( - 'Try the next step - merge "composer.json" files from packages to the root one:%s "vendor/bin/monorepo-builder merge"', - PHP_EOL - ); + $message = \sprintf('Try the next step - merge "composer.json" files from packages to the root one:%s "vendor/bin/monorepo-builder merge"', \PHP_EOL); $this->symfonyStyle->note($message); - return self::SUCCESS; } } diff --git a/packages/Merge/Application/MergedAndDecoratedComposerJsonFactory.php b/packages/Merge/Application/MergedAndDecoratedComposerJsonFactory.php index 7633fcf727..72a7d7f1c0 100644 --- a/packages/Merge/Application/MergedAndDecoratedComposerJsonFactory.php +++ b/packages/Merge/Application/MergedAndDecoratedComposerJsonFactory.php @@ -1,50 +1,50 @@ composerJsonMerger = $composerJsonMerger; + $this->composerJsonDecorators = $composerJsonDecorators; } - /** * @param SmartFileInfo[] $packageFileInfos */ - public function createFromRootConfigAndPackageFileInfos( - ComposerJson $mainComposerJson, - array $packageFileInfos - ): void { + public function createFromRootConfigAndPackageFileInfos(ComposerJson $mainComposerJson, array $packageFileInfos) : void + { $mergedAndDecoratedComposerJson = $this->mergePackageFileInfosAndDecorate($packageFileInfos); - $this->composerJsonMerger->mergeJsonToRoot($mainComposerJson, $mergedAndDecoratedComposerJson); } - /** * @param SmartFileInfo[] $packageFileInfos */ - private function mergePackageFileInfosAndDecorate(array $packageFileInfos): ComposerJson + private function mergePackageFileInfosAndDecorate(array $packageFileInfos) : ComposerJson { $mergedComposerJson = $this->composerJsonMerger->mergeFileInfos($packageFileInfos); foreach ($this->composerJsonDecorators as $composerJsonDecorator) { $composerJsonDecorator->decorate($mergedComposerJson); } - return $mergedComposerJson; } } diff --git a/packages/Merge/Arrays/ArraySorter.php b/packages/Merge/Arrays/ArraySorter.php index f42b27c219..4b835ab2fe 100644 --- a/packages/Merge/Arrays/ArraySorter.php +++ b/packages/Merge/Arrays/ArraySorter.php @@ -1,7 +1,6 @@ isSequential($array)) { - sort($array); + \sort($array); } else { - ksort($array); + \ksort($array); } - foreach ($array as $key => $value) { - if (is_array($value)) { + if (\is_array($value)) { $array[$key] = $this->recursiveSort($value); } } - return $array; } - /** * @param mixed[] $array */ - private function isSequential(array $array): bool + private function isSequential(array $array) : bool { - $zeroToItemCount = range(0, count($array) - 1); - return array_keys($array) === $zeroToItemCount; + $zeroToItemCount = \range(0, \count($array) - 1); + return \array_keys($array) === $zeroToItemCount; } } diff --git a/packages/Merge/Arrays/SortedParameterMerger.php b/packages/Merge/Arrays/SortedParameterMerger.php index fdf1620a64..5eb551366f 100644 --- a/packages/Merge/Arrays/SortedParameterMerger.php +++ b/packages/Merge/Arrays/SortedParameterMerger.php @@ -1,40 +1,42 @@ parametersMerger = $parametersMerger; + $this->arraySorter = $arraySorter; } - /** * @param mixed[] $firstArray * @param mixed[] $secondArray * @return mixed[] */ - public function mergeRecursiveAndSort(array $firstArray, array $secondArray): array + public function mergeRecursiveAndSort(array $firstArray, array $secondArray) : array { $mergedArray = $this->parametersMerger->mergeWithCombine($firstArray, $secondArray); - return $this->arraySorter->recursiveSort($mergedArray); } - /** * @param mixed[] $firstArray * @param mixed[] $secondArray * @return mixed[] */ - public function mergeAndSort(array $firstArray, array $secondArray): array + public function mergeAndSort(array $firstArray, array $secondArray) : array { $mergedArray = $this->parametersMerger->merge($firstArray, $secondArray); - return $this->arraySorter->recursiveSort($mergedArray); } } diff --git a/packages/Merge/Cleaner/RequireRequireDevDuplicateCleaner.php b/packages/Merge/Cleaner/RequireRequireDevDuplicateCleaner.php index 6f6d6ba9fe..36ecdd39b9 100644 --- a/packages/Merge/Cleaner/RequireRequireDevDuplicateCleaner.php +++ b/packages/Merge/Cleaner/RequireRequireDevDuplicateCleaner.php @@ -1,29 +1,25 @@ $requireDev * @return array */ - public function unsetPackageFromRequire(ComposerJson $mainComposerJson, array $requireDev): array + public function unsetPackageFromRequire(ComposerJson $mainComposerJson, array $requireDev) : array { // give require priority $requirePackageNames = $mainComposerJson->getRequirePackageNames(); foreach ($requirePackageNames as $requirePackageName) { - if (! isset($requireDev[$requirePackageName])) { + if (!isset($requireDev[$requirePackageName])) { continue; } - unset($requireDev[$requirePackageName]); } - return $requireDev; } } diff --git a/packages/Merge/Command/MergeCommand.php b/packages/Merge/Command/MergeCommand.php index bd449bf00e..2cf041bc80 100644 --- a/packages/Merge/Command/MergeCommand.php +++ b/packages/Merge/Command/MergeCommand.php @@ -1,11 +1,10 @@ composerJsonProvider = $composerJsonProvider; + $this->composerJsonFactory = $composerJsonFactory; + $this->jsonFileManager = $jsonFileManager; + $this->mergedAndDecoratedComposerJsonFactory = $mergedAndDecoratedComposerJsonFactory; + $this->sourcesPresenceValidator = $sourcesPresenceValidator; + $this->conflictingVersionsGuard = $conflictingVersionsGuard; parent::__construct(); } - - protected function configure(): void + protected function configure() : void { $this->setName('merge'); - $this->setDescription('Merge "composer.json" from all found packages to root one'); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { $this->sourcesPresenceValidator->validatePackageComposerJsons(); - $this->conflictingVersionsGuard->ensureNoConflictingPackageVersions(); - - $rootComposerJsonFilePath = getcwd() . '/composer.json'; + $rootComposerJsonFilePath = \getcwd() . '/composer.json'; $rootComposerJson = $this->getRootComposerJson($rootComposerJsonFilePath); $packageFileInfos = $this->composerJsonProvider->getPackagesComposerFileInfos(); - - $this->mergedAndDecoratedComposerJsonFactory->createFromRootConfigAndPackageFileInfos( - $rootComposerJson, - $packageFileInfos - ); - + $this->mergedAndDecoratedComposerJsonFactory->createFromRootConfigAndPackageFileInfos($rootComposerJson, $packageFileInfos); $this->jsonFileManager->printComposerJsonToFilePath($rootComposerJson, $rootComposerJsonFilePath); $this->symfonyStyle->success('Root "composer.json" was updated.'); - return self::SUCCESS; } - - private function getRootComposerJson(string $rootComposerJsonFilePath): ComposerJson + private function getRootComposerJson(string $rootComposerJsonFilePath) : ComposerJson { $rootComposerJson = $this->composerJsonFactory->createFromFilePath($rootComposerJsonFilePath); // ignore "provide" section in current root composer.json $rootComposerJson->setProvide([]); - return $rootComposerJson; } } diff --git a/packages/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator.php b/packages/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator.php index 042c71c9ec..bef43d5d1d 100644 --- a/packages/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator.php +++ b/packages/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator.php @@ -1,32 +1,36 @@ composerJsonMerger = $composerJsonMerger; + $this->modifyingComposerJsonProvider = $modifyingComposerJsonProvider; } - - public function decorate(ComposerJson $composerJson): void + public function decorate(ComposerJson $composerJson) : void { $appendingComposerJson = $this->modifyingComposerJsonProvider->getAppendingComposerJson(); - if (! $appendingComposerJson instanceof ComposerJson) { + if (!$appendingComposerJson instanceof ComposerJson) { return; } - $this->composerJsonMerger->mergeJsonToRoot($composerJson, $appendingComposerJson); } } diff --git a/packages/Merge/ComposerJsonDecorator/FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php b/packages/Merge/ComposerJsonDecorator/FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php index 9fc6b58cb2..fcfe532833 100644 --- a/packages/Merge/ComposerJsonDecorator/FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php +++ b/packages/Merge/ComposerJsonDecorator/FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php @@ -1,35 +1,28 @@ getRequire() === []) { return; } - if ($composerJson->getRequireDev() === []) { return; } - $duplicatedPackages = $composerJson->getDuplicatedRequirePackages(); - $currentRequireDev = $composerJson->getRequireDev(); - $packages = array_keys($currentRequireDev); - + $packages = \array_keys($currentRequireDev); foreach ($packages as $package) { - if (in_array($package, $duplicatedPackages, true)) { + if (\in_array($package, $duplicatedPackages, \true)) { unset($currentRequireDev[$package]); } } - $composerJson->setRequireDev($currentRequireDev); } } diff --git a/packages/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator.php b/packages/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator.php index fb69c771fa..08341b1f04 100644 --- a/packages/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator.php +++ b/packages/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator.php @@ -1,134 +1,112 @@ modifyingComposerJsonProvider = $modifyingComposerJsonProvider; } - - public function decorate(ComposerJson $composerJson): void + public function decorate(ComposerJson $composerJson) : void { $removingComposerJson = $this->modifyingComposerJsonProvider->getRemovingComposerJson(); - if (! $removingComposerJson instanceof ComposerJson) { + if (!$removingComposerJson instanceof ComposerJson) { return; } - $this->processRequire($composerJson, $removingComposerJson); $this->processRequireDev($composerJson, $removingComposerJson); - $this->processAutoload($composerJson, $removingComposerJson); $this->processAutoloadDev($composerJson, $removingComposerJson); - $this->processRoot($composerJson, $removingComposerJson); } - - private function processRequire(ComposerJson $composerJson, ComposerJson $composerJsonToRemove): void + private function processRequire(ComposerJson $composerJson, ComposerJson $composerJsonToRemove) : void { if ($composerJsonToRemove->getRequire() === []) { return; } - $currentRequire = $composerJson->getRequire(); - $packages = array_keys($composerJsonToRemove->getRequire()); - + $packages = \array_keys($composerJsonToRemove->getRequire()); foreach ($packages as $package) { unset($currentRequire[$package]); } - $composerJson->setRequire($currentRequire); } - - private function processRequireDev(ComposerJson $composerJson, ComposerJson $composerJsonToRemove): void + private function processRequireDev(ComposerJson $composerJson, ComposerJson $composerJsonToRemove) : void { if ($composerJsonToRemove->getRequireDev() === []) { return; } - $currentRequireDev = $composerJson->getRequireDev(); - $packages = array_keys($composerJsonToRemove->getRequireDev()); + $packages = \array_keys($composerJsonToRemove->getRequireDev()); foreach ($packages as $package) { unset($currentRequireDev[$package]); } - $composerJson->setRequireDev($currentRequireDev); } - - private function processAutoload(ComposerJson $composerJson, ComposerJson $composerJsonToRemove): void + private function processAutoload(ComposerJson $composerJson, ComposerJson $composerJsonToRemove) : void { if ($composerJsonToRemove->getAutoload() === []) { return; } - $currentAutoload = $composerJson->getAutoload(); $autoloads = $composerJsonToRemove->getAutoload(); foreach ($autoloads as $type => $autoloadList) { - if (! is_array($autoloadList)) { + if (!\is_array($autoloadList)) { continue; } - - $namespaces = array_keys($autoloadList); + $namespaces = \array_keys($autoloadList); foreach ($namespaces as $namespace) { unset($currentAutoload[$type][$namespace]); } } - $composerJson->setAutoload($currentAutoload); } - - private function processAutoloadDev(ComposerJson $composerJson, ComposerJson $composerJsonToRemove): void + private function processAutoloadDev(ComposerJson $composerJson, ComposerJson $composerJsonToRemove) : void { if ($composerJsonToRemove->getAutoloadDev() === []) { return; } - $currentAutoloadDev = $composerJson->getAutoloadDev(); $autoloadDev = $composerJsonToRemove->getAutoloadDev(); foreach ($autoloadDev as $type => $autoloadList) { - if (! is_array($autoloadList)) { + if (!\is_array($autoloadList)) { continue; } - - $namespaces = array_keys($autoloadList); + $namespaces = \array_keys($autoloadList); foreach ($namespaces as $namespace) { unset($currentAutoloadDev[$type][$namespace]); } } - $composerJson->setAutoloadDev($currentAutoloadDev); } - - private function processRoot(ComposerJson $composerJson, ComposerJson $removingComposerJson): void + private function processRoot(ComposerJson $composerJson, ComposerJson $removingComposerJson) : void { if ($removingComposerJson->getMinimumStability()) { $composerJson->removeMinimumStability(); } - if ($removingComposerJson->getPreferStable()) { $composerJson->removePreferStable(); } - - if (count($removingComposerJson->getRepositories()) !== 1) { + if (\count($removingComposerJson->getRepositories()) !== 1) { return; } - if ($removingComposerJson->getRepositories()[0] !== Option::REMOVE_COMPLETELY) { return; } - $composerJson->setRepositories([]); } } diff --git a/packages/Merge/ComposerJsonDecorator/ReplaceSectionJsonDecorator.php b/packages/Merge/ComposerJsonDecorator/ReplaceSectionJsonDecorator.php index 4e17349ec2..114ccd6961 100644 --- a/packages/Merge/ComposerJsonDecorator/ReplaceSectionJsonDecorator.php +++ b/packages/Merge/ComposerJsonDecorator/ReplaceSectionJsonDecorator.php @@ -1,30 +1,29 @@ mergedPackagesCollector = $mergedPackagesCollector; } - - public function decorate(ComposerJson $composerJson): void + public function decorate(ComposerJson $composerJson) : void { $mergedPackages = $this->mergedPackagesCollector->getPackages(); - foreach ($mergedPackages as $mergedPackage) { // prevent value override if ($composerJson->isReplacePackageSet($mergedPackage)) { continue; } - $composerJson->setReplacePackage($mergedPackage, 'self.version'); } } diff --git a/packages/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator.php b/packages/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator.php index 11730081fa..b6d8af282f 100644 --- a/packages/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator.php +++ b/packages/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator.php @@ -1,12 +1,10 @@ processReplaceRepositoriesRelativePath($composerJson); $this->processRemoveDuplicates($composerJson); } - - private function processReplaceRepositoriesRelativePath(ComposerJson $composerJson): void + private function processReplaceRepositoriesRelativePath(ComposerJson $composerJson) : void { $repositories = $composerJson->getRepositories(); - foreach ($repositories as $index => $repository) { if (($repository['type'] ?? '') !== 'path') { continue; } - - $repositories[$index]['url'] = str_replace(self::UP_DIRECTORY, '', $repository['url']); + $repositories[$index]['url'] = \str_replace(self::UP_DIRECTORY, '', $repository['url']); } - $composerJson->setRepositories($repositories); } - - private function processRemoveDuplicates(ComposerJson $composerJson): void + private function processRemoveDuplicates(ComposerJson $composerJson) : void { $repositories = $composerJson->getRepositories(); $paths = []; - foreach ($repositories as $index => $repository) { if (($repository['type'] ?? '') !== 'path') { continue; } - - if (in_array((string) $repository['url'], $paths, true)) { + if (\in_array((string) $repository['url'], $paths, \true)) { unset($repositories[$index]); } - $paths[] = $repository['url']; } - $composerJson->setRepositories($repositories); } } diff --git a/packages/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator.php b/packages/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator.php index be5dc4ce4a..70cd8f69c9 100644 --- a/packages/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator.php +++ b/packages/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator.php @@ -1,13 +1,11 @@ mergedPackagesCollector = $mergedPackagesCollector; } - - public function decorate(ComposerJson $composerJson): void + public function decorate(ComposerJson $composerJson) : void { $require = $this->filterOutMergedPackages($composerJson->getRequire()); $composerJson->setRequire($require); - $requireDev = $this->filterOutMergedPackages($composerJson->getRequireDev()); $composerJson->setRequireDev($requireDev); } - /** * @param mixed[] $require * @return mixed[] */ - private function filterOutMergedPackages(array $require): array + private function filterOutMergedPackages(array $require) : array { - $packageNames = array_keys($require); + $packageNames = \array_keys($require); foreach ($packageNames as $packageName) { - if (! in_array($packageName, $this->mergedPackagesCollector->getPackages(), true)) { + if (!\in_array($packageName, $this->mergedPackagesCollector->getPackages(), \true)) { continue; } - unset($require[$packageName]); } - return $require; } } diff --git a/packages/Merge/ComposerJsonDecorator/SortComposerJsonDecorator.php b/packages/Merge/ComposerJsonDecorator/SortComposerJsonDecorator.php index 5bc9d15258..d2252e95eb 100644 --- a/packages/Merge/ComposerJsonDecorator/SortComposerJsonDecorator.php +++ b/packages/Merge/ComposerJsonDecorator/SortComposerJsonDecorator.php @@ -1,14 +1,12 @@ sectionOrder = $parameterProvider->provideArrayParameter(Option::SECTION_ORDER); } - - public function decorate(ComposerJson $composerJson): void + public function decorate(ComposerJson $composerJson) : void { $orderedKeys = $composerJson->getOrderedKeys(); - - usort( - $orderedKeys, - fn (string $key1, string $key2): int => $this->findKeyPosition($key1) <=> $this->findKeyPosition($key2) - ); - + \usort($orderedKeys, function (string $key1, string $key2) : int { + return $this->findKeyPosition($key1) <=> $this->findKeyPosition($key2); + }); $composerJson->setOrderedKeys($orderedKeys); } - - private function findKeyPosition(string $key): int | string | bool + /** + * @return int|string|bool + */ + private function findKeyPosition(string $key) { - return array_search($key, $this->sectionOrder, true); + return \array_search($key, $this->sectionOrder, \true); } } diff --git a/packages/Merge/ComposerJsonMerger.php b/packages/Merge/ComposerJsonMerger.php index be34011964..15abd38c47 100644 --- a/packages/Merge/ComposerJsonMerger.php +++ b/packages/Merge/ComposerJsonMerger.php @@ -1,7 +1,6 @@ composerJsonFactory = $composerJsonFactory; + $this->mergedPackagesCollector = $mergedPackagesCollector; + $this->composerKeyMergers = $composerKeyMergers; + $this->composerPathNormalizers = $composerPathNormalizers; } - /** * @param SmartFileInfo[] $composerPackagesFileInfos */ - public function mergeFileInfos(array $composerPackagesFileInfos): ComposerJson + public function mergeFileInfos(array $composerPackagesFileInfos) : ComposerJson { $mainComposerJson = $this->composerJsonFactory->createFromArray([]); - foreach ($composerPackagesFileInfos as $composerPackageFileInfo) { $packageComposerJson = $this->composerJsonFactory->createFromFileInfo($composerPackageFileInfo); - - $this->mergeJsonToRootWithPackageFileInfo( - $mainComposerJson, - $packageComposerJson, - $composerPackageFileInfo - ); + $this->mergeJsonToRootWithPackageFileInfo($mainComposerJson, $packageComposerJson, $composerPackageFileInfo); } - return $mainComposerJson; } - - public function mergeJsonToRoot(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function mergeJsonToRoot(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { $name = $newComposerJson->getName(); if ($name !== null) { $this->mergedPackagesCollector->addPackage($name); } - foreach ($this->composerKeyMergers as $composerKeyMerger) { $composerKeyMerger->merge($mainComposerJson, $newComposerJson); } } - - private function mergeJsonToRootWithPackageFileInfo( - ComposerJson $mainComposerJson, - ComposerJson $newComposerJson, - SmartFileInfo $packageFileInfo - ): void { + private function mergeJsonToRootWithPackageFileInfo(ComposerJson $mainComposerJson, ComposerJson $newComposerJson, SmartFileInfo $packageFileInfo) : void + { // prepare paths before autolaod merging foreach ($this->composerPathNormalizers as $composerPathNormalizer) { $composerPathNormalizer->normalizePaths($newComposerJson, $packageFileInfo); } - $this->mergeJsonToRoot($mainComposerJson, $newComposerJson); } } diff --git a/packages/Merge/ComposerKeyMerger/AuthorComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/AuthorComposerKeyMerger.php index c13daabdb6..dc1672610d 100644 --- a/packages/Merge/ComposerKeyMerger/AuthorComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/AuthorComposerKeyMerger.php @@ -1,26 +1,21 @@ getAuthors() === []) { return; } - - $mainAuthors = array_column($mainComposerJson->getAuthors(), null, 'name'); - $newAuthors = array_column($newComposerJson->getAuthors(), null, 'name'); - - $authors = array_merge($mainAuthors, $newAuthors); - $authors = array_values($authors); - + $mainAuthors = \array_column($mainComposerJson->getAuthors(), null, 'name'); + $newAuthors = \array_column($newComposerJson->getAuthors(), null, 'name'); + $authors = \array_merge($mainAuthors, $newAuthors); + $authors = \array_values($authors); $mainComposerJson->setAuthors($authors); } } diff --git a/packages/Merge/ComposerKeyMerger/AutoloadComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/AutoloadComposerKeyMerger.php index 872173c635..d1dc364e5b 100644 --- a/packages/Merge/ComposerKeyMerger/AutoloadComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/AutoloadComposerKeyMerger.php @@ -1,30 +1,27 @@ sortedParameterMerger = $sortedParameterMerger; } - - public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { if ($newComposerJson->getAutoload() === []) { return; } - - $autoload = $this->sortedParameterMerger->mergeRecursiveAndSort( - $mainComposerJson->getAutoload(), - $newComposerJson->getAutoload() - ); + $autoload = $this->sortedParameterMerger->mergeRecursiveAndSort($mainComposerJson->getAutoload(), $newComposerJson->getAutoload()); $mainComposerJson->setAutoload($autoload); } } diff --git a/packages/Merge/ComposerKeyMerger/AutoloadDevComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/AutoloadDevComposerKeyMerger.php index c159a4ed8c..0b224ee5b7 100644 --- a/packages/Merge/ComposerKeyMerger/AutoloadDevComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/AutoloadDevComposerKeyMerger.php @@ -1,31 +1,27 @@ sortedParameterMerger = $sortedParameterMerger; } - - public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { if ($newComposerJson->getAutoloadDev() === []) { return; } - - $autoloadDev = $this->sortedParameterMerger->mergeRecursiveAndSort( - $mainComposerJson->getAutoloadDev(), - $newComposerJson->getAutoloadDev() - ); - + $autoloadDev = $this->sortedParameterMerger->mergeRecursiveAndSort($mainComposerJson->getAutoloadDev(), $newComposerJson->getAutoloadDev()); $mainComposerJson->setAutoloadDev($autoloadDev); } } diff --git a/packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php index 480c653f65..c0bc0cb4d7 100644 --- a/packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php @@ -1,53 +1,47 @@ sortedParameterMerger = $sortedParameterMerger; } - - public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { if ($newComposerJson->getExtra() === []) { return; } - // clean content not desired to merge $newComposerJsonExtra = $newComposerJson->getExtra(); // part of the plugin only if (isset($newComposerJsonExtra[self::PHPSTAN]['includes'])) { unset($newComposerJsonExtra[self::PHPSTAN]['includes']); - if ($newComposerJsonExtra[self::PHPSTAN] === []) { unset($newComposerJsonExtra[self::PHPSTAN]); } } - $extra = $this->sortedParameterMerger->mergeRecursiveAndSort($mainComposerJson->getExtra(), $newComposerJsonExtra); - // do not merge extra alias as only for local packages if (isset($extra['branch-alias'])) { unset($extra['branch-alias']); } - - if (! is_array($extra)) { + if (!\is_array($extra)) { return; } - $mainComposerJson->setExtra($extra); } } diff --git a/packages/Merge/ComposerKeyMerger/MinimalStabilityKeyMerger.php b/packages/Merge/ComposerKeyMerger/MinimalStabilityKeyMerger.php index 801a37ef21..f8b907f2ab 100644 --- a/packages/Merge/ComposerKeyMerger/MinimalStabilityKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/MinimalStabilityKeyMerger.php @@ -1,34 +1,30 @@ getMinimumStability()); - } catch (InvalidPreReleaseSuffixException) { + } catch (InvalidPreReleaseSuffixException $exception) { return; } - try { $mainStability = new PreReleaseSuffix((string) $mainComposerJson->getMinimumStability()); - } catch (InvalidPreReleaseSuffixException) { + } catch (InvalidPreReleaseSuffixException $exception) { $mainStability = null; } - - if (! $mainStability instanceof PreReleaseSuffix || $mainStability->isGreaterThan($newStability)) { + if (!$mainStability instanceof PreReleaseSuffix || $mainStability->isGreaterThan($newStability)) { $mainComposerJson->setMinimumStability($newStability->asString()); } } diff --git a/packages/Merge/ComposerKeyMerger/PreferStableKeyMerger.php b/packages/Merge/ComposerKeyMerger/PreferStableKeyMerger.php index 3916343981..e5b872f248 100644 --- a/packages/Merge/ComposerKeyMerger/PreferStableKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/PreferStableKeyMerger.php @@ -1,20 +1,17 @@ getPreferStable() === null) { return; } - $mainComposerJson->setPreferStable($newComposerJson->getPreferStable()); } } diff --git a/packages/Merge/ComposerKeyMerger/ProvideComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/ProvideComposerKeyMerger.php index 5c7b5ea21b..94b12b1520 100644 --- a/packages/Merge/ComposerKeyMerger/ProvideComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/ProvideComposerKeyMerger.php @@ -1,71 +1,61 @@ sortedParameterMerger = $sortedParameterMerger; } - - public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { if ($newComposerJson->getProvide() === []) { return; } - - $provide = $this->sortedParameterMerger->mergeRecursiveAndSort( - $this->explodeVersions($newComposerJson->getProvide()), - $this->explodeVersions($mainComposerJson->getProvide()) - ); - + $provide = $this->sortedParameterMerger->mergeRecursiveAndSort($this->explodeVersions($newComposerJson->getProvide()), $this->explodeVersions($mainComposerJson->getProvide())); $mainComposerJson->setProvide($this->mergeVersions($provide)); } - /** * @param array $provide * * @return array> */ - private function explodeVersions(array $provide): array + private function explodeVersions(array $provide) : array { $explodedProvide = []; - foreach ($provide as $packageName => $versionString) { - $versions = explode('|', $versionString); + $versions = \explode('|', $versionString); foreach ($versions as $version) { $explodedProvide[$packageName][] = \trim($version); } } - return $explodedProvide; } - /** * @param array> $provide * * @return array */ - private function mergeVersions(array $provide): array + private function mergeVersions(array $provide) : array { $mergedProvide = []; - foreach ($provide as $packageName => $versions) { - if (\in_array('*', $versions, true)) { + if (\in_array('*', $versions, \true)) { $mergedProvide[$packageName] = '*'; } else { - $uniqueVersions = array_unique($versions); - $mergedProvide[$packageName] = implode('|', $uniqueVersions); + $uniqueVersions = \array_unique($versions); + $mergedProvide[$packageName] = \implode('|', $uniqueVersions); } } - return $mergedProvide; } } diff --git a/packages/Merge/ComposerKeyMerger/ReplaceComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/ReplaceComposerKeyMerger.php index 6188b1f345..2353eb2127 100644 --- a/packages/Merge/ComposerKeyMerger/ReplaceComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/ReplaceComposerKeyMerger.php @@ -1,21 +1,18 @@ getReplace() === []) { return; } - - $replace = array_merge($newComposerJson->getReplace(), $mainComposerJson->getReplace()); + $replace = \array_merge($newComposerJson->getReplace(), $mainComposerJson->getReplace()); $mainComposerJson->setReplace($replace); } } diff --git a/packages/Merge/ComposerKeyMerger/RepositoriesComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/RepositoriesComposerKeyMerger.php index 2e9095f303..c58b407f00 100644 --- a/packages/Merge/ComposerKeyMerger/RepositoriesComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/RepositoriesComposerKeyMerger.php @@ -1,36 +1,31 @@ sortedParameterMerger = $sortedParameterMerger; } - - public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { if ($newComposerJson->getRepositories() === []) { return; } - - $repositories = $this->sortedParameterMerger->mergeRecursiveAndSort( - $mainComposerJson->getRepositories(), - $newComposerJson->getRepositories() - ); - + $repositories = $this->sortedParameterMerger->mergeRecursiveAndSort($mainComposerJson->getRepositories(), $newComposerJson->getRepositories()); // uniquate special cases, ref https://github.com/symplify/symplify/issues/1197 - $repositories = array_unique($repositories, SORT_REGULAR); + $repositories = \array_unique($repositories, \SORT_REGULAR); // remove keys - $repositories = array_values($repositories); - + $repositories = \array_values($repositories); $mainComposerJson->setRepositories($repositories); } } diff --git a/packages/Merge/ComposerKeyMerger/RequireComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/RequireComposerKeyMerger.php index 3db0a2ef28..5d9c5a1fc7 100644 --- a/packages/Merge/ComposerKeyMerger/RequireComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/RequireComposerKeyMerger.php @@ -1,39 +1,35 @@ sortedParameterMerger = $sortedParameterMerger; + $this->requireRequireDevDuplicateCleaner = $requireRequireDevDuplicateCleaner; } - - public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { if ($newComposerJson->getRequire() === []) { return; } - - $require = $this->sortedParameterMerger->mergeAndSort( - $newComposerJson->getRequire(), - $mainComposerJson->getRequire() - ); - + $require = $this->sortedParameterMerger->mergeAndSort($newComposerJson->getRequire(), $mainComposerJson->getRequire()); $mainComposerJson->setRequire($require); - - $requireDev = $this->requireRequireDevDuplicateCleaner->unsetPackageFromRequire( - $mainComposerJson, - $mainComposerJson->getRequireDev() - ); + $requireDev = $this->requireRequireDevDuplicateCleaner->unsetPackageFromRequire($mainComposerJson, $mainComposerJson->getRequireDev()); $mainComposerJson->setRequireDev($requireDev); } } diff --git a/packages/Merge/ComposerKeyMerger/RequireDevComposerKeyMerger.php b/packages/Merge/ComposerKeyMerger/RequireDevComposerKeyMerger.php index 80910f621c..5d802e48bb 100644 --- a/packages/Merge/ComposerKeyMerger/RequireDevComposerKeyMerger.php +++ b/packages/Merge/ComposerKeyMerger/RequireDevComposerKeyMerger.php @@ -1,35 +1,34 @@ sortedParameterMerger = $sortedParameterMerger; + $this->requireRequireDevDuplicateCleaner = $requireRequireDevDuplicateCleaner; } - - public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson): void + public function merge(ComposerJson $mainComposerJson, ComposerJson $newComposerJson) : void { if ($newComposerJson->getRequireDev() === []) { return; } - - $requireDev = $this->sortedParameterMerger->mergeAndSort( - $newComposerJson->getRequireDev(), - $mainComposerJson->getRequireDev() - ); - + $requireDev = $this->sortedParameterMerger->mergeAndSort($newComposerJson->getRequireDev(), $mainComposerJson->getRequireDev()); $requireDev = $this->requireRequireDevDuplicateCleaner->unsetPackageFromRequire($mainComposerJson, $requireDev); - $mainComposerJson->setRequireDev($requireDev); } } diff --git a/packages/Merge/Configuration/MergedPackagesCollector.php b/packages/Merge/Configuration/MergedPackagesCollector.php index 22a27fe3b1..d42229d77a 100644 --- a/packages/Merge/Configuration/MergedPackagesCollector.php +++ b/packages/Merge/Configuration/MergedPackagesCollector.php @@ -1,7 +1,6 @@ packages[] = $package; } - /** * @return string[] */ - public function getPackages(): array + public function getPackages() : array { - $this->packages = array_unique($this->packages); - - sort($this->packages); - + $this->packages = \array_unique($this->packages); + \sort($this->packages); return $this->packages; } } diff --git a/packages/Merge/Configuration/ModifyingComposerJsonProvider.php b/packages/Merge/Configuration/ModifyingComposerJsonProvider.php index 989af9c4f3..c227d2bfe2 100644 --- a/packages/Merge/Configuration/ModifyingComposerJsonProvider.php +++ b/packages/Merge/Configuration/ModifyingComposerJsonProvider.php @@ -1,39 +1,41 @@ composerJsonFactory = $composerJsonFactory; + $this->parameterProvider = $parameterProvider; } - - public function getRemovingComposerJson(): ?ComposerJson + public function getRemovingComposerJson() : ?ComposerJson { $dataToRemove = $this->parameterProvider->provideArrayParameter(Option::DATA_TO_REMOVE); if ($dataToRemove === []) { return null; } - return $this->composerJsonFactory->createFromArray($dataToRemove); } - - public function getAppendingComposerJson(): ?ComposerJson + public function getAppendingComposerJson() : ?ComposerJson { $dataToAppend = $this->parameterProvider->provideArrayParameter(Option::DATA_TO_APPEND); if ($dataToAppend === []) { return null; } - return $this->composerJsonFactory->createFromArray($dataToAppend); } } diff --git a/packages/Merge/Contract/ComposerJsonDecoratorInterface.php b/packages/Merge/Contract/ComposerJsonDecoratorInterface.php index e9ac049a8d..1c426a6e6c 100644 --- a/packages/Merge/Contract/ComposerJsonDecoratorInterface.php +++ b/packages/Merge/Contract/ComposerJsonDecoratorInterface.php @@ -1,12 +1,10 @@ versionValidator = $versionValidator; + $this->composerJsonProvider = $composerJsonProvider; + $this->conflictingPackageVersionsReporter = $conflictingPackageVersionsReporter; } - - public function ensureNoConflictingPackageVersions(): void + public function ensureNoConflictingPackageVersions() : void { - $conflictingPackageVersions = $this->versionValidator->findConflictingPackageVersionsInFileInfos( - $this->composerJsonProvider->getPackagesComposerFileInfos() - ); - + $conflictingPackageVersions = $this->versionValidator->findConflictingPackageVersionsInFileInfos($this->composerJsonProvider->getPackagesComposerFileInfos()); if ($conflictingPackageVersions === []) { return; } - $this->conflictingPackageVersionsReporter->report($conflictingPackageVersions); - throw new ShouldNotHappenException('Fix conflicting package version first'); } } diff --git a/packages/Merge/PathResolver/AutoloadPathNormalizer.php b/packages/Merge/PathResolver/AutoloadPathNormalizer.php index a542245ef5..8c0ff6df73 100644 --- a/packages/Merge/PathResolver/AutoloadPathNormalizer.php +++ b/packages/Merge/PathResolver/AutoloadPathNormalizer.php @@ -1,13 +1,11 @@ normalizeAutoloadArray($packageFile, $packageComposerJson->getAutoload()); $packageComposerJson->setAutoload($autoload); - $autoloadDev = $this->normalizeAutoloadArray($packageFile, $packageComposerJson->getAutoloadDev()); $packageComposerJson->setAutoloadDev($autoloadDev); } - /** * @param array $autoloadArray * @return array */ - private function normalizeAutoloadArray(SmartFileInfo $packageFile, array $autoloadArray): array + private function normalizeAutoloadArray(SmartFileInfo $packageFile, array $autoloadArray) : array { foreach (self::SECTIONS_WITH_PATH as $sectionWithPath) { - if (! isset($autoloadArray[$sectionWithPath])) { + if (!isset($autoloadArray[$sectionWithPath])) { continue; } - $autoloadArray[$sectionWithPath] = $this->relativizePath($autoloadArray[$sectionWithPath], $packageFile); } - return $autoloadArray; } - /** * @param mixed[] $autoloadSubsection * @return mixed[] */ - private function relativizePath(array $autoloadSubsection, SmartFileInfo $packageFileInfo): array + private function relativizePath(array $autoloadSubsection, SmartFileInfo $packageFileInfo) : array { - $packageRelativeDirectory = dirname($packageFileInfo->getRelativeFilePathFromDirectory(getcwd())); - + $packageRelativeDirectory = \dirname($packageFileInfo->getRelativeFilePathFromDirectory(\getcwd())); foreach ($autoloadSubsection as $key => $value) { - if (is_array($value)) { - $autoloadSubsection[$key] = array_map( - fn ($path): string => $this->relativizeSinglePath($packageRelativeDirectory, $path), - $value - ); + if (\is_array($value)) { + $autoloadSubsection[$key] = \array_map(function ($path) use($packageRelativeDirectory) : string { + return $this->relativizeSinglePath($packageRelativeDirectory, $path); + }, $value); } else { $autoloadSubsection[$key] = $this->relativizeSinglePath($packageRelativeDirectory, $value); } } - return $autoloadSubsection; } - - private function relativizeSinglePath(string $packageRelativeDirectory, string $path): string + private function relativizeSinglePath(string $packageRelativeDirectory, string $path) : string { // prevent prefixing, as vendor is the same in both locations - if (\str_starts_with($path, 'vendor/')) { + if (\strncmp($path, 'vendor/', \strlen('vendor/')) === 0) { return $path; } - - return $packageRelativeDirectory . '/' . ltrim($path, '/'); + return $packageRelativeDirectory . '/' . \ltrim($path, '/'); } } diff --git a/packages/Merge/PathResolver/ComposerPatchesPathNormalizer.php b/packages/Merge/PathResolver/ComposerPatchesPathNormalizer.php index e28a8e1817..ef6b90d562 100644 --- a/packages/Merge/PathResolver/ComposerPatchesPathNormalizer.php +++ b/packages/Merge/PathResolver/ComposerPatchesPathNormalizer.php @@ -1,13 +1,11 @@ normalizeExtraArray($packageFile, $packageComposerJson->getExtra()); $packageComposerJson->setExtra($extra); } - /** * @param array $extraArray * @return array */ - private function normalizeExtraArray(SmartFileInfo $packageFile, array $extraArray): array + private function normalizeExtraArray(SmartFileInfo $packageFile, array $extraArray) : array { foreach (self::SECTIONS_WITH_PATH as $sectionWithPath) { - if (! isset($extraArray[$sectionWithPath])) { + if (!isset($extraArray[$sectionWithPath])) { continue; } - $extraArray[$sectionWithPath] = $this->relativizePath($extraArray[$sectionWithPath], $packageFile); } - return $extraArray; } - /** * @param mixed[] $patchesSubSection * @return mixed[] */ - private function relativizePath(array $patchesSubSection, SmartFileInfo $packageFileInfo): array + private function relativizePath(array $patchesSubSection, SmartFileInfo $packageFileInfo) : array { - $packageRelativeDirectory = dirname($packageFileInfo->getRelativeFilePathFromDirectory(getcwd())); - + $packageRelativeDirectory = \dirname($packageFileInfo->getRelativeFilePathFromDirectory(\getcwd())); foreach ($patchesSubSection as $key => $value) { - if (is_array($value)) { - $patchesSubSection[$key] = array_map( - fn ($path): string => $this->relativizeSinglePath($packageRelativeDirectory, $path), - $value - ); + if (\is_array($value)) { + $patchesSubSection[$key] = \array_map(function ($path) use($packageRelativeDirectory) : string { + return $this->relativizeSinglePath($packageRelativeDirectory, $path); + }, $value); } } - return $patchesSubSection; } - - private function relativizeSinglePath(string $packageRelativeDirectory, string $path): string + private function relativizeSinglePath(string $packageRelativeDirectory, string $path) : string { - if (\str_starts_with($path, 'vendor/') || \str_starts_with($path, './vendor/')) { - return preg_replace('#^(\./)?vendor/[^/]+/[^/]+#', $packageRelativeDirectory, $path); + if (\strncmp($path, 'vendor/', \strlen('vendor/')) === 0 || \strncmp($path, './vendor/', \strlen('./vendor/')) === 0) { + return \preg_replace('#^(\\./)?vendor/[^/]+/[^/]+#', $packageRelativeDirectory, $path); } - return $path; } } diff --git a/packages/Propagate/Command/PropagateCommand.php b/packages/Propagate/Command/PropagateCommand.php index cd35369a3a..f042887f11 100644 --- a/packages/Propagate/Command/PropagateCommand.php +++ b/packages/Propagate/Command/PropagateCommand.php @@ -1,74 +1,68 @@ composerJsonProvider = $composerJsonProvider; + $this->versionPropagator = $versionPropagator; + $this->jsonFileManager = $jsonFileManager; parent::__construct(); } - - protected function configure(): void + protected function configure() : void { $this->setName('propagate'); - $this->setDescription( - 'Propagate versions from root "composer.json" to all packages, the opposite of "merge" command' - ); + $this->setDescription('Propagate versions from root "composer.json" to all packages, the opposite of "merge" command'); $this->addOption(Option::DRY_RUN, null, InputOption::VALUE_NONE, 'Report conflict on missing types'); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { $rootComposerJson = $this->composerJsonProvider->getRootComposerJson(); - $isDryRun = (bool) $input->getOption(Option::DRY_RUN); - foreach ($this->composerJsonProvider->getPackageComposerJsons() as $packageComposerJson) { $originalPackageComposerJson = clone $packageComposerJson; - $this->versionPropagator->propagate($rootComposerJson, $packageComposerJson); if ($originalPackageComposerJson->getJsonArray() === $packageComposerJson->getJsonArray()) { continue; } - $packageFileInfo = $packageComposerJson->getFileInfo(); - if (! $packageFileInfo instanceof SmartFileInfo) { + if (!$packageFileInfo instanceof SmartFileInfo) { throw new MissingComposerJsonException(); } - if ($isDryRun) { $this->symfonyStyle->error('Run "composer propagate" to update package versions'); return self::FAILURE; } - $this->jsonFileManager->printComposerJsonToFilePath($packageComposerJson, $packageFileInfo->getRealPath()); - - $message = sprintf( - '"%s" was updated to inherit root composer.json versions', - $packageFileInfo->getRelativeFilePathFromCwd() - ); + $message = \sprintf('"%s" was updated to inherit root composer.json versions', $packageFileInfo->getRelativeFilePathFromCwd()); $this->symfonyStyle->note($message); } - $this->symfonyStyle->success('Propagation was successful'); - return self::SUCCESS; } } diff --git a/packages/Propagate/VersionPropagator.php b/packages/Propagate/VersionPropagator.php index af8cc4fa07..f6999b4f4f 100644 --- a/packages/Propagate/VersionPropagator.php +++ b/packages/Propagate/VersionPropagator.php @@ -1,22 +1,18 @@ getRequire(), $mainComposerJson->getRequireDev()); - + $packagesToVersions = \array_merge($mainComposerJson->getRequire(), $mainComposerJson->getRequireDev()); foreach ($packagesToVersions as $packageName => $packageVersion) { - if (! $otherComposerJson->hasPackage($packageName)) { + if (!$otherComposerJson->hasPackage($packageName)) { continue; } - $otherComposerJson->changePackageVersion($packageName, $packageVersion); } } diff --git a/packages/Release/Command/ReleaseCommand.php b/packages/Release/Command/ReleaseCommand.php index 9c9293a1bd..45fbf4e602 100644 --- a/packages/Release/Command/ReleaseCommand.php +++ b/packages/Release/Command/ReleaseCommand.php @@ -1,13 +1,12 @@ releaseWorkerProvider = $releaseWorkerProvider; + $this->sourcesPresenceValidator = $sourcesPresenceValidator; + $this->stageResolver = $stageResolver; + $this->versionResolver = $versionResolver; + $this->releaseWorkerReporter = $releaseWorkerReporter; parent::__construct(); } - - protected function configure(): void + protected function configure() : void { $this->setName('release'); $this->setDescription('Perform release process with set Release Workers.'); - - $description = sprintf( - 'Release version, in format ".." or "v.. or one of keywords: "%s"', - implode('", "', SemVersion::ALL) - ); + $description = \sprintf('Release version, in format ".." or "v.. or one of keywords: "%s"', \implode('", "', SemVersion::ALL)); $this->addArgument(Option::VERSION, InputArgument::REQUIRED, $description); - - $this->addOption( - Option::DRY_RUN, - null, - InputOption::VALUE_NONE, - 'Do not perform operations, just their preview' - ); - + $this->addOption(Option::DRY_RUN, null, InputOption::VALUE_NONE, 'Do not perform operations, just their preview'); $this->addOption(Option::STAGE, null, InputOption::VALUE_REQUIRED, 'Name of stage to perform', Stage::MAIN); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { $this->sourcesPresenceValidator->validateRootComposerJsonName(); - // validation phase $stage = $this->stageResolver->resolveFromInput($input); - $releaseWorkers = $this->releaseWorkerProvider->provideByStage($stage); if ($releaseWorkers === []) { - $errorMessage = sprintf( - 'There are no release workers registered. Be sure to add them to "%s"', - File::CONFIG - ); + $errorMessage = \sprintf('There are no release workers registered. Be sure to add them to "%s"', File::CONFIG); $this->symfonyStyle->error($errorMessage); - return self::FAILURE; } - - $totalWorkerCount = count($releaseWorkers); + $totalWorkerCount = \count($releaseWorkers); $i = 0; $isDryRun = (bool) $input->getOption(Option::DRY_RUN); $version = $this->versionResolver->resolveVersion($input, $stage); - foreach ($releaseWorkers as $releaseWorker) { - $title = sprintf('%d/%d) ', ++$i, $totalWorkerCount) . $releaseWorker->getDescription($version); + $title = \sprintf('%d/%d) ', ++$i, $totalWorkerCount) . $releaseWorker->getDescription($version); $this->symfonyStyle->title($title); $this->releaseWorkerReporter->printMetadata($releaseWorker); - - if (! $isDryRun) { - if (method_exists($releaseWorker,'shouldConfirm') - && $releaseWorker->shouldConfirm()['whenTrue']() - && ! $this->symfonyStyle->confirm($releaseWorker->shouldConfirm()['message']) - ){ - return self::FAILURE; + if (!$isDryRun) { + if (\method_exists($releaseWorker, 'shouldConfirm') && $releaseWorker->shouldConfirm()['whenTrue']() && !$this->symfonyStyle->confirm($releaseWorker->shouldConfirm()['message'])) { + return self::FAILURE; } - $releaseWorker->work($version); } } - if ($isDryRun) { $this->symfonyStyle->note('Running in dry mode, nothing is changed'); } elseif ($stage === Stage::MAIN) { - $message = sprintf('Version "%s" is now released!', $version->getVersionString()); + $message = \sprintf('Version "%s" is now released!', $version->getVersionString()); $this->symfonyStyle->success($message); } else { - $finishedMessage = sprintf( - 'Stage "%s" for version "%s" is now finished!', - $stage, - $version->getVersionString() - ); + $finishedMessage = \sprintf('Stage "%s" for version "%s" is now finished!', $stage, $version->getVersionString()); $this->symfonyStyle->success($finishedMessage); } - return self::SUCCESS; } } diff --git a/packages/Release/Configuration/StageResolver.php b/packages/Release/Configuration/StageResolver.php index 2f07d09e7f..b9079cb30b 100644 --- a/packages/Release/Configuration/StageResolver.php +++ b/packages/Release/Configuration/StageResolver.php @@ -1,32 +1,31 @@ releaseGuard = $releaseGuard; } - - public function resolveFromInput(InputInterface $input): string + public function resolveFromInput(InputInterface $input) : string { $stage = (string) $input->getOption(Option::STAGE); - // empty if ($stage === Stage::MAIN) { $this->releaseGuard->guardRequiredStageOnEmptyStage(); } else { $this->releaseGuard->guardStage($stage); } - return $stage; } } diff --git a/packages/Release/Configuration/VersionResolver.php b/packages/Release/Configuration/VersionResolver.php index 51be58a108..b3f00a26cc 100644 --- a/packages/Release/Configuration/VersionResolver.php +++ b/packages/Release/Configuration/VersionResolver.php @@ -1,22 +1,23 @@ versionFactory = $versionFactory; } - - public function resolveVersion(InputInterface $input, string $stage): Version + public function resolveVersion(InputInterface $input, string $stage) : Version { /** @var string $versionArgument */ $versionArgument = $input->getArgument(Option::VERSION); diff --git a/packages/Release/Contract/ReleaseWorker/ReleaseWorkerInterface.php b/packages/Release/Contract/ReleaseWorker/ReleaseWorkerInterface.php index 7aafe30928..08ab26219a 100644 --- a/packages/Release/Contract/ReleaseWorker/ReleaseWorkerInterface.php +++ b/packages/Release/Contract/ReleaseWorker/ReleaseWorkerInterface.php @@ -1,11 +1,9 @@ " */ - public function getStage(): string; + public function getStage() : string; } diff --git a/packages/Release/Exception/ConfigurationException.php b/packages/Release/Exception/ConfigurationException.php index 277b7b4c5b..d5cf165453 100644 --- a/packages/Release/Exception/ConfigurationException.php +++ b/packages/Release/Exception/ConfigurationException.php @@ -1,11 +1,9 @@ tagResolver = $tagResolver; + $this->releaseWorkers = $releaseWorkers; $this->isStageRequired = $parameterProvider->provideBoolParameter(Option::IS_STAGE_REQUIRED); - $this->stagesToAllowExistingTag = $parameterProvider->provideArrayParameter( - Option::STAGES_TO_ALLOW_EXISTING_TAG - ); + $this->stagesToAllowExistingTag = $parameterProvider->provideArrayParameter(Option::STAGES_TO_ALLOW_EXISTING_TAG); } - - public function guardRequiredStageOnEmptyStage(): void + public function guardRequiredStageOnEmptyStage() : void { // there are no stages → nothing to filter by if ($this->getStages() === []) { return; } - // stage is optional → all right - if (! $this->isStageRequired) { + if (!$this->isStageRequired) { return; } - // stage is required → show options - throw new ConfigurationException(sprintf( - 'Set "--%s " option first. Pick one of: "%s"', - Option::STAGE, - implode('", "', $this->getStages()) - )); + throw new ConfigurationException(\sprintf('Set "--%s " option first. Pick one of: "%s"', Option::STAGE, \implode('", "', $this->getStages()))); } - - public function guardStage(string $stage): void + public function guardStage(string $stage) : void { // stage is correct - if (in_array($stage, $this->getStages(), true)) { + if (\in_array($stage, $this->getStages(), \true)) { return; } - // stage has invalid value - throw new ConfigurationException(sprintf( - 'Stage "%s" was not found. Pick one of: "%s"', - $stage, - implode('", "', $this->getStages()) - )); + throw new ConfigurationException(\sprintf('Stage "%s" was not found. Pick one of: "%s"', $stage, \implode('", "', $this->getStages()))); } - - public function guardVersion(Version $version, string $stage): void + public function guardVersion(Version $version, string $stage) : void { // stage is set and it doesn't need a validation - if ($stage !== Stage::MAIN && in_array($stage, $this->stagesToAllowExistingTag, true)) { + if ($stage !== Stage::MAIN && \in_array($stage, $this->stagesToAllowExistingTag, \true)) { return; } - $this->ensureVersionIsNewerThanLastOne($version); } - /** * @return string[] */ - private function getStages(): array + private function getStages() : array { if ($this->stages !== []) { return $this->stages; } - $stages = []; foreach ($this->releaseWorkers as $releaseWorker) { if ($releaseWorker instanceof StageAwareInterface) { $stages[] = $releaseWorker->getStage(); } } - - $this->stages = array_unique($stages); - + $this->stages = \array_unique($stages); return $this->stages; } - - private function ensureVersionIsNewerThanLastOne(Version $version): void + private function ensureVersionIsNewerThanLastOne(Version $version) : void { - $mostRecentVersionString = $this->tagResolver->resolve(getcwd()); - + $mostRecentVersionString = $this->tagResolver->resolve(\getcwd()); // no tag yet if ($mostRecentVersionString === null) { return; } - // normalize to workaround phar-io bug - $mostRecentVersionString = strtolower($mostRecentVersionString); - + $mostRecentVersionString = \strtolower($mostRecentVersionString); // validation $mostRecentVersion = new Version($mostRecentVersionString); if ($version->isGreaterThan($mostRecentVersion)) { return; } - - throw new InvalidGitVersionException(sprintf( - 'Provided version "%s" must be greater than the last one: "%s"', - $version->getVersionString(), - $mostRecentVersion->getVersionString() - )); + throw new InvalidGitVersionException(\sprintf('Provided version "%s" must be greater than the last one: "%s"', $version->getVersionString(), $mostRecentVersion->getVersionString())); } } diff --git a/packages/Release/Output/ReleaseWorkerReporter.php b/packages/Release/Output/ReleaseWorkerReporter.php index 33d6831ec7..0d384011b1 100644 --- a/packages/Release/Output/ReleaseWorkerReporter.php +++ b/packages/Release/Output/ReleaseWorkerReporter.php @@ -1,32 +1,31 @@ symfonyStyle = $symfonyStyle; } - - public function printMetadata(ReleaseWorkerInterface $releaseWorker): void + public function printMetadata(ReleaseWorkerInterface $releaseWorker) : void { - if (! $this->symfonyStyle->isVerbose()) { + if (!$this->symfonyStyle->isVerbose()) { return; } - // show debug data on -v/--verbose/--debug - $this->symfonyStyle->writeln('class: ' . $releaseWorker::class); + $this->symfonyStyle->writeln('class: ' . \get_class($releaseWorker)); if ($releaseWorker instanceof StageAwareInterface) { $this->symfonyStyle->writeln('stage: ' . $releaseWorker->getStage()); } - $this->symfonyStyle->newLine(); } } diff --git a/packages/Release/Process/ProcessRunner.php b/packages/Release/Process/ProcessRunner.php index 0bc724f286..2d66188814 100644 --- a/packages/Release/Process/ProcessRunner.php +++ b/packages/Release/Process/ProcessRunner.php @@ -1,75 +1,66 @@ symfonyStyle = $symfonyStyle; } - /** * @param string|string[] $commandLine */ - public function run(string | array $commandLine, ?string $cwd = null): string + public function run($commandLine, ?string $cwd = null) : string { if ($this->symfonyStyle->isVerbose()) { $this->symfonyStyle->note('Running process: ' . $this->normalizeToString($commandLine)); } - $process = $this->createProcess($commandLine, $cwd); $process->run(); - $this->reportResult($process); - return $process->getOutput(); } - /** * @param string|string[] $content */ - private function normalizeToString(string | array $content): string + private function normalizeToString($content) : string { - if (is_array($content)) { - return implode(' ', $content); + if (\is_array($content)) { + return \implode(' ', $content); } - return $content; } - /** * @param string|string[] $commandLine */ - private function createProcess(string | array $commandLine, ?string $cwd): Process + private function createProcess($commandLine, ?string $cwd) : Process { // @since Symfony 4.2: https://github.com/symfony/symfony/pull/27821 - if (is_string($commandLine) && method_exists(Process::class, 'fromShellCommandline')) { + if (\is_string($commandLine) && \method_exists(Process::class, 'fromShellCommandline')) { return Process::fromShellCommandline($commandLine, $cwd, null, null, self::TIMEOUT); } - return new Process($commandLine, $cwd, null, null, self::TIMEOUT); } - - private function reportResult(Process $process): void + private function reportResult(Process $process) : void { if ($process->isSuccessful()) { return; } - throw new ProcessFailedException($process); } } diff --git a/packages/Release/ReleaseWorker/AddTagToChangelogReleaseWorker.php b/packages/Release/ReleaseWorker/AddTagToChangelogReleaseWorker.php index 28047767d5..0deb489662 100644 --- a/packages/Release/ReleaseWorker/AddTagToChangelogReleaseWorker.php +++ b/packages/Release/ReleaseWorker/AddTagToChangelogReleaseWorker.php @@ -1,55 +1,45 @@ smartFileSystem = $smartFileSystem; } - - public function work(Version $version): void + public function work(Version $version) : void { - $changelogFilePath = getcwd() . '/CHANGELOG.md'; - if (! file_exists($changelogFilePath)) { + $changelogFilePath = \getcwd() . '/CHANGELOG.md'; + if (!\file_exists($changelogFilePath)) { return; } - $newHeadline = $this->createNewHeadline($version); - $changelogFileContent = $this->smartFileSystem->readFile($changelogFilePath); - $changelogFileContent = Strings::replace( - $changelogFileContent, - self::UNRELEASED_HEADLINE_REGEX, - '## ' . $newHeadline - ); - + $changelogFileContent = Strings::replace($changelogFileContent, self::UNRELEASED_HEADLINE_REGEX, '## ' . $newHeadline); $this->smartFileSystem->dumpFile($changelogFilePath, $changelogFileContent); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { $newHeadline = $this->createNewHeadline($version); - - return sprintf('Change "Unreleased" in `CHANGELOG.md` to "%s"', $newHeadline); + return \sprintf('Change "Unreleased" in `CHANGELOG.md` to "%s"', $newHeadline); } - - private function createNewHeadline(Version $version): string + private function createNewHeadline(Version $version) : string { $dateTime = new DateTime(); return $version->getVersionString() . ' - ' . $dateTime->format('Y-m-d'); diff --git a/packages/Release/ReleaseWorker/PushNextDevReleaseWorker.php b/packages/Release/ReleaseWorker/PushNextDevReleaseWorker.php index da4a85cd1c..536e04c478 100644 --- a/packages/Release/ReleaseWorker/PushNextDevReleaseWorker.php +++ b/packages/Release/ReleaseWorker/PushNextDevReleaseWorker.php @@ -1,7 +1,6 @@ processRunner = $processRunner; + $this->versionUtils = $versionUtils; $this->branchName = $parameterProvider->provideStringParameter(Option::DEFAULT_BRANCH_NAME); } - - public function work(Version $version): void + public function work(Version $version) : void { $versionInString = $this->getVersionDev($version); - - $gitAddCommitCommand = sprintf( - 'git add . && git commit --allow-empty -m "open %s" && git push origin "%s"', - $versionInString, - $this->branchName - ); - + $gitAddCommitCommand = \sprintf('git add . && git commit --allow-empty -m "open %s" && git push origin "%s"', $versionInString, $this->branchName); $this->processRunner->run($gitAddCommitCommand); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { $versionInString = $this->getVersionDev($version); - - return sprintf('Push "%s" open to remote repository', $versionInString); + return \sprintf('Push "%s" open to remote repository', $versionInString); } - - private function getVersionDev(Version $version): string + private function getVersionDev(Version $version) : string { return $this->versionUtils->getNextAliasFormat($version); } diff --git a/packages/Release/ReleaseWorker/PushTagReleaseWorker.php b/packages/Release/ReleaseWorker/PushTagReleaseWorker.php index 10596627a8..d2c316598b 100644 --- a/packages/Release/ReleaseWorker/PushTagReleaseWorker.php +++ b/packages/Release/ReleaseWorker/PushTagReleaseWorker.php @@ -1,27 +1,27 @@ processRunner = $processRunner; } - - public function work(Version $version): void + public function work(Version $version) : void { $this->processRunner->run('git push --tags'); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { - return sprintf('Push "%s" tag to remote repository', $version->getVersionString()); + return \sprintf('Push "%s" tag to remote repository', $version->getVersionString()); } } diff --git a/packages/Release/ReleaseWorker/SetCurrentMutualDependenciesReleaseWorker.php b/packages/Release/ReleaseWorker/SetCurrentMutualDependenciesReleaseWorker.php index fd46c33912..71bce72aec 100644 --- a/packages/Release/ReleaseWorker/SetCurrentMutualDependenciesReleaseWorker.php +++ b/packages/Release/ReleaseWorker/SetCurrentMutualDependenciesReleaseWorker.php @@ -1,7 +1,6 @@ versionUtils = $versionUtils; + $this->dependencyUpdater = $dependencyUpdater; + $this->composerJsonProvider = $composerJsonProvider; + $this->packageNamesProvider = $packageNamesProvider; } - - public function work(Version $version): void + public function work(Version $version) : void { $versionInString = $this->versionUtils->getRequiredFormat($version); - - $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion( - $this->composerJsonProvider->getPackagesComposerFileInfos(), - $this->packageNamesProvider->provide(), - $versionInString - ); - + $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion($this->composerJsonProvider->getPackagesComposerFileInfos(), $this->packageNamesProvider->provide(), $versionInString); // give time to propagate values before commit - sleep(1); + \sleep(1); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { $versionInString = $this->versionUtils->getRequiredFormat($version); - - return sprintf('Set packages mutual dependencies to "%s" version', $versionInString); + return \sprintf('Set packages mutual dependencies to "%s" version', $versionInString); } } diff --git a/packages/Release/ReleaseWorker/SetNextMutualDependenciesReleaseWorker.php b/packages/Release/ReleaseWorker/SetNextMutualDependenciesReleaseWorker.php index 2157003db2..d673fa8c43 100644 --- a/packages/Release/ReleaseWorker/SetNextMutualDependenciesReleaseWorker.php +++ b/packages/Release/ReleaseWorker/SetNextMutualDependenciesReleaseWorker.php @@ -1,7 +1,6 @@ composerJsonProvider = $composerJsonProvider; + $this->dependencyUpdater = $dependencyUpdater; + $this->packageNamesProvider = $packageNamesProvider; + $this->versionUtils = $versionUtils; } - - public function work(Version $version): void + public function work(Version $version) : void { $versionInString = $this->versionUtils->getRequiredNextFormat($version); - - $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion( - $this->composerJsonProvider->getPackagesComposerFileInfos(), - $this->packageNamesProvider->provide(), - $versionInString - ); + $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion($this->composerJsonProvider->getPackagesComposerFileInfos(), $this->packageNamesProvider->provide(), $versionInString); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { $versionInString = $this->versionUtils->getRequiredNextFormat($version); - - return sprintf('Set packages mutual dependencies to "%s" (alias of dev version)', $versionInString); + return \sprintf('Set packages mutual dependencies to "%s" (alias of dev version)', $versionInString); } } diff --git a/packages/Release/ReleaseWorker/TagVersionReleaseWorker.php b/packages/Release/ReleaseWorker/TagVersionReleaseWorker.php index 802e94fd01..78e999acdd 100644 --- a/packages/Release/ReleaseWorker/TagVersionReleaseWorker.php +++ b/packages/Release/ReleaseWorker/TagVersionReleaseWorker.php @@ -1,71 +1,61 @@ processRunner = $processRunner; $this->branchName = $parameterProvider->provideStringParameter(Option::DEFAULT_BRANCH_NAME); } - /** * @return array */ - public function shouldConfirm(): array + public function shouldConfirm() : array { - return [ - 'whenTrue' => fn(): bool => self::getDefaultBranch() !== null && self::getCurrentBranch() !== self::getDefaultBranch(), - 'message'=> sprintf('Do you want to release it on the [ %s ] branch?',self::getCurrentBranch()) - ]; + return ['whenTrue' => function () : bool { + return self::getDefaultBranch() !== null && self::getCurrentBranch() !== self::getDefaultBranch(); + }, 'message' => \sprintf('Do you want to release it on the [ %s ] branch?', self::getCurrentBranch())]; } - - public function work(Version $version): void + public function work(Version $version) : void { try { - $gitAddCommitCommand = sprintf( - 'git add . && git commit -m "prepare release" && git push origin "%s"', - $this->branchName - ); - + $gitAddCommitCommand = \sprintf('git add . && git commit -m "prepare release" && git push origin "%s"', $this->branchName); $this->processRunner->run($gitAddCommitCommand); - } catch (Throwable) { + } catch (Throwable $exception) { // nothing to commit } - $this->processRunner->run('git tag ' . $version->getOriginalString()); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { - return sprintf('Add local tag "%s"', $version->getOriginalString()); + return \sprintf('Add local tag "%s"', $version->getOriginalString()); } - - private function getCurrentBranch(): ?string + private function getCurrentBranch() : ?string { - exec('git rev-parse --abbrev-ref HEAD',$outputs,$result_code); - + \exec('git rev-parse --abbrev-ref HEAD', $outputs, $result_code); return $result_code === 0 ? $outputs[0] : null; } - - private function getDefaultBranch(): ?string + private function getDefaultBranch() : ?string { - exec('git remote set-head origin -a'); - exec("git symbolic-ref --short refs/remotes/origin/HEAD | cut -d '/' -f 2",$outputs,$result_code); - + \exec('git remote set-head origin -a'); + \exec("git symbolic-ref --short refs/remotes/origin/HEAD | cut -d '/' -f 2", $outputs, $result_code); return $result_code === 0 ? $outputs[0] ?? null : null; } } diff --git a/packages/Release/ReleaseWorker/UpdateBranchAliasReleaseWorker.php b/packages/Release/ReleaseWorker/UpdateBranchAliasReleaseWorker.php index b1d0182592..3934e59f2b 100644 --- a/packages/Release/ReleaseWorker/UpdateBranchAliasReleaseWorker.php +++ b/packages/Release/ReleaseWorker/UpdateBranchAliasReleaseWorker.php @@ -1,7 +1,6 @@ devMasterAliasUpdater = $devMasterAliasUpdater; + $this->composerJsonProvider = $composerJsonProvider; + $this->versionUtils = $versionUtils; } - - public function work(Version $version): void + public function work(Version $version) : void { $nextAlias = $this->versionUtils->getNextAliasFormat($version); - - $this->devMasterAliasUpdater->updateFileInfosWithAlias( - $this->composerJsonProvider->getPackagesComposerFileInfos(), - $nextAlias - ); + $this->devMasterAliasUpdater->updateFileInfosWithAlias($this->composerJsonProvider->getPackagesComposerFileInfos(), $nextAlias); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { $nextAlias = $this->versionUtils->getNextAliasFormat($version); - - return sprintf('Set branch alias "%s" to all packages', $nextAlias); + return \sprintf('Set branch alias "%s" to all packages', $nextAlias); } } diff --git a/packages/Release/ReleaseWorker/UpdateReplaceReleaseWorker.php b/packages/Release/ReleaseWorker/UpdateReplaceReleaseWorker.php index fdcdded105..9bf544a960 100644 --- a/packages/Release/ReleaseWorker/UpdateReplaceReleaseWorker.php +++ b/packages/Release/ReleaseWorker/UpdateReplaceReleaseWorker.php @@ -1,7 +1,6 @@ composerJsonProvider = $composerJsonProvider; + $this->jsonFileManager = $jsonFileManager; } - - public function work(Version $version): void + public function work(Version $version) : void { $rootComposerJson = $this->composerJsonProvider->getRootComposerJson(); - $replace = $rootComposerJson->getReplace(); - $packageNames = $this->composerJsonProvider->getPackageNames(); - $newReplace = []; - foreach (array_keys($replace) as $package) { - if (! in_array($package, $packageNames, true)) { + foreach (\array_keys($replace) as $package) { + if (!\in_array($package, $packageNames, \true)) { continue; } - $newReplace[$package] = $version->getVersionString(); } - if ($replace === $newReplace) { return; } - $rootComposerJson->setReplace($newReplace); - $rootFileInfo = $rootComposerJson->getFileInfo(); - if (! $rootFileInfo instanceof SmartFileInfo) { + if (!$rootFileInfo instanceof SmartFileInfo) { throw new MissingComposerJsonException(); } - $this->jsonFileManager->printJsonToFileInfo($rootComposerJson->getJsonArray(), $rootFileInfo); } - - public function getDescription(Version $version): string + public function getDescription(Version $version) : string { return 'Update "replace" version in "composer.json" to new tag to avoid circular dependencies conflicts'; } diff --git a/packages/Release/ReleaseWorkerProvider.php b/packages/Release/ReleaseWorkerProvider.php index 4246809b87..11b50ab723 100644 --- a/packages/Release/ReleaseWorkerProvider.php +++ b/packages/Release/ReleaseWorkerProvider.php @@ -1,49 +1,46 @@ releaseWorkers = $releaseWorkers; } - /** * @param Stage::*|string $stage * @return ReleaseWorkerInterface[]|StageAwareInterface[] */ - public function provideByStage(string $stage): array + public function provideByStage(string $stage) : array { if ($stage === Stage::MAIN) { return $this->releaseWorkers; } - $activeReleaseWorkers = []; foreach ($this->releaseWorkers as $releaseWorker) { - if (! $releaseWorker instanceof StageAwareInterface) { + if (!$releaseWorker instanceof StageAwareInterface) { continue; } - if ($stage !== $releaseWorker->getStage()) { continue; } - $activeReleaseWorkers[] = $releaseWorker; } - return $activeReleaseWorkers; } } diff --git a/packages/Release/ValueObject/SemVersion.php b/packages/Release/ValueObject/SemVersion.php index 66f863d809..abf8424a22 100644 --- a/packages/Release/ValueObject/SemVersion.php +++ b/packages/Release/ValueObject/SemVersion.php @@ -1,7 +1,6 @@ releaseGuard = $releaseGuard; + $this->tagResolver = $tagResolver; } - - public function createValidVersion(string $versionArgument, string $stage): Version + public function createValidVersion(string $versionArgument, string $stage) : Version { // normalize to workaround phar-io bug - $versionArgument = strtolower($versionArgument); - + $versionArgument = \strtolower($versionArgument); // remove 4th level - if (in_array($versionArgument, SemVersion::ALL, true)) { + if (\in_array($versionArgument, SemVersion::ALL, \true)) { return $this->resolveNextVersionByVersionKind($versionArgument); } - // this object performs validation of version $version = new Version($versionArgument); $this->releaseGuard->guardVersion($version, $stage); - return $version; } - - private function resolveNextVersionByVersionKind(string $versionKind): Version + private function resolveNextVersionByVersionKind(string $versionKind) : Version { // get current version - $mostRecentVersionString = $this->tagResolver->resolve(getcwd()); + $mostRecentVersionString = $this->tagResolver->resolve(\getcwd()); if ($mostRecentVersionString === null) { // the very first tag return new Version('v0.1.0'); } - // narrow long invalid version like 10.5.2.72 to 10.5.2 - $dotCount = substr_count($mostRecentVersionString, '.'); + $dotCount = \substr_count($mostRecentVersionString, '.'); if ($dotCount === 3) { $mostRecentVersionString = Strings::before($mostRecentVersionString, '.', -1); } - $mostRecentVersion = new Version($mostRecentVersionString); - - $value = $mostRecentVersion->getMajor() - ->getValue(); - $currentMinorVersion = $mostRecentVersion->getMinor() - ->getValue(); - $currentPatchVersion = $mostRecentVersion->getPatch() - ->getValue(); - + $value = $mostRecentVersion->getMajor()->getValue(); + $currentMinorVersion = $mostRecentVersion->getMinor()->getValue(); + $currentPatchVersion = $mostRecentVersion->getPatch()->getValue(); if ($versionKind === SemVersion::MAJOR) { ++$value; $currentMinorVersion = 0; $currentPatchVersion = 0; } - if ($versionKind === SemVersion::MINOR) { ++$currentMinorVersion; $currentPatchVersion = 0; } - if ($versionKind === SemVersion::PATCH) { ++$currentPatchVersion; } - - return new Version(sprintf('%d.%d.%d', $value, $currentMinorVersion, $currentPatchVersion)); + return new Version(\sprintf('%d.%d.%d', $value, $currentMinorVersion, $currentPatchVersion)); } } diff --git a/packages/Testing/Command/LocalizeComposerPathsCommand.php b/packages/Testing/Command/LocalizeComposerPathsCommand.php index 075a0569fd..2e04519f38 100644 --- a/packages/Testing/Command/LocalizeComposerPathsCommand.php +++ b/packages/Testing/Command/LocalizeComposerPathsCommand.php @@ -1,60 +1,60 @@ composerJsonProvider = $composerJsonProvider; + $this->composerJsonRequireUpdater = $composerJsonRequireUpdater; + $this->composerJsonRepositoriesUpdater = $composerJsonRepositoriesUpdater; parent::__construct(); } - - protected function configure(): void + protected function configure() : void { $this->setName('localize-composer-paths'); $this->setDescription('Set mutual package paths to local packages - use for pre-split package testing'); $this->addArgument(Option::PACKAGE_COMPOSER_JSON, InputArgument::REQUIRED, 'Path to package "composer.json"'); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { $packageComposerJson = (string) $input->getArgument(Option::PACKAGE_COMPOSER_JSON); Assert::fileExists($packageComposerJson, __METHOD__); - $packageComposerJsonFileInfo = new SmartFileInfo($packageComposerJson); $rootComposerJson = $this->composerJsonProvider->getRootComposerJson(); - // 1. update "require" to "*" for all local packages $packagesFileInfos = $this->composerJsonProvider->getPackagesComposerFileInfos(); foreach ($packagesFileInfos as $packageFileInfo) { $this->composerJsonRequireUpdater->processPackage($packageFileInfo); } - // 2. update "repository" to "*" for current composer.json - $this->composerJsonRepositoriesUpdater->processPackage($packageComposerJsonFileInfo, $rootComposerJson, false); - - $message = sprintf( - 'Package paths in "%s" have been updated', - $packageComposerJsonFileInfo->getRelativeFilePathFromCwd() - ); + $this->composerJsonRepositoriesUpdater->processPackage($packageComposerJsonFileInfo, $rootComposerJson, \false); + $message = \sprintf('Package paths in "%s" have been updated', $packageComposerJsonFileInfo->getRelativeFilePathFromCwd()); $this->symfonyStyle->success($message); - return self::SUCCESS; } } diff --git a/packages/Testing/ComposerJson/ComposerJsonSymlinker.php b/packages/Testing/ComposerJson/ComposerJsonSymlinker.php index cdc64bef11..f9e2696867 100644 --- a/packages/Testing/ComposerJson/ComposerJsonSymlinker.php +++ b/packages/Testing/ComposerJson/ComposerJsonSymlinker.php @@ -1,42 +1,48 @@ composerJsonProvider = $composerJsonProvider; + $this->packagePathResolver = $packagePathResolver; + $this->jsonFileManager = $jsonFileManager; } - /** * The relative to the local package is calculated by appending: * - the relative path from the target package to root @@ -45,58 +51,31 @@ public function __construct( * @param string[] $packageNames * @return mixed[] */ - public function decoratePackageComposerJsonWithPackageSymlinks( - SmartFileInfo $packageFileInfo, - array $packageNames, - SmartFileInfo $mainComposerJsonFileInfo, - bool $symlink - ): array { - $relativePathFromTargetPackageToRoot = $this->packagePathResolver->resolveRelativeFolderPathToLocalPackage( - $mainComposerJsonFileInfo, - $packageFileInfo - ); + public function decoratePackageComposerJsonWithPackageSymlinks(SmartFileInfo $packageFileInfo, array $packageNames, SmartFileInfo $mainComposerJsonFileInfo, bool $symlink) : array + { + $relativePathFromTargetPackageToRoot = $this->packagePathResolver->resolveRelativeFolderPathToLocalPackage($mainComposerJsonFileInfo, $packageFileInfo); $packageComposerJson = $this->jsonFileManager->loadFromFileInfo($packageFileInfo); - // @see https://getcomposer.org/doc/05-repositories.md#path foreach ($packageNames as $packageName) { $usedPackageFileInfo = $this->composerJsonProvider->getPackageFileInfoByName($packageName); - - $relativeDirectoryFromRootToLocalPackage = $this->packagePathResolver->resolveRelativeDirectoryToRoot( - $mainComposerJsonFileInfo, - $usedPackageFileInfo - ); + $relativeDirectoryFromRootToLocalPackage = $this->packagePathResolver->resolveRelativeDirectoryToRoot($mainComposerJsonFileInfo, $usedPackageFileInfo); $relativePathToLocalPackage = $relativePathFromTargetPackageToRoot . $relativeDirectoryFromRootToLocalPackage; - - $repositoriesContentJson = [ - self::TYPE => 'path', - self::URL => $relativePathToLocalPackage, - self::OPTIONS => [ - 'symlink' => $symlink, - ], - ]; - - if (array_key_exists(ComposerJsonSection::REPOSITORIES, $packageComposerJson)) { - $packageComposerJson = $this->addRepositoryEntryToPackageComposerJson( - $packageComposerJson, - $repositoriesContentJson - ); + $repositoriesContentJson = [self::TYPE => 'path', self::URL => $relativePathToLocalPackage, self::OPTIONS => ['symlink' => $symlink]]; + if (\array_key_exists(ComposerJsonSection::REPOSITORIES, $packageComposerJson)) { + $packageComposerJson = $this->addRepositoryEntryToPackageComposerJson($packageComposerJson, $repositoriesContentJson); } else { $packageComposerJson[ComposerJsonSection::REPOSITORIES][] = $repositoriesContentJson; } } - return $packageComposerJson; } - /** * @param mixed[] $packageComposerJson * @param mixed[] $repositoriesContent * @return mixed[] */ - private function addRepositoryEntryToPackageComposerJson( - array $packageComposerJson, - array $repositoriesContent - ): array { + private function addRepositoryEntryToPackageComposerJson(array $packageComposerJson, array $repositoriesContent) : array + { // First check if this entry already exists and, if so, replace it foreach ($packageComposerJson[ComposerJsonSection::REPOSITORIES] as $key => $repository) { if ($this->isSamePackageEntry($repository, $repositoriesContent)) { @@ -106,34 +85,28 @@ private function addRepositoryEntryToPackageComposerJson( } else { unset($packageComposerJson[ComposerJsonSection::REPOSITORIES][$key][self::OPTIONS]); } - return $packageComposerJson; } } - // Add the new entry - array_unshift($packageComposerJson[ComposerJsonSection::REPOSITORIES], $repositoriesContent); + \array_unshift($packageComposerJson[ComposerJsonSection::REPOSITORIES], $repositoriesContent); return $packageComposerJson; } - /** * @param mixed[] $repository * @param mixed[] $repositoriesContent */ - private function isSamePackageEntry(array $repository, array $repositoriesContent): bool + private function isSamePackageEntry(array $repository, array $repositoriesContent) : bool { - if (! isset($repository[self::TYPE])) { - return false; + if (!isset($repository[self::TYPE])) { + return \false; } - if ($repository[self::TYPE] !== $repositoriesContent[self::TYPE]) { - return false; + return \false; } - - if (! isset($repository[self::URL])) { - return false; + if (!isset($repository[self::URL])) { + return \false; } - return $repository[self::URL] === $repositoriesContent[self::URL]; } } diff --git a/packages/Testing/ComposerJson/ComposerVersionManipulator.php b/packages/Testing/ComposerJson/ComposerVersionManipulator.php index 504a2cca3c..4eca68685e 100644 --- a/packages/Testing/ComposerJson/ComposerVersionManipulator.php +++ b/packages/Testing/ComposerJson/ComposerVersionManipulator.php @@ -1,46 +1,40 @@ branchAliasTarget = self::COMPOSER_BRANCH_PREFIX . $parameterProvider->provideStringParameter( - Option::DEFAULT_BRANCH_NAME - ); + $this->branchAliasTarget = self::COMPOSER_BRANCH_PREFIX . $parameterProvider->provideStringParameter(Option::DEFAULT_BRANCH_NAME); } - /** * @param mixed[] $packageComposerJson * @param string[] $usedPackageNames * @return mixed[] */ - public function decorateAsteriskVersionForUsedPackages(array $packageComposerJson, array $usedPackageNames): array + public function decorateAsteriskVersionForUsedPackages(array $packageComposerJson, array $usedPackageNames) : array { foreach ([ComposerJsonSection::REQUIRE, ComposerJsonSection::REQUIRE_DEV] as $section) { foreach ($usedPackageNames as $usedPackageName) { - if (! isset($packageComposerJson[$section][$usedPackageName])) { + if (!isset($packageComposerJson[$section][$usedPackageName])) { continue; } - $packageComposerJson[$section][$usedPackageName] = $this->branchAliasTarget; } } - return $packageComposerJson; } } diff --git a/packages/Testing/ComposerJsonRepositoriesUpdater.php b/packages/Testing/ComposerJsonRepositoriesUpdater.php index 7a2f36206c..8a819ed246 100644 --- a/packages/Testing/ComposerJsonRepositoriesUpdater.php +++ b/packages/Testing/ComposerJsonRepositoriesUpdater.php @@ -1,73 +1,74 @@ packageNamesProvider = $packageNamesProvider; + $this->jsonFileManager = $jsonFileManager; + $this->symfonyStyle = $symfonyStyle; + $this->composerJsonSymlinker = $composerJsonSymlinker; + $this->usedPackagesResolver = $usedPackagesResolver; + $this->consoleDiffer = $consoleDiffer; } - - public function processPackage(SmartFileInfo $packageFileInfo, ComposerJson $rootComposerJson, bool $symlink): void + public function processPackage(SmartFileInfo $packageFileInfo, ComposerJson $rootComposerJson, bool $symlink) : void { $packageComposerJson = $this->jsonFileManager->loadFromFileInfo($packageFileInfo); - $usedPackageNames = $this->usedPackagesResolver->resolveForPackage($packageComposerJson); if ($usedPackageNames === []) { - $message = sprintf( - 'Package "%s" does not use any mutual dependencies, so we skip it', - $packageFileInfo->getRelativeFilePathFromCwd() - ); + $message = \sprintf('Package "%s" does not use any mutual dependencies, so we skip it', $packageFileInfo->getRelativeFilePathFromCwd()); $this->symfonyStyle->note($message); return; } - // possibly replace them all to cover recursive secondary dependencies $packageNames = $this->packageNamesProvider->provide(); - $oldComposerJsonContents = $packageFileInfo->getContents(); - $rootComposerJsonFileInfo = $rootComposerJson->getFileInfo(); - if (! $rootComposerJsonFileInfo instanceof SmartFileInfo) { + if (!$rootComposerJsonFileInfo instanceof SmartFileInfo) { throw new ShouldNotHappenException(); } - - $decoreatedPackageComposerJson = $this->composerJsonSymlinker->decoratePackageComposerJsonWithPackageSymlinks( - $packageFileInfo, - $packageNames, - $rootComposerJsonFileInfo, - $symlink - ); - - $newComposerJsonContents = $this->jsonFileManager->printJsonToFileInfoAndReturn( - $decoreatedPackageComposerJson, - $packageFileInfo - ); - - $message = sprintf('File "%s" was updated', $packageFileInfo->getRelativeFilePathFromCwd()); + $decoreatedPackageComposerJson = $this->composerJsonSymlinker->decoratePackageComposerJsonWithPackageSymlinks($packageFileInfo, $packageNames, $rootComposerJsonFileInfo, $symlink); + $newComposerJsonContents = $this->jsonFileManager->printJsonToFileInfoAndReturn($decoreatedPackageComposerJson, $packageFileInfo); + $message = \sprintf('File "%s" was updated', $packageFileInfo->getRelativeFilePathFromCwd()); $this->symfonyStyle->title($message); - $diff = $this->consoleDiffer->diff($oldComposerJsonContents, $newComposerJsonContents); $this->symfonyStyle->writeln($diff); - $this->symfonyStyle->newLine(2); } } diff --git a/packages/Testing/ComposerJsonRequireUpdater.php b/packages/Testing/ComposerJsonRequireUpdater.php index 21c3a1b888..02ee1774bc 100644 --- a/packages/Testing/ComposerJsonRequireUpdater.php +++ b/packages/Testing/ComposerJsonRequireUpdater.php @@ -1,59 +1,60 @@ jsonFileManager = $jsonFileManager; + $this->symfonyStyle = $symfonyStyle; + $this->composerVersionManipulator = $composerVersionManipulator; + $this->usedPackagesResolver = $usedPackagesResolver; + $this->consoleDiffer = $consoleDiffer; } - - public function processPackage(SmartFileInfo $packageFileInfo): void + public function processPackage(SmartFileInfo $packageFileInfo) : void { $packageComposerJson = $this->jsonFileManager->loadFromFileInfo($packageFileInfo); - $usedPackageNames = $this->usedPackagesResolver->resolveForPackage($packageComposerJson); if ($usedPackageNames === []) { - $message = sprintf( - 'Package "%s" does not use any mutual dependencies, so we skip it', - $packageFileInfo->getRelativeFilePathFromCwd() - ); + $message = \sprintf('Package "%s" does not use any mutual dependencies, so we skip it', $packageFileInfo->getRelativeFilePathFromCwd()); $this->symfonyStyle->note($message); return; } - - $packageComposerJson = $this->composerVersionManipulator->decorateAsteriskVersionForUsedPackages( - $packageComposerJson, - $usedPackageNames - ); - + $packageComposerJson = $this->composerVersionManipulator->decorateAsteriskVersionForUsedPackages($packageComposerJson, $usedPackageNames); $oldComposerJsonContents = $packageFileInfo->getContents(); - - $newComposerJsonContents = $this->jsonFileManager->printJsonToFileInfoAndReturn( - $packageComposerJson, - $packageFileInfo - ); - - $message = sprintf('File "%s" was updated', $packageFileInfo->getRelativeFilePathFromCwd()); + $newComposerJsonContents = $this->jsonFileManager->printJsonToFileInfoAndReturn($packageComposerJson, $packageFileInfo); + $message = \sprintf('File "%s" was updated', $packageFileInfo->getRelativeFilePathFromCwd()); $this->symfonyStyle->title($message); - $diff = $this->consoleDiffer->diff($oldComposerJsonContents, $newComposerJsonContents); $this->symfonyStyle->writeln($diff); - $this->symfonyStyle->newLine(2); } } diff --git a/packages/Testing/PackageDependency/UsedPackagesResolver.php b/packages/Testing/PackageDependency/UsedPackagesResolver.php index d826972ed1..e07326ad8e 100644 --- a/packages/Testing/PackageDependency/UsedPackagesResolver.php +++ b/packages/Testing/PackageDependency/UsedPackagesResolver.php @@ -1,42 +1,39 @@ packageNamesProvider = $packageNamesProvider; } - /** * @param mixed[] $packageComposerJson * @return string[] */ - public function resolveForPackage(array $packageComposerJson): array + public function resolveForPackage(array $packageComposerJson) : array { $usedPackageNames = []; - foreach ([ComposerJsonSection::REQUIRE, ComposerJsonSection::REQUIRE_DEV] as $section) { - if (! isset($packageComposerJson[$section])) { + if (!isset($packageComposerJson[$section])) { continue; } - - $packageNames = array_keys($packageComposerJson[$section]); + $packageNames = \array_keys($packageComposerJson[$section]); foreach ($packageNames as $packageName) { - if (! in_array($packageName, $this->packageNamesProvider->provide(), true)) { + if (!\in_array($packageName, $this->packageNamesProvider->provide(), \true)) { continue; } - $usedPackageNames[] = $packageName; } } - return $usedPackageNames; } } diff --git a/packages/Testing/PathResolver/PackagePathResolver.php b/packages/Testing/PathResolver/PackagePathResolver.php index f2b5751a66..cd3ad41ffa 100644 --- a/packages/Testing/PathResolver/PackagePathResolver.php +++ b/packages/Testing/PathResolver/PackagePathResolver.php @@ -1,11 +1,9 @@ getRealPath()); + public function resolveRelativeFolderPathToLocalPackage(SmartFileInfo $rootComposerFileInfo, SmartFileInfo $packageComposerFileInfo) : string + { + $currentDirectory = \dirname($packageComposerFileInfo->getRealPath()); $nestingLevel = 0; - while ($currentDirectory . '/composer.json' !== $rootComposerFileInfo->getRealPath()) { ++$nestingLevel; - $currentDirectory = dirname($currentDirectory); + $currentDirectory = \dirname($currentDirectory); } - - return str_repeat('../', $nestingLevel); + return \str_repeat('../', $nestingLevel); } - - public function resolveRelativeDirectoryToRoot( - SmartFileInfo $rootComposerFileInfo, - SmartFileInfo $packageComposerFileInfo - ): string { - $rootDirectory = dirname($rootComposerFileInfo->getRealPath()); - - return dirname($packageComposerFileInfo->getRelativeFilePathFromDirectory($rootDirectory)); + public function resolveRelativeDirectoryToRoot(SmartFileInfo $rootComposerFileInfo, SmartFileInfo $packageComposerFileInfo) : string + { + $rootDirectory = \dirname($rootComposerFileInfo->getRealPath()); + return \dirname($packageComposerFileInfo->getRelativeFilePathFromDirectory($rootDirectory)); } } diff --git a/packages/Testing/ValueObject/Option.php b/packages/Testing/ValueObject/Option.php index 47685bfba3..b7e2a3cf2a 100644 --- a/packages/Testing/ValueObject/Option.php +++ b/packages/Testing/ValueObject/Option.php @@ -1,7 +1,6 @@ - - - tests - packages/*/tests - - diff --git a/prefix-code.sh b/prefix-code.sh deleted file mode 100644 index 2adfe7830e..0000000000 --- a/prefix-code.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash - -# inspired from https://github.com/rectorphp/rector/blob/main/build/build-rector-scoped.sh - -# see https://stackoverflow.com/questions/66644233/how-to-propagate-colors-from-bash-script-to-github-action?noredirect=1#comment117811853_66644233 -export TERM=xterm-color - -# show errors -set -e - -# script fails if trying to access to an undefined variable -set -u - - -# functions -note() -{ - MESSAGE=$1; - printf "\n"; - echo "\033[0;33m[NOTE] $MESSAGE\033[0m"; -} - -# --------------------------- - -# 2. scope it -note "Downloading php-scoper 0.17.5" -# @todo upgrade to 0.18.1 -wget https://github.com/humbug/php-scoper/releases/download/0.17.5/php-scoper.phar -N --no-verbose - - -note "Running php-scoper" - -# Work around possible PHP memory limits -php -d memory_limit=-1 php-scoper.phar add-prefix bin config src packages vendor composer.json --config scoper.php --force --ansi --output-dir scoped-code - -# the output code is in "/scoped-code", lets move it up -# the local directories have to be empty to move easily -rm -r bin config src vendor composer.json packages -mv scoped-code/* . - -note "Dumping Composer Autoload" -composer dump-autoload --ansi --classmap-authoritative --no-dev - -# make bin/ecs runnable without "php" -chmod 777 "bin/monorepo-builder" -chmod 777 "bin/monorepo-builder.php" - -note "Finished" - diff --git a/rector.php b/rector.php deleted file mode 100644 index d3dcf5140e..0000000000 --- a/rector.php +++ /dev/null @@ -1,46 +0,0 @@ -sets([ - SetList::CODE_QUALITY, - SetList::DEAD_CODE, - // @todo bump to PHP 8.1 - LevelSetList::UP_TO_PHP_80, - SetList::CODING_STYLE, - SetList::TYPE_DECLARATION, - SetList::NAMING, - SetList::PRIVATIZATION, - SetList::EARLY_RETURN, - PHPUnitSetList::PHPUNIT_CODE_QUALITY, - ]); - - $rectorConfig->rules([ - Rector\PHPUnit\PHPUnit70\Rector\Class_\RemoveDataProviderTestPrefixRector::class, - Rector\PHPUnit\PHPUnit100\Rector\Class_\StaticDataProviderClassMethodRector::class, - Rector\PHPUnit\AnnotationsToAttributes\Rector\ClassMethod\DataProviderAnnotationToAttributeRector::class, - - ]); - - $rectorConfig->paths([ - __DIR__ . '/config', - __DIR__ . '/src', - __DIR__ . '/tests', - __DIR__ . '/packages', - __DIR__ . '/packages-tests', - ]); - - $rectorConfig->importNames(); - - $rectorConfig->skip([ - '*/scoper.php', - '*/Source/*', - '*/Fixture/*', - ]); -}; diff --git a/scoper.php b/scoper.php deleted file mode 100644 index dc888fb9b9..0000000000 --- a/scoper.php +++ /dev/null @@ -1,91 +0,0 @@ -format('Ym'); - -// @see https://github.com/humbug/php-scoper/blob/master/docs/further-reading.md -use Nette\Utils\Strings; - -$polyfillsBootstraps = array_map( - static fn (SplFileInfo $fileInfo) => $fileInfo->getPathname(), - iterator_to_array( - Finder::create() - ->files() - ->in(__DIR__ . '/vendor/symfony/polyfill-*') - ->name('bootstrap*.php'), - false, - ), -); - -$polyfillsStubs = array_map( - static fn (SplFileInfo $fileInfo) => $fileInfo->getPathname(), - iterator_to_array( - Finder::create() - ->files() - ->in(__DIR__ . '/vendor/symfony/polyfill-*/Resources/stubs') - ->name('*.php'), - false, - ), -); - -// see https://github.com/humbug/php-scoper -return [ - 'prefix' => 'MonorepoBuilderPrefix' . $timestamp, - 'exclude-files' => [ - // these paths are relative to this file location, so it should be in the root directory - 'vendor/symfony/deprecation-contracts/function.php', - ...$polyfillsBootstraps, - ...$polyfillsStubs, - ], - 'exclude-namespaces' => [ - '#^Symplify\\\\MonorepoBuilder#', - '#^Symfony\\\\Polyfill#', - // part of public API in \Symplify\MonorepoBuilder\Release\Contract\ReleaseWorker\ReleaseWorkerInterface - '#^PharIo\\\\Version#', - ], - 'exclude-constants' => ['#^SYMFONY\_[\p{L}_]+$#'], - 'expose-classes' => [ - 'Normalizer', - // part of public interface of configs.php - 'Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection', - 'Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator', - ], - 'patchers' => [ - // scope symfony configs - function (string $filePath, string $prefix, string $content): string { - if (! Strings::match($filePath, '#(packages|config|services)\.php$#')) { - return $content; - } - - // fix symfony config load scoping, except CodingStandard and EasyCodingStandard - $content = Strings::replace( - $content, - '#load\(\'Symplify\\\\\\\\(?[A-Za-z]+)#', - function (array $match) use ($prefix) { - return 'load(\'' . $prefix . '\Symplify\\' . $match['package_name']; - } - ); - - return $content; - }, - - // scope symfony configs - function (string $filePath, string $prefix, string $content): string { - if (! Strings::match($filePath, '#(packages|config|services)\.php$#')) { - return $content; - } - - // unprefix symfony config - return Strings::replace( - $content, - '#load\(\'' . $prefix . '\\\\Symplify\\\\MonorepoBuilder#', - 'load(\'' . 'Symplify\\MonorepoBuilder', - ); - }, - ], -]; diff --git a/src/Command/BumpInterdependencyCommand.php b/src/Command/BumpInterdependencyCommand.php index ab3c7571fe..e1ceaa2cc7 100644 --- a/src/Command/BumpInterdependencyCommand.php +++ b/src/Command/BumpInterdependencyCommand.php @@ -1,69 +1,62 @@ dependencyUpdater = $dependencyUpdater; + $this->composerJsonProvider = $composerJsonProvider; + $this->sourcesPresenceValidator = $sourcesPresenceValidator; parent::__construct(); } - - protected function configure(): void + protected function configure() : void { $this->setName('bump-interdependency'); $this->setDescription('Bump dependency of split packages on each other'); - $this->addArgument( - self::VERSION_ARGUMENT, - InputArgument::REQUIRED, - 'New version of inter-dependencies, e.g. "^4.4.2"' - ); + $this->addArgument(self::VERSION_ARGUMENT, InputArgument::REQUIRED, 'New version of inter-dependencies, e.g. "^4.4.2"'); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { $this->sourcesPresenceValidator->validateRootComposerJsonName(); - /** @var string $version */ $version = $input->getArgument(self::VERSION_ARGUMENT); - $rootComposerJson = $this->composerJsonProvider->getRootComposerJson(); - // @todo resolve better for only found packages // see https://github.com/symplify/symplify/pull/1037/files $vendorName = $rootComposerJson->getVendorName(); if ($vendorName === null) { throw new ShouldNotHappenException(); } - - $this->dependencyUpdater->updateFileInfosWithVendorAndVersion( - $this->composerJsonProvider->getPackagesComposerFileInfos(), - $vendorName, - $version - ); - - $successMessage = sprintf('Inter-dependencies of packages were updated to "%s".', $version); + $this->dependencyUpdater->updateFileInfosWithVendorAndVersion($this->composerJsonProvider->getPackagesComposerFileInfos(), $vendorName, $version); + $successMessage = \sprintf('Inter-dependencies of packages were updated to "%s".', $version); $this->symfonyStyle->success($successMessage); - return self::SUCCESS; } } diff --git a/src/Command/PackageAliasCommand.php b/src/Command/PackageAliasCommand.php index a3d00a062f..b2b00c1508 100644 --- a/src/Command/PackageAliasCommand.php +++ b/src/Command/PackageAliasCommand.php @@ -1,47 +1,51 @@ packageComposerFinder = $packageComposerFinder; + $this->devMasterAliasUpdater = $devMasterAliasUpdater; + $this->expectedAliasResolver = $expectedAliasResolver; parent::__construct(); } - - protected function configure(): void + protected function configure() : void { $this->setName('package-alias'); $this->setDescription('Updates branch alias in "composer.json" all found packages'); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { $composerPackageFiles = $this->packageComposerFinder->getPackageComposerFiles(); if ($composerPackageFiles === []) { $this->symfonyStyle->error('No "composer.json" were found in packages.'); return self::FAILURE; } - $expectedAlias = $this->expectedAliasResolver->resolve(); - $this->devMasterAliasUpdater->updateFileInfosWithAlias($composerPackageFiles, $expectedAlias); - - $message = sprintf('Alias was updated to "%s" in all packages.', $expectedAlias); + $message = \sprintf('Alias was updated to "%s" in all packages.', $expectedAlias); $this->symfonyStyle->success($message); - return self::SUCCESS; } } diff --git a/src/Command/ValidateCommand.php b/src/Command/ValidateCommand.php index 8d23e6f1d2..dae38242d4 100644 --- a/src/Command/ValidateCommand.php +++ b/src/Command/ValidateCommand.php @@ -1,50 +1,55 @@ composerJsonProvider = $composerJsonProvider; + $this->versionValidator = $versionValidator; + $this->conflictingPackageVersionsReporter = $conflictingPackageVersionsReporter; + $this->sourcesPresenceValidator = $sourcesPresenceValidator; parent::__construct(); } - - protected function configure(): void + protected function configure() : void { $this->setName('validate'); $this->setDescription('Validates synchronized versions in "composer.json" in all found packages.'); } - - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute(InputInterface $input, OutputInterface $output) : int { $this->sourcesPresenceValidator->validatePackageComposerJsons(); - - $conflictingPackageVersions = $this->versionValidator->findConflictingPackageVersionsInFileInfos( - $this->composerJsonProvider->getRootAndPackageFileInfos() - ); - + $conflictingPackageVersions = $this->versionValidator->findConflictingPackageVersionsInFileInfos($this->composerJsonProvider->getRootAndPackageFileInfos()); if ($conflictingPackageVersions === []) { $this->symfonyStyle->success('All packages "composer.json" files use same package versions.'); - return self::SUCCESS; } - $this->conflictingPackageVersionsReporter->report($conflictingPackageVersions); - return self::FAILURE; } } diff --git a/src/Config/MBConfig.php b/src/Config/MBConfig.php index cf52ed4d74..b3e35e47b7 100644 --- a/src/Config/MBConfig.php +++ b/src/Config/MBConfig.php @@ -1,108 +1,92 @@ parameters(); $parameters->set(Option::PACKAGE_DIRECTORIES, $packageDirectories); } - - public static function isDisableDefaultWorkers(): bool + public static function isDisableDefaultWorkers() : bool { return self::$disableDefaultWorkers; } - - public static function disableDefaultWorkers(): void + public static function disableDefaultWorkers() : void { - self::$disableDefaultWorkers = true; + self::$disableDefaultWorkers = \true; } - /** * @param string[] $packageDirectories */ - public function packageDirectoriesExcludes(array $packageDirectories): void + public function packageDirectoriesExcludes(array $packageDirectories) : void { Assert::allString($packageDirectories); Assert::allFileExists($packageDirectories); - $parameters = $this->parameters(); $parameters->set(Option::PACKAGE_DIRECTORIES_EXCLUDES, $packageDirectories); } - - public function defaultBranch(string $defaultBranch): void + public function defaultBranch(string $defaultBranch) : void { $parameters = $this->parameters(); $parameters->set(Option::DEFAULT_BRANCH_NAME, $defaultBranch); } - /** * @param array $dataToRemove */ - public function dataToRemove(array $dataToRemove): void + public function dataToRemove(array $dataToRemove) : void { - Assert::allString(array_keys($dataToRemove)); - + Assert::allString(\array_keys($dataToRemove)); $parameters = $this->parameters(); $parameters->set(Option::DATA_TO_REMOVE, $dataToRemove); } - /** * @param array $dataToAppend */ - public function dataToAppend(array $dataToAppend): void + public function dataToAppend(array $dataToAppend) : void { - Assert::allString(array_keys($dataToAppend)); - + Assert::allString(\array_keys($dataToAppend)); $parameters = $this->parameters(); $parameters->set(Option::DATA_TO_APPEND, $dataToAppend); } - /** * @param array> $workerClasses */ - public function workers(array $workerClasses): void + public function workers(array $workerClasses) : void { Assert::allString($workerClasses); Assert::allIsAOf($workerClasses, ReleaseWorkerInterface::class); - $services = $this->services(); - foreach ($workerClasses as $workerClass) { $services->set($workerClass); } } - - public function packageAliasFormat(string $packageAliasFormat): void + public function packageAliasFormat(string $packageAliasFormat) : void { $parameters = $this->parameters(); $parameters->set(Option::PACKAGE_ALIAS_FORMAT, $packageAliasFormat); } - /** * @param string[] $sectionOrder */ - public function composerSectionOrder(array $sectionOrder): void + public function composerSectionOrder(array $sectionOrder) : void { Assert::allString($sectionOrder); - $parameters = $this->parameters(); $parameters->set(Option::SECTION_ORDER, $sectionOrder); } diff --git a/src/Console/MonorepoBuilderApplication.php b/src/Console/MonorepoBuilderApplication.php index c1ea6f9e4f..23093b91f5 100644 --- a/src/Console/MonorepoBuilderApplication.php +++ b/src/Console/MonorepoBuilderApplication.php @@ -1,12 +1,10 @@ jsonFileManager = $jsonFileManager; } - /** * @param SmartFileInfo[] $smartFileInfos * @param string[] $packageNames */ - public function updateFileInfosWithPackagesAndVersion( - array $smartFileInfos, - array $packageNames, - string $version - ): void { + public function updateFileInfosWithPackagesAndVersion(array $smartFileInfos, array $packageNames, string $version) : void + { foreach ($smartFileInfos as $smartFileInfo) { $json = $this->jsonFileManager->loadFromFileInfo($smartFileInfo); - $json = $this->processSectionWithPackages($json, $packageNames, $version, ComposerJsonSection::REQUIRE); - $json = $this->processSectionWithPackages($json, $packageNames, $version, ComposerJsonSection::REQUIRE_DEV); - $this->jsonFileManager->printJsonToFileInfo($json, $smartFileInfo); } } - /** * @param SmartFileInfo[] $smartFileInfos */ - public function updateFileInfosWithVendorAndVersion( - array $smartFileInfos, - string $vendor, - string $version - ): void { + public function updateFileInfosWithVendorAndVersion(array $smartFileInfos, string $vendor, string $version) : void + { foreach ($smartFileInfos as $smartFileInfo) { $json = $this->jsonFileManager->loadFromFileInfo($smartFileInfo); - $json = $this->processSection($json, $vendor, $version, ComposerJsonSection::REQUIRE); $json = $this->processSection($json, $vendor, $version, ComposerJsonSection::REQUIRE_DEV); - $this->jsonFileManager->printJsonToFileInfo($json, $smartFileInfo); } } - /** * @param mixed[] $json * @param string[] $parentPackageNames * @param ComposerJsonSection::* $section * @return mixed[] */ - private function processSectionWithPackages( - array $json, - array $parentPackageNames, - string $targetVersion, - string $section - ): array { - if (! isset($json[$section])) { + private function processSectionWithPackages(array $json, array $parentPackageNames, string $targetVersion, string $section) : array + { + if (!isset($json[$section])) { return $json; } - - $packageNames = array_keys($json[$section]); + $packageNames = \array_keys($json[$section]); foreach ($packageNames as $packageName) { - if (! in_array($packageName, $parentPackageNames, true)) { + if (!\in_array($packageName, $parentPackageNames, \true)) { continue; } - $json[$section][$packageName] = $targetVersion; } - return $json; } - /** * @param mixed[] $json * @param ComposerJsonSection::* $section * @return mixed[] */ - private function processSection(array $json, string $vendor, string $targetVersion, string $section): array + private function processSection(array $json, string $vendor, string $targetVersion, string $section) : array { - if (! isset($json[$section])) { + if (!isset($json[$section])) { return $json; } - foreach ($json[$section] as $packageName => $packageVersion) { if ($this->shouldSkip($vendor, $targetVersion, $packageName, $packageVersion)) { continue; } - $json[$section][$packageName] = $targetVersion; } - return $json; } - - private function shouldSkip( - string $vendor, - string $targetVersion, - string $packageName, - string $packageVersion - ): bool { - if (! \str_starts_with($packageName, $vendor . '/')) { - return true; + private function shouldSkip(string $vendor, string $targetVersion, string $packageName, string $packageVersion) : bool + { + if (\strncmp($packageName, $vendor . '/', \strlen($vendor . '/')) !== 0) { + return \true; } - return $packageVersion === $targetVersion; } } diff --git a/src/DevMasterAliasUpdater.php b/src/DevMasterAliasUpdater.php index 95223f95d8..2e78141e58 100644 --- a/src/DevMasterAliasUpdater.php +++ b/src/DevMasterAliasUpdater.php @@ -1,74 +1,66 @@ branchAliasTarget = self::COMPOSER_BRANCH_PREFIX . $parameterProvider->provideStringParameter( - Option::DEFAULT_BRANCH_NAME - ); + /** + * @var string + */ + private $branchAliasTarget; + public function __construct(JsonFileManager $jsonFileManager, ParameterProvider $parameterProvider) + { + $this->jsonFileManager = $jsonFileManager; + $this->branchAliasTarget = self::COMPOSER_BRANCH_PREFIX . $parameterProvider->provideStringParameter(Option::DEFAULT_BRANCH_NAME); } - /** * @param SmartFileInfo[] $fileInfos */ - public function updateFileInfosWithAlias(array $fileInfos, string $alias): void + public function updateFileInfosWithAlias(array $fileInfos, string $alias) : void { foreach ($fileInfos as $fileInfo) { $json = $this->jsonFileManager->loadFromFileInfo($fileInfo); if ($this->shouldSkip($json, $alias)) { continue; } - $json[self::EXTRA][self::BRANCH_ALIAS][$this->branchAliasTarget] = $alias; - $this->jsonFileManager->printJsonToFileInfo($json, $fileInfo); } } - /** * @param mixed[] $json */ - private function shouldSkip(array $json, string $alias): bool + private function shouldSkip(array $json, string $alias) : bool { // update only when already present - if (! isset($json[self::EXTRA][self::BRANCH_ALIAS][$this->branchAliasTarget])) { - return true; + if (!isset($json[self::EXTRA][self::BRANCH_ALIAS][$this->branchAliasTarget])) { + return \true; } - $currentAlias = $json[self::EXTRA][self::BRANCH_ALIAS][$this->branchAliasTarget]; - return $currentAlias === $alias; } } diff --git a/src/Exception/ConfigurationException.php b/src/Exception/ConfigurationException.php index 1328c141e8..59175abcf4 100644 --- a/src/Exception/ConfigurationException.php +++ b/src/Exception/ConfigurationException.php @@ -1,11 +1,9 @@ jsonFileManager = $jsonFileManager; + $this->packageComposerFinder = $packageComposerFinder; + $this->composerJsonFactory = $composerJsonFactory; } - /** * @return SmartFileInfo[] */ - public function getPackagesComposerFileInfos(): array + public function getPackagesComposerFileInfos() : array { return $this->packageComposerFinder->getPackageComposerFiles(); } - /** * @return SmartFileInfo[] */ - public function getRootAndPackageFileInfos(): array + public function getRootAndPackageFileInfos() : array { - return array_merge( - $this->getPackagesComposerFileInfos(), - [$this->packageComposerFinder->getRootPackageComposerFile()] - ); + return \array_merge($this->getPackagesComposerFileInfos(), [$this->packageComposerFinder->getRootPackageComposerFile()]); } - /** * @return ComposerJson[] */ - public function getPackageComposerJsons(): array + public function getPackageComposerJsons() : array { $packageComposerJsons = []; foreach ($this->getPackagesComposerFileInfos() as $packagesComposerFileInfo) { $packageComposerJsons[] = $this->composerJsonFactory->createFromFileInfo($packagesComposerFileInfo); } - return $packageComposerJsons; } - /** * @return string[] */ - public function getPackageNames(): array + public function getPackageNames() : array { $packageNames = []; foreach ($this->getPackagesComposerFileInfos() as $packagesComposerFileInfo) { $packageComposerJson = $this->composerJsonFactory->createFromFileInfo($packagesComposerFileInfo); $packageName = $packageComposerJson->getName(); - if (! is_string($packageName)) { + if (!\is_string($packageName)) { continue; } - $packageNames[] = $packageName; } - return $packageNames; } - - public function getPackageFileInfoByName(string $packageName): SmartFileInfo + public function getPackageFileInfoByName(string $packageName) : SmartFileInfo { foreach ($this->getPackagesComposerFileInfos() as $packagesComposerFileInfo) { $json = $this->jsonFileManager->loadFromFileInfo($packagesComposerFileInfo); - if (! isset($json['name'])) { + if (!isset($json['name'])) { continue; } - if ($json['name'] !== $packageName) { continue; } - return $packagesComposerFileInfo; } - throw new ShouldNotHappenException(); } - - public function getRootComposerJson(): ComposerJson + public function getRootComposerJson() : ComposerJson { $rootPackageComposerFile = $this->packageComposerFinder->getRootPackageComposerFile(); return $this->composerJsonFactory->createFromFileInfo($rootPackageComposerFile); diff --git a/src/Finder/PackageComposerFinder.php b/src/Finder/PackageComposerFinder.php index 380915cc9c..d90a0af2e2 100644 --- a/src/Finder/PackageComposerFinder.php +++ b/src/Finder/PackageComposerFinder.php @@ -1,96 +1,69 @@ finderSanitizer = $finderSanitizer; $this->packageDirectories = $parameterProvider->provideArrayParameter(Option::PACKAGE_DIRECTORIES); - $this->packageDirectoriesExcludes = $parameterProvider->provideArrayParameter( - Option::PACKAGE_DIRECTORIES_EXCLUDES - ); + $this->packageDirectoriesExcludes = $parameterProvider->provideArrayParameter(Option::PACKAGE_DIRECTORIES_EXCLUDES); } - - public function getRootPackageComposerFile(): SmartFileInfo + public function getRootPackageComposerFile() : SmartFileInfo { - return new SmartFileInfo(getcwd() . DIRECTORY_SEPARATOR . 'composer.json'); + return new SmartFileInfo(\getcwd() . \DIRECTORY_SEPARATOR . 'composer.json'); } - /** * @return SmartFileInfo[] */ - public function getPackageComposerFiles(): array + public function getPackageComposerFiles() : array { if ($this->packageDirectories === []) { - $errorMessage = sprintf( - 'First define package directories in "monorepo-builder.php" config.%sUse $parameters->set(Option::%s, "...");', - PHP_EOL, - Option::PACKAGE_DIRECTORIES - ); + $errorMessage = \sprintf('First define package directories in "monorepo-builder.php" config.%sUse $parameters->set(Option::%s, "...");', \PHP_EOL, Option::PACKAGE_DIRECTORIES); throw new ConfigurationException($errorMessage); } - if ($this->cachedPackageComposerFiles === []) { - $finder = Finder::create() - ->files() - ->in($this->packageDirectories) - // sub-directory for wrapping to phar - ->exclude('compiler') - // "init" command template data - ->exclude('templates') - ->exclude('vendor') - // usually designed for prefixed/downgraded versions - ->exclude('build') - ->exclude('node_modules') - ->name('composer.json'); - + $finder = Finder::create()->files()->in($this->packageDirectories)->exclude('compiler')->exclude('templates')->exclude('vendor')->exclude('build')->exclude('node_modules')->name('composer.json'); if ($this->packageDirectoriesExcludes !== []) { $finder->exclude($this->packageDirectoriesExcludes); } - - if (! $this->isPHPUnit()) { + if (!$this->isPHPUnit()) { $finder->notPath('#tests#'); } - $this->cachedPackageComposerFiles = $this->finderSanitizer->sanitize($finder); } - return $this->cachedPackageComposerFiles; } - - private function isPHPUnit(): bool + private function isPHPUnit() : bool { // defined by PHPUnit - return defined('PHPUNIT_COMPOSER_INSTALL') || defined('__PHPUNIT_PHAR__'); + return \defined('MonorepoBuilderPrefix202310\\PHPUNIT_COMPOSER_INSTALL') || \defined('MonorepoBuilderPrefix202310\\__PHPUNIT_PHAR__'); } } diff --git a/src/Git/ExpectedAliasResolver.php b/src/Git/ExpectedAliasResolver.php index 878053a711..1cfe197ec6 100644 --- a/src/Git/ExpectedAliasResolver.php +++ b/src/Git/ExpectedAliasResolver.php @@ -1,26 +1,25 @@ versionUtils = $versionUtils; } - - public function resolve(): string + public function resolve() : string { $process = new Process(['git', 'describe', '--abbrev=0', '--tags']); $process->run(); - $output = $process->getOutput(); - return $this->versionUtils->getNextAliasFormat($output); } } diff --git a/src/Git/MostRecentTagResolver.php b/src/Git/MostRecentTagResolver.php index e7b92e249c..c9e5449688 100644 --- a/src/Git/MostRecentTagResolver.php +++ b/src/Git/MostRecentTagResolver.php @@ -1,55 +1,49 @@ processRunner = $processRunner; } - /** * Returns null, when there are no local tags yet */ - public function resolve(string $gitDirectory): ?string + public function resolve(string $gitDirectory) : ?string { $tagList = $this->parseTags($this->processRunner->run(self::COMMAND, $gitDirectory)); - /** @var string $theMostRecentTag */ - $theMostRecentTag = (string) array_pop($tagList); - + $theMostRecentTag = (string) \array_pop($tagList); if ($theMostRecentTag === '') { return null; } - return $theMostRecentTag; } - /** * @return string[] */ - private function parseTags(string $commandResult): array + private function parseTags(string $commandResult) : array { - $tags = trim($commandResult); - + $tags = \trim($commandResult); // Remove all "\r" chars in case the CLI env like the Windows OS. // Otherwise (ConEmu, git bash, mingw cli, e.g.), leave as is. - $normalizedTags = str_replace("\r", '', $tags); - - return explode("\n", $normalizedTags); + $normalizedTags = \str_replace("\r", '', $tags); + return \explode("\n", $normalizedTags); } } diff --git a/src/Kernel/MonorepoBuilderKernel.php b/src/Kernel/MonorepoBuilderKernel.php index f32329bbb8..b162375930 100644 --- a/src/Kernel/MonorepoBuilderKernel.php +++ b/src/Kernel/MonorepoBuilderKernel.php @@ -1,28 +1,24 @@ create($configFiles, $compilerPasses, []); } } diff --git a/src/Package/PackageNamesProvider.php b/src/Package/PackageNamesProvider.php index 30dc99ced3..321f17c1a1 100644 --- a/src/Package/PackageNamesProvider.php +++ b/src/Package/PackageNamesProvider.php @@ -1,35 +1,38 @@ composerJsonProvider = $composerJsonProvider; + $this->jsonFileManager = $jsonFileManager; } - /** * @return string[] */ - public function provide(): array + public function provide() : array { if ($this->names !== []) { return $this->names; } - $packagesFileInfos = $this->composerJsonProvider->getPackagesComposerFileInfos(); foreach ($packagesFileInfos as $packageFileInfo) { $name = $this->extractNameFromFileInfo($packageFileInfo); @@ -37,14 +40,11 @@ public function provide(): array $this->names[] = $name; } } - return $this->names; } - - private function extractNameFromFileInfo(SmartFileInfo $smartFileInfo): ?string + private function extractNameFromFileInfo(SmartFileInfo $smartFileInfo) : ?string { $json = $this->jsonFileManager->loadFromFileInfo($smartFileInfo); - return $json['name'] ?? null; } } diff --git a/src/Utils/RelativeFilePathHelper.php b/src/Utils/RelativeFilePathHelper.php index 6a87d3c27b..5413a91689 100644 --- a/src/Utils/RelativeFilePathHelper.php +++ b/src/Utils/RelativeFilePathHelper.php @@ -1,14 +1,12 @@ makePathRelative((string) \realpath($filePath), \getcwd()); diff --git a/src/Utils/VersionUtils.php b/src/Utils/VersionUtils.php index c1a25f60cd..f282503640 100644 --- a/src/Utils/VersionUtils.php +++ b/src/Utils/VersionUtils.php @@ -1,79 +1,71 @@ packageAliasFormat = $parameterProvider->provideStringParameter(Option::PACKAGE_ALIAS_FORMAT); } - - public function getNextAliasFormat(Version | string $version): string + /** + * @param \PharIo\Version\Version|string $version + */ + public function getNextAliasFormat($version) : string { $version = $this->normalizeVersion($version); - /** @var Version $minor */ $minor = $this->getNextMinorNumber($version); - - return str_replace( - ['', ''], - [$version->getMajor()->getValue(), $minor], - $this->packageAliasFormat - ); + return \str_replace(['', ''], [$version->getMajor()->getValue(), $minor], $this->packageAliasFormat); } - - public function getRequiredNextFormat(Version | string $version): string + /** + * @param \PharIo\Version\Version|string $version + */ + public function getRequiredNextFormat($version) : string { $version = $this->normalizeVersion($version); $minor = $this->getNextMinorNumber($version); - return '^' . $version->getMajor()->getValue() . '.' . $minor; } - - public function getRequiredFormat(Version | string $version): string + /** + * @param \PharIo\Version\Version|string $version + */ + public function getRequiredFormat($version) : string { $version = $this->normalizeVersion($version); - $requireVersion = '^' . $version->getMajor()->getValue() . '.' . $version->getMinor()->getValue(); - - $value = $version->getPatch() - ->getValue(); + $value = $version->getPatch()->getValue(); if ($value > 0) { $requireVersion .= '.' . $value; } - return $requireVersion; } - - private function normalizeVersion(Version | string $version): Version + /** + * @param \PharIo\Version\Version|string $version + */ + private function normalizeVersion($version) : Version { - if (is_string($version)) { + if (\is_string($version)) { return new Version($version); } - return $version; } - - private function getNextMinorNumber(Version $version): int + private function getNextMinorNumber(Version $version) : int { if ($version->hasPreReleaseSuffix()) { - return (int) $version->getMinor() - ->getValue(); + return (int) $version->getMinor()->getValue(); } - - return $version->getMinor() - ->getValue() + 1; + return $version->getMinor()->getValue() + 1; } } diff --git a/src/Validator/ConflictingPackageVersionsReporter.php b/src/Validator/ConflictingPackageVersionsReporter.php index c2c0ac7d35..e92971ba00 100644 --- a/src/Validator/ConflictingPackageVersionsReporter.php +++ b/src/Validator/ConflictingPackageVersionsReporter.php @@ -1,47 +1,43 @@ symfonyStyle = $symfonyStyle; } - /** * @param array> $conflictingPackages */ - public function report(array $conflictingPackages): void + public function report(array $conflictingPackages) : void { foreach ($conflictingPackages as $packageName => $filesToVersions) { - $message = sprintf('Package "%s" has incompatible version', $packageName); + $message = \sprintf('Package "%s" has incompatible version', $packageName); $this->symfonyStyle->title($message); - $tableRows = $this->createTableRows($filesToVersions); $this->symfonyStyle->table(['File', 'Version'], $tableRows); } - $this->symfonyStyle->error('Found conflicting package versions, fix them first.'); } - /** * @param array $filesToVersions * @return array */ - private function createTableRows(array $filesToVersions): array + private function createTableRows(array $filesToVersions) : array { $tableRows = []; - foreach ($filesToVersions as $file => $version) { $tableRows[] = [RelativeFilePathHelper::resolveFromCwd($file), $version]; } - return $tableRows; } } diff --git a/src/Validator/SourcesPresenceValidator.php b/src/Validator/SourcesPresenceValidator.php index e672d9b440..eceab4a599 100644 --- a/src/Validator/SourcesPresenceValidator.php +++ b/src/Validator/SourcesPresenceValidator.php @@ -1,48 +1,41 @@ composerJsonProvider = $composerJsonProvider; $this->packageDirectories = $parameterProvider->provideArrayParameter(Option::PACKAGE_DIRECTORIES); } - - public function validatePackageComposerJsons(): void + public function validatePackageComposerJsons() : void { $composerPackageFiles = $this->composerJsonProvider->getPackagesComposerFileInfos(); if ($composerPackageFiles !== []) { return; } - - throw new InvalidComposerJsonSetupException(sprintf( - 'No package "composer.json" was found in package directories: "%s". Add "composer.json" or configure another directory in "parameters > package_directories"', - implode('", "', $this->packageDirectories) - )); + throw new InvalidComposerJsonSetupException(\sprintf('No package "composer.json" was found in package directories: "%s". Add "composer.json" or configure another directory in "parameters > package_directories"', \implode('", "', $this->packageDirectories))); } - - public function validateRootComposerJsonName(): void + public function validateRootComposerJsonName() : void { $rootComposerJson = $this->composerJsonProvider->getRootComposerJson(); if ($rootComposerJson->getName() !== null) { return; } - throw new InvalidComposerJsonSetupException('Complete "name" to your root "composer.json".'); } } diff --git a/src/ValueObject/File.php b/src/ValueObject/File.php index 73b0250f56..320257accf 100644 --- a/src/ValueObject/File.php +++ b/src/ValueObject/File.php @@ -1,7 +1,6 @@ jsonFileManager = $jsonFileManager; + $this->modifyingComposerJsonProvider = $modifyingComposerJsonProvider; + $this->parameterProvider = $parameterProvider; } - /** * @param SmartFileInfo[] $smartFileInfos * @return string[][] */ - public function findConflictingPackageVersionsInFileInfos(array $smartFileInfos): array + public function findConflictingPackageVersionsInFileInfos(array $smartFileInfos) : array { $packageVersionsPerFile = []; $packageVersionsPerFile = $this->appendAppendingComposerJson($packageVersionsPerFile); - foreach ($smartFileInfos as $smartFileInfo) { $json = $this->jsonFileManager->loadFromFileInfo($smartFileInfo); - foreach (self::SECTIONS as $section) { - if (! isset($json[$section])) { + if (!isset($json[$section])) { continue; } - foreach ($json[$section] as $packageName => $packageVersion) { $filePath = $smartFileInfo->getRelativeFilePathFromCwd(); $packageVersionsPerFile[$packageName][$filePath] = $packageVersion; } } } - return $this->filterConflictingPackageVersionsPerFile($packageVersionsPerFile); } - /** * @param mixed[] $packageVersionsPerFile * @return mixed[] */ - private function appendAppendingComposerJson(array $packageVersionsPerFile): array + private function appendAppendingComposerJson(array $packageVersionsPerFile) : array { $appendingComposerJson = $this->modifyingComposerJsonProvider->getAppendingComposerJson(); - if (! $appendingComposerJson instanceof ComposerJson) { + if (!$appendingComposerJson instanceof ComposerJson) { return $packageVersionsPerFile; } - $requires = $appendingComposerJson->getRequire(); foreach ($requires as $packageName => $packageVersion) { $packageVersionsPerFile[$packageName][File::CONFIG] = $packageVersion; } - $requiredevs = $appendingComposerJson->getRequireDev(); foreach ($requiredevs as $packageName => $packageVersion) { $packageVersionsPerFile[$packageName][File::CONFIG] = $packageVersion; } - return $packageVersionsPerFile; } - /** * @param array> $packageVersionsPerFile * @return array> */ - private function filterConflictingPackageVersionsPerFile(array $packageVersionsPerFile): array + private function filterConflictingPackageVersionsPerFile(array $packageVersionsPerFile) : array { $conflictingPackageVersionsPerFile = []; foreach ($packageVersionsPerFile as $packageName => $filesToVersions) { - $uniqueVersions = array_unique($filesToVersions); - if (count($uniqueVersions) <= 1) { + $uniqueVersions = \array_unique($filesToVersions); + if (\count($uniqueVersions) <= 1) { continue; } - if ($this->isPackageAllowedVersionConflict($packageName)) { continue; } - // sort by versions to make more readable - asort($filesToVersions); - + \asort($filesToVersions); $conflictingPackageVersionsPerFile[$packageName] = $filesToVersions; } - return $conflictingPackageVersionsPerFile; } - - private function isPackageAllowedVersionConflict(string $packageName): bool + private function isPackageAllowedVersionConflict(string $packageName) : bool { - $excludePackageVersionConflicts = $this->parameterProvider->provideArrayParameter( - Option::EXCLUDE_PACKAGE_VERSION_CONFLICTS - ); - - return in_array($packageName, $excludePackageVersionConflicts, true); + $excludePackageVersionConflicts = $this->parameterProvider->provideArrayParameter(Option::EXCLUDE_PACKAGE_VERSION_CONFLICTS); + return \in_array($packageName, $excludePackageVersionConflicts, \true); } } diff --git a/tests/ConflictingUpdater/Fixture/expected_composer.test b/tests/ConflictingUpdater/Fixture/expected_composer.test deleted file mode 100644 index f306703934..0000000000 --- a/tests/ConflictingUpdater/Fixture/expected_composer.test +++ /dev/null @@ -1,8 +0,0 @@ -{ - "require": { - "symplify/package-builder": "^9.2" - }, - "conflict": { - "symplify/another-package": "<9.2.0" - } -} diff --git a/tests/ConflictingUpdater/Fixture/input_composer_backup.test b/tests/ConflictingUpdater/Fixture/input_composer_backup.test deleted file mode 100644 index 21111b7ee5..0000000000 --- a/tests/ConflictingUpdater/Fixture/input_composer_backup.test +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "symplify/package-builder": "^9.2" - } -} diff --git a/tests/DependencyUpdater/DependencyUpdaterTest.php b/tests/DependencyUpdater/DependencyUpdaterTest.php deleted file mode 100644 index 5202ae0c62..0000000000 --- a/tests/DependencyUpdater/DependencyUpdaterTest.php +++ /dev/null @@ -1,40 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - - $this->dependencyUpdater = $this->getService(DependencyUpdater::class); - $this->smartFileSystem = $this->getService(SmartFileSystem::class); - } - - protected function tearDown(): void - { - $this->smartFileSystem->copy(__DIR__ . '/Source/backup-first.json', __DIR__ . '/Source/first.json'); - } - - public function testUpdateFileInfosWithVendorAndVersion(): void - { - $fileInfos = [new SmartFileInfo(__DIR__ . '/Source/first.json')]; - - $this->dependencyUpdater->updateFileInfosWithVendorAndVersion($fileInfos, 'ex', '5.0-dev'); - - $this->assertFileEquals(__DIR__ . '/Source/expected-first.json', __DIR__ . '/Source/first.json'); - } -} diff --git a/tests/DependencyUpdater/Source/backup-first.json b/tests/DependencyUpdater/Source/backup-first.json deleted file mode 100644 index 8167647107..0000000000 --- a/tests/DependencyUpdater/Source/backup-first.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "require": { - "ex/package-one": "4.0-dev", - "ex/package-two": "4.0-dev", - "example/package-one": "4.0-dev" - }, - "require-dev": { - "ex/package-one": "4.0-dev", - "ex/package-two": "4.0-dev", - "example/package-one": "4.0-dev" - } -} diff --git a/tests/DependencyUpdater/Source/expected-first.json b/tests/DependencyUpdater/Source/expected-first.json deleted file mode 100644 index 3fe26da0e7..0000000000 --- a/tests/DependencyUpdater/Source/expected-first.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "require": { - "ex/package-one": "5.0-dev", - "ex/package-two": "5.0-dev", - "example/package-one": "4.0-dev" - }, - "require-dev": { - "ex/package-one": "5.0-dev", - "ex/package-two": "5.0-dev", - "example/package-one": "4.0-dev" - } -} diff --git a/tests/DependencyUpdater/Source/first.json b/tests/DependencyUpdater/Source/first.json deleted file mode 100644 index 3fe26da0e7..0000000000 --- a/tests/DependencyUpdater/Source/first.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "require": { - "ex/package-one": "5.0-dev", - "ex/package-two": "5.0-dev", - "example/package-one": "4.0-dev" - }, - "require-dev": { - "ex/package-one": "5.0-dev", - "ex/package-two": "5.0-dev", - "example/package-one": "4.0-dev" - } -} diff --git a/tests/DevMasterAliasUpdater/DevMasterAliasUpdaterTest.php b/tests/DevMasterAliasUpdater/DevMasterAliasUpdaterTest.php deleted file mode 100644 index 5e3c22b0da..0000000000 --- a/tests/DevMasterAliasUpdater/DevMasterAliasUpdaterTest.php +++ /dev/null @@ -1,40 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - - $this->devMasterAliasUpdater = $this->getService(DevMasterAliasUpdater::class); - $this->smartFileSystem = $this->getService(SmartFileSystem::class); - } - - protected function tearDown(): void - { - $this->smartFileSystem->copy(__DIR__ . '/Source/backup-first.json', __DIR__ . '/Source/first.json'); - } - - public function test(): void - { - $fileInfos = [new SmartFileInfo(__DIR__ . '/Source/first.json')]; - - $this->devMasterAliasUpdater->updateFileInfosWithAlias($fileInfos, '4.5-dev'); - - $this->assertFileEquals(__DIR__ . '/Source/expected-first.json', __DIR__ . '/Source/first.json'); - } -} diff --git a/tests/DevMasterAliasUpdater/Source/backup-first.json b/tests/DevMasterAliasUpdater/Source/backup-first.json deleted file mode 100644 index 4f02dd275b..0000000000 --- a/tests/DevMasterAliasUpdater/Source/backup-first.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - } -} diff --git a/tests/DevMasterAliasUpdater/Source/expected-first.json b/tests/DevMasterAliasUpdater/Source/expected-first.json deleted file mode 100644 index 70cf34d202..0000000000 --- a/tests/DevMasterAliasUpdater/Source/expected-first.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extra": { - "branch-alias": { - "dev-master": "4.5-dev" - } - } -} diff --git a/tests/DevMasterAliasUpdater/Source/first.json b/tests/DevMasterAliasUpdater/Source/first.json deleted file mode 100644 index 70cf34d202..0000000000 --- a/tests/DevMasterAliasUpdater/Source/first.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extra": { - "branch-alias": { - "dev-master": "4.5-dev" - } - } -} diff --git a/tests/FileSystem/JsonFileManager/JsonFileManagerTest.php b/tests/FileSystem/JsonFileManager/JsonFileManagerTest.php deleted file mode 100644 index 807b916c7f..0000000000 --- a/tests/FileSystem/JsonFileManager/JsonFileManagerTest.php +++ /dev/null @@ -1,101 +0,0 @@ - - */ - private const CREATED_JSON = [ - 'key' => 'value', - ]; - - /** - * @var array - */ - private const UPDATED_JSON = [ - 'key' => 'updatedValue', - ]; - - private JsonFileManager $jsonFileManager; - - private SmartFileSystem $smartFileSystem; - - protected function setUp(): void - { - $this->bootKernelWithConfigs(MonorepoBuilderKernel::class, [ - __DIR__ . '/config/inlined_section_config.php', - ]); - - $this->jsonFileManager = $this->getService(JsonFileManager::class); - $this->smartFileSystem = $this->getService(SmartFileSystem::class); - } - - protected function tearDown(): void - { - $this->smartFileSystem->remove(__DIR__ . '/Source/second.json'); - $this->smartFileSystem->remove(__DIR__ . '/Source/third.json'); - } - - public function testLoad(): void - { - $expectedJson = [ - 'key' => 'value', - ]; - - $loadedJson = $this->jsonFileManager->loadFromFilePath(__DIR__ . '/Source/first.json'); - $this->assertSame($expectedJson, $loadedJson); - - $loadedJsonFromFileInfo = $this->jsonFileManager->loadFromFileInfo( - new SmartFileInfo(__DIR__ . '/Source/first.json') - ); - $this->assertSame($expectedJson, $loadedJsonFromFileInfo); - } - - public function testPrint(): void - { - $this->jsonFileManager->printJsonToFileInfo( - self::CREATED_JSON, - new SmartFileInfo(__DIR__ . '/Source/dynamic.json') - ); - $loadedJsonFromFileInfo = $this->jsonFileManager->loadFromFileInfo( - new SmartFileInfo(__DIR__ . '/Source/dynamic.json') - ); - $this->assertSame(self::CREATED_JSON, $loadedJsonFromFileInfo); - $this->jsonFileManager->printJsonToFileInfo( - self::UPDATED_JSON, - new SmartFileInfo(__DIR__ . '/Source/dynamic.json') - ); - $loadedJsonFromFileInfo = $this->jsonFileManager->loadFromFileInfo( - new SmartFileInfo(__DIR__ . '/Source/dynamic.json') - ); - $this->assertSame(self::UPDATED_JSON, $loadedJsonFromFileInfo); - } - - public function testEncodeArrayToString(): void - { - $jsonContent = $this->jsonFileManager->encodeJsonToFileContent([ - 'another_key' => 'another_value', - ]); - $this->assertJsonStringEqualsJsonFile(__DIR__ . '/Source/expected-second.json', $jsonContent); - } - - public function testSaveWithInlinedSections(): void - { - $fileContent = $this->jsonFileManager->encodeJsonToFileContent([ - 'inline_section' => [1, 2, 3], - 'normal_section' => [1, 2, 3], - ]); - - $this->assertJsonStringEqualsJsonFile(__DIR__ . '/Source/expected-inlined.json', $fileContent); - } -} diff --git a/tests/FileSystem/JsonFileManager/Source/dynamic.json b/tests/FileSystem/JsonFileManager/Source/dynamic.json deleted file mode 100644 index 39ad2e037a..0000000000 --- a/tests/FileSystem/JsonFileManager/Source/dynamic.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "key": "updatedValue" -} diff --git a/tests/FileSystem/JsonFileManager/Source/expected-inlined.json b/tests/FileSystem/JsonFileManager/Source/expected-inlined.json deleted file mode 100644 index 42feee7b3f..0000000000 --- a/tests/FileSystem/JsonFileManager/Source/expected-inlined.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "inline_section": [1, 2, 3], - "normal_section": [ - 1, - 2, - 3 - ] -} diff --git a/tests/FileSystem/JsonFileManager/Source/expected-second.json b/tests/FileSystem/JsonFileManager/Source/expected-second.json deleted file mode 100644 index 9a861e9f73..0000000000 --- a/tests/FileSystem/JsonFileManager/Source/expected-second.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "another_key": "another_value" -} diff --git a/tests/FileSystem/JsonFileManager/Source/first.json b/tests/FileSystem/JsonFileManager/Source/first.json deleted file mode 100644 index 21da3b262a..0000000000 --- a/tests/FileSystem/JsonFileManager/Source/first.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "key": "value" -} diff --git a/tests/FileSystem/JsonFileManager/config/inlined_section_config.php b/tests/FileSystem/JsonFileManager/config/inlined_section_config.php deleted file mode 100644 index 3b4b93b1a1..0000000000 --- a/tests/FileSystem/JsonFileManager/config/inlined_section_config.php +++ /dev/null @@ -1,11 +0,0 @@ -parameters(); - $parameters->set(Option::INLINE_SECTIONS, ['inline_section']); -}; diff --git a/tests/Finder/PackageComposerFinder/PackageComposerFinderTest.php b/tests/Finder/PackageComposerFinder/PackageComposerFinderTest.php deleted file mode 100644 index da3ba380f5..0000000000 --- a/tests/Finder/PackageComposerFinder/PackageComposerFinderTest.php +++ /dev/null @@ -1,25 +0,0 @@ -bootKernelWithConfigs(MonorepoBuilderKernel::class, [__DIR__ . '/Source/source_config.php']); - $this->packageComposerFinder = $this->getService(PackageComposerFinder::class); - } - - public function test(): void - { - $this->assertCount(2, $this->packageComposerFinder->getPackageComposerFiles()); - } -} diff --git a/tests/Finder/PackageComposerFinder/Source/First/ExcludeThis/composer.json b/tests/Finder/PackageComposerFinder/Source/First/ExcludeThis/composer.json deleted file mode 100644 index 1934c075f5..0000000000 --- a/tests/Finder/PackageComposerFinder/Source/First/ExcludeThis/composer.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "first/excludePackage" -} diff --git a/tests/Finder/PackageComposerFinder/Source/First/composer.json b/tests/Finder/PackageComposerFinder/Source/First/composer.json deleted file mode 100644 index f372441a1e..0000000000 --- a/tests/Finder/PackageComposerFinder/Source/First/composer.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "first/package" -} diff --git a/tests/Finder/PackageComposerFinder/Source/Second/composer.json b/tests/Finder/PackageComposerFinder/Source/Second/composer.json deleted file mode 100644 index fc72d607e2..0000000000 --- a/tests/Finder/PackageComposerFinder/Source/Second/composer.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "second/package" -} diff --git a/tests/Finder/PackageComposerFinder/Source/source_config.php b/tests/Finder/PackageComposerFinder/Source/source_config.php deleted file mode 100644 index 70501f55c2..0000000000 --- a/tests/Finder/PackageComposerFinder/Source/source_config.php +++ /dev/null @@ -1,17 +0,0 @@ -parameters(); - $parameters->set(Option::PACKAGE_DIRECTORIES, [ - __DIR__ . '/../Source', - ]); - - $parameters->set(Option::PACKAGE_DIRECTORIES_EXCLUDES, [ - 'ExcludeThis', - ]); -}; diff --git a/tests/InterdependencyUpdater/InterdependencyUpdaterTest.php b/tests/InterdependencyUpdater/InterdependencyUpdaterTest.php deleted file mode 100644 index 2f9e5fb003..0000000000 --- a/tests/InterdependencyUpdater/InterdependencyUpdaterTest.php +++ /dev/null @@ -1,53 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - - $this->dependencyUpdater = $this->getService(DependencyUpdater::class); - $this->smartFileSystem = $this->getService(SmartFileSystem::class); - } - - protected function tearDown(): void - { - $this->smartFileSystem->copy(__DIR__ . '/Source/backup-first.json', __DIR__ . '/Source/first.json', true); - } - - public function testVendor(): void - { - $this->dependencyUpdater->updateFileInfosWithVendorAndVersion( - [new SmartFileInfo(__DIR__ . '/Source/first.json')], - 'symplify', - '^5.0' - ); - - $this->assertFileEquals(__DIR__ . '/Source/expected-first-vendor.json', __DIR__ . '/Source/first.json'); - } - - public function testPackages(): void - { - $this->dependencyUpdater->updateFileInfosWithPackagesAndVersion( - [new SmartFileInfo(__DIR__ . '/Source/first.json')], - ['symplify/coding-standard'], - '^6.0' - ); - - $this->assertFileEquals(__DIR__ . '/Source/expected-first-packages.json', __DIR__ . '/Source/first.json'); - } -} diff --git a/tests/InterdependencyUpdater/Source/backup-first.json b/tests/InterdependencyUpdater/Source/backup-first.json deleted file mode 100644 index 2b57f4a800..0000000000 --- a/tests/InterdependencyUpdater/Source/backup-first.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "require": { - "symplify/coding-standard": "^4.0", - "symplify/monorepo-builder": "^4.0" - } -} diff --git a/tests/InterdependencyUpdater/Source/expected-first-packages.json b/tests/InterdependencyUpdater/Source/expected-first-packages.json deleted file mode 100644 index 7c8d0288e7..0000000000 --- a/tests/InterdependencyUpdater/Source/expected-first-packages.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "require": { - "symplify/coding-standard": "^6.0", - "symplify/monorepo-builder": "^4.0" - } -} diff --git a/tests/InterdependencyUpdater/Source/expected-first-vendor.json b/tests/InterdependencyUpdater/Source/expected-first-vendor.json deleted file mode 100644 index f3bfb33a96..0000000000 --- a/tests/InterdependencyUpdater/Source/expected-first-vendor.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "require": { - "symplify/coding-standard": "^5.0", - "symplify/monorepo-builder": "^5.0" - } -} diff --git a/tests/InterdependencyUpdater/Source/first.json b/tests/InterdependencyUpdater/Source/first.json deleted file mode 100644 index 2b57f4a800..0000000000 --- a/tests/InterdependencyUpdater/Source/first.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "require": { - "symplify/coding-standard": "^4.0", - "symplify/monorepo-builder": "^4.0" - } -} diff --git a/tests/Utils/VersionUtilsTest.php b/tests/Utils/VersionUtilsTest.php deleted file mode 100644 index 36f8cefb00..0000000000 --- a/tests/Utils/VersionUtilsTest.php +++ /dev/null @@ -1,67 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - $this->versionUtils = $this->getService(VersionUtils::class); - } - - #[DataProvider('provideDataAlias')] - public function testAlias(string $currentVersion, string $expectedVersion): void - { - $nextAliasVersion = $this->versionUtils->getNextAliasFormat($currentVersion); - $this->assertSame($expectedVersion, $nextAliasVersion); - } - - public static function provideDataAlias(): Iterator - { - yield ['v4.0.0', '4.1-dev']; - yield ['4.0.0', '4.1-dev']; - yield ['4.5.0', '4.6-dev']; - yield ['v8.0-beta', '8.0-dev']; - } - - #[DataProvider('provideDataForRequiredNextVersion')] - public function testRequiredNextVersion(string $currentVersion, string $expectedVersion): void - { - $nextRequiredVersion = $this->versionUtils->getRequiredNextFormat($currentVersion); - $this->assertSame($expectedVersion, $nextRequiredVersion); - } - - public static function provideDataForRequiredNextVersion(): Iterator - { - yield ['v4.0.0', '^4.1']; - yield ['4.0.0', '^4.1']; - yield ['8.0-beta', '^8.0']; - } - - #[DataProvider('provideDataForRequiredVersion')] - public function testRequiredVersion(string $currentVersion, string $expectedVersion): void - { - $requiredVersion = $this->versionUtils->getRequiredFormat($currentVersion); - $this->assertSame($expectedVersion, $requiredVersion); - } - - /** - * @return Iterator - */ - public static function provideDataForRequiredVersion(): Iterator - { - yield ['v4.0.0', '^4.0']; - yield ['4.0.0', '^4.0']; - } -} diff --git a/tests/VersionValidator/Source/first.json b/tests/VersionValidator/Source/first.json deleted file mode 100644 index e5378e7eee..0000000000 --- a/tests/VersionValidator/Source/first.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "some/package": "^1.0" - } -} \ No newline at end of file diff --git a/tests/VersionValidator/Source/second.json b/tests/VersionValidator/Source/second.json deleted file mode 100644 index 3ec3ec4226..0000000000 --- a/tests/VersionValidator/Source/second.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "some/package": "^2.0" - } -} \ No newline at end of file diff --git a/tests/VersionValidator/VersionValidatorTest.php b/tests/VersionValidator/VersionValidatorTest.php deleted file mode 100644 index cdedabe8e9..0000000000 --- a/tests/VersionValidator/VersionValidatorTest.php +++ /dev/null @@ -1,52 +0,0 @@ -bootKernel(MonorepoBuilderKernel::class); - - $this->versionValidator = $this->getService(VersionValidator::class); - $this->finderSanitizer = $this->getService(FinderSanitizer::class); - } - - public function test(): void - { - $finder = Finder::create() - ->name('*.json') - ->in(__DIR__ . '/Source'); - - $fileInfos = $this->finderSanitizer->sanitize($finder); - - $conflictingPackageVersionsPerFile = $this->versionValidator->findConflictingPackageVersionsInFileInfos( - $fileInfos - ); - - $this->assertArrayHasKey('some/package', $conflictingPackageVersionsPerFile); - - $firstJson = new SmartFileInfo(__DIR__ . DIRECTORY_SEPARATOR . 'Source' . DIRECTORY_SEPARATOR . 'first.json'); - $secondJson = new SmartFileInfo(__DIR__ . DIRECTORY_SEPARATOR . 'Source' . DIRECTORY_SEPARATOR . 'second.json'); - - $expectedConflictingVersionsPerFile = [ - $firstJson->getRelativeFilePathFromCwd() => '^1.0', - $secondJson->getRelativeFilePathFromCwd() => '^2.0', - ]; - - $this->assertSame($expectedConflictingVersionsPerFile, $conflictingPackageVersionsPerFile['some/package']); - } -} diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000000..3094fc798b --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,25 @@ +realpath = \realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = \fopen($this->realpath, $mode); + $this->position = 0; + return (bool) $this->handle; + } + public function stream_read($count) + { + $data = \fread($this->handle, $count); + if ($this->position === 0) { + $data = \preg_replace('{^#!.*\\r?\\n}', '', $data); + } + $this->position += \strlen($data); + return $data; + } + public function stream_cast($castAs) + { + return $this->handle; + } + public function stream_close() + { + \fclose($this->handle); + } + public function stream_lock($operation) + { + return $operation ? \flock($this->handle, $operation) : \true; + } + public function stream_seek($offset, $whence) + { + if (0 === \fseek($this->handle, $offset, $whence)) { + $this->position = \ftell($this->handle); + return \true; + } + return \false; + } + public function stream_tell() + { + return $this->position; + } + public function stream_eof() + { + return \feof($this->handle); + } + public function stream_stat() + { + return array(); + } + public function stream_set_option($option, $arg1, $arg2) + { + return \true; + } + public function url_stat($path, $flags) + { + $path = \substr($path, 17); + if (\file_exists($path)) { + return \stat($path); + } + return \false; + } + } + } + if (\function_exists('stream_get_wrappers') && \in_array('phpvfscomposer', \stream_get_wrappers(), \true) || \function_exists('stream_wrapper_register') && \stream_wrapper_register('phpvfscomposer', 'MonorepoBuilderPrefix202310\\Composer\\BinProxyWrapper')) { + return include "phpvfscomposer://" . __DIR__ . '/..' . '/symplify/easy-testing/bin/easy-testing'; + } +} +return include __DIR__ . '/..' . '/symplify/easy-testing/bin/easy-testing'; diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php new file mode 100644 index 0000000000..7824d8f7ea --- /dev/null +++ b/vendor/composer/ClassLoader.php @@ -0,0 +1,579 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000000..85e0594e8a --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,313 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Composer; + +use MonorepoBuilderPrefix202310\Composer\Autoload\ClassLoader; +use MonorepoBuilderPrefix202310\Composer\Semver\VersionParser; +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + /** + * @var bool|null + */ + private static $canGetVendors; + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = \array_keys($installed['versions']); + } + if (1 === \count($packages)) { + return $packages[0]; + } + return \array_keys(\array_flip(\call_user_func_array('array_merge', $packages))); + } + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + return $packagesByType; + } + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = \true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === \false; + } + } + return \false; + } + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + return $provided->matches($constraint); + } + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (\array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = \array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (\array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = \array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (\array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = \array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + return \implode(' || ', $ranges); + } + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + return $installed['versions'][$packageName]['version']; + } + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + return $installed['versions'][$packageName]['pretty_version']; + } + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + return $installed['versions'][$packageName]['reference']; + } + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + return $installed[0]['root']; + } + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @\trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', \E_USER_DEPRECATED); + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (\substr(__DIR__, -8, 1) !== 'C') { + self::$installed = (include __DIR__ . '/installed.php'); + } else { + self::$installed = array(); + } + } + return self::$installed; + } + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = \method_exists('MonorepoBuilderPrefix202310\\Composer\\Autoload\\ClassLoader', 'getRegisteredLoaders'); + } + $installed = array(); + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (\is_file($vendorDir . '/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = (require $vendorDir . '/composer/installed.php'); + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && \strtr($vendorDir . '/composer', '\\', '/') === \strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[\count($installed) - 1]; + } + } + } + } + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (\substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = (require __DIR__ . '/installed.php'); + self::$installed = $required; + } else { + self::$installed = array(); + } + } + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + return $installed; + } +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 0000000000..f27399a042 --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000000..432bc9d3b4 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,709 @@ + $vendorDir . '/composer/InstalledVersions.php', + 'MonorepoBuilderPrefix202310\\Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\HtmlStringable' => $vendorDir . '/nette/utils/src/HtmlStringable.php', + 'MonorepoBuilderPrefix202310\\Nette\\IOException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php', + 'MonorepoBuilderPrefix202310\\Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php', + 'MonorepoBuilderPrefix202310\\Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/compatibility.php', + 'MonorepoBuilderPrefix202310\\Nette\\Localization\\Translator' => $vendorDir . '/nette/utils/src/Translator.php', + 'MonorepoBuilderPrefix202310\\Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\SmartObject' => $vendorDir . '/nette/utils/src/SmartObject.php', + 'MonorepoBuilderPrefix202310\\Nette\\StaticClass' => $vendorDir . '/nette/utils/src/StaticClass.php', + 'MonorepoBuilderPrefix202310\\Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Floats' => $vendorDir . '/nette/utils/src/Utils/Floats.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Helpers' => $vendorDir . '/nette/utils/src/Utils/Helpers.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/compatibility.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ObjectMixin' => $vendorDir . '/nette/utils/src/Utils/ObjectMixin.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Type' => $vendorDir . '/nette/utils/src/Utils/Type.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php', + 'MonorepoBuilderPrefix202310\\Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php', + 'MonorepoBuilderPrefix202310\\Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\ConfigurationException' => $vendorDir . '/sebastian/diff/src/Exception/ConfigurationException.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ClassBuilder' => $vendorDir . '/symfony/config/Builder/ClassBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ConfigBuilderGenerator' => $vendorDir . '/symfony/config/Builder/ConfigBuilderGenerator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ConfigBuilderGeneratorInterface' => $vendorDir . '/symfony/config/Builder/ConfigBuilderGeneratorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ConfigBuilderInterface' => $vendorDir . '/symfony/config/Builder/ConfigBuilderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\Method' => $vendorDir . '/symfony/config/Builder/Method.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\Property' => $vendorDir . '/symfony/config/Builder/Property.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCache' => $vendorDir . '/symfony/config/ConfigCache.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCacheFactory' => $vendorDir . '/symfony/config/ConfigCacheFactory.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCacheFactoryInterface' => $vendorDir . '/symfony/config/ConfigCacheFactoryInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCacheInterface' => $vendorDir . '/symfony/config/ConfigCacheInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ArrayNode' => $vendorDir . '/symfony/config/Definition/ArrayNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\BaseNode' => $vendorDir . '/symfony/config/Definition/BaseNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\BooleanNode' => $vendorDir . '/symfony/config/Definition/BooleanNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/ArrayNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\BooleanNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/BooleanNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\BuilderAwareInterface' => $vendorDir . '/symfony/config/Definition/Builder/BuilderAwareInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\EnumNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/EnumNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ExprBuilder' => $vendorDir . '/symfony/config/Definition/Builder/ExprBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\FloatNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/FloatNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\IntegerNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/IntegerNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\MergeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/MergeBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NodeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/NodeBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/NodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface' => $vendorDir . '/symfony/config/Definition/Builder/NodeParentInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NormalizationBuilder' => $vendorDir . '/symfony/config/Definition/Builder/NormalizationBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NumericNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/NumericNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ParentNodeDefinitionInterface' => $vendorDir . '/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ScalarNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/ScalarNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/TreeBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ValidationBuilder' => $vendorDir . '/symfony/config/Definition/Builder/ValidationBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\VariableNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/VariableNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ConfigurableInterface' => $vendorDir . '/symfony/config/Definition/ConfigurableInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Configuration' => $vendorDir . '/symfony/config/Definition/Configuration.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ConfigurationInterface' => $vendorDir . '/symfony/config/Definition/ConfigurationInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Configurator\\DefinitionConfigurator' => $vendorDir . '/symfony/config/Definition/Configurator/DefinitionConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Dumper\\XmlReferenceDumper' => $vendorDir . '/symfony/config/Definition/Dumper/XmlReferenceDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Dumper\\YamlReferenceDumper' => $vendorDir . '/symfony/config/Definition/Dumper/YamlReferenceDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\EnumNode' => $vendorDir . '/symfony/config/Definition/EnumNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\DuplicateKeyException' => $vendorDir . '/symfony/config/Definition/Exception/DuplicateKeyException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\Exception' => $vendorDir . '/symfony/config/Definition/Exception/Exception.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\ForbiddenOverwriteException' => $vendorDir . '/symfony/config/Definition/Exception/ForbiddenOverwriteException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\InvalidConfigurationException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidConfigurationException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\InvalidDefinitionException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidDefinitionException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\InvalidTypeException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidTypeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\UnsetKeyException' => $vendorDir . '/symfony/config/Definition/Exception/UnsetKeyException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\FloatNode' => $vendorDir . '/symfony/config/Definition/FloatNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\IntegerNode' => $vendorDir . '/symfony/config/Definition/IntegerNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Loader\\DefinitionFileLoader' => $vendorDir . '/symfony/config/Definition/Loader/DefinitionFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\NodeInterface' => $vendorDir . '/symfony/config/Definition/NodeInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\NumericNode' => $vendorDir . '/symfony/config/Definition/NumericNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Processor' => $vendorDir . '/symfony/config/Definition/Processor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\PrototypeNodeInterface' => $vendorDir . '/symfony/config/Definition/PrototypeNodeInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\PrototypedArrayNode' => $vendorDir . '/symfony/config/Definition/PrototypedArrayNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ScalarNode' => $vendorDir . '/symfony/config/Definition/ScalarNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\VariableNode' => $vendorDir . '/symfony/config/Definition/VariableNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Exception\\FileLoaderImportCircularReferenceException' => $vendorDir . '/symfony/config/Exception/FileLoaderImportCircularReferenceException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Exception\\FileLocatorFileNotFoundException' => $vendorDir . '/symfony/config/Exception/FileLocatorFileNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Exception\\LoaderLoadException' => $vendorDir . '/symfony/config/Exception/LoaderLoadException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\FileLocator' => $vendorDir . '/symfony/config/FileLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\FileLocatorInterface' => $vendorDir . '/symfony/config/FileLocatorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\DelegatingLoader' => $vendorDir . '/symfony/config/Loader/DelegatingLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\DirectoryAwareLoaderInterface' => $vendorDir . '/symfony/config/Loader/DirectoryAwareLoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\FileLoader' => $vendorDir . '/symfony/config/Loader/FileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/config/Loader/GlobFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\Loader' => $vendorDir . '/symfony/config/Loader/Loader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\LoaderInterface' => $vendorDir . '/symfony/config/Loader/LoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\LoaderResolver' => $vendorDir . '/symfony/config/Loader/LoaderResolver.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\LoaderResolverInterface' => $vendorDir . '/symfony/config/Loader/LoaderResolverInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\ParamConfigurator' => $vendorDir . '/symfony/config/Loader/ParamConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ResourceCheckerConfigCache' => $vendorDir . '/symfony/config/ResourceCheckerConfigCache.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ResourceCheckerConfigCacheFactory' => $vendorDir . '/symfony/config/ResourceCheckerConfigCacheFactory.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ResourceCheckerInterface' => $vendorDir . '/symfony/config/ResourceCheckerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ClassExistenceResource' => $vendorDir . '/symfony/config/Resource/ClassExistenceResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ComposerResource' => $vendorDir . '/symfony/config/Resource/ComposerResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\DirectoryResource' => $vendorDir . '/symfony/config/Resource/DirectoryResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\FileExistenceResource' => $vendorDir . '/symfony/config/Resource/FileExistenceResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\FileResource' => $vendorDir . '/symfony/config/Resource/FileResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\GlobResource' => $vendorDir . '/symfony/config/Resource/GlobResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ReflectionClassResource' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ResourceInterface' => $vendorDir . '/symfony/config/Resource/ResourceInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\SelfCheckingResourceChecker' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceChecker.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\SelfCheckingResourceInterface' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Util\\Exception\\InvalidXmlException' => $vendorDir . '/symfony/config/Util/Exception/InvalidXmlException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Util\\Exception\\XmlParsingException' => $vendorDir . '/symfony/config/Util/Exception/XmlParsingException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Util\\XmlUtils' => $vendorDir . '/symfony/config/Util/XmlUtils.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Attribute\\AsCommand' => $vendorDir . '/symfony/console/Attribute/AsCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CI\\GithubActionReporter' => $vendorDir . '/symfony/console/CI/GithubActionReporter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Color' => $vendorDir . '/symfony/console/Color.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => $vendorDir . '/symfony/console/CommandLoader/CommandLoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/ContainerCommandLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/FactoryCommandLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\CompleteCommand' => $vendorDir . '/symfony/console/Command/CompleteCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\DumpCompletionCommand' => $vendorDir . '/symfony/console/Command/DumpCompletionCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\LazyCommand' => $vendorDir . '/symfony/console/Command/LazyCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\LockableTrait' => $vendorDir . '/symfony/console/Command/LockableTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\SignalableCommandInterface' => $vendorDir . '/symfony/console/Command/SignalableCommandInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\CompletionInput' => $vendorDir . '/symfony/console/Completion/CompletionInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\CompletionSuggestions' => $vendorDir . '/symfony/console/Completion/CompletionSuggestions.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\BashCompletionOutput' => $vendorDir . '/symfony/console/Completion/Output/BashCompletionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\CompletionOutputInterface' => $vendorDir . '/symfony/console/Completion/Output/CompletionOutputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\FishCompletionOutput' => $vendorDir . '/symfony/console/Completion/Output/FishCompletionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\ZshCompletionOutput' => $vendorDir . '/symfony/console/Completion/Output/ZshCompletionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Suggestion' => $vendorDir . '/symfony/console/Completion/Suggestion.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Cursor' => $vendorDir . '/symfony/console/Cursor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => $vendorDir . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\ReStructuredTextDescriptor' => $vendorDir . '/symfony/console/Descriptor/ReStructuredTextDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\EventListener\\ErrorListener' => $vendorDir . '/symfony/console/EventListener/ErrorListener.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => $vendorDir . '/symfony/console/Event/ConsoleErrorEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleSignalEvent' => $vendorDir . '/symfony/console/Event/ConsoleSignalEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\MissingInputException' => $vendorDir . '/symfony/console/Exception/MissingInputException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => $vendorDir . '/symfony/console/Exception/NamespaceNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatter' => $vendorDir . '/symfony/console/Formatter/NullOutputFormatter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/NullOutputFormatterStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\Dumper' => $vendorDir . '/symfony/console/Helper/Dumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\OutputWrapper' => $vendorDir . '/symfony/console/Helper/OutputWrapper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableCellStyle' => $vendorDir . '/symfony/console/Helper/TableCellStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableRows' => $vendorDir . '/symfony/console/Helper/TableRows.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\StreamableInputInterface' => $vendorDir . '/symfony/console/Input/StreamableInputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\AnsiColorMode' => $vendorDir . '/symfony/console/Output/AnsiColorMode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => $vendorDir . '/symfony/console/Output/ConsoleSectionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\TrimmedBufferOutput' => $vendorDir . '/symfony/console/Output/TrimmedBufferOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry' => $vendorDir . '/symfony/console/SignalRegistry/SignalRegistry.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\SingleCommandApplication' => $vendorDir . '/symfony/console/SingleCommandApplication.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Terminal' => $vendorDir . '/symfony/console/Terminal.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\CommandCompletionTester' => $vendorDir . '/symfony/console/Tester/CommandCompletionTester.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\Constraint\\CommandIsSuccessful' => $vendorDir . '/symfony/console/Tester/Constraint/CommandIsSuccessful.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\TesterTrait' => $vendorDir . '/symfony/console/Tester/TesterTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Alias' => $vendorDir . '/symfony/dependency-injection/Alias.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\AbstractArgument' => $vendorDir . '/symfony/dependency-injection/Argument/AbstractArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ArgumentInterface' => $vendorDir . '/symfony/dependency-injection/Argument/ArgumentInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\BoundArgument' => $vendorDir . '/symfony/dependency-injection/Argument/BoundArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\IteratorArgument' => $vendorDir . '/symfony/dependency-injection/Argument/IteratorArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ReferenceSetArgumentTrait' => $vendorDir . '/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\RewindableGenerator' => $vendorDir . '/symfony/dependency-injection/Argument/RewindableGenerator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ServiceClosureArgument' => $vendorDir . '/symfony/dependency-injection/Argument/ServiceClosureArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ServiceLocator' => $vendorDir . '/symfony/dependency-injection/Argument/ServiceLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ServiceLocatorArgument' => $vendorDir . '/symfony/dependency-injection/Argument/ServiceLocatorArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\TaggedIteratorArgument' => $vendorDir . '/symfony/dependency-injection/Argument/TaggedIteratorArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\AsDecorator' => $vendorDir . '/symfony/dependency-injection/Attribute/AsDecorator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\AsTaggedItem' => $vendorDir . '/symfony/dependency-injection/Attribute/AsTaggedItem.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure' => $vendorDir . '/symfony/dependency-injection/Attribute/Autoconfigure.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\AutoconfigureTag' => $vendorDir . '/symfony/dependency-injection/Attribute/AutoconfigureTag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\Autowire' => $vendorDir . '/symfony/dependency-injection/Attribute/Autowire.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\MapDecorated' => $vendorDir . '/symfony/dependency-injection/Attribute/MapDecorated.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator' => $vendorDir . '/symfony/dependency-injection/Attribute/TaggedIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator' => $vendorDir . '/symfony/dependency-injection/Attribute/TaggedLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\Target' => $vendorDir . '/symfony/dependency-injection/Attribute/Target.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\When' => $vendorDir . '/symfony/dependency-injection/Attribute/When.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ChildDefinition' => $vendorDir . '/symfony/dependency-injection/ChildDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AbstractRecursivePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AbstractRecursivePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AliasDeprecatedPublicServicesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AliasDeprecatedPublicServicesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AnalyzeServiceReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AttributeAutoconfigurationPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutoAliasServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutoAliasServicePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowireAsDecoratorPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowireAsDecoratorPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowirePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowirePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowireRequiredMethodsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowireRequiredPropertiesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowireRequiredPropertiesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckArgumentsValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckCircularReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckDefinitionValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckExceptionOnInvalidReferenceBehaviorPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckReferenceValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckTypeDeclarationsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\Compiler' => $vendorDir . '/symfony/dependency-injection/Compiler/Compiler.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface' => $vendorDir . '/symfony/dependency-injection/Compiler/CompilerPassInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\DecoratorServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/DecoratorServicePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\DefinitionErrorExceptionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ExtensionCompilerPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\InlineServiceDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationPass' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\PassConfig' => $vendorDir . '/symfony/dependency-injection/Compiler/PassConfig.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait' => $vendorDir . '/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterAutoconfigureAttributesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterAutoconfigureAttributesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterEnvVarProcessorsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterReverseContainerPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterServiceSubscribersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RemoveAbstractDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RemovePrivateAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RemoveUnusedDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ReplaceAliasByActualDefinitionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveBindingsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveBindingsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveChildDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveClassPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveClassPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveDecoratorStackPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveDecoratorStackPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveEnvPlaceholdersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveFactoryClassPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveHotPathPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveHotPathPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInstanceofConditionalsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInvalidReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveNamedArgumentsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveNoPreloadPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveNoPreloadPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveParameterPlaceHoldersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveReferencesToAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveServiceSubscribersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveTaggedIteratorArgumentPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceLocatorTagPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraph' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphEdge' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphNode' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ValidateEnvPlaceholdersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResource' => $vendorDir . '/symfony/dependency-injection/Config/ContainerParametersResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResourceChecker' => $vendorDir . '/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Container' => $vendorDir . '/symfony/dependency-injection/Container.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerAwareInterface' => $vendorDir . '/symfony/dependency-injection/ContainerAwareInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerAwareTrait' => $vendorDir . '/symfony/dependency-injection/ContainerAwareTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerBuilder' => $vendorDir . '/symfony/dependency-injection/ContainerBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerInterface' => $vendorDir . '/symfony/dependency-injection/ContainerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Definition' => $vendorDir . '/symfony/dependency-injection/Definition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\Dumper' => $vendorDir . '/symfony/dependency-injection/Dumper/Dumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\DumperInterface' => $vendorDir . '/symfony/dependency-injection/Dumper/DumperInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\GraphvizDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/GraphvizDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\PhpDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/PhpDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\Preloader' => $vendorDir . '/symfony/dependency-injection/Dumper/Preloader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\XmlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/XmlDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\YamlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/YamlDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\EnvVarLoaderInterface' => $vendorDir . '/symfony/dependency-injection/EnvVarLoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\EnvVarProcessor' => $vendorDir . '/symfony/dependency-injection/EnvVarProcessor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\EnvVarProcessorInterface' => $vendorDir . '/symfony/dependency-injection/EnvVarProcessorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\AutowiringFailedException' => $vendorDir . '/symfony/dependency-injection/Exception/AutowiringFailedException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\BadMethodCallException' => $vendorDir . '/symfony/dependency-injection/Exception/BadMethodCallException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\EnvNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/EnvNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\EnvParameterException' => $vendorDir . '/symfony/dependency-injection/Exception/EnvParameterException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/dependency-injection/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/dependency-injection/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\InvalidParameterTypeException' => $vendorDir . '/symfony/dependency-injection/Exception/InvalidParameterTypeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\LogicException' => $vendorDir . '/symfony/dependency-injection/Exception/LogicException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\OutOfBoundsException' => $vendorDir . '/symfony/dependency-injection/Exception/OutOfBoundsException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ParameterCircularReferenceException' => $vendorDir . '/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ParameterNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/ParameterNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\RuntimeException' => $vendorDir . '/symfony/dependency-injection/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ServiceCircularReferenceException' => $vendorDir . '/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ServiceNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/ServiceNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ExpressionLanguage' => $vendorDir . '/symfony/dependency-injection/ExpressionLanguage.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ExpressionLanguageProvider' => $vendorDir . '/symfony/dependency-injection/ExpressionLanguageProvider.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\AbstractExtension' => $vendorDir . '/symfony/dependency-injection/Extension/AbstractExtension.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ConfigurableExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/ConfigurableExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ConfigurationExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\Extension' => $vendorDir . '/symfony/dependency-injection/Extension/Extension.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/ExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ExtensionTrait' => $vendorDir . '/symfony/dependency-injection/Extension/ExtensionTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\PrependExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/PrependExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\InstantiatorInterface' => $vendorDir . '/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\RealServiceInstantiator' => $vendorDir . '/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\DumperInterface' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\NullDumper' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\ProxyHelper' => $vendorDir . '/symfony/dependency-injection/LazyProxy/ProxyHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\ClosureLoader' => $vendorDir . '/symfony/dependency-injection/Loader/ClosureLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AliasConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ClosureReferenceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ClosureReferenceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\DefaultsConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\EnvConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/EnvConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InlineServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InstanceofConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ParametersConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\PrototypeConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ReferenceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServicesConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AbstractTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ArgumentTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutoconfigureTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutowireTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\BindTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\CallTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ClassTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ConfiguratorTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DecorateTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DeprecateTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FactoryTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FileTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\LazyTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ParentTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PropertyTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PublicTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ShareTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\SyntheticTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\TagTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\DirectoryLoader' => $vendorDir . '/symfony/dependency-injection/Loader/DirectoryLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\FileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/FileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/GlobFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\IniFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/IniFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/XmlFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/YamlFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Parameter' => $vendorDir . '/symfony/dependency-injection/Parameter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ContainerBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ContainerBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ContainerBagInterface' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\EnvPlaceholderParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\FrozenParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBagInterface' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Reference' => $vendorDir . '/symfony/dependency-injection/Reference.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ReverseContainer' => $vendorDir . '/symfony/dependency-injection/ReverseContainer.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ServiceLocator' => $vendorDir . '/symfony/dependency-injection/ServiceLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\TaggedContainerInterface' => $vendorDir . '/symfony/dependency-injection/TaggedContainerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\TypedReference' => $vendorDir . '/symfony/dependency-injection/TypedReference.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Variable' => $vendorDir . '/symfony/dependency-injection/Variable.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => $vendorDir . '/symfony/filesystem/Exception/FileNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\IOException' => $vendorDir . '/symfony/filesystem/Exception/IOException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\IOExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/IOExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/filesystem/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\RuntimeException' => $vendorDir . '/symfony/filesystem/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Filesystem' => $vendorDir . '/symfony/filesystem/Filesystem.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Path' => $vendorDir . '/symfony/filesystem/Path.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Comparator\\Comparator' => $vendorDir . '/symfony/finder/Comparator/Comparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Comparator\\DateComparator' => $vendorDir . '/symfony/finder/Comparator/DateComparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Comparator\\NumberComparator' => $vendorDir . '/symfony/finder/Comparator/NumberComparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => $vendorDir . '/symfony/finder/Exception/AccessDeniedException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Exception\\DirectoryNotFoundException' => $vendorDir . '/symfony/finder/Exception/DirectoryNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Finder' => $vendorDir . '/symfony/finder/Finder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Gitignore' => $vendorDir . '/symfony/finder/Gitignore.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Glob' => $vendorDir . '/symfony/finder/Glob.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => $vendorDir . '/symfony/finder/Iterator/CustomFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DateRangeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DepthRangeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => $vendorDir . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FileTypeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilecontentFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilenameFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\LazyIterator' => $vendorDir . '/symfony/finder/Iterator/LazyIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => $vendorDir . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => $vendorDir . '/symfony/finder/Iterator/PathFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => $vendorDir . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Iterator/SortableIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\VcsIgnoredFilterIterator' => $vendorDir . '/symfony/finder/Iterator/VcsIgnoredFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/SplFileInfo.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Exception/LogicException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ProcessFailedException' => $vendorDir . '/symfony/process/Exception/ProcessFailedException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ProcessSignaledException' => $vendorDir . '/symfony/process/Exception/ProcessSignaledException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => $vendorDir . '/symfony/process/Exception/ProcessTimedOutException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\RuntimeException' => $vendorDir . '/symfony/process/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\ExecutableFinder' => $vendorDir . '/symfony/process/ExecutableFinder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\InputStream' => $vendorDir . '/symfony/process/InputStream.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\PhpExecutableFinder' => $vendorDir . '/symfony/process/PhpExecutableFinder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\PhpProcess' => $vendorDir . '/symfony/process/PhpProcess.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\AbstractPipes' => $vendorDir . '/symfony/process/Pipes/AbstractPipes.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\PipesInterface' => $vendorDir . '/symfony/process/Pipes/PipesInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\UnixPipes' => $vendorDir . '/symfony/process/Pipes/UnixPipes.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\WindowsPipes' => $vendorDir . '/symfony/process/Pipes/WindowsPipes.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Process.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/ProcessUtils.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\AbstractString' => $vendorDir . '/symfony/string/AbstractString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\AbstractUnicodeString' => $vendorDir . '/symfony/string/AbstractUnicodeString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\ByteString' => $vendorDir . '/symfony/string/ByteString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\CodePointString' => $vendorDir . '/symfony/string/CodePointString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/string/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/string/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Exception\\RuntimeException' => $vendorDir . '/symfony/string/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Inflector\\EnglishInflector' => $vendorDir . '/symfony/string/Inflector/EnglishInflector.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Inflector\\FrenchInflector' => $vendorDir . '/symfony/string/Inflector/FrenchInflector.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Inflector\\InflectorInterface' => $vendorDir . '/symfony/string/Inflector/InflectorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\LazyString' => $vendorDir . '/symfony/string/LazyString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Slugger\\AsciiSlugger' => $vendorDir . '/symfony/string/Slugger/AsciiSlugger.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Slugger\\SluggerInterface' => $vendorDir . '/symfony/string/Slugger/SluggerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\UnicodeString' => $vendorDir . '/symfony/string/UnicodeString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\Attribute\\Required' => $vendorDir . '/symfony/service-contracts/Attribute/Required.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => $vendorDir . '/symfony/service-contracts/Attribute/SubscribedService.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ResetInterface' => $vendorDir . '/symfony/service-contracts/ResetInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceLocatorTrait' => $vendorDir . '/symfony/service-contracts/ServiceLocatorTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceProviderInterface' => $vendorDir . '/symfony/service-contracts/ServiceProviderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberTrait.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\DependencyInjection\\CompilerPass\\AutowireArrayParameterCompilerPass' => $vendorDir . '/symplify/autowire-array-parameter/src/DependencyInjection/CompilerPass/AutowireArrayParameterCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\DependencyInjection\\DefinitionFinder' => $vendorDir . '/symplify/autowire-array-parameter/src/DependencyInjection/DefinitionFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\DocBlock\\ParamTypeDocBlockResolver' => $vendorDir . '/symplify/autowire-array-parameter/src/DocBlock/ParamTypeDocBlockResolver.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\Exception\\DependencyInjection\\DefinitionForTypeNotFoundException' => $vendorDir . '/symplify/autowire-array-parameter/src/Exception/DependencyInjection/DefinitionForTypeNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\Skipper\\ParameterSkipper' => $vendorDir . '/symplify/autowire-array-parameter/src/Skipper/ParameterSkipper.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\TypeResolver\\ParameterTypeResolver' => $vendorDir . '/symplify/autowire-array-parameter/src/TypeResolver/ParameterTypeResolver.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\Command\\ValidateFixtureSkipNamingCommand' => $vendorDir . '/symplify/easy-testing/src/Command/ValidateFixtureSkipNamingCommand.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\DataProvider\\StaticFixtureFinder' => $vendorDir . '/symplify/easy-testing/src/DataProvider/StaticFixtureFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\DataProvider\\StaticFixtureUpdater' => $vendorDir . '/symplify/easy-testing/src/DataProvider/StaticFixtureUpdater.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\Finder\\FixtureFinder' => $vendorDir . '/symplify/easy-testing/src/Finder/FixtureFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\FixtureSplitter\\TrioFixtureSplitter' => $vendorDir . '/symplify/easy-testing/src/FixtureSplitter/TrioFixtureSplitter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\Kernel\\EasyTestingKernel' => $vendorDir . '/symplify/easy-testing/src/Kernel/EasyTestingKernel.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\MissplacedSkipPrefixResolver' => $vendorDir . '/symplify/easy-testing/src/MissplacedSkipPrefixResolver.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\PHPUnit\\Behavior\\DirectoryAssertableTrait' => $vendorDir . '/symplify/easy-testing/src/PHPUnit/Behavior/DirectoryAssertableTrait.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\PHPUnit\\StaticPHPUnitEnvironment' => $vendorDir . '/symplify/easy-testing/src/PHPUnit/StaticPHPUnitEnvironment.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\StaticFixtureSplitter' => $vendorDir . '/symplify/easy-testing/src/StaticFixtureSplitter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\EasyTestingConfig' => $vendorDir . '/symplify/easy-testing/src/ValueObject/EasyTestingConfig.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\ExpectedAndOutputFileInfoPair' => $vendorDir . '/symplify/easy-testing/src/ValueObject/ExpectedAndOutputFileInfoPair.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\FixtureSplit\\TrioContent' => $vendorDir . '/symplify/easy-testing/src/ValueObject/FixtureSplit/TrioContent.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\IncorrectAndMissingSkips' => $vendorDir . '/symplify/easy-testing/src/ValueObject/IncorrectAndMissingSkips.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\InputAndExpected' => $vendorDir . '/symplify/easy-testing/src/ValueObject/InputAndExpected.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\InputFileInfoAndExpected' => $vendorDir . '/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpected.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\InputFileInfoAndExpectedFileInfo' => $vendorDir . '/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpectedFileInfo.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\Option' => $vendorDir . '/symplify/easy-testing/src/ValueObject/Option.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\Prefix' => $vendorDir . '/symplify/easy-testing/src/ValueObject/Prefix.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\SplitLine' => $vendorDir . '/symplify/easy-testing/src/ValueObject/SplitLine.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Composer\\VendorDirProvider' => $vendorDir . '/symplify/package-builder/src/Composer/VendorDirProvider.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Command\\AbstractSymplifyCommand' => $vendorDir . '/symplify/package-builder/src/Console/Command/AbstractSymplifyCommand.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Formatter\\ColorConsoleDiffFormatter' => $vendorDir . '/symplify/package-builder/src/Console/Formatter/ColorConsoleDiffFormatter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Input\\StaticInputDetector' => $vendorDir . '/symplify/package-builder/src/Console/Input/StaticInputDetector.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Output\\ConsoleDiffer' => $vendorDir . '/symplify/package-builder/src/Console/Output/ConsoleDiffer.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Style\\SymfonyStyleFactory' => $vendorDir . '/symplify/package-builder/src/Console/Style/SymfonyStyleFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\DependencyInjection\\CompilerPass\\AutowireInterfacesCompilerPass' => $vendorDir . '/symplify/package-builder/src/DependencyInjection/CompilerPass/AutowireInterfacesCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\DependencyInjection\\FileLoader\\ParameterMergingPhpFileLoader' => $vendorDir . '/symplify/package-builder/src/DependencyInjection/FileLoader/ParameterMergingPhpFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Diff\\DifferFactory' => $vendorDir . '/symplify/package-builder/src/Diff/DifferFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Diff\\Output\\CompleteUnifiedDiffOutputBuilderFactory' => $vendorDir . '/symplify/package-builder/src/Diff/Output/CompleteUnifiedDiffOutputBuilderFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\HttpKernel\\MissingInterfaceException' => $vendorDir . '/symplify/package-builder/src/Exception/HttpKernel/MissingInterfaceException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\InvalidPrivatePropertyTypeException' => $vendorDir . '/symplify/package-builder/src/Exception/InvalidPrivatePropertyTypeException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\MissingPrivatePropertyException' => $vendorDir . '/symplify/package-builder/src/Exception/MissingPrivatePropertyException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\MissingServiceException' => $vendorDir . '/symplify/package-builder/src/Exception/MissingServiceException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Parameter\\ParameterProvider' => $vendorDir . '/symplify/package-builder/src/Parameter/ParameterProvider.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Php\\TypeChecker' => $vendorDir . '/symplify/package-builder/src/Php/TypeChecker.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Reflection\\ClassLikeExistenceChecker' => $vendorDir . '/symplify/package-builder/src/Reflection/ClassLikeExistenceChecker.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Reflection\\PrivatesAccessor' => $vendorDir . '/symplify/package-builder/src/Reflection/PrivatesAccessor.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Reflection\\PrivatesCaller' => $vendorDir . '/symplify/package-builder/src/Reflection/PrivatesCaller.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Strings\\StringFormatConverter' => $vendorDir . '/symplify/package-builder/src/Strings/StringFormatConverter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\ValueObject\\ConsoleColorDiffConfig' => $vendorDir . '/symplify/package-builder/src/ValueObject/ConsoleColorDiffConfig.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\ValueObject\\MethodName' => $vendorDir . '/symplify/package-builder/src/ValueObject/MethodName.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\ValueObject\\Option' => $vendorDir . '/symplify/package-builder/src/ValueObject/Option.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Yaml\\ParametersMerger' => $vendorDir . '/symplify/package-builder/src/Yaml/ParametersMerger.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Exception\\DirectoryNotFoundException' => $vendorDir . '/symplify/smart-file-system/src/Exception/DirectoryNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Exception\\FileNotFoundException' => $vendorDir . '/symplify/smart-file-system/src/Exception/FileNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\FileSystemFilter' => $vendorDir . '/symplify/smart-file-system/src/FileSystemFilter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\FileSystemGuard' => $vendorDir . '/symplify/smart-file-system/src/FileSystemGuard.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Finder\\FinderSanitizer' => $vendorDir . '/symplify/smart-file-system/src/Finder/FinderSanitizer.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Finder\\SmartFinder' => $vendorDir . '/symplify/smart-file-system/src/Finder/SmartFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Json\\JsonFileSystem' => $vendorDir . '/symplify/smart-file-system/src/Json/JsonFileSystem.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Normalizer\\PathNormalizer' => $vendorDir . '/symplify/smart-file-system/src/Normalizer/PathNormalizer.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\SmartFileInfo' => $vendorDir . '/symplify/smart-file-system/src/SmartFileInfo.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\SmartFileSystem' => $vendorDir . '/symplify/smart-file-system/src/SmartFileSystem.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Config\\Loader\\ParameterMergingLoaderFactory' => $vendorDir . '/symplify/symplify-kernel/src/Config/Loader/ParameterMergingLoaderFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\ContainerBuilderFactory' => $vendorDir . '/symplify/symplify-kernel/src/ContainerBuilderFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Contract\\Config\\LoaderFactoryInterface' => $vendorDir . '/symplify/symplify-kernel/src/Contract/Config/LoaderFactoryInterface.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Contract\\LightKernelInterface' => $vendorDir . '/symplify/symplify-kernel/src/Contract/LightKernelInterface.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\DependencyInjection\\LoadExtensionConfigsCompilerPass' => $vendorDir . '/symplify/symplify-kernel/src/DependencyInjection/LoadExtensionConfigsCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Exception\\BootException' => $vendorDir . '/symplify/symplify-kernel/src/Exception/BootException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Exception\\ShouldNotHappenException' => $vendorDir . '/symplify/symplify-kernel/src/Exception/ShouldNotHappenException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\HttpKernel\\AbstractSymplifyKernel' => $vendorDir . '/symplify/symplify-kernel/src/HttpKernel/AbstractSymplifyKernel.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\ValueObject\\KernelBootAndApplicationRun' => $vendorDir . '/symplify/symplify-kernel/src/ValueObject/KernelBootAndApplicationRun.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\ValueObject\\SymplifyKernelConfig' => $vendorDir . '/symplify/symplify-kernel/src/ValueObject/SymplifyKernelConfig.php', + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\Assert' => $vendorDir . '/webmozart/assert/src/Assert.php', + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\InvalidArgumentException' => $vendorDir . '/webmozart/assert/src/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\Mixin' => $vendorDir . '/webmozart/assert/src/Mixin.php', + 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', + 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AnyVersionConstraint.php', + 'PharIo\\Version\\BuildMetaData' => $vendorDir . '/phar-io/version/src/BuildMetaData.php', + 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/exceptions/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidPreReleaseSuffixException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php', + 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidVersionException.php', + 'PharIo\\Version\\NoBuildMetaDataException' => $vendorDir . '/phar-io/version/src/exceptions/NoBuildMetaDataException.php', + 'PharIo\\Version\\NoPreReleaseSuffixException' => $vendorDir . '/phar-io/version/src/exceptions/NoPreReleaseSuffixException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', + 'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php', + 'Symfony\\Polyfill\\Intl\\Grapheme\\Grapheme' => $vendorDir . '/symfony/polyfill-intl-grapheme/Grapheme.php', + 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php', + 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', + 'Symplify\\MonorepoBuilder\\Command\\BumpInterdependencyCommand' => $baseDir . '/src/Command/BumpInterdependencyCommand.php', + 'Symplify\\MonorepoBuilder\\Command\\PackageAliasCommand' => $baseDir . '/src/Command/PackageAliasCommand.php', + 'Symplify\\MonorepoBuilder\\Command\\ValidateCommand' => $baseDir . '/src/Command/ValidateCommand.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ComposerJsonFactory' => $baseDir . '/packages/ComposerJsonManipulator/ComposerJsonFactory.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\FileSystem\\JsonFileManager' => $baseDir . '/packages/ComposerJsonManipulator/FileSystem/JsonFileManager.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Json\\JsonCleaner' => $baseDir . '/packages/ComposerJsonManipulator/Json/JsonCleaner.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Json\\JsonInliner' => $baseDir . '/packages/ComposerJsonManipulator/Json/JsonInliner.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Printer\\ComposerJsonPrinter' => $baseDir . '/packages/ComposerJsonManipulator/Printer/ComposerJsonPrinter.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Sorter\\ComposerPackageSorter' => $baseDir . '/packages/ComposerJsonManipulator/Sorter/ComposerPackageSorter.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ValueObject\\ComposerJson' => $baseDir . '/packages/ComposerJsonManipulator/ValueObject/ComposerJson.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ValueObject\\ComposerJsonSection' => $baseDir . '/packages/ComposerJsonManipulator/ValueObject/ComposerJsonSection.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ValueObject\\Option' => $baseDir . '/packages/ComposerJsonManipulator/ValueObject/Option.php', + 'Symplify\\MonorepoBuilder\\Config\\MBConfig' => $baseDir . '/src/Config/MBConfig.php', + 'Symplify\\MonorepoBuilder\\Console\\MonorepoBuilderApplication' => $baseDir . '/src/Console/MonorepoBuilderApplication.php', + 'Symplify\\MonorepoBuilder\\Contract\\Git\\TagResolverInterface' => $baseDir . '/src/Contract/Git/TagResolverInterface.php', + 'Symplify\\MonorepoBuilder\\DependencyUpdater' => $baseDir . '/src/DependencyUpdater.php', + 'Symplify\\MonorepoBuilder\\DevMasterAliasUpdater' => $baseDir . '/src/DevMasterAliasUpdater.php', + 'Symplify\\MonorepoBuilder\\Exception\\ConfigurationException' => $baseDir . '/src/Exception/ConfigurationException.php', + 'Symplify\\MonorepoBuilder\\Exception\\Git\\InvalidGitVersionException' => $baseDir . '/src/Exception/Git/InvalidGitVersionException.php', + 'Symplify\\MonorepoBuilder\\Exception\\MissingComposerJsonException' => $baseDir . '/src/Exception/MissingComposerJsonException.php', + 'Symplify\\MonorepoBuilder\\Exception\\Validator\\InvalidComposerJsonSetupException' => $baseDir . '/src/Exception/Validator/InvalidComposerJsonSetupException.php', + 'Symplify\\MonorepoBuilder\\FileSystem\\ComposerJsonProvider' => $baseDir . '/src/FileSystem/ComposerJsonProvider.php', + 'Symplify\\MonorepoBuilder\\Finder\\PackageComposerFinder' => $baseDir . '/src/Finder/PackageComposerFinder.php', + 'Symplify\\MonorepoBuilder\\Git\\ExpectedAliasResolver' => $baseDir . '/src/Git/ExpectedAliasResolver.php', + 'Symplify\\MonorepoBuilder\\Git\\MostRecentTagResolver' => $baseDir . '/src/Git/MostRecentTagResolver.php', + 'Symplify\\MonorepoBuilder\\Init\\Command\\InitCommand' => $baseDir . '/packages/Init/Command/InitCommand.php', + 'Symplify\\MonorepoBuilder\\Kernel\\MonorepoBuilderKernel' => $baseDir . '/src/Kernel/MonorepoBuilderKernel.php', + 'Symplify\\MonorepoBuilder\\Merge\\Application\\MergedAndDecoratedComposerJsonFactory' => $baseDir . '/packages/Merge/Application/MergedAndDecoratedComposerJsonFactory.php', + 'Symplify\\MonorepoBuilder\\Merge\\Arrays\\ArraySorter' => $baseDir . '/packages/Merge/Arrays/ArraySorter.php', + 'Symplify\\MonorepoBuilder\\Merge\\Arrays\\SortedParameterMerger' => $baseDir . '/packages/Merge/Arrays/SortedParameterMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\Cleaner\\RequireRequireDevDuplicateCleaner' => $baseDir . '/packages/Merge/Cleaner/RequireRequireDevDuplicateCleaner.php', + 'Symplify\\MonorepoBuilder\\Merge\\Command\\MergeCommand' => $baseDir . '/packages/Merge/Command/MergeCommand.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\AppenderComposerJsonDecorator' => $baseDir . '/packages/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\FilterOutDuplicatedRequireAndRequireDevJsonDecorator' => $baseDir . '/packages/Merge/ComposerJsonDecorator/FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\RemoverComposerJsonDecorator' => $baseDir . '/packages/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\ReplaceSectionJsonDecorator' => $baseDir . '/packages/Merge/ComposerJsonDecorator/ReplaceSectionJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\RepositoryPathComposerJsonDecorator' => $baseDir . '/packages/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\RootRemoveComposerJsonDecorator' => $baseDir . '/packages/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\SortComposerJsonDecorator' => $baseDir . '/packages/Merge/ComposerJsonDecorator/SortComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonMerger' => $baseDir . '/packages/Merge/ComposerJsonMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\AuthorComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/AuthorComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\AutoloadComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/AutoloadComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\AutoloadDevComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/AutoloadDevComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\ExtraComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\MinimalStabilityKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/MinimalStabilityKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\PreferStableKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/PreferStableKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\ProvideComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/ProvideComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\ReplaceComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/ReplaceComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\RepositoriesComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/RepositoriesComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\RequireComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/RequireComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\RequireDevComposerKeyMerger' => $baseDir . '/packages/Merge/ComposerKeyMerger/RequireDevComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\Configuration\\MergedPackagesCollector' => $baseDir . '/packages/Merge/Configuration/MergedPackagesCollector.php', + 'Symplify\\MonorepoBuilder\\Merge\\Configuration\\ModifyingComposerJsonProvider' => $baseDir . '/packages/Merge/Configuration/ModifyingComposerJsonProvider.php', + 'Symplify\\MonorepoBuilder\\Merge\\Contract\\ComposerJsonDecoratorInterface' => $baseDir . '/packages/Merge/Contract/ComposerJsonDecoratorInterface.php', + 'Symplify\\MonorepoBuilder\\Merge\\Contract\\ComposerKeyMergerInterface' => $baseDir . '/packages/Merge/Contract/ComposerKeyMergerInterface.php', + 'Symplify\\MonorepoBuilder\\Merge\\Contract\\ComposerPathNormalizerInterface' => $baseDir . '/packages/Merge/Contract/ComposerPathNormalizerInterface.php', + 'Symplify\\MonorepoBuilder\\Merge\\Guard\\ConflictingVersionsGuard' => $baseDir . '/packages/Merge/Guard/ConflictingVersionsGuard.php', + 'Symplify\\MonorepoBuilder\\Merge\\PathResolver\\AutoloadPathNormalizer' => $baseDir . '/packages/Merge/PathResolver/AutoloadPathNormalizer.php', + 'Symplify\\MonorepoBuilder\\Merge\\PathResolver\\ComposerPatchesPathNormalizer' => $baseDir . '/packages/Merge/PathResolver/ComposerPatchesPathNormalizer.php', + 'Symplify\\MonorepoBuilder\\Package\\PackageNamesProvider' => $baseDir . '/src/Package/PackageNamesProvider.php', + 'Symplify\\MonorepoBuilder\\Propagate\\Command\\PropagateCommand' => $baseDir . '/packages/Propagate/Command/PropagateCommand.php', + 'Symplify\\MonorepoBuilder\\Propagate\\VersionPropagator' => $baseDir . '/packages/Propagate/VersionPropagator.php', + 'Symplify\\MonorepoBuilder\\Release\\Command\\ReleaseCommand' => $baseDir . '/packages/Release/Command/ReleaseCommand.php', + 'Symplify\\MonorepoBuilder\\Release\\Configuration\\StageResolver' => $baseDir . '/packages/Release/Configuration/StageResolver.php', + 'Symplify\\MonorepoBuilder\\Release\\Configuration\\VersionResolver' => $baseDir . '/packages/Release/Configuration/VersionResolver.php', + 'Symplify\\MonorepoBuilder\\Release\\Contract\\ReleaseWorker\\ReleaseWorkerInterface' => $baseDir . '/packages/Release/Contract/ReleaseWorker/ReleaseWorkerInterface.php', + 'Symplify\\MonorepoBuilder\\Release\\Contract\\ReleaseWorker\\StageAwareInterface' => $baseDir . '/packages/Release/Contract/ReleaseWorker/StageAwareInterface.php', + 'Symplify\\MonorepoBuilder\\Release\\Exception\\ConfigurationException' => $baseDir . '/packages/Release/Exception/ConfigurationException.php', + 'Symplify\\MonorepoBuilder\\Release\\Exception\\MissingComposerJsonException' => $baseDir . '/packages/Release/Exception/MissingComposerJsonException.php', + 'Symplify\\MonorepoBuilder\\Release\\Guard\\ReleaseGuard' => $baseDir . '/packages/Release/Guard/ReleaseGuard.php', + 'Symplify\\MonorepoBuilder\\Release\\Output\\ReleaseWorkerReporter' => $baseDir . '/packages/Release/Output/ReleaseWorkerReporter.php', + 'Symplify\\MonorepoBuilder\\Release\\Process\\ProcessRunner' => $baseDir . '/packages/Release/Process/ProcessRunner.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorkerProvider' => $baseDir . '/packages/Release/ReleaseWorkerProvider.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\AddTagToChangelogReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/AddTagToChangelogReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\PushNextDevReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/PushNextDevReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\PushTagReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/PushTagReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\SetCurrentMutualDependenciesReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/SetCurrentMutualDependenciesReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\SetNextMutualDependenciesReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/SetNextMutualDependenciesReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\TagVersionReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/TagVersionReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\UpdateBranchAliasReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/UpdateBranchAliasReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\UpdateReplaceReleaseWorker' => $baseDir . '/packages/Release/ReleaseWorker/UpdateReplaceReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ValueObject\\SemVersion' => $baseDir . '/packages/Release/ValueObject/SemVersion.php', + 'Symplify\\MonorepoBuilder\\Release\\ValueObject\\Stage' => $baseDir . '/packages/Release/ValueObject/Stage.php', + 'Symplify\\MonorepoBuilder\\Release\\Version\\VersionFactory' => $baseDir . '/packages/Release/Version/VersionFactory.php', + 'Symplify\\MonorepoBuilder\\Testing\\Command\\LocalizeComposerPathsCommand' => $baseDir . '/packages/Testing/Command/LocalizeComposerPathsCommand.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJsonRepositoriesUpdater' => $baseDir . '/packages/Testing/ComposerJsonRepositoriesUpdater.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJsonRequireUpdater' => $baseDir . '/packages/Testing/ComposerJsonRequireUpdater.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJson\\ComposerJsonSymlinker' => $baseDir . '/packages/Testing/ComposerJson/ComposerJsonSymlinker.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJson\\ComposerVersionManipulator' => $baseDir . '/packages/Testing/ComposerJson/ComposerVersionManipulator.php', + 'Symplify\\MonorepoBuilder\\Testing\\PackageDependency\\UsedPackagesResolver' => $baseDir . '/packages/Testing/PackageDependency/UsedPackagesResolver.php', + 'Symplify\\MonorepoBuilder\\Testing\\PathResolver\\PackagePathResolver' => $baseDir . '/packages/Testing/PathResolver/PackagePathResolver.php', + 'Symplify\\MonorepoBuilder\\Testing\\ValueObject\\Option' => $baseDir . '/packages/Testing/ValueObject/Option.php', + 'Symplify\\MonorepoBuilder\\Utils\\RelativeFilePathHelper' => $baseDir . '/src/Utils/RelativeFilePathHelper.php', + 'Symplify\\MonorepoBuilder\\Utils\\VersionUtils' => $baseDir . '/src/Utils/VersionUtils.php', + 'Symplify\\MonorepoBuilder\\Validator\\ConflictingPackageVersionsReporter' => $baseDir . '/src/Validator/ConflictingPackageVersionsReporter.php', + 'Symplify\\MonorepoBuilder\\Validator\\SourcesPresenceValidator' => $baseDir . '/src/Validator/SourcesPresenceValidator.php', + 'Symplify\\MonorepoBuilder\\ValueObject\\File' => $baseDir . '/src/ValueObject/File.php', + 'Symplify\\MonorepoBuilder\\ValueObject\\Option' => $baseDir . '/src/ValueObject/Option.php', + 'Symplify\\MonorepoBuilder\\VersionValidator' => $baseDir . '/src/VersionValidator.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 0000000000..4eb79a1c2a --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,15 @@ + $vendorDir . '/symfony/deprecation-contracts/function.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', + 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000000..15a2ff3ad6 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($baseDir . '/src', $baseDir . '/packages'), + 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), + 'Symfony\\Polyfill\\Intl\\Grapheme\\' => array($vendorDir . '/symfony/polyfill-intl-grapheme'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\' => array($vendorDir . '/symplify/symplify-kernel/src'), + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\' => array($vendorDir . '/symplify/smart-file-system/src'), + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\' => array($vendorDir . '/symplify/package-builder/src'), + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\' => array($vendorDir . '/symplify/easy-testing/src'), + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\' => array($vendorDir . '/symplify/autowire-array-parameter/src'), + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\' => array($vendorDir . '/symfony/dependency-injection'), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'), + 'MonorepoBuilderPrefix202310\\Psr\\Container\\' => array($vendorDir . '/psr/container/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000000..5d57c63259 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,49 @@ +setClassMapAuthoritative(true); + $loader->register(true); + + $filesToLoad = \Composer\Autoload\ComposerStaticInit40522c779707518f5fc82043e1269113::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); + } + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 0000000000..dedf6b52db --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,843 @@ + __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', + 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', + 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'S' => + array ( + 'Symplify\\MonorepoBuilder\\' => 25, + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, + 'Symfony\\Polyfill\\Intl\\Grapheme\\' => 31, + 'Symfony\\Polyfill\\Ctype\\' => 23, + ), + 'M' => + array ( + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\' => 45, + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\' => 52, + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\' => 53, + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\' => 52, + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\' => 49, + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\' => 60, + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\' => 54, + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\' => 53, + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\' => 54, + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\' => 53, + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\' => 57, + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\' => 66, + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\' => 54, + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\' => 53, + 'MonorepoBuilderPrefix202310\\Psr\\Container\\' => 42, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symplify\\MonorepoBuilder\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + 1 => __DIR__ . '/../..' . '/packages', + ), + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', + ), + 'Symfony\\Polyfill\\Intl\\Grapheme\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme', + ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\' => + array ( + 0 => __DIR__ . '/..' . '/webmozart/assert/src', + ), + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\' => + array ( + 0 => __DIR__ . '/..' . '/symplify/symplify-kernel/src', + ), + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\' => + array ( + 0 => __DIR__ . '/..' . '/symplify/smart-file-system/src', + ), + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\' => + array ( + 0 => __DIR__ . '/..' . '/symplify/package-builder/src', + ), + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\' => + array ( + 0 => __DIR__ . '/..' . '/symplify/easy-testing/src', + ), + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\' => + array ( + 0 => __DIR__ . '/..' . '/symplify/autowire-array-parameter/src', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/service-contracts', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/string', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/process', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/finder', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/filesystem', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/dependency-injection', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/console', + ), + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/config', + ), + 'MonorepoBuilderPrefix202310\\Psr\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/container/src', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'MonorepoBuilderPrefix202310\\Nette\\ArgumentOutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\DeprecatedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\DirectoryNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\FileNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\HtmlStringable' => __DIR__ . '/..' . '/nette/utils/src/HtmlStringable.php', + 'MonorepoBuilderPrefix202310\\Nette\\IOException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\InvalidArgumentException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\InvalidStateException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Iterators\\CachingIterator' => __DIR__ . '/..' . '/nette/utils/src/Iterators/CachingIterator.php', + 'MonorepoBuilderPrefix202310\\Nette\\Iterators\\Mapper' => __DIR__ . '/..' . '/nette/utils/src/Iterators/Mapper.php', + 'MonorepoBuilderPrefix202310\\Nette\\Localization\\ITranslator' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php', + 'MonorepoBuilderPrefix202310\\Nette\\Localization\\Translator' => __DIR__ . '/..' . '/nette/utils/src/Translator.php', + 'MonorepoBuilderPrefix202310\\Nette\\MemberAccessException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\NotImplementedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\NotSupportedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\OutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\SmartObject' => __DIR__ . '/..' . '/nette/utils/src/SmartObject.php', + 'MonorepoBuilderPrefix202310\\Nette\\StaticClass' => __DIR__ . '/..' . '/nette/utils/src/StaticClass.php', + 'MonorepoBuilderPrefix202310\\Nette\\UnexpectedValueException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ArrayHash' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayHash.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ArrayList' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayList.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Arrays' => __DIR__ . '/..' . '/nette/utils/src/Utils/Arrays.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\AssertionException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Callback' => __DIR__ . '/..' . '/nette/utils/src/Utils/Callback.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\DateTime' => __DIR__ . '/..' . '/nette/utils/src/Utils/DateTime.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\FileSystem' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileSystem.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Floats' => __DIR__ . '/..' . '/nette/utils/src/Utils/Floats.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Helpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/Helpers.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Html' => __DIR__ . '/..' . '/nette/utils/src/Utils/Html.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\IHtmlString' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Image' => __DIR__ . '/..' . '/nette/utils/src/Utils/Image.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ImageException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Json' => __DIR__ . '/..' . '/nette/utils/src/Utils/Json.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\JsonException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ObjectHelpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/ObjectHelpers.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\ObjectMixin' => __DIR__ . '/..' . '/nette/utils/src/Utils/ObjectMixin.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Paginator' => __DIR__ . '/..' . '/nette/utils/src/Utils/Paginator.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Random' => __DIR__ . '/..' . '/nette/utils/src/Utils/Random.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Reflection' => __DIR__ . '/..' . '/nette/utils/src/Utils/Reflection.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\RegexpException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Strings' => __DIR__ . '/..' . '/nette/utils/src/Utils/Strings.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Type' => __DIR__ . '/..' . '/nette/utils/src/Utils/Type.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\UnknownImageFileException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'MonorepoBuilderPrefix202310\\Nette\\Utils\\Validators' => __DIR__ . '/..' . '/nette/utils/src/Utils/Validators.php', + 'MonorepoBuilderPrefix202310\\Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php', + 'MonorepoBuilderPrefix202310\\Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\ConfigurationException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/ConfigurationException.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', + 'MonorepoBuilderPrefix202310\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ClassBuilder' => __DIR__ . '/..' . '/symfony/config/Builder/ClassBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ConfigBuilderGenerator' => __DIR__ . '/..' . '/symfony/config/Builder/ConfigBuilderGenerator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ConfigBuilderGeneratorInterface' => __DIR__ . '/..' . '/symfony/config/Builder/ConfigBuilderGeneratorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\ConfigBuilderInterface' => __DIR__ . '/..' . '/symfony/config/Builder/ConfigBuilderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\Method' => __DIR__ . '/..' . '/symfony/config/Builder/Method.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Builder\\Property' => __DIR__ . '/..' . '/symfony/config/Builder/Property.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCache' => __DIR__ . '/..' . '/symfony/config/ConfigCache.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCacheFactory' => __DIR__ . '/..' . '/symfony/config/ConfigCacheFactory.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCacheFactoryInterface' => __DIR__ . '/..' . '/symfony/config/ConfigCacheFactoryInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ConfigCacheInterface' => __DIR__ . '/..' . '/symfony/config/ConfigCacheInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ArrayNode' => __DIR__ . '/..' . '/symfony/config/Definition/ArrayNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\BaseNode' => __DIR__ . '/..' . '/symfony/config/Definition/BaseNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\BooleanNode' => __DIR__ . '/..' . '/symfony/config/Definition/BooleanNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/ArrayNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\BooleanNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/BooleanNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\BuilderAwareInterface' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/BuilderAwareInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\EnumNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/EnumNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ExprBuilder' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/ExprBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\FloatNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/FloatNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\IntegerNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/IntegerNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\MergeBuilder' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/MergeBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NodeBuilder' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/NodeBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/NodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/NodeParentInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NormalizationBuilder' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/NormalizationBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\NumericNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/NumericNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ParentNodeDefinitionInterface' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ScalarNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/ScalarNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/TreeBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\ValidationBuilder' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/ValidationBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Builder\\VariableNodeDefinition' => __DIR__ . '/..' . '/symfony/config/Definition/Builder/VariableNodeDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ConfigurableInterface' => __DIR__ . '/..' . '/symfony/config/Definition/ConfigurableInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Configuration' => __DIR__ . '/..' . '/symfony/config/Definition/Configuration.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ConfigurationInterface' => __DIR__ . '/..' . '/symfony/config/Definition/ConfigurationInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Configurator\\DefinitionConfigurator' => __DIR__ . '/..' . '/symfony/config/Definition/Configurator/DefinitionConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Dumper\\XmlReferenceDumper' => __DIR__ . '/..' . '/symfony/config/Definition/Dumper/XmlReferenceDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Dumper\\YamlReferenceDumper' => __DIR__ . '/..' . '/symfony/config/Definition/Dumper/YamlReferenceDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\EnumNode' => __DIR__ . '/..' . '/symfony/config/Definition/EnumNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\DuplicateKeyException' => __DIR__ . '/..' . '/symfony/config/Definition/Exception/DuplicateKeyException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\Exception' => __DIR__ . '/..' . '/symfony/config/Definition/Exception/Exception.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\ForbiddenOverwriteException' => __DIR__ . '/..' . '/symfony/config/Definition/Exception/ForbiddenOverwriteException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\InvalidConfigurationException' => __DIR__ . '/..' . '/symfony/config/Definition/Exception/InvalidConfigurationException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\InvalidDefinitionException' => __DIR__ . '/..' . '/symfony/config/Definition/Exception/InvalidDefinitionException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\InvalidTypeException' => __DIR__ . '/..' . '/symfony/config/Definition/Exception/InvalidTypeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Exception\\UnsetKeyException' => __DIR__ . '/..' . '/symfony/config/Definition/Exception/UnsetKeyException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\FloatNode' => __DIR__ . '/..' . '/symfony/config/Definition/FloatNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\IntegerNode' => __DIR__ . '/..' . '/symfony/config/Definition/IntegerNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Loader\\DefinitionFileLoader' => __DIR__ . '/..' . '/symfony/config/Definition/Loader/DefinitionFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\NodeInterface' => __DIR__ . '/..' . '/symfony/config/Definition/NodeInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\NumericNode' => __DIR__ . '/..' . '/symfony/config/Definition/NumericNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\Processor' => __DIR__ . '/..' . '/symfony/config/Definition/Processor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\PrototypeNodeInterface' => __DIR__ . '/..' . '/symfony/config/Definition/PrototypeNodeInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\PrototypedArrayNode' => __DIR__ . '/..' . '/symfony/config/Definition/PrototypedArrayNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\ScalarNode' => __DIR__ . '/..' . '/symfony/config/Definition/ScalarNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Definition\\VariableNode' => __DIR__ . '/..' . '/symfony/config/Definition/VariableNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Exception\\FileLoaderImportCircularReferenceException' => __DIR__ . '/..' . '/symfony/config/Exception/FileLoaderImportCircularReferenceException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Exception\\FileLocatorFileNotFoundException' => __DIR__ . '/..' . '/symfony/config/Exception/FileLocatorFileNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Exception\\LoaderLoadException' => __DIR__ . '/..' . '/symfony/config/Exception/LoaderLoadException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\FileLocator' => __DIR__ . '/..' . '/symfony/config/FileLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\FileLocatorInterface' => __DIR__ . '/..' . '/symfony/config/FileLocatorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\DelegatingLoader' => __DIR__ . '/..' . '/symfony/config/Loader/DelegatingLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\DirectoryAwareLoaderInterface' => __DIR__ . '/..' . '/symfony/config/Loader/DirectoryAwareLoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\FileLoader' => __DIR__ . '/..' . '/symfony/config/Loader/FileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\GlobFileLoader' => __DIR__ . '/..' . '/symfony/config/Loader/GlobFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\Loader' => __DIR__ . '/..' . '/symfony/config/Loader/Loader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\LoaderInterface' => __DIR__ . '/..' . '/symfony/config/Loader/LoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\LoaderResolver' => __DIR__ . '/..' . '/symfony/config/Loader/LoaderResolver.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\LoaderResolverInterface' => __DIR__ . '/..' . '/symfony/config/Loader/LoaderResolverInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Loader\\ParamConfigurator' => __DIR__ . '/..' . '/symfony/config/Loader/ParamConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ResourceCheckerConfigCache' => __DIR__ . '/..' . '/symfony/config/ResourceCheckerConfigCache.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ResourceCheckerConfigCacheFactory' => __DIR__ . '/..' . '/symfony/config/ResourceCheckerConfigCacheFactory.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\ResourceCheckerInterface' => __DIR__ . '/..' . '/symfony/config/ResourceCheckerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ClassExistenceResource' => __DIR__ . '/..' . '/symfony/config/Resource/ClassExistenceResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ComposerResource' => __DIR__ . '/..' . '/symfony/config/Resource/ComposerResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\DirectoryResource' => __DIR__ . '/..' . '/symfony/config/Resource/DirectoryResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\FileExistenceResource' => __DIR__ . '/..' . '/symfony/config/Resource/FileExistenceResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\FileResource' => __DIR__ . '/..' . '/symfony/config/Resource/FileResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\GlobResource' => __DIR__ . '/..' . '/symfony/config/Resource/GlobResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ReflectionClassResource' => __DIR__ . '/..' . '/symfony/config/Resource/ReflectionClassResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\ResourceInterface' => __DIR__ . '/..' . '/symfony/config/Resource/ResourceInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\SelfCheckingResourceChecker' => __DIR__ . '/..' . '/symfony/config/Resource/SelfCheckingResourceChecker.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Resource\\SelfCheckingResourceInterface' => __DIR__ . '/..' . '/symfony/config/Resource/SelfCheckingResourceInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Util\\Exception\\InvalidXmlException' => __DIR__ . '/..' . '/symfony/config/Util/Exception/InvalidXmlException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Util\\Exception\\XmlParsingException' => __DIR__ . '/..' . '/symfony/config/Util/Exception/XmlParsingException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\Util\\XmlUtils' => __DIR__ . '/..' . '/symfony/config/Util/XmlUtils.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Application' => __DIR__ . '/..' . '/symfony/console/Application.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Attribute\\AsCommand' => __DIR__ . '/..' . '/symfony/console/Attribute/AsCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CI\\GithubActionReporter' => __DIR__ . '/..' . '/symfony/console/CI/GithubActionReporter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Color' => __DIR__ . '/..' . '/symfony/console/Color.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => __DIR__ . '/..' . '/symfony/console/CommandLoader/CommandLoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => __DIR__ . '/..' . '/symfony/console/CommandLoader/ContainerCommandLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => __DIR__ . '/..' . '/symfony/console/CommandLoader/FactoryCommandLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\Command' => __DIR__ . '/..' . '/symfony/console/Command/Command.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\CompleteCommand' => __DIR__ . '/..' . '/symfony/console/Command/CompleteCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\DumpCompletionCommand' => __DIR__ . '/..' . '/symfony/console/Command/DumpCompletionCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\HelpCommand' => __DIR__ . '/..' . '/symfony/console/Command/HelpCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\LazyCommand' => __DIR__ . '/..' . '/symfony/console/Command/LazyCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\ListCommand' => __DIR__ . '/..' . '/symfony/console/Command/ListCommand.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\LockableTrait' => __DIR__ . '/..' . '/symfony/console/Command/LockableTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Command\\SignalableCommandInterface' => __DIR__ . '/..' . '/symfony/console/Command/SignalableCommandInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\CompletionInput' => __DIR__ . '/..' . '/symfony/console/Completion/CompletionInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\CompletionSuggestions' => __DIR__ . '/..' . '/symfony/console/Completion/CompletionSuggestions.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\BashCompletionOutput' => __DIR__ . '/..' . '/symfony/console/Completion/Output/BashCompletionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\CompletionOutputInterface' => __DIR__ . '/..' . '/symfony/console/Completion/Output/CompletionOutputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\FishCompletionOutput' => __DIR__ . '/..' . '/symfony/console/Completion/Output/FishCompletionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Output\\ZshCompletionOutput' => __DIR__ . '/..' . '/symfony/console/Completion/Output/ZshCompletionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Completion\\Suggestion' => __DIR__ . '/..' . '/symfony/console/Completion/Suggestion.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\ConsoleEvents' => __DIR__ . '/..' . '/symfony/console/ConsoleEvents.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Cursor' => __DIR__ . '/..' . '/symfony/console/Cursor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => __DIR__ . '/..' . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => __DIR__ . '/..' . '/symfony/console/Descriptor/ApplicationDescription.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\Descriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/Descriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => __DIR__ . '/..' . '/symfony/console/Descriptor/DescriptorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/JsonDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/MarkdownDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\ReStructuredTextDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/ReStructuredTextDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/TextDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/XmlDescriptor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\EventListener\\ErrorListener' => __DIR__ . '/..' . '/symfony/console/EventListener/ErrorListener.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleCommandEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleErrorEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleSignalEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleSignalEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleTerminateEvent.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/CommandNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/console/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\InvalidOptionException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidOptionException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/console/Exception/LogicException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\MissingInputException' => __DIR__ . '/..' . '/symfony/console/Exception/MissingInputException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/NamespaceNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/console/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatter' => __DIR__ . '/..' . '/symfony/console/Formatter/NullOutputFormatter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatterStyle' => __DIR__ . '/..' . '/symfony/console/Formatter/NullOutputFormatterStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatter' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleStack.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DebugFormatterHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\DescriptorHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DescriptorHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\Dumper' => __DIR__ . '/..' . '/symfony/console/Helper/Dumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\FormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/FormatterHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\Helper' => __DIR__ . '/..' . '/symfony/console/Helper/Helper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\HelperInterface' => __DIR__ . '/..' . '/symfony/console/Helper/HelperInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\HelperSet' => __DIR__ . '/..' . '/symfony/console/Helper/HelperSet.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\InputAwareHelper' => __DIR__ . '/..' . '/symfony/console/Helper/InputAwareHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\OutputWrapper' => __DIR__ . '/..' . '/symfony/console/Helper/OutputWrapper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\ProcessHelper' => __DIR__ . '/..' . '/symfony/console/Helper/ProcessHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\ProgressBar' => __DIR__ . '/..' . '/symfony/console/Helper/ProgressBar.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\ProgressIndicator' => __DIR__ . '/..' . '/symfony/console/Helper/ProgressIndicator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\QuestionHelper' => __DIR__ . '/..' . '/symfony/console/Helper/QuestionHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => __DIR__ . '/..' . '/symfony/console/Helper/SymfonyQuestionHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\Table' => __DIR__ . '/..' . '/symfony/console/Helper/Table.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableCell' => __DIR__ . '/..' . '/symfony/console/Helper/TableCell.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableCellStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableCellStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableRows' => __DIR__ . '/..' . '/symfony/console/Helper/TableRows.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableSeparator' => __DIR__ . '/..' . '/symfony/console/Helper/TableSeparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Helper\\TableStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\ArgvInput' => __DIR__ . '/..' . '/symfony/console/Input/ArgvInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\ArrayInput' => __DIR__ . '/..' . '/symfony/console/Input/ArrayInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\Input' => __DIR__ . '/..' . '/symfony/console/Input/Input.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputArgument' => __DIR__ . '/..' . '/symfony/console/Input/InputArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputAwareInterface' => __DIR__ . '/..' . '/symfony/console/Input/InputAwareInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputDefinition' => __DIR__ . '/..' . '/symfony/console/Input/InputDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputInterface' => __DIR__ . '/..' . '/symfony/console/Input/InputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\InputOption' => __DIR__ . '/..' . '/symfony/console/Input/InputOption.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\StreamableInputInterface' => __DIR__ . '/..' . '/symfony/console/Input/StreamableInputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Input\\StringInput' => __DIR__ . '/..' . '/symfony/console/Input/StringInput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Logger\\ConsoleLogger' => __DIR__ . '/..' . '/symfony/console/Logger/ConsoleLogger.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\AnsiColorMode' => __DIR__ . '/..' . '/symfony/console/Output/AnsiColorMode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\BufferedOutput' => __DIR__ . '/..' . '/symfony/console/Output/BufferedOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\ConsoleOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleSectionOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\NullOutput' => __DIR__ . '/..' . '/symfony/console/Output/NullOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\Output' => __DIR__ . '/..' . '/symfony/console/Output/Output.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\OutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/OutputInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\StreamOutput' => __DIR__ . '/..' . '/symfony/console/Output/StreamOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Output\\TrimmedBufferOutput' => __DIR__ . '/..' . '/symfony/console/Output/TrimmedBufferOutput.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Question\\ChoiceQuestion' => __DIR__ . '/..' . '/symfony/console/Question/ChoiceQuestion.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => __DIR__ . '/..' . '/symfony/console/Question/ConfirmationQuestion.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Question\\Question' => __DIR__ . '/..' . '/symfony/console/Question/Question.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry' => __DIR__ . '/..' . '/symfony/console/SignalRegistry/SignalRegistry.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\SingleCommandApplication' => __DIR__ . '/..' . '/symfony/console/SingleCommandApplication.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Style\\OutputStyle' => __DIR__ . '/..' . '/symfony/console/Style/OutputStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Style\\StyleInterface' => __DIR__ . '/..' . '/symfony/console/Style/StyleInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Style\\SymfonyStyle' => __DIR__ . '/..' . '/symfony/console/Style/SymfonyStyle.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Terminal' => __DIR__ . '/..' . '/symfony/console/Terminal.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\ApplicationTester' => __DIR__ . '/..' . '/symfony/console/Tester/ApplicationTester.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\CommandCompletionTester' => __DIR__ . '/..' . '/symfony/console/Tester/CommandCompletionTester.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\CommandTester' => __DIR__ . '/..' . '/symfony/console/Tester/CommandTester.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\Constraint\\CommandIsSuccessful' => __DIR__ . '/..' . '/symfony/console/Tester/Constraint/CommandIsSuccessful.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\Tester\\TesterTrait' => __DIR__ . '/..' . '/symfony/console/Tester/TesterTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Alias' => __DIR__ . '/..' . '/symfony/dependency-injection/Alias.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\AbstractArgument' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/AbstractArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ArgumentInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/ArgumentInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\BoundArgument' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/BoundArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\IteratorArgument' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/IteratorArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ReferenceSetArgumentTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\RewindableGenerator' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/RewindableGenerator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ServiceClosureArgument' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/ServiceClosureArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ServiceLocator' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/ServiceLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\ServiceLocatorArgument' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/ServiceLocatorArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Argument\\TaggedIteratorArgument' => __DIR__ . '/..' . '/symfony/dependency-injection/Argument/TaggedIteratorArgument.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\AsDecorator' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/AsDecorator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\AsTaggedItem' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/AsTaggedItem.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\Autoconfigure' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/Autoconfigure.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\AutoconfigureTag' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/AutoconfigureTag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\Autowire' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/Autowire.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\MapDecorated' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/MapDecorated.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/TaggedIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/TaggedLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\Target' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/Target.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Attribute\\When' => __DIR__ . '/..' . '/symfony/dependency-injection/Attribute/When.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ChildDefinition' => __DIR__ . '/..' . '/symfony/dependency-injection/ChildDefinition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AbstractRecursivePass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AbstractRecursivePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AliasDeprecatedPublicServicesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AliasDeprecatedPublicServicesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AnalyzeServiceReferencesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AttributeAutoconfigurationPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutoAliasServicePass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AutoAliasServicePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowireAsDecoratorPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AutowireAsDecoratorPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowirePass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AutowirePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowireRequiredMethodsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\AutowireRequiredPropertiesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/AutowireRequiredPropertiesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckArgumentsValidityPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckCircularReferencesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckDefinitionValidityPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckExceptionOnInvalidReferenceBehaviorPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckReferenceValidityPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CheckTypeDeclarationsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\Compiler' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/Compiler.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/CompilerPassInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\DecoratorServicePass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/DecoratorServicePass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\DefinitionErrorExceptionPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ExtensionCompilerPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\InlineServiceDefinitionsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\PassConfig' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/PassConfig.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterAutoconfigureAttributesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/RegisterAutoconfigureAttributesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterEnvVarProcessorsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterReverseContainerPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RegisterServiceSubscribersPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RemoveAbstractDefinitionsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RemovePrivateAliasesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\RemoveUnusedDefinitionsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ReplaceAliasByActualDefinitionPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveBindingsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveBindingsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveChildDefinitionsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveClassPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveClassPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveDecoratorStackPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveDecoratorStackPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveEnvPlaceholdersPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveFactoryClassPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveHotPathPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveHotPathPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInstanceofConditionalsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInvalidReferencesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveNamedArgumentsPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveNoPreloadPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveNoPreloadPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveParameterPlaceHoldersPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveReferencesToAliasesPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveServiceSubscribersPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ResolveTaggedIteratorArgumentPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceLocatorTagPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraph' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphEdge' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphNode' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Compiler\\ValidateEnvPlaceholdersPass' => __DIR__ . '/..' . '/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResource' => __DIR__ . '/..' . '/symfony/dependency-injection/Config/ContainerParametersResource.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResourceChecker' => __DIR__ . '/..' . '/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Container' => __DIR__ . '/..' . '/symfony/dependency-injection/Container.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerAwareInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/ContainerAwareInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerAwareTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/ContainerAwareTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerBuilder' => __DIR__ . '/..' . '/symfony/dependency-injection/ContainerBuilder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ContainerInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/ContainerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Definition' => __DIR__ . '/..' . '/symfony/dependency-injection/Definition.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\Dumper' => __DIR__ . '/..' . '/symfony/dependency-injection/Dumper/Dumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\DumperInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Dumper/DumperInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\GraphvizDumper' => __DIR__ . '/..' . '/symfony/dependency-injection/Dumper/GraphvizDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\PhpDumper' => __DIR__ . '/..' . '/symfony/dependency-injection/Dumper/PhpDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\Preloader' => __DIR__ . '/..' . '/symfony/dependency-injection/Dumper/Preloader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\XmlDumper' => __DIR__ . '/..' . '/symfony/dependency-injection/Dumper/XmlDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\YamlDumper' => __DIR__ . '/..' . '/symfony/dependency-injection/Dumper/YamlDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\EnvVarLoaderInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/EnvVarLoaderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\EnvVarProcessor' => __DIR__ . '/..' . '/symfony/dependency-injection/EnvVarProcessor.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\EnvVarProcessorInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/EnvVarProcessorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\AutowiringFailedException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/AutowiringFailedException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\BadMethodCallException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/BadMethodCallException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\EnvNotFoundException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/EnvNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\EnvParameterException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/EnvParameterException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\InvalidParameterTypeException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/InvalidParameterTypeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/LogicException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\OutOfBoundsException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/OutOfBoundsException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ParameterCircularReferenceException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ParameterNotFoundException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/ParameterNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ServiceCircularReferenceException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Exception\\ServiceNotFoundException' => __DIR__ . '/..' . '/symfony/dependency-injection/Exception/ServiceNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ExpressionLanguage' => __DIR__ . '/..' . '/symfony/dependency-injection/ExpressionLanguage.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ExpressionLanguageProvider' => __DIR__ . '/..' . '/symfony/dependency-injection/ExpressionLanguageProvider.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/symfony/dependency-injection/Extension/AbstractExtension.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ConfigurableExtensionInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Extension/ConfigurableExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ConfigurationExtensionInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\Extension' => __DIR__ . '/..' . '/symfony/dependency-injection/Extension/Extension.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Extension/ExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\ExtensionTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Extension/ExtensionTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Extension\\PrependExtensionInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/Extension/PrependExtensionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\InstantiatorInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\RealServiceInstantiator' => __DIR__ . '/..' . '/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\DumperInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\NullDumper' => __DIR__ . '/..' . '/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\LazyProxy\\ProxyHelper' => __DIR__ . '/..' . '/symfony/dependency-injection/LazyProxy/ProxyHelper.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\ClosureLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/ClosureLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractServiceConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AliasConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ClosureReferenceConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/ClosureReferenceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\DefaultsConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\EnvConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/EnvConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InlineServiceConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InstanceofConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ParametersConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\PrototypeConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ReferenceConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServiceConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServicesConfigurator' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AbstractTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ArgumentTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutoconfigureTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutowireTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\BindTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\CallTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ClassTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ConfiguratorTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DecorateTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DeprecateTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FactoryTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FileTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\LazyTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ParentTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PropertyTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PublicTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ShareTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\SyntheticTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\TagTrait' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\DirectoryLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/DirectoryLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\FileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/FileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\GlobFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/GlobFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\IniFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/IniFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\PhpFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/PhpFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\XmlFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/XmlFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' => __DIR__ . '/..' . '/symfony/dependency-injection/Loader/YamlFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Parameter' => __DIR__ . '/..' . '/symfony/dependency-injection/Parameter.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ContainerBag' => __DIR__ . '/..' . '/symfony/dependency-injection/ParameterBag/ContainerBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ContainerBagInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\EnvPlaceholderParameterBag' => __DIR__ . '/..' . '/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\FrozenParameterBag' => __DIR__ . '/..' . '/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag' => __DIR__ . '/..' . '/symfony/dependency-injection/ParameterBag/ParameterBag.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBagInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Reference' => __DIR__ . '/..' . '/symfony/dependency-injection/Reference.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ReverseContainer' => __DIR__ . '/..' . '/symfony/dependency-injection/ReverseContainer.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\ServiceLocator' => __DIR__ . '/..' . '/symfony/dependency-injection/ServiceLocator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\TaggedContainerInterface' => __DIR__ . '/..' . '/symfony/dependency-injection/TaggedContainerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\TypedReference' => __DIR__ . '/..' . '/symfony/dependency-injection/TypedReference.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Variable' => __DIR__ . '/..' . '/symfony/dependency-injection/Variable.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/filesystem/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/FileNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\IOException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/IOException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\IOExceptionInterface' => __DIR__ . '/..' . '/symfony/filesystem/Exception/IOExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Filesystem' => __DIR__ . '/..' . '/symfony/filesystem/Filesystem.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\Path' => __DIR__ . '/..' . '/symfony/filesystem/Path.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Comparator\\Comparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/Comparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Comparator\\DateComparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/DateComparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Comparator\\NumberComparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/NumberComparator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => __DIR__ . '/..' . '/symfony/finder/Exception/AccessDeniedException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Exception\\DirectoryNotFoundException' => __DIR__ . '/..' . '/symfony/finder/Exception/DirectoryNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Finder' => __DIR__ . '/..' . '/symfony/finder/Finder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Gitignore' => __DIR__ . '/..' . '/symfony/finder/Gitignore.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Glob' => __DIR__ . '/..' . '/symfony/finder/Glob.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/CustomFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/DateRangeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/DepthRangeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FileTypeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilecontentFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilenameFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\LazyIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/LazyIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/PathFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SizeRangeFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\SortableIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SortableIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\Iterator\\VcsIgnoredFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/VcsIgnoredFilterIterator.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\SplFileInfo' => __DIR__ . '/..' . '/symfony/finder/SplFileInfo.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/process/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/process/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/process/Exception/LogicException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ProcessFailedException' => __DIR__ . '/..' . '/symfony/process/Exception/ProcessFailedException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ProcessSignaledException' => __DIR__ . '/..' . '/symfony/process/Exception/ProcessSignaledException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => __DIR__ . '/..' . '/symfony/process/Exception/ProcessTimedOutException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/process/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\ExecutableFinder' => __DIR__ . '/..' . '/symfony/process/ExecutableFinder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\InputStream' => __DIR__ . '/..' . '/symfony/process/InputStream.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\PhpExecutableFinder' => __DIR__ . '/..' . '/symfony/process/PhpExecutableFinder.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\PhpProcess' => __DIR__ . '/..' . '/symfony/process/PhpProcess.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\AbstractPipes' => __DIR__ . '/..' . '/symfony/process/Pipes/AbstractPipes.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\PipesInterface' => __DIR__ . '/..' . '/symfony/process/Pipes/PipesInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\UnixPipes' => __DIR__ . '/..' . '/symfony/process/Pipes/UnixPipes.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Pipes\\WindowsPipes' => __DIR__ . '/..' . '/symfony/process/Pipes/WindowsPipes.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\Process' => __DIR__ . '/..' . '/symfony/process/Process.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\ProcessUtils' => __DIR__ . '/..' . '/symfony/process/ProcessUtils.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\AbstractString' => __DIR__ . '/..' . '/symfony/string/AbstractString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\AbstractUnicodeString' => __DIR__ . '/..' . '/symfony/string/AbstractUnicodeString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\ByteString' => __DIR__ . '/..' . '/symfony/string/ByteString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\CodePointString' => __DIR__ . '/..' . '/symfony/string/CodePointString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/string/Exception/ExceptionInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/string/Exception/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/string/Exception/RuntimeException.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Inflector\\EnglishInflector' => __DIR__ . '/..' . '/symfony/string/Inflector/EnglishInflector.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Inflector\\FrenchInflector' => __DIR__ . '/..' . '/symfony/string/Inflector/FrenchInflector.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Inflector\\InflectorInterface' => __DIR__ . '/..' . '/symfony/string/Inflector/InflectorInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\LazyString' => __DIR__ . '/..' . '/symfony/string/LazyString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Slugger\\AsciiSlugger' => __DIR__ . '/..' . '/symfony/string/Slugger/AsciiSlugger.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\Slugger\\SluggerInterface' => __DIR__ . '/..' . '/symfony/string/Slugger/SluggerInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\UnicodeString' => __DIR__ . '/..' . '/symfony/string/UnicodeString.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\Attribute\\Required' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/Required.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/SubscribedService.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ResetInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ResetInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceLocatorTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceLocatorTrait.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceProviderInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceProviderInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberInterface.php', + 'MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberTrait.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\DependencyInjection\\CompilerPass\\AutowireArrayParameterCompilerPass' => __DIR__ . '/..' . '/symplify/autowire-array-parameter/src/DependencyInjection/CompilerPass/AutowireArrayParameterCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\DependencyInjection\\DefinitionFinder' => __DIR__ . '/..' . '/symplify/autowire-array-parameter/src/DependencyInjection/DefinitionFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\DocBlock\\ParamTypeDocBlockResolver' => __DIR__ . '/..' . '/symplify/autowire-array-parameter/src/DocBlock/ParamTypeDocBlockResolver.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\Exception\\DependencyInjection\\DefinitionForTypeNotFoundException' => __DIR__ . '/..' . '/symplify/autowire-array-parameter/src/Exception/DependencyInjection/DefinitionForTypeNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\Skipper\\ParameterSkipper' => __DIR__ . '/..' . '/symplify/autowire-array-parameter/src/Skipper/ParameterSkipper.php', + 'MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\TypeResolver\\ParameterTypeResolver' => __DIR__ . '/..' . '/symplify/autowire-array-parameter/src/TypeResolver/ParameterTypeResolver.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\Command\\ValidateFixtureSkipNamingCommand' => __DIR__ . '/..' . '/symplify/easy-testing/src/Command/ValidateFixtureSkipNamingCommand.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\DataProvider\\StaticFixtureFinder' => __DIR__ . '/..' . '/symplify/easy-testing/src/DataProvider/StaticFixtureFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\DataProvider\\StaticFixtureUpdater' => __DIR__ . '/..' . '/symplify/easy-testing/src/DataProvider/StaticFixtureUpdater.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\Finder\\FixtureFinder' => __DIR__ . '/..' . '/symplify/easy-testing/src/Finder/FixtureFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\FixtureSplitter\\TrioFixtureSplitter' => __DIR__ . '/..' . '/symplify/easy-testing/src/FixtureSplitter/TrioFixtureSplitter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\Kernel\\EasyTestingKernel' => __DIR__ . '/..' . '/symplify/easy-testing/src/Kernel/EasyTestingKernel.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\MissplacedSkipPrefixResolver' => __DIR__ . '/..' . '/symplify/easy-testing/src/MissplacedSkipPrefixResolver.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\PHPUnit\\Behavior\\DirectoryAssertableTrait' => __DIR__ . '/..' . '/symplify/easy-testing/src/PHPUnit/Behavior/DirectoryAssertableTrait.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\PHPUnit\\StaticPHPUnitEnvironment' => __DIR__ . '/..' . '/symplify/easy-testing/src/PHPUnit/StaticPHPUnitEnvironment.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\StaticFixtureSplitter' => __DIR__ . '/..' . '/symplify/easy-testing/src/StaticFixtureSplitter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\EasyTestingConfig' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/EasyTestingConfig.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\ExpectedAndOutputFileInfoPair' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/ExpectedAndOutputFileInfoPair.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\FixtureSplit\\TrioContent' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/FixtureSplit/TrioContent.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\IncorrectAndMissingSkips' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/IncorrectAndMissingSkips.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\InputAndExpected' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/InputAndExpected.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\InputFileInfoAndExpected' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpected.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\InputFileInfoAndExpectedFileInfo' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpectedFileInfo.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\Option' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/Option.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\Prefix' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/Prefix.php', + 'MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\ValueObject\\SplitLine' => __DIR__ . '/..' . '/symplify/easy-testing/src/ValueObject/SplitLine.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Composer\\VendorDirProvider' => __DIR__ . '/..' . '/symplify/package-builder/src/Composer/VendorDirProvider.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Command\\AbstractSymplifyCommand' => __DIR__ . '/..' . '/symplify/package-builder/src/Console/Command/AbstractSymplifyCommand.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Formatter\\ColorConsoleDiffFormatter' => __DIR__ . '/..' . '/symplify/package-builder/src/Console/Formatter/ColorConsoleDiffFormatter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Input\\StaticInputDetector' => __DIR__ . '/..' . '/symplify/package-builder/src/Console/Input/StaticInputDetector.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Output\\ConsoleDiffer' => __DIR__ . '/..' . '/symplify/package-builder/src/Console/Output/ConsoleDiffer.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Console\\Style\\SymfonyStyleFactory' => __DIR__ . '/..' . '/symplify/package-builder/src/Console/Style/SymfonyStyleFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\DependencyInjection\\CompilerPass\\AutowireInterfacesCompilerPass' => __DIR__ . '/..' . '/symplify/package-builder/src/DependencyInjection/CompilerPass/AutowireInterfacesCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\DependencyInjection\\FileLoader\\ParameterMergingPhpFileLoader' => __DIR__ . '/..' . '/symplify/package-builder/src/DependencyInjection/FileLoader/ParameterMergingPhpFileLoader.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Diff\\DifferFactory' => __DIR__ . '/..' . '/symplify/package-builder/src/Diff/DifferFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Diff\\Output\\CompleteUnifiedDiffOutputBuilderFactory' => __DIR__ . '/..' . '/symplify/package-builder/src/Diff/Output/CompleteUnifiedDiffOutputBuilderFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\HttpKernel\\MissingInterfaceException' => __DIR__ . '/..' . '/symplify/package-builder/src/Exception/HttpKernel/MissingInterfaceException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\InvalidPrivatePropertyTypeException' => __DIR__ . '/..' . '/symplify/package-builder/src/Exception/InvalidPrivatePropertyTypeException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\MissingPrivatePropertyException' => __DIR__ . '/..' . '/symplify/package-builder/src/Exception/MissingPrivatePropertyException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Exception\\MissingServiceException' => __DIR__ . '/..' . '/symplify/package-builder/src/Exception/MissingServiceException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Parameter\\ParameterProvider' => __DIR__ . '/..' . '/symplify/package-builder/src/Parameter/ParameterProvider.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Php\\TypeChecker' => __DIR__ . '/..' . '/symplify/package-builder/src/Php/TypeChecker.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Reflection\\ClassLikeExistenceChecker' => __DIR__ . '/..' . '/symplify/package-builder/src/Reflection/ClassLikeExistenceChecker.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Reflection\\PrivatesAccessor' => __DIR__ . '/..' . '/symplify/package-builder/src/Reflection/PrivatesAccessor.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Reflection\\PrivatesCaller' => __DIR__ . '/..' . '/symplify/package-builder/src/Reflection/PrivatesCaller.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Strings\\StringFormatConverter' => __DIR__ . '/..' . '/symplify/package-builder/src/Strings/StringFormatConverter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\ValueObject\\ConsoleColorDiffConfig' => __DIR__ . '/..' . '/symplify/package-builder/src/ValueObject/ConsoleColorDiffConfig.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\ValueObject\\MethodName' => __DIR__ . '/..' . '/symplify/package-builder/src/ValueObject/MethodName.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\ValueObject\\Option' => __DIR__ . '/..' . '/symplify/package-builder/src/ValueObject/Option.php', + 'MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Yaml\\ParametersMerger' => __DIR__ . '/..' . '/symplify/package-builder/src/Yaml/ParametersMerger.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Exception\\DirectoryNotFoundException' => __DIR__ . '/..' . '/symplify/smart-file-system/src/Exception/DirectoryNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Exception\\FileNotFoundException' => __DIR__ . '/..' . '/symplify/smart-file-system/src/Exception/FileNotFoundException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\FileSystemFilter' => __DIR__ . '/..' . '/symplify/smart-file-system/src/FileSystemFilter.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\FileSystemGuard' => __DIR__ . '/..' . '/symplify/smart-file-system/src/FileSystemGuard.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Finder\\FinderSanitizer' => __DIR__ . '/..' . '/symplify/smart-file-system/src/Finder/FinderSanitizer.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Finder\\SmartFinder' => __DIR__ . '/..' . '/symplify/smart-file-system/src/Finder/SmartFinder.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Json\\JsonFileSystem' => __DIR__ . '/..' . '/symplify/smart-file-system/src/Json/JsonFileSystem.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Normalizer\\PathNormalizer' => __DIR__ . '/..' . '/symplify/smart-file-system/src/Normalizer/PathNormalizer.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\SmartFileInfo' => __DIR__ . '/..' . '/symplify/smart-file-system/src/SmartFileInfo.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\SmartFileSystem' => __DIR__ . '/..' . '/symplify/smart-file-system/src/SmartFileSystem.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Config\\Loader\\ParameterMergingLoaderFactory' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/Config/Loader/ParameterMergingLoaderFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\ContainerBuilderFactory' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/ContainerBuilderFactory.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Contract\\Config\\LoaderFactoryInterface' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/Contract/Config/LoaderFactoryInterface.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Contract\\LightKernelInterface' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/Contract/LightKernelInterface.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\DependencyInjection\\LoadExtensionConfigsCompilerPass' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/DependencyInjection/LoadExtensionConfigsCompilerPass.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Exception\\BootException' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/Exception/BootException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Exception\\ShouldNotHappenException' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/Exception/ShouldNotHappenException.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\HttpKernel\\AbstractSymplifyKernel' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/HttpKernel/AbstractSymplifyKernel.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\ValueObject\\KernelBootAndApplicationRun' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/ValueObject/KernelBootAndApplicationRun.php', + 'MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\ValueObject\\SymplifyKernelConfig' => __DIR__ . '/..' . '/symplify/symplify-kernel/src/ValueObject/SymplifyKernelConfig.php', + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\Assert' => __DIR__ . '/..' . '/webmozart/assert/src/Assert.php', + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\InvalidArgumentException' => __DIR__ . '/..' . '/webmozart/assert/src/InvalidArgumentException.php', + 'MonorepoBuilderPrefix202310\\Webmozart\\Assert\\Mixin' => __DIR__ . '/..' . '/webmozart/assert/src/Mixin.php', + 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', + 'PharIo\\Version\\AbstractVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AnyVersionConstraint.php', + 'PharIo\\Version\\BuildMetaData' => __DIR__ . '/..' . '/phar-io/version/src/BuildMetaData.php', + 'PharIo\\Version\\ExactVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidPreReleaseSuffixException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php', + 'PharIo\\Version\\InvalidVersionException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/InvalidVersionException.php', + 'PharIo\\Version\\NoBuildMetaDataException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/NoBuildMetaDataException.php', + 'PharIo\\Version\\NoPreReleaseSuffixException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/NoPreReleaseSuffixException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => __DIR__ . '/..' . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => __DIR__ . '/..' . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => __DIR__ . '/..' . '/phar-io/version/src/VersionNumber.php', + 'Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php', + 'Symfony\\Polyfill\\Intl\\Grapheme\\Grapheme' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/Grapheme.php', + 'Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php', + 'Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php', + 'Symplify\\MonorepoBuilder\\Command\\BumpInterdependencyCommand' => __DIR__ . '/../..' . '/src/Command/BumpInterdependencyCommand.php', + 'Symplify\\MonorepoBuilder\\Command\\PackageAliasCommand' => __DIR__ . '/../..' . '/src/Command/PackageAliasCommand.php', + 'Symplify\\MonorepoBuilder\\Command\\ValidateCommand' => __DIR__ . '/../..' . '/src/Command/ValidateCommand.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ComposerJsonFactory' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/ComposerJsonFactory.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\FileSystem\\JsonFileManager' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/FileSystem/JsonFileManager.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Json\\JsonCleaner' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/Json/JsonCleaner.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Json\\JsonInliner' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/Json/JsonInliner.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Printer\\ComposerJsonPrinter' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/Printer/ComposerJsonPrinter.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\Sorter\\ComposerPackageSorter' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/Sorter/ComposerPackageSorter.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ValueObject\\ComposerJson' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/ValueObject/ComposerJson.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ValueObject\\ComposerJsonSection' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/ValueObject/ComposerJsonSection.php', + 'Symplify\\MonorepoBuilder\\ComposerJsonManipulator\\ValueObject\\Option' => __DIR__ . '/../..' . '/packages/ComposerJsonManipulator/ValueObject/Option.php', + 'Symplify\\MonorepoBuilder\\Config\\MBConfig' => __DIR__ . '/../..' . '/src/Config/MBConfig.php', + 'Symplify\\MonorepoBuilder\\Console\\MonorepoBuilderApplication' => __DIR__ . '/../..' . '/src/Console/MonorepoBuilderApplication.php', + 'Symplify\\MonorepoBuilder\\Contract\\Git\\TagResolverInterface' => __DIR__ . '/../..' . '/src/Contract/Git/TagResolverInterface.php', + 'Symplify\\MonorepoBuilder\\DependencyUpdater' => __DIR__ . '/../..' . '/src/DependencyUpdater.php', + 'Symplify\\MonorepoBuilder\\DevMasterAliasUpdater' => __DIR__ . '/../..' . '/src/DevMasterAliasUpdater.php', + 'Symplify\\MonorepoBuilder\\Exception\\ConfigurationException' => __DIR__ . '/../..' . '/src/Exception/ConfigurationException.php', + 'Symplify\\MonorepoBuilder\\Exception\\Git\\InvalidGitVersionException' => __DIR__ . '/../..' . '/src/Exception/Git/InvalidGitVersionException.php', + 'Symplify\\MonorepoBuilder\\Exception\\MissingComposerJsonException' => __DIR__ . '/../..' . '/src/Exception/MissingComposerJsonException.php', + 'Symplify\\MonorepoBuilder\\Exception\\Validator\\InvalidComposerJsonSetupException' => __DIR__ . '/../..' . '/src/Exception/Validator/InvalidComposerJsonSetupException.php', + 'Symplify\\MonorepoBuilder\\FileSystem\\ComposerJsonProvider' => __DIR__ . '/../..' . '/src/FileSystem/ComposerJsonProvider.php', + 'Symplify\\MonorepoBuilder\\Finder\\PackageComposerFinder' => __DIR__ . '/../..' . '/src/Finder/PackageComposerFinder.php', + 'Symplify\\MonorepoBuilder\\Git\\ExpectedAliasResolver' => __DIR__ . '/../..' . '/src/Git/ExpectedAliasResolver.php', + 'Symplify\\MonorepoBuilder\\Git\\MostRecentTagResolver' => __DIR__ . '/../..' . '/src/Git/MostRecentTagResolver.php', + 'Symplify\\MonorepoBuilder\\Init\\Command\\InitCommand' => __DIR__ . '/../..' . '/packages/Init/Command/InitCommand.php', + 'Symplify\\MonorepoBuilder\\Kernel\\MonorepoBuilderKernel' => __DIR__ . '/../..' . '/src/Kernel/MonorepoBuilderKernel.php', + 'Symplify\\MonorepoBuilder\\Merge\\Application\\MergedAndDecoratedComposerJsonFactory' => __DIR__ . '/../..' . '/packages/Merge/Application/MergedAndDecoratedComposerJsonFactory.php', + 'Symplify\\MonorepoBuilder\\Merge\\Arrays\\ArraySorter' => __DIR__ . '/../..' . '/packages/Merge/Arrays/ArraySorter.php', + 'Symplify\\MonorepoBuilder\\Merge\\Arrays\\SortedParameterMerger' => __DIR__ . '/../..' . '/packages/Merge/Arrays/SortedParameterMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\Cleaner\\RequireRequireDevDuplicateCleaner' => __DIR__ . '/../..' . '/packages/Merge/Cleaner/RequireRequireDevDuplicateCleaner.php', + 'Symplify\\MonorepoBuilder\\Merge\\Command\\MergeCommand' => __DIR__ . '/../..' . '/packages/Merge/Command/MergeCommand.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\AppenderComposerJsonDecorator' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonDecorator/AppenderComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\FilterOutDuplicatedRequireAndRequireDevJsonDecorator' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonDecorator/FilterOutDuplicatedRequireAndRequireDevJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\RemoverComposerJsonDecorator' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonDecorator/RemoverComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\ReplaceSectionJsonDecorator' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonDecorator/ReplaceSectionJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\RepositoryPathComposerJsonDecorator' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonDecorator/RepositoryPathComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\RootRemoveComposerJsonDecorator' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonDecorator/RootRemoveComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonDecorator\\SortComposerJsonDecorator' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonDecorator/SortComposerJsonDecorator.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerJsonMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerJsonMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\AuthorComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/AuthorComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\AutoloadComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/AutoloadComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\AutoloadDevComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/AutoloadDevComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\ExtraComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/ExtraComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\MinimalStabilityKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/MinimalStabilityKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\PreferStableKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/PreferStableKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\ProvideComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/ProvideComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\ReplaceComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/ReplaceComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\RepositoriesComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/RepositoriesComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\RequireComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/RequireComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\ComposerKeyMerger\\RequireDevComposerKeyMerger' => __DIR__ . '/../..' . '/packages/Merge/ComposerKeyMerger/RequireDevComposerKeyMerger.php', + 'Symplify\\MonorepoBuilder\\Merge\\Configuration\\MergedPackagesCollector' => __DIR__ . '/../..' . '/packages/Merge/Configuration/MergedPackagesCollector.php', + 'Symplify\\MonorepoBuilder\\Merge\\Configuration\\ModifyingComposerJsonProvider' => __DIR__ . '/../..' . '/packages/Merge/Configuration/ModifyingComposerJsonProvider.php', + 'Symplify\\MonorepoBuilder\\Merge\\Contract\\ComposerJsonDecoratorInterface' => __DIR__ . '/../..' . '/packages/Merge/Contract/ComposerJsonDecoratorInterface.php', + 'Symplify\\MonorepoBuilder\\Merge\\Contract\\ComposerKeyMergerInterface' => __DIR__ . '/../..' . '/packages/Merge/Contract/ComposerKeyMergerInterface.php', + 'Symplify\\MonorepoBuilder\\Merge\\Contract\\ComposerPathNormalizerInterface' => __DIR__ . '/../..' . '/packages/Merge/Contract/ComposerPathNormalizerInterface.php', + 'Symplify\\MonorepoBuilder\\Merge\\Guard\\ConflictingVersionsGuard' => __DIR__ . '/../..' . '/packages/Merge/Guard/ConflictingVersionsGuard.php', + 'Symplify\\MonorepoBuilder\\Merge\\PathResolver\\AutoloadPathNormalizer' => __DIR__ . '/../..' . '/packages/Merge/PathResolver/AutoloadPathNormalizer.php', + 'Symplify\\MonorepoBuilder\\Merge\\PathResolver\\ComposerPatchesPathNormalizer' => __DIR__ . '/../..' . '/packages/Merge/PathResolver/ComposerPatchesPathNormalizer.php', + 'Symplify\\MonorepoBuilder\\Package\\PackageNamesProvider' => __DIR__ . '/../..' . '/src/Package/PackageNamesProvider.php', + 'Symplify\\MonorepoBuilder\\Propagate\\Command\\PropagateCommand' => __DIR__ . '/../..' . '/packages/Propagate/Command/PropagateCommand.php', + 'Symplify\\MonorepoBuilder\\Propagate\\VersionPropagator' => __DIR__ . '/../..' . '/packages/Propagate/VersionPropagator.php', + 'Symplify\\MonorepoBuilder\\Release\\Command\\ReleaseCommand' => __DIR__ . '/../..' . '/packages/Release/Command/ReleaseCommand.php', + 'Symplify\\MonorepoBuilder\\Release\\Configuration\\StageResolver' => __DIR__ . '/../..' . '/packages/Release/Configuration/StageResolver.php', + 'Symplify\\MonorepoBuilder\\Release\\Configuration\\VersionResolver' => __DIR__ . '/../..' . '/packages/Release/Configuration/VersionResolver.php', + 'Symplify\\MonorepoBuilder\\Release\\Contract\\ReleaseWorker\\ReleaseWorkerInterface' => __DIR__ . '/../..' . '/packages/Release/Contract/ReleaseWorker/ReleaseWorkerInterface.php', + 'Symplify\\MonorepoBuilder\\Release\\Contract\\ReleaseWorker\\StageAwareInterface' => __DIR__ . '/../..' . '/packages/Release/Contract/ReleaseWorker/StageAwareInterface.php', + 'Symplify\\MonorepoBuilder\\Release\\Exception\\ConfigurationException' => __DIR__ . '/../..' . '/packages/Release/Exception/ConfigurationException.php', + 'Symplify\\MonorepoBuilder\\Release\\Exception\\MissingComposerJsonException' => __DIR__ . '/../..' . '/packages/Release/Exception/MissingComposerJsonException.php', + 'Symplify\\MonorepoBuilder\\Release\\Guard\\ReleaseGuard' => __DIR__ . '/../..' . '/packages/Release/Guard/ReleaseGuard.php', + 'Symplify\\MonorepoBuilder\\Release\\Output\\ReleaseWorkerReporter' => __DIR__ . '/../..' . '/packages/Release/Output/ReleaseWorkerReporter.php', + 'Symplify\\MonorepoBuilder\\Release\\Process\\ProcessRunner' => __DIR__ . '/../..' . '/packages/Release/Process/ProcessRunner.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorkerProvider' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorkerProvider.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\AddTagToChangelogReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/AddTagToChangelogReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\PushNextDevReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/PushNextDevReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\PushTagReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/PushTagReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\SetCurrentMutualDependenciesReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/SetCurrentMutualDependenciesReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\SetNextMutualDependenciesReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/SetNextMutualDependenciesReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\TagVersionReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/TagVersionReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\UpdateBranchAliasReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/UpdateBranchAliasReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ReleaseWorker\\UpdateReplaceReleaseWorker' => __DIR__ . '/../..' . '/packages/Release/ReleaseWorker/UpdateReplaceReleaseWorker.php', + 'Symplify\\MonorepoBuilder\\Release\\ValueObject\\SemVersion' => __DIR__ . '/../..' . '/packages/Release/ValueObject/SemVersion.php', + 'Symplify\\MonorepoBuilder\\Release\\ValueObject\\Stage' => __DIR__ . '/../..' . '/packages/Release/ValueObject/Stage.php', + 'Symplify\\MonorepoBuilder\\Release\\Version\\VersionFactory' => __DIR__ . '/../..' . '/packages/Release/Version/VersionFactory.php', + 'Symplify\\MonorepoBuilder\\Testing\\Command\\LocalizeComposerPathsCommand' => __DIR__ . '/../..' . '/packages/Testing/Command/LocalizeComposerPathsCommand.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJsonRepositoriesUpdater' => __DIR__ . '/../..' . '/packages/Testing/ComposerJsonRepositoriesUpdater.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJsonRequireUpdater' => __DIR__ . '/../..' . '/packages/Testing/ComposerJsonRequireUpdater.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJson\\ComposerJsonSymlinker' => __DIR__ . '/../..' . '/packages/Testing/ComposerJson/ComposerJsonSymlinker.php', + 'Symplify\\MonorepoBuilder\\Testing\\ComposerJson\\ComposerVersionManipulator' => __DIR__ . '/../..' . '/packages/Testing/ComposerJson/ComposerVersionManipulator.php', + 'Symplify\\MonorepoBuilder\\Testing\\PackageDependency\\UsedPackagesResolver' => __DIR__ . '/../..' . '/packages/Testing/PackageDependency/UsedPackagesResolver.php', + 'Symplify\\MonorepoBuilder\\Testing\\PathResolver\\PackagePathResolver' => __DIR__ . '/../..' . '/packages/Testing/PathResolver/PackagePathResolver.php', + 'Symplify\\MonorepoBuilder\\Testing\\ValueObject\\Option' => __DIR__ . '/../..' . '/packages/Testing/ValueObject/Option.php', + 'Symplify\\MonorepoBuilder\\Utils\\RelativeFilePathHelper' => __DIR__ . '/../..' . '/src/Utils/RelativeFilePathHelper.php', + 'Symplify\\MonorepoBuilder\\Utils\\VersionUtils' => __DIR__ . '/../..' . '/src/Utils/VersionUtils.php', + 'Symplify\\MonorepoBuilder\\Validator\\ConflictingPackageVersionsReporter' => __DIR__ . '/../..' . '/src/Validator/ConflictingPackageVersionsReporter.php', + 'Symplify\\MonorepoBuilder\\Validator\\SourcesPresenceValidator' => __DIR__ . '/../..' . '/src/Validator/SourcesPresenceValidator.php', + 'Symplify\\MonorepoBuilder\\ValueObject\\File' => __DIR__ . '/../..' . '/src/ValueObject/File.php', + 'Symplify\\MonorepoBuilder\\ValueObject\\Option' => __DIR__ . '/../..' . '/src/ValueObject/Option.php', + 'Symplify\\MonorepoBuilder\\VersionValidator' => __DIR__ . '/../..' . '/src/VersionValidator.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit40522c779707518f5fc82043e1269113::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit40522c779707518f5fc82043e1269113::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit40522c779707518f5fc82043e1269113::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000000..063c7a28b0 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,1729 @@ +{ + "packages": [ + { + "name": "nette\/utils", + "version": "v3.2.10", + "version_normalized": "3.2.10.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/nette\/utils.git", + "reference": "a4175c62652f2300c8017fb7e640f9ccb11648d2" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/nette\/utils\/zipball\/a4175c62652f2300c8017fb7e640f9ccb11648d2", + "reference": "a4175c62652f2300c8017fb7e640f9ccb11648d2", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.4" + }, + "conflict": { + "nette\/di": "<3.0.6" + }, + "require-dev": { + "jetbrains\/phpstorm-attributes": "dev-master", + "nette\/tester": "~2.0", + "phpstan\/phpstan": "^1.0", + "tracy\/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "time": "2023-07-30T15:38:18+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https:\/\/davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https:\/\/nette.org\/contributors" + } + ], + "description": "\ud83d\udee0 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding\/decoding, validation, slug or strong password generating etc.", + "homepage": "https:\/\/nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https:\/\/github.com\/nette\/utils\/issues", + "source": "https:\/\/github.com\/nette\/utils\/tree\/v3.2.10" + }, + "install-path": "..\/nette\/utils" + }, + { + "name": "phar-io\/version", + "version": "3.2.1", + "version_normalized": "3.2.1.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/phar-io\/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/phar-io\/version\/zipball\/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2022-02-21T01:04:05+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https:\/\/github.com\/phar-io\/version\/issues", + "source": "https:\/\/github.com\/phar-io\/version\/tree\/3.2.1" + }, + "install-path": "..\/phar-io\/version" + }, + { + "name": "psr\/container", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/php-fig\/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/php-fig\/container\/zipball\/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "time": "2021-11-05T16:47:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Psr\\Container\\": "src\/" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https:\/\/www.php-fig.org\/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https:\/\/github.com\/php-fig\/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https:\/\/github.com\/php-fig\/container\/issues", + "source": "https:\/\/github.com\/php-fig\/container\/tree\/2.0.2" + }, + "install-path": "..\/psr\/container" + }, + { + "name": "sebastian\/diff", + "version": "5.0.3", + "version_normalized": "5.0.3.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/sebastianbergmann\/diff.git", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/sebastianbergmann\/diff\/zipball\/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit\/phpunit": "^10.0", + "symfony\/process": "^4.2 || ^5" + }, + "time": "2023-05-01T07:48:21+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https:\/\/github.com\/sebastianbergmann\/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https:\/\/github.com\/sebastianbergmann\/diff\/issues", + "security": "https:\/\/github.com\/sebastianbergmann\/diff\/security\/policy", + "source": "https:\/\/github.com\/sebastianbergmann\/diff\/tree\/5.0.3" + }, + "funding": [ + { + "url": "https:\/\/github.com\/sebastianbergmann", + "type": "github" + } + ], + "install-path": "..\/sebastian\/diff" + }, + { + "name": "symfony\/config", + "version": "v6.3.2", + "version_normalized": "6.3.2.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/config.git", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/config\/zipball\/b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony\/deprecation-contracts": "^2.5|^3", + "symfony\/filesystem": "^5.4|^6.0", + "symfony\/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony\/finder": "<5.4", + "symfony\/service-contracts": "<2.5" + }, + "require-dev": { + "symfony\/event-dispatcher": "^5.4|^6.0", + "symfony\/finder": "^5.4|^6.0", + "symfony\/messenger": "^5.4|^6.0", + "symfony\/service-contracts": "^2.5|^3", + "symfony\/yaml": "^5.4|^6.0" + }, + "time": "2023-07-19T20:22:16+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https:\/\/symfony.com", + "support": { + "source": "https:\/\/github.com\/symfony\/config\/tree\/v6.3.2" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/config" + }, + { + "name": "symfony\/console", + "version": "v6.3.4", + "version_normalized": "6.3.4.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/console.git", + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/console\/zipball\/eca495f2ee845130855ddf1cf18460c38966c8b6", + "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony\/deprecation-contracts": "^2.5|^3", + "symfony\/polyfill-mbstring": "~1.0", + "symfony\/service-contracts": "^2.5|^3", + "symfony\/string": "^5.4|^6.0" + }, + "conflict": { + "symfony\/dependency-injection": "<5.4", + "symfony\/dotenv": "<5.4", + "symfony\/event-dispatcher": "<5.4", + "symfony\/lock": "<5.4", + "symfony\/process": "<5.4" + }, + "provide": { + "psr\/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr\/log": "^1|^2|^3", + "symfony\/config": "^5.4|^6.0", + "symfony\/dependency-injection": "^5.4|^6.0", + "symfony\/event-dispatcher": "^5.4|^6.0", + "symfony\/lock": "^5.4|^6.0", + "symfony\/process": "^5.4|^6.0", + "symfony\/var-dumper": "^5.4|^6.0" + }, + "time": "2023-08-16T10:10:12+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https:\/\/symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https:\/\/github.com\/symfony\/console\/tree\/v6.3.4" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/console" + }, + { + "name": "symfony\/dependency-injection", + "version": "v6.1.12", + "version_normalized": "6.1.12.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/dependency-injection.git", + "reference": "360c9d0948e1fe675336346d5862e8e55b378d90" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/dependency-injection\/zipball\/360c9d0948e1fe675336346d5862e8e55b378d90", + "reference": "360c9d0948e1fe675336346d5862e8e55b378d90", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr\/container": "^1.1|^2.0", + "symfony\/deprecation-contracts": "^2.1|^3", + "symfony\/service-contracts": "^1.1.6|^2.0|^3.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony\/config": "<6.1", + "symfony\/finder": "<5.4", + "symfony\/proxy-manager-bridge": "<5.4", + "symfony\/yaml": "<5.4" + }, + "provide": { + "psr\/container-implementation": "1.1|2.0", + "symfony\/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony\/config": "^6.1", + "symfony\/expression-language": "^5.4|^6.0", + "symfony\/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony\/config": "", + "symfony\/expression-language": "For using expressions in service container configuration", + "symfony\/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony\/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony\/yaml": "" + }, + "time": "2023-01-30T15:43:30+00:00", + "type": "library", + "extra": { + "patches_applied": [ + "https:\/\/raw.githubusercontent.com\/symplify\/vendor-patch-files\/main\/patches\/generic-php-config-loader.patch" + ] + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https:\/\/symfony.com", + "support": { + "source": "https:\/\/github.com\/symfony\/dependency-injection\/tree\/v6.1.12" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/dependency-injection" + }, + { + "name": "symfony\/deprecation-contracts", + "version": "v3.3.0", + "version_normalized": "3.3.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/deprecation-contracts\/zipball\/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "time": "2023-05-23T14:45:45+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony\/contracts", + "url": "https:\/\/github.com\/symfony\/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https:\/\/symfony.com", + "support": { + "source": "https:\/\/github.com\/symfony\/deprecation-contracts\/tree\/v3.3.0" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/deprecation-contracts" + }, + { + "name": "symfony\/filesystem", + "version": "v6.3.1", + "version_normalized": "6.3.1.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/filesystem.git", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/filesystem\/zipball\/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony\/polyfill-ctype": "~1.8", + "symfony\/polyfill-mbstring": "~1.8" + }, + "time": "2023-06-01T08:30:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https:\/\/symfony.com", + "support": { + "source": "https:\/\/github.com\/symfony\/filesystem\/tree\/v6.3.1" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/filesystem" + }, + { + "name": "symfony\/finder", + "version": "v6.3.5", + "version_normalized": "6.3.5.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/finder.git", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/finder\/zipball\/a1b31d88c0e998168ca7792f222cbecee47428c4", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony\/filesystem": "^6.0" + }, + "time": "2023-09-26T12:56:25+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https:\/\/symfony.com", + "support": { + "source": "https:\/\/github.com\/symfony\/finder\/tree\/v6.3.5" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/finder" + }, + { + "name": "symfony\/polyfill-ctype", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/polyfill-ctype\/zipball\/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https:\/\/symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https:\/\/github.com\/symfony\/polyfill-ctype\/tree\/v1.28.0" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/polyfill-ctype" + }, + { + "name": "symfony\/polyfill-intl-grapheme", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/polyfill-intl-grapheme.git", + "reference": "875e90aeea2777b6f135677f618529449334a612" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/polyfill-intl-grapheme\/zipball\/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https:\/\/symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https:\/\/github.com\/symfony\/polyfill-intl-grapheme\/tree\/v1.28.0" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/polyfill-intl-grapheme" + }, + { + "name": "symfony\/polyfill-intl-normalizer", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/polyfill-intl-normalizer\/zipball\/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources\/stubs" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https:\/\/symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https:\/\/github.com\/symfony\/polyfill-intl-normalizer\/tree\/v1.28.0" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/polyfill-intl-normalizer" + }, + { + "name": "symfony\/polyfill-mbstring", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/polyfill-mbstring\/zipball\/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2023-07-28T09:04:16+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https:\/\/symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https:\/\/github.com\/symfony\/polyfill-mbstring\/tree\/v1.28.0" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/polyfill-mbstring" + }, + { + "name": "symfony\/process", + "version": "v6.3.4", + "version_normalized": "6.3.4.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/process.git", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/process\/zipball\/0b5c29118f2e980d455d2e34a5659f4579847c54", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "time": "2023-08-07T10:39:22+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https:\/\/symfony.com", + "support": { + "source": "https:\/\/github.com\/symfony\/process\/tree\/v6.3.4" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/process" + }, + { + "name": "symfony\/service-contracts", + "version": "v3.3.0", + "version_normalized": "3.3.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/service-contracts.git", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/service-contracts\/zipball\/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr\/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "time": "2023-05-23T14:45:45+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony\/contracts", + "url": "https:\/\/github.com\/symfony\/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "\/Test\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https:\/\/symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https:\/\/github.com\/symfony\/service-contracts\/tree\/v3.3.0" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/service-contracts" + }, + { + "name": "symfony\/string", + "version": "v6.3.5", + "version_normalized": "6.3.5.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symfony\/string.git", + "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symfony\/string\/zipball\/13d76d0fb049051ed12a04bef4f9de8715bea339", + "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony\/polyfill-ctype": "~1.8", + "symfony\/polyfill-intl-grapheme": "~1.0", + "symfony\/polyfill-intl-normalizer": "~1.0", + "symfony\/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony\/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony\/error-handler": "^5.4|^6.0", + "symfony\/http-client": "^5.4|^6.0", + "symfony\/intl": "^6.2", + "symfony\/translation-contracts": "^2.5|^3.0", + "symfony\/var-exporter": "^5.4|^6.0" + }, + "time": "2023-09-18T10:38:32+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "Resources\/functions.php" + ], + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https:\/\/symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https:\/\/github.com\/symfony\/string\/tree\/v6.3.5" + }, + "funding": [ + { + "url": "https:\/\/symfony.com\/sponsor", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/fabpot", + "type": "github" + }, + { + "url": "https:\/\/tidelift.com\/funding\/github\/packagist\/symfony\/symfony", + "type": "tidelift" + } + ], + "install-path": "..\/symfony\/string" + }, + { + "name": "symplify\/autowire-array-parameter", + "version": "11.1.26", + "version_normalized": "11.1.26.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symplify\/autowire-array-parameter.git", + "reference": "ca9094e65223fbff7bb18d162df19312f9802a81" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symplify\/autowire-array-parameter\/zipball\/ca9094e65223fbff7bb18d162df19312f9802a81", + "reference": "ca9094e65223fbff7bb18d162df19312f9802a81", + "shasum": "" + }, + "require": { + "nette\/utils": "^3.2", + "php": ">=8.1", + "symfony\/dependency-injection": "6.1.*" + }, + "require-dev": { + "php-parallel-lint\/php-parallel-lint": "^1.3", + "phpstan\/extension-installer": "^1.2", + "phpunit\/phpunit": "^9.5.26", + "rector\/rector": "^0.15.10", + "symplify\/easy-ci": "^11.1", + "symplify\/easy-coding-standard": "^11.1", + "symplify\/package-builder": "^11.2", + "symplify\/phpstan-extensions": "^11.1", + "symplify\/symplify-kernel": "^11.2", + "tomasvotruba\/unused-public": "^0.0.34" + }, + "time": "2023-02-03T09:12:23+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\": "src" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "description": "Autowire array parameters for your Symfony applications", + "support": { + "source": "https:\/\/github.com\/symplify\/autowire-array-parameter\/tree\/11.1.26" + }, + "funding": [ + { + "url": "https:\/\/www.paypal.me\/rectorphp", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/tomasvotruba", + "type": "github" + } + ], + "abandoned": "symfony\/dependency-injection", + "install-path": "..\/symplify\/autowire-array-parameter" + }, + { + "name": "symplify\/easy-testing", + "version": "11.1.25", + "version_normalized": "11.1.25.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symplify\/easy-testing.git", + "reference": "a9fd0eed1b33847f175f085d9803f5bf299cba4b" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symplify\/easy-testing\/zipball\/a9fd0eed1b33847f175f085d9803f5bf299cba4b", + "reference": "a9fd0eed1b33847f175f085d9803f5bf299cba4b", + "shasum": "" + }, + "require": { + "nette\/utils": "^3.2", + "php": ">=8.1", + "symfony\/console": "^6.2", + "symfony\/dependency-injection": "6.1.*", + "symfony\/finder": "^6.2", + "symplify\/package-builder": "^11.1.25", + "symplify\/smart-file-system": "^11.1.25", + "symplify\/symplify-kernel": "^11.1.25" + }, + "conflict": { + "symplify\/autowire-array-parameter": "<11.1.25", + "symplify\/coding-standard": "<11.1.24", + "symplify\/config-transformer": "<11.1.24", + "symplify\/easy-ci": "<11.1.24", + "symplify\/easy-parallel": "<11.1.25", + "symplify\/monorepo-builder": "<11.1.24", + "symplify\/php-config-printer": "<11.1.25", + "symplify\/phpstan-extensions": "<11.1.25", + "symplify\/phpstan-rules": "<11.1.24", + "symplify\/rule-doc-generator": "<11.1.25", + "symplify\/rule-doc-generator-contracts": "<11.1.25", + "symplify\/symfony-static-dumper": "<11.1.25" + }, + "require-dev": { + "phpunit\/phpunit": "^9.5.26" + }, + "time": "2023-01-28T10:13:33+00:00", + "bin": [ + "bin\/easy-testing" + ], + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\": "src" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "description": "Testing made easy", + "support": { + "source": "https:\/\/github.com\/symplify\/easy-testing\/tree\/11.1.25" + }, + "funding": [ + { + "url": "https:\/\/www.paypal.me\/rectorphp", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/tomasvotruba", + "type": "github" + } + ], + "install-path": "..\/symplify\/easy-testing" + }, + { + "name": "symplify\/package-builder", + "version": "11.3.0", + "version_normalized": "11.3.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symplify\/package-builder.git", + "reference": "99d055542e9ab631297b6765e2a3257261f9d667" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symplify\/package-builder\/zipball\/99d055542e9ab631297b6765e2a3257261f9d667", + "reference": "99d055542e9ab631297b6765e2a3257261f9d667", + "shasum": "" + }, + "require": { + "nette\/utils": "^3.2", + "php": ">=8.1", + "sebastian\/diff": "^5.0", + "symfony\/config": "^6.2", + "symfony\/console": "^6.2", + "symfony\/dependency-injection": "6.1.*", + "symfony\/finder": "^6.2" + }, + "require-dev": { + "php-parallel-lint\/php-parallel-lint": "^1.3", + "phpstan\/extension-installer": "^1.2", + "phpunit\/phpunit": "^10.0", + "rector\/rector": "^0.15.10", + "symplify\/easy-ci": "^11.2.0", + "symplify\/easy-coding-standard": "^11.2", + "symplify\/phpstan-extensions": "^11.1", + "symplify\/phpstan-rules": "^11.2", + "symplify\/symplify-kernel": "^11.1", + "tomasvotruba\/unused-public": "^0.0.34" + }, + "time": "2023-02-05T14:53:28+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\": "src" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "description": "Dependency Injection, Console and Kernel toolkit for Symplify packages.", + "support": { + "source": "https:\/\/github.com\/symplify\/package-builder\/tree\/11.3.0" + }, + "funding": [ + { + "url": "https:\/\/www.paypal.me\/rectorphp", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/tomasvotruba", + "type": "github" + } + ], + "install-path": "..\/symplify\/package-builder" + }, + { + "name": "symplify\/smart-file-system", + "version": "11.1.26", + "version_normalized": "11.1.26.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symplify\/smart-file-system.git", + "reference": "f3b006424d08359cccaf4e2e38cf3f9ef2effca6" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symplify\/smart-file-system\/zipball\/f3b006424d08359cccaf4e2e38cf3f9ef2effca6", + "reference": "f3b006424d08359cccaf4e2e38cf3f9ef2effca6", + "shasum": "" + }, + "require": { + "nette\/utils": "^3.2", + "php": ">=8.1", + "symfony\/filesystem": "^6.2", + "symfony\/finder": "^6.2", + "symplify\/easy-testing": "^11.1" + }, + "require-dev": { + "php-parallel-lint\/php-parallel-lint": "^1.3", + "phpstan\/extension-installer": "^1.2", + "phpunit\/phpunit": "^9.5.26", + "rector\/rector": "^0.15.10", + "symplify\/easy-ci": "^11.1", + "symplify\/easy-coding-standard": "^11.1", + "symplify\/phpstan-extensions": "^11.1", + "symplify\/phpstan-rules": "11.2.3.72", + "symplify\/symplify-kernel": "^11.1", + "tomasvotruba\/unused-public": "^0.0.34" + }, + "time": "2023-02-05T13:38:33+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\": "src" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "description": "Sanitized FileInfo with safe getRealPath() and other handy methods", + "support": { + "source": "https:\/\/github.com\/symplify\/smart-file-system\/tree\/11.1.26" + }, + "funding": [ + { + "url": "https:\/\/www.paypal.me\/rectorphp", + "type": "custom" + }, + { + "url": "https:\/\/github.com\/tomasvotruba", + "type": "github" + } + ], + "install-path": "..\/symplify\/smart-file-system" + }, + { + "name": "symplify\/symplify-kernel", + "version": "11.1.25", + "version_normalized": "11.1.25.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/symplify\/symplify-kernel.git", + "reference": "15b29ac9aedea76dc7b1a3524614e881594fccf5" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/symplify\/symplify-kernel\/zipball\/15b29ac9aedea76dc7b1a3524614e881594fccf5", + "reference": "15b29ac9aedea76dc7b1a3524614e881594fccf5", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony\/console": "^6.2", + "symfony\/dependency-injection": "6.1.*", + "symplify\/autowire-array-parameter": "^11.1.25", + "symplify\/package-builder": "^11.1.25", + "symplify\/smart-file-system": "^11.1.25", + "webmozart\/assert": "^1.11" + }, + "conflict": { + "symplify\/coding-standard": "<11.1.24", + "symplify\/config-transformer": "<11.1.24", + "symplify\/easy-ci": "<11.1.24", + "symplify\/easy-parallel": "<11.1.25", + "symplify\/easy-testing": "<11.1.25", + "symplify\/monorepo-builder": "<11.1.24", + "symplify\/php-config-printer": "<11.1.25", + "symplify\/phpstan-extensions": "<11.1.25", + "symplify\/phpstan-rules": "<11.1.24", + "symplify\/rule-doc-generator": "<11.1.25", + "symplify\/rule-doc-generator-contracts": "<11.1.25", + "symplify\/symfony-static-dumper": "<11.1.25" + }, + "require-dev": { + "phpunit\/phpunit": "^9.5.26" + }, + "time": "2023-01-28T10:13:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\": "src" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "description": "Internal Kernel for Symplify packages", + "support": { + "source": "https:\/\/github.com\/symplify\/symplify-kernel\/tree\/11.1.25" + }, + "install-path": "..\/symplify\/symplify-kernel" + }, + { + "name": "webmozart\/assert", + "version": "1.11.0", + "version_normalized": "1.11.0.0", + "source": { + "type": "git", + "url": "https:\/\/github.com\/webmozarts\/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https:\/\/api.github.com\/repos\/webmozarts\/assert\/zipball\/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan\/phpstan": "<0.12.20", + "vimeo\/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit\/phpunit": "^8.5.13" + }, + "time": "2022-06-03T18:03:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Webmozart\\Assert\\": "src\/" + } + }, + "notification-url": "https:\/\/packagist.org\/downloads\/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input\/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https:\/\/github.com\/webmozarts\/assert\/issues", + "source": "https:\/\/github.com\/webmozarts\/assert\/tree\/1.11.0" + }, + "install-path": "..\/webmozart\/assert" + } + ], + "dev": false, + "dev-package-names": [] +} \ No newline at end of file diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 0000000000..3f2507ff5e --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,5 @@ + array('name' => 'symplify/monorepo-builder', 'pretty_version' => '11.2.19', 'version' => '11.2.19.0', 'reference' => '2cecb2b3870ace9d74dcddb86c9727155c3a6783', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('nette/utils' => array('pretty_version' => 'v3.2.10', 'version' => '3.2.10.0', 'reference' => 'a4175c62652f2300c8017fb7e640f9ccb11648d2', 'type' => 'library', 'install_path' => __DIR__ . '/../nette/utils', 'aliases' => array(), 'dev_requirement' => \false), 'phar-io/version' => array('pretty_version' => '3.2.1', 'version' => '3.2.1.0', 'reference' => '4f7fd7836c6f332bb2933569e566a0d6c4cbed74', 'type' => 'library', 'install_path' => __DIR__ . '/../phar-io/version', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container' => array('pretty_version' => '2.0.2', 'version' => '2.0.2.0', 'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.1|2.0')), 'psr/log-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0|2.0|3.0')), 'sebastian/diff' => array('pretty_version' => '5.0.3', 'version' => '5.0.3.0', 'reference' => '912dc2fbe3e3c1e7873313cc801b100b6c68c87b', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/diff', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/config' => array('pretty_version' => 'v6.3.2', 'version' => '6.3.2.0', 'reference' => 'b47ca238b03e7b0d7880ffd1cf06e8d637ca1467', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/config', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/console' => array('pretty_version' => 'v6.3.4', 'version' => '6.3.4.0', 'reference' => 'eca495f2ee845130855ddf1cf18460c38966c8b6', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/dependency-injection' => array('pretty_version' => 'v6.1.12', 'version' => '6.1.12.0', 'reference' => '360c9d0948e1fe675336346d5862e8e55b378d90', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dependency-injection', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/deprecation-contracts' => array('pretty_version' => 'v3.3.0', 'version' => '3.3.0.0', 'reference' => '7c3aff79d10325257a001fcf92d991f24fc967cf', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/filesystem' => array('pretty_version' => 'v6.3.1', 'version' => '6.3.1.0', 'reference' => 'edd36776956f2a6fcf577edb5b05eb0e3bdc52ae', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/finder' => array('pretty_version' => 'v6.3.5', 'version' => '6.3.5.0', 'reference' => 'a1b31d88c0e998168ca7792f222cbecee47428c4', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/finder', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-ctype' => array('pretty_version' => 'v1.28.0', 'version' => '1.28.0.0', 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-intl-grapheme' => array('pretty_version' => 'v1.28.0', 'version' => '1.28.0.0', 'reference' => '875e90aeea2777b6f135677f618529449334a612', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-intl-normalizer' => array('pretty_version' => 'v1.28.0', 'version' => '1.28.0.0', 'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-mbstring' => array('pretty_version' => 'v1.28.0', 'version' => '1.28.0.0', 'reference' => '42292d99c55abe617799667f454222c54c60e229', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/process' => array('pretty_version' => 'v6.3.4', 'version' => '6.3.4.0', 'reference' => '0b5c29118f2e980d455d2e34a5659f4579847c54', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/service-contracts' => array('pretty_version' => 'v3.3.0', 'version' => '3.3.0.0', 'reference' => '40da9cc13ec349d9e4966ce18b5fbcd724ab10a4', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/service-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.1|2.0|3.0')), 'symfony/string' => array('pretty_version' => 'v6.3.5', 'version' => '6.3.5.0', 'reference' => '13d76d0fb049051ed12a04bef4f9de8715bea339', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/string', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/autowire-array-parameter' => array('pretty_version' => '11.1.26', 'version' => '11.1.26.0', 'reference' => 'ca9094e65223fbff7bb18d162df19312f9802a81', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/autowire-array-parameter', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/easy-testing' => array('pretty_version' => '11.1.25', 'version' => '11.1.25.0', 'reference' => 'a9fd0eed1b33847f175f085d9803f5bf299cba4b', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symplify/easy-testing', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/monorepo-builder' => array('pretty_version' => '11.2.19', 'version' => '11.2.19.0', 'reference' => '2cecb2b3870ace9d74dcddb86c9727155c3a6783', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/package-builder' => array('pretty_version' => '11.3.0', 'version' => '11.3.0.0', 'reference' => '99d055542e9ab631297b6765e2a3257261f9d667', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/package-builder', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/smart-file-system' => array('pretty_version' => '11.1.26', 'version' => '11.1.26.0', 'reference' => 'f3b006424d08359cccaf4e2e38cf3f9ef2effca6', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/smart-file-system', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/symplify-kernel' => array('pretty_version' => '11.1.25', 'version' => '11.1.25.0', 'reference' => '15b29ac9aedea76dc7b1a3524614e881594fccf5', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/symplify-kernel', 'aliases' => array(), 'dev_requirement' => \false), 'webmozart/assert' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', 'type' => 'library', 'install_path' => __DIR__ . '/../webmozart/assert', 'aliases' => array(), 'dev_requirement' => \false))); diff --git a/vendor/nette/utils/composer.json b/vendor/nette/utils/composer.json new file mode 100644 index 0000000000..c107f1f0c5 --- /dev/null +++ b/vendor/nette/utils/composer.json @@ -0,0 +1,72 @@ +{ + "name": "nette\/utils", + "description": "\ud83d\udee0 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding\/decoding, validation, slug or strong password generating etc.", + "keywords": [ + "nette", + "images", + "json", + "password", + "validation", + "utility", + "string", + "array", + "core", + "slugify", + "utf-8", + "unicode", + "paginator", + "datetime" + ], + "homepage": "https:\/\/nette.org", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https:\/\/davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https:\/\/nette.org\/contributors" + } + ], + "require": { + "php": ">=7.2 <8.4" + }, + "require-dev": { + "nette\/tester": "~2.0", + "tracy\/tracy": "^2.3", + "phpstan\/phpstan": "^1.0", + "jetbrains\/phpstorm-attributes": "dev-master" + }, + "conflict": { + "nette\/di": "<3.0.6" + }, + "suggest": { + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available", + "ext-gd": "to use Image", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "autoload": { + "classmap": [ + "src\/" + ] + }, + "minimum-stability": "dev", + "scripts": { + "phpstan": "phpstan analyse", + "tester": "tester tests -s" + }, + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + } +} \ No newline at end of file diff --git a/vendor/nette/utils/license.md b/vendor/nette/utils/license.md new file mode 100644 index 0000000000..cf741bd05f --- /dev/null +++ b/vendor/nette/utils/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as is" and +any express or implied warranties, including, but not limited to, the implied +warranties of merchantability and fitness for a particular purpose are +disclaimed. In no event shall the copyright owner or contributors be liable for +any direct, indirect, incidental, special, exemplary, or consequential damages +(including, but not limited to, procurement of substitute goods or services; +loss of use, data, or profits; or business interruption) however caused and on +any theory of liability, whether in contract, strict liability, or tort +(including negligence or otherwise) arising in any way out of the use of this +software, even if advised of the possibility of such damage. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/utils/readme.md b/vendor/nette/utils/readme.md new file mode 100644 index 0000000000..5317b8e654 --- /dev/null +++ b/vendor/nette/utils/readme.md @@ -0,0 +1,54 @@ +Nette Utility Classes +===================== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/utils.svg)](https://packagist.org/packages/nette/utils) +[![Tests](https://github.com/nette/utils/workflows/Tests/badge.svg?branch=master)](https://github.com/nette/utils/actions) +[![Coverage Status](https://coveralls.io/repos/github/nette/utils/badge.svg?branch=master)](https://coveralls.io/github/nette/utils?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/utils/v/stable)](https://github.com/nette/utils/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/utils/blob/master/license.md) + + +Introduction +------------ + +In package nette/utils you will find a set of [useful classes](https://doc.nette.org/utils) for everyday use: + +- [Arrays](https://doc.nette.org/utils/arrays) - manipulate arrays +- [Callback](https://doc.nette.org/utils/callback) - PHP callbacks +- [Date and Time](https://doc.nette.org/utils/datetime) - modify times and dates +- [Filesystem](https://doc.nette.org/utils/filesystem) - copying, renaming, … +- [Helper Functions](https://doc.nette.org/utils/helpers) +- [HTML elements](https://doc.nette.org/utils/html-elements) - generate HTML +- [Images](https://doc.nette.org/utils/images) - crop, resize, rotate images +- [JSON](https://doc.nette.org/utils/json) - encoding and decoding +- [Generating Random Strings](https://doc.nette.org/utils/random) +- [Paginator](https://doc.nette.org/utils/paginator) - pagination math +- [PHP Reflection](https://doc.nette.org/utils/reflection) +- [Strings](https://doc.nette.org/utils/strings) - useful text functions +- [SmartObject](https://doc.nette.org/utils/smartobject) - PHP object enhancements +- [Validation](https://doc.nette.org/utils/validators) - validate inputs +- [Type](https://doc.nette.org/utils/type) - PHP data type + + +Installation +------------ + +The recommended way to install is via Composer: + +``` +composer require nette/utils +``` + +- Nette Utils 3.2 is compatible with PHP 7.2 to 8.3 +- Nette Utils 3.1 is compatible with PHP 7.1 to 8.0 +- Nette Utils 3.0 is compatible with PHP 7.1 to 8.0 +- Nette Utils 2.5 is compatible with PHP 5.6 to 8.0 + +[Support Me](https://github.com/sponsors/dg) +-------------------------------------------- + +Do you like Nette Utils? Are you looking forward to the new features? + +[![Buy me a coffee](https://files.nette.org/icons/donation-3.svg)](https://github.com/sponsors/dg) + +Thank you! diff --git a/vendor/nette/utils/src/HtmlStringable.php b/vendor/nette/utils/src/HtmlStringable.php new file mode 100644 index 0000000000..b03d8c98f2 --- /dev/null +++ b/vendor/nette/utils/src/HtmlStringable.php @@ -0,0 +1,17 @@ +getIterator(); + } while ($iterator instanceof \IteratorAggregate); + \assert($iterator instanceof \Iterator); + } elseif ($iterator instanceof \Iterator) { + } elseif ($iterator instanceof \Traversable) { + $iterator = new \IteratorIterator($iterator); + } else { + throw new Nette\InvalidArgumentException(\sprintf('Invalid argument passed to %s; array or Traversable expected, %s given.', self::class, \is_object($iterator) ? \get_class($iterator) : \gettype($iterator))); + } + parent::__construct($iterator, 0); + } + /** + * Is the current element the first one? + */ + public function isFirst(?int $gridWidth = null) : bool + { + return $this->counter === 1 || $gridWidth && $this->counter !== 0 && ($this->counter - 1) % $gridWidth === 0; + } + /** + * Is the current element the last one? + */ + public function isLast(?int $gridWidth = null) : bool + { + return !$this->hasNext() || $gridWidth && $this->counter % $gridWidth === 0; + } + /** + * Is the iterator empty? + */ + public function isEmpty() : bool + { + return $this->counter === 0; + } + /** + * Is the counter odd? + */ + public function isOdd() : bool + { + return $this->counter % 2 === 1; + } + /** + * Is the counter even? + */ + public function isEven() : bool + { + return $this->counter % 2 === 0; + } + /** + * Returns the counter. + */ + public function getCounter() : int + { + return $this->counter; + } + /** + * Returns the count of elements. + */ + public function count() : int + { + $inner = $this->getInnerIterator(); + if ($inner instanceof \Countable) { + return $inner->count(); + } else { + throw new Nette\NotSupportedException('Iterator is not countable.'); + } + } + /** + * Forwards to the next element. + */ + public function next() : void + { + parent::next(); + if (parent::valid()) { + $this->counter++; + } + } + /** + * Rewinds the Iterator. + */ + public function rewind() : void + { + parent::rewind(); + $this->counter = parent::valid() ? 1 : 0; + } + /** + * Returns the next key. + * @return mixed + */ + public function getNextKey() + { + return $this->getInnerIterator()->key(); + } + /** + * Returns the next element. + * @return mixed + */ + public function getNextValue() + { + return $this->getInnerIterator()->current(); + } +} diff --git a/vendor/nette/utils/src/Iterators/Mapper.php b/vendor/nette/utils/src/Iterators/Mapper.php new file mode 100644 index 0000000000..4918fc194d --- /dev/null +++ b/vendor/nette/utils/src/Iterators/Mapper.php @@ -0,0 +1,27 @@ +callback = $callback; + } + #[\ReturnTypeWillChange] + public function current() + { + return ($this->callback)(parent::current(), parent::key()); + } +} diff --git a/vendor/nette/utils/src/SmartObject.php b/vendor/nette/utils/src/SmartObject.php new file mode 100644 index 0000000000..0b3a4d5fb5 --- /dev/null +++ b/vendor/nette/utils/src/SmartObject.php @@ -0,0 +1,120 @@ +{$name} ?? null; + if (\is_iterable($handlers)) { + foreach ($handlers as $handler) { + $handler(...$args); + } + } elseif ($handlers !== null) { + throw new UnexpectedValueException("Property {$class}::\${$name} must be iterable or null, " . \gettype($handlers) . ' given.'); + } + } else { + ObjectHelpers::strictCall($class, $name); + } + } + /** + * @throws MemberAccessException + */ + public static function __callStatic(string $name, array $args) + { + ObjectHelpers::strictStaticCall(static::class, $name); + } + /** + * @return mixed + * @throws MemberAccessException if the property is not defined. + */ + public function &__get(string $name) + { + $class = static::class; + if ($prop = ObjectHelpers::getMagicProperties($class)[$name] ?? null) { + // property getter + if (!($prop & 0b1)) { + throw new MemberAccessException("Cannot read a write-only property {$class}::\${$name}."); + } + $m = ($prop & 0b10 ? 'get' : 'is') . \ucfirst($name); + if ($prop & 0b10000) { + $trace = \debug_backtrace(0, 1)[0]; + // suppose this method is called from __call() + $loc = isset($trace['file'], $trace['line']) ? " in {$trace['file']} on line {$trace['line']}" : ''; + \trigger_error("Property {$class}::\${$name} is deprecated, use {$class}::{$m}() method{$loc}.", \E_USER_DEPRECATED); + } + if ($prop & 0b100) { + // return by reference + return $this->{$m}(); + } else { + $val = $this->{$m}(); + return $val; + } + } else { + ObjectHelpers::strictGet($class, $name); + } + } + /** + * @param mixed $value + * @return void + * @throws MemberAccessException if the property is not defined or is read-only + */ + public function __set(string $name, $value) + { + $class = static::class; + if (ObjectHelpers::hasProperty($class, $name)) { + // unsetted property + $this->{$name} = $value; + } elseif ($prop = ObjectHelpers::getMagicProperties($class)[$name] ?? null) { + // property setter + if (!($prop & 0b1000)) { + throw new MemberAccessException("Cannot write to a read-only property {$class}::\${$name}."); + } + $m = 'set' . \ucfirst($name); + if ($prop & 0b10000) { + $trace = \debug_backtrace(0, 1)[0]; + // suppose this method is called from __call() + $loc = isset($trace['file'], $trace['line']) ? " in {$trace['file']} on line {$trace['line']}" : ''; + \trigger_error("Property {$class}::\${$name} is deprecated, use {$class}::{$m}() method{$loc}.", \E_USER_DEPRECATED); + } + $this->{$m}($value); + } else { + ObjectHelpers::strictSet($class, $name); + } + } + /** + * @return void + * @throws MemberAccessException + */ + public function __unset(string $name) + { + $class = static::class; + if (!ObjectHelpers::hasProperty($class, $name)) { + throw new MemberAccessException("Cannot unset the property {$class}::\${$name}."); + } + } + public function __isset(string $name) : bool + { + return isset(ObjectHelpers::getMagicProperties(static::class)[$name]); + } +} diff --git a/vendor/nette/utils/src/StaticClass.php b/vendor/nette/utils/src/StaticClass.php new file mode 100644 index 0000000000..a22c3d95aa --- /dev/null +++ b/vendor/nette/utils/src/StaticClass.php @@ -0,0 +1,32 @@ + + * @implements \ArrayAccess + */ +class ArrayHash extends \stdClass implements \ArrayAccess, \Countable, \IteratorAggregate +{ + /** + * Transforms array to ArrayHash. + * @param array $array + * @return static + */ + public static function from(array $array, bool $recursive = \true) + { + $obj = new static(); + foreach ($array as $key => $value) { + $obj->{$key} = $recursive && \is_array($value) ? static::from($value, \true) : $value; + } + return $obj; + } + /** + * Returns an iterator over all items. + * @return \RecursiveArrayIterator + */ + public function getIterator() : \RecursiveArrayIterator + { + return new \RecursiveArrayIterator((array) $this); + } + /** + * Returns items count. + */ + public function count() : int + { + return \count((array) $this); + } + /** + * Replaces or appends a item. + * @param array-key $key + * @param T $value + */ + public function offsetSet($key, $value) : void + { + if (!\is_scalar($key)) { + // prevents null + throw new Nette\InvalidArgumentException(\sprintf('Key must be either a string or an integer, %s given.', \gettype($key))); + } + $this->{$key} = $value; + } + /** + * Returns a item. + * @param array-key $key + * @return T + */ + #[\ReturnTypeWillChange] + public function offsetGet($key) + { + return $this->{$key}; + } + /** + * Determines whether a item exists. + * @param array-key $key + */ + public function offsetExists($key) : bool + { + return isset($this->{$key}); + } + /** + * Removes the element from this list. + * @param array-key $key + */ + public function offsetUnset($key) : void + { + unset($this->{$key}); + } +} diff --git a/vendor/nette/utils/src/Utils/ArrayList.php b/vendor/nette/utils/src/Utils/ArrayList.php new file mode 100644 index 0000000000..c68f8570c5 --- /dev/null +++ b/vendor/nette/utils/src/Utils/ArrayList.php @@ -0,0 +1,111 @@ + + * @implements \ArrayAccess + */ +class ArrayList implements \ArrayAccess, \Countable, \IteratorAggregate +{ + use Nette\SmartObject; + /** @var mixed[] */ + private $list = []; + /** + * Transforms array to ArrayList. + * @param list $array + * @return static + */ + public static function from(array $array) + { + if (!Arrays::isList($array)) { + throw new Nette\InvalidArgumentException('Array is not valid list.'); + } + $obj = new static(); + $obj->list = $array; + return $obj; + } + /** + * Returns an iterator over all items. + * @return \ArrayIterator + */ + public function getIterator() : \ArrayIterator + { + return new \ArrayIterator($this->list); + } + /** + * Returns items count. + */ + public function count() : int + { + return \count($this->list); + } + /** + * Replaces or appends a item. + * @param int|null $index + * @param T $value + * @throws Nette\OutOfRangeException + */ + public function offsetSet($index, $value) : void + { + if ($index === null) { + $this->list[] = $value; + } elseif (!\is_int($index) || $index < 0 || $index >= \count($this->list)) { + throw new Nette\OutOfRangeException('Offset invalid or out of range'); + } else { + $this->list[$index] = $value; + } + } + /** + * Returns a item. + * @param int $index + * @return T + * @throws Nette\OutOfRangeException + */ + #[\ReturnTypeWillChange] + public function offsetGet($index) + { + if (!\is_int($index) || $index < 0 || $index >= \count($this->list)) { + throw new Nette\OutOfRangeException('Offset invalid or out of range'); + } + return $this->list[$index]; + } + /** + * Determines whether a item exists. + * @param int $index + */ + public function offsetExists($index) : bool + { + return \is_int($index) && $index >= 0 && $index < \count($this->list); + } + /** + * Removes the element at the specified position in this list. + * @param int $index + * @throws Nette\OutOfRangeException + */ + public function offsetUnset($index) : void + { + if (!\is_int($index) || $index < 0 || $index >= \count($this->list)) { + throw new Nette\OutOfRangeException('Offset invalid or out of range'); + } + \array_splice($this->list, $index, 1); + } + /** + * Prepends a item. + * @param T $value + */ + public function prepend($value) : void + { + $first = \array_slice($this->list, 0, 1); + $this->offsetSet(0, $value); + \array_splice($this->list, 1, 0, $first); + } +} diff --git a/vendor/nette/utils/src/Utils/Arrays.php b/vendor/nette/utils/src/Utils/Arrays.php new file mode 100644 index 0000000000..1e83306709 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Arrays.php @@ -0,0 +1,394 @@ + $array + * @param array-key|array-key[] $key + * @param ?T $default + * @return ?T + * @throws Nette\InvalidArgumentException if item does not exist and default value is not provided + */ + public static function get(array $array, $key, $default = null) + { + foreach (is_array($key) ? $key : [$key] as $k) { + if (is_array($array) && \array_key_exists($k, $array)) { + $array = $array[$k]; + } else { + if (\func_num_args() < 3) { + throw new Nette\InvalidArgumentException("Missing item '{$k}'."); + } + return $default; + } + } + return $array; + } + /** + * Returns reference to array item. If the index does not exist, new one is created with value null. + * @template T + * @param array $array + * @param array-key|array-key[] $key + * @return ?T + * @throws Nette\InvalidArgumentException if traversed item is not an array + */ + public static function &getRef(array &$array, $key) + { + foreach (is_array($key) ? $key : [$key] as $k) { + if (is_array($array) || $array === null) { + $array =& $array[$k]; + } else { + throw new Nette\InvalidArgumentException('Traversed item is not an array.'); + } + } + return $array; + } + /** + * Recursively merges two fields. It is useful, for example, for merging tree structures. It behaves as + * the + operator for array, ie. it adds a key/value pair from the second array to the first one and retains + * the value from the first array in the case of a key collision. + * @template T1 + * @template T2 + * @param array $array1 + * @param array $array2 + * @return array + */ + public static function mergeTree(array $array1, array $array2) : array + { + $res = $array1 + $array2; + foreach (\array_intersect_key($array1, $array2) as $k => $v) { + if (is_array($v) && is_array($array2[$k])) { + $res[$k] = self::mergeTree($v, $array2[$k]); + } + } + return $res; + } + /** + * Returns zero-indexed position of given array key. Returns null if key is not found. + * @param array-key $key + * @return int|null offset if it is found, null otherwise + */ + public static function getKeyOffset(array $array, $key) : ?int + { + return Helpers::falseToNull(\array_search(self::toKey($key), \array_keys($array), \true)); + } + /** + * @deprecated use getKeyOffset() + */ + public static function searchKey(array $array, $key) : ?int + { + return self::getKeyOffset($array, $key); + } + /** + * Tests an array for the presence of value. + * @param mixed $value + */ + public static function contains(array $array, $value) : bool + { + return \in_array($value, $array, \true); + } + /** + * Returns the first item from the array or null if array is empty. + * @template T + * @param array $array + * @return ?T + */ + public static function first(array $array) + { + return count($array) ? \reset($array) : null; + } + /** + * Returns the last item from the array or null if array is empty. + * @template T + * @param array $array + * @return ?T + */ + public static function last(array $array) + { + return count($array) ? \end($array) : null; + } + /** + * Inserts the contents of the $inserted array into the $array immediately after the $key. + * If $key is null (or does not exist), it is inserted at the beginning. + * @param array-key|null $key + */ + public static function insertBefore(array &$array, $key, array $inserted) : void + { + $offset = $key === null ? 0 : (int) self::getKeyOffset($array, $key); + $array = \array_slice($array, 0, $offset, \true) + $inserted + \array_slice($array, $offset, count($array), \true); + } + /** + * Inserts the contents of the $inserted array into the $array before the $key. + * If $key is null (or does not exist), it is inserted at the end. + * @param array-key|null $key + */ + public static function insertAfter(array &$array, $key, array $inserted) : void + { + if ($key === null || ($offset = self::getKeyOffset($array, $key)) === null) { + $offset = count($array) - 1; + } + $array = \array_slice($array, 0, $offset + 1, \true) + $inserted + \array_slice($array, $offset + 1, count($array), \true); + } + /** + * Renames key in array. + * @param array-key $oldKey + * @param array-key $newKey + */ + public static function renameKey(array &$array, $oldKey, $newKey) : bool + { + $offset = self::getKeyOffset($array, $oldKey); + if ($offset === null) { + return \false; + } + $val =& $array[$oldKey]; + $keys = \array_keys($array); + $keys[$offset] = $newKey; + $array = \array_combine($keys, $array); + $array[$newKey] =& $val; + return \true; + } + /** + * Returns only those array items, which matches a regular expression $pattern. + * @param string[] $array + * @return string[] + */ + public static function grep( + array $array, + /** + * @language + */ + string $pattern, + int $flags = 0 + ) : array + { + return Strings::pcre('preg_grep', [$pattern, $array, $flags]); + } + /** + * Transforms multidimensional array to flat array. + */ + public static function flatten(array $array, bool $preserveKeys = \false) : array + { + $res = []; + $cb = $preserveKeys ? function ($v, $k) use(&$res) : void { + $res[$k] = $v; + } : function ($v) use(&$res) : void { + $res[] = $v; + }; + \array_walk_recursive($array, $cb); + return $res; + } + /** + * Checks if the array is indexed in ascending order of numeric keys from zero, a.k.a list. + * @param mixed $value + */ + public static function isList($value) : bool + { + $arrayIsListFunction = function (array $array) : bool { + if (\function_exists('array_is_list')) { + return \array_is_list($array); + } + if ($array === []) { + return \true; + } + $current_key = 0; + foreach ($array as $key => $noop) { + if ($key !== $current_key) { + return \false; + } + ++$current_key; + } + return \true; + }; + return is_array($value) && (\PHP_VERSION_ID < 80100 ? !$value || \array_keys($value) === \range(0, count($value) - 1) : $arrayIsListFunction($value)); + } + /** + * Reformats table to associative tree. Path looks like 'field|field[]field->field=field'. + * @param string|string[] $path + * @return array|\stdClass + */ + public static function associate(array $array, $path) + { + $parts = is_array($path) ? $path : \preg_split('#(\\[\\]|->|=|\\|)#', $path, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); + if (!$parts || $parts === ['->'] || $parts[0] === '=' || $parts[0] === '|') { + throw new Nette\InvalidArgumentException("Invalid path '{$path}'."); + } + $res = $parts[0] === '->' ? new \stdClass() : []; + foreach ($array as $rowOrig) { + $row = (array) $rowOrig; + $x =& $res; + for ($i = 0; $i < count($parts); $i++) { + $part = $parts[$i]; + if ($part === '[]') { + $x =& $x[]; + } elseif ($part === '=') { + if (isset($parts[++$i])) { + $x = $row[$parts[$i]]; + $row = null; + } + } elseif ($part === '->') { + if (isset($parts[++$i])) { + if ($x === null) { + $x = new \stdClass(); + } + $x =& $x->{$row[$parts[$i]]}; + } else { + $row = is_object($rowOrig) ? $rowOrig : (object) $row; + } + } elseif ($part !== '|') { + $x =& $x[(string) $row[$part]]; + } + } + if ($x === null) { + $x = $row; + } + } + return $res; + } + /** + * Normalizes array to associative array. Replace numeric keys with their values, the new value will be $filling. + * @param mixed $filling + */ + public static function normalize(array $array, $filling = null) : array + { + $res = []; + foreach ($array as $k => $v) { + $res[is_int($k) ? $v : $k] = is_int($k) ? $filling : $v; + } + return $res; + } + /** + * Returns and removes the value of an item from an array. If it does not exist, it throws an exception, + * or returns $default, if provided. + * @template T + * @param array $array + * @param array-key $key + * @param ?T $default + * @return ?T + * @throws Nette\InvalidArgumentException if item does not exist and default value is not provided + */ + public static function pick(array &$array, $key, $default = null) + { + if (\array_key_exists($key, $array)) { + $value = $array[$key]; + unset($array[$key]); + return $value; + } elseif (\func_num_args() < 3) { + throw new Nette\InvalidArgumentException("Missing item '{$key}'."); + } else { + return $default; + } + } + /** + * Tests whether at least one element in the array passes the test implemented by the + * provided callback with signature `function ($value, $key, array $array): bool`. + */ + public static function some(iterable $array, callable $callback) : bool + { + foreach ($array as $k => $v) { + if ($callback($v, $k, $array)) { + return \true; + } + } + return \false; + } + /** + * Tests whether all elements in the array pass the test implemented by the provided function, + * which has the signature `function ($value, $key, array $array): bool`. + */ + public static function every(iterable $array, callable $callback) : bool + { + foreach ($array as $k => $v) { + if (!$callback($v, $k, $array)) { + return \false; + } + } + return \true; + } + /** + * Calls $callback on all elements in the array and returns the array of return values. + * The callback has the signature `function ($value, $key, array $array): bool`. + */ + public static function map(iterable $array, callable $callback) : array + { + $res = []; + foreach ($array as $k => $v) { + $res[$k] = $callback($v, $k, $array); + } + return $res; + } + /** + * Invokes all callbacks and returns array of results. + * @param callable[] $callbacks + */ + public static function invoke(iterable $callbacks, ...$args) : array + { + $res = []; + foreach ($callbacks as $k => $cb) { + $res[$k] = $cb(...$args); + } + return $res; + } + /** + * Invokes method on every object in an array and returns array of results. + * @param object[] $objects + */ + public static function invokeMethod(iterable $objects, string $method, ...$args) : array + { + $res = []; + foreach ($objects as $k => $obj) { + $res[$k] = $obj->{$method}(...$args); + } + return $res; + } + /** + * Copies the elements of the $array array to the $object object and then returns it. + * @template T of object + * @param T $object + * @return T + */ + public static function toObject(iterable $array, $object) + { + foreach ($array as $k => $v) { + $object->{$k} = $v; + } + return $object; + } + /** + * Converts value to array key. + * @param mixed $value + * @return array-key + */ + public static function toKey($value) + { + return \key([$value => null]); + } + /** + * Returns copy of the $array where every item is converted to string + * and prefixed by $prefix and suffixed by $suffix. + * @param string[] $array + * @return string[] + */ + public static function wrap(array $array, string $prefix = '', string $suffix = '') : array + { + $res = []; + foreach ($array as $k => $v) { + $res[$k] = $prefix . $v . $suffix; + } + return $res; + } +} diff --git a/vendor/nette/utils/src/Utils/Callback.php b/vendor/nette/utils/src/Utils/Callback.php new file mode 100644 index 0000000000..8f7759257a --- /dev/null +++ b/vendor/nette/utils/src/Utils/Callback.php @@ -0,0 +1,151 @@ +getMessage()); + } + } + /** + * Invokes callback. + * @return mixed + * @deprecated + */ + public static function invoke($callable, ...$args) + { + \trigger_error(__METHOD__ . '() is deprecated, use native invoking.', \E_USER_DEPRECATED); + self::check($callable); + return $callable(...$args); + } + /** + * Invokes callback with an array of parameters. + * @return mixed + * @deprecated + */ + public static function invokeArgs($callable, array $args = []) + { + \trigger_error(__METHOD__ . '() is deprecated, use native invoking.', \E_USER_DEPRECATED); + self::check($callable); + return $callable(...$args); + } + /** + * Invokes internal PHP function with own error handler. + * @return mixed + */ + public static function invokeSafe(string $function, array $args, callable $onError) + { + $prev = \set_error_handler(function ($severity, $message, $file) use($onError, &$prev, $function) : ?bool { + if ($file === __FILE__) { + $msg = \ini_get('html_errors') ? Html::htmlToText($message) : $message; + $msg = \preg_replace("#^{$function}\\(.*?\\): #", '', $msg); + if ($onError($msg, $severity) !== \false) { + return null; + } + } + return $prev ? $prev(...\func_get_args()) : \false; + }); + try { + return $function(...$args); + } finally { + \restore_error_handler(); + } + } + /** + * Checks that $callable is valid PHP callback. Otherwise throws exception. If the $syntax is set to true, only verifies + * that $callable has a valid structure to be used as a callback, but does not verify if the class or method actually exists. + * @param mixed $callable + * @return callable + * @throws Nette\InvalidArgumentException + */ + public static function check($callable, bool $syntax = \false) + { + if (!\is_callable($callable, $syntax)) { + throw new Nette\InvalidArgumentException($syntax ? 'Given value is not a callable type.' : \sprintf("Callback '%s' is not callable.", self::toString($callable))); + } + return $callable; + } + /** + * Converts PHP callback to textual form. Class or method may not exists. + * @param mixed $callable + */ + public static function toString($callable) : string + { + if ($callable instanceof \Closure) { + $inner = self::unwrap($callable); + return '{closure' . ($inner instanceof \Closure ? '}' : ' ' . self::toString($inner) . '}'); + } elseif (is_string($callable) && $callable[0] === "\x00") { + return '{lambda}'; + } else { + \is_callable(is_object($callable) ? [$callable, '__invoke'] : $callable, \true, $textual); + return $textual; + } + } + /** + * Returns reflection for method or function used in PHP callback. + * @param callable $callable type check is escalated to ReflectionException + * @return \ReflectionMethod|\ReflectionFunction + * @throws \ReflectionException if callback is not valid + */ + public static function toReflection($callable) : \ReflectionFunctionAbstract + { + if ($callable instanceof \Closure) { + $callable = self::unwrap($callable); + } + if (is_string($callable) && \strpos($callable, '::')) { + return new \ReflectionMethod($callable); + } elseif (is_array($callable)) { + return new \ReflectionMethod($callable[0], $callable[1]); + } elseif (is_object($callable) && !$callable instanceof \Closure) { + return new \ReflectionMethod($callable, '__invoke'); + } else { + return new \ReflectionFunction($callable); + } + } + /** + * Checks whether PHP callback is function or static method. + */ + public static function isStatic(callable $callable) : bool + { + return is_string(is_array($callable) ? $callable[0] : $callable); + } + /** + * Unwraps closure created by Closure::fromCallable(). + * @return callable|array + */ + public static function unwrap(\Closure $closure) + { + $r = new \ReflectionFunction($closure); + $class = $r->getClosureScopeClass(); + if (\substr($r->name, -1) === '}') { + return $closure; + } elseif (($obj = $r->getClosureThis()) && $class && \get_class($obj) === $class->name) { + return [$obj, $r->name]; + } elseif ($class) { + return [$class->name, $r->name]; + } else { + return $r->name; + } + } +} diff --git a/vendor/nette/utils/src/Utils/DateTime.php b/vendor/nette/utils/src/Utils/DateTime.php new file mode 100644 index 0000000000..53682f8ec5 --- /dev/null +++ b/vendor/nette/utils/src/Utils/DateTime.php @@ -0,0 +1,105 @@ +format('Y-m-d H:i:s.u'), $time->getTimezone()); + } elseif (\is_numeric($time)) { + if ($time <= self::YEAR) { + $time += \time(); + } + return (new static('@' . $time))->setTimezone(new \DateTimeZone(\date_default_timezone_get())); + } else { + // textual or null + return new static((string) $time); + } + } + /** + * Creates DateTime object. + * @return static + * @throws Nette\InvalidArgumentException if the date and time are not valid. + */ + public static function fromParts(int $year, int $month, int $day, int $hour = 0, int $minute = 0, float $second = 0.0) + { + $s = \sprintf('%04d-%02d-%02d %02d:%02d:%02.5F', $year, $month, $day, $hour, $minute, $second); + if (!\checkdate($month, $day, $year) || $hour < 0 || $hour > 23 || $minute < 0 || $minute > 59 || $second < 0 || $second >= 60) { + throw new Nette\InvalidArgumentException("Invalid date '{$s}'"); + } + return new static($s); + } + /** + * Returns new DateTime object formatted according to the specified format. + * @param string $format The format the $time parameter should be in + * @param string $time + * @param string|\DateTimeZone $timezone (default timezone is used if null is passed) + * @return static|false + */ + #[\ReturnTypeWillChange] + public static function createFromFormat($format, $time, $timezone = null) + { + if ($timezone === null) { + $timezone = new \DateTimeZone(\date_default_timezone_get()); + } elseif (\is_string($timezone)) { + $timezone = new \DateTimeZone($timezone); + } elseif (!$timezone instanceof \DateTimeZone) { + throw new Nette\InvalidArgumentException('Invalid timezone given'); + } + $date = parent::createFromFormat($format, $time, $timezone); + return $date ? static::from($date) : \false; + } + /** + * Returns JSON representation in ISO 8601 (used by JavaScript). + */ + public function jsonSerialize() : string + { + return $this->format('c'); + } + /** + * Returns the date and time in the format 'Y-m-d H:i:s'. + */ + public function __toString() : string + { + return $this->format('Y-m-d H:i:s'); + } + /** + * Creates a copy with a modified time. + * @return static + */ + public function modifyClone(string $modify = '') + { + $dolly = clone $this; + return $modify ? $dolly->modify($modify) : $dolly; + } +} diff --git a/vendor/nette/utils/src/Utils/FileSystem.php b/vendor/nette/utils/src/Utils/FileSystem.php new file mode 100644 index 0000000000..6eaa30746e --- /dev/null +++ b/vendor/nette/utils/src/Utils/FileSystem.php @@ -0,0 +1,186 @@ +getPathname()); + } + foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($origin, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item) { + if ($item->isDir()) { + static::createDir($target . '/' . $iterator->getSubPathName()); + } else { + static::copy($item->getPathname(), $target . '/' . $iterator->getSubPathName()); + } + } + } else { + static::createDir(\dirname($target)); + if (($s = @\fopen($origin, 'rb')) && ($d = @\fopen($target, 'wb')) && @\stream_copy_to_stream($s, $d) === \false) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to copy file '%s' to '%s'. %s", self::normalizePath($origin), self::normalizePath($target), Helpers::getLastError())); + } + } + } + /** + * Deletes a file or an entire directory if exists. If the directory is not empty, it deletes its contents first. + * @throws Nette\IOException on error occurred + */ + public static function delete(string $path) : void + { + if (\is_file($path) || \is_link($path)) { + $func = \DIRECTORY_SEPARATOR === '\\' && \is_dir($path) ? 'rmdir' : 'unlink'; + if (!@$func($path)) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to delete '%s'. %s", self::normalizePath($path), Helpers::getLastError())); + } + } elseif (\is_dir($path)) { + foreach (new \FilesystemIterator($path) as $item) { + static::delete($item->getPathname()); + } + if (!@\rmdir($path)) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to delete directory '%s'. %s", self::normalizePath($path), Helpers::getLastError())); + } + } + } + /** + * Renames or moves a file or a directory. Overwrites existing files and directories by default. + * @throws Nette\IOException on error occurred + * @throws Nette\InvalidStateException if $overwrite is set to false and destination already exists + */ + public static function rename(string $origin, string $target, bool $overwrite = \true) : void + { + if (!$overwrite && \file_exists($target)) { + throw new Nette\InvalidStateException(\sprintf("File or directory '%s' already exists.", self::normalizePath($target))); + } elseif (!\file_exists($origin)) { + throw new Nette\IOException(\sprintf("File or directory '%s' not found.", self::normalizePath($origin))); + } else { + static::createDir(\dirname($target)); + if (\realpath($origin) !== \realpath($target)) { + static::delete($target); + } + if (!@\rename($origin, $target)) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to rename file or directory '%s' to '%s'. %s", self::normalizePath($origin), self::normalizePath($target), Helpers::getLastError())); + } + } + } + /** + * Reads the content of a file. + * @throws Nette\IOException on error occurred + */ + public static function read(string $file) : string + { + $content = @\file_get_contents($file); + // @ is escalated to exception + if ($content === \false) { + throw new Nette\IOException(\sprintf("Unable to read file '%s'. %s", self::normalizePath($file), Helpers::getLastError())); + } + return $content; + } + /** + * Writes the string to a file. + * @throws Nette\IOException on error occurred + */ + public static function write(string $file, string $content, ?int $mode = 0666) : void + { + static::createDir(\dirname($file)); + if (@\file_put_contents($file, $content) === \false) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to write file '%s'. %s", self::normalizePath($file), Helpers::getLastError())); + } + if ($mode !== null && !@\chmod($file, $mode)) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to chmod file '%s' to mode %s. %s", self::normalizePath($file), \decoct($mode), Helpers::getLastError())); + } + } + /** + * Sets file permissions to `$fileMode` or directory permissions to `$dirMode`. + * Recursively traverses and sets permissions on the entire contents of the directory as well. + * @throws Nette\IOException on error occurred + */ + public static function makeWritable(string $path, int $dirMode = 0777, int $fileMode = 0666) : void + { + if (\is_file($path)) { + if (!@\chmod($path, $fileMode)) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to chmod file '%s' to mode %s. %s", self::normalizePath($path), \decoct($fileMode), Helpers::getLastError())); + } + } elseif (\is_dir($path)) { + foreach (new \FilesystemIterator($path) as $item) { + static::makeWritable($item->getPathname(), $dirMode, $fileMode); + } + if (!@\chmod($path, $dirMode)) { + // @ is escalated to exception + throw new Nette\IOException(\sprintf("Unable to chmod directory '%s' to mode %s. %s", self::normalizePath($path), \decoct($dirMode), Helpers::getLastError())); + } + } else { + throw new Nette\IOException(\sprintf("File or directory '%s' not found.", self::normalizePath($path))); + } + } + /** + * Determines if the path is absolute. + */ + public static function isAbsolute(string $path) : bool + { + return (bool) \preg_match('#([a-z]:)?[/\\\\]|[a-z][a-z0-9+.-]*://#Ai', $path); + } + /** + * Normalizes `..` and `.` and directory separators in path. + */ + public static function normalizePath(string $path) : string + { + $parts = $path === '' ? [] : \preg_split('~[/\\\\]+~', $path); + $res = []; + foreach ($parts as $part) { + if ($part === '..' && $res && \end($res) !== '..' && \end($res) !== '') { + \array_pop($res); + } elseif ($part !== '.') { + $res[] = $part; + } + } + return $res === [''] ? \DIRECTORY_SEPARATOR : \implode(\DIRECTORY_SEPARATOR, $res); + } + /** + * Joins all segments of the path and normalizes the result. + */ + public static function joinPaths(string ...$paths) : string + { + return self::normalizePath(\implode('/', $paths)); + } +} diff --git a/vendor/nette/utils/src/Utils/Floats.php b/vendor/nette/utils/src/Utils/Floats.php new file mode 100644 index 0000000000..237868e00b --- /dev/null +++ b/vendor/nette/utils/src/Utils/Floats.php @@ -0,0 +1,83 @@ + $b it returns 1 + * @throws \LogicException if one of parameters is NAN + */ + public static function compare(float $a, float $b) : int + { + if (\is_nan($a) || \is_nan($b)) { + throw new \LogicException('Trying to compare NAN'); + } elseif (!\is_finite($a) && !\is_finite($b) && $a === $b) { + return 0; + } + $diff = \abs($a - $b); + if ($diff < self::Epsilon || $diff / \max(\abs($a), \abs($b)) < self::Epsilon) { + return 0; + } + return $a < $b ? -1 : 1; + } + /** + * Returns true if $a = $b + * @throws \LogicException if one of parameters is NAN + */ + public static function areEqual(float $a, float $b) : bool + { + return self::compare($a, $b) === 0; + } + /** + * Returns true if $a < $b + * @throws \LogicException if one of parameters is NAN + */ + public static function isLessThan(float $a, float $b) : bool + { + return self::compare($a, $b) < 0; + } + /** + * Returns true if $a <= $b + * @throws \LogicException if one of parameters is NAN + */ + public static function isLessThanOrEqualTo(float $a, float $b) : bool + { + return self::compare($a, $b) <= 0; + } + /** + * Returns true if $a > $b + * @throws \LogicException if one of parameters is NAN + */ + public static function isGreaterThan(float $a, float $b) : bool + { + return self::compare($a, $b) > 0; + } + /** + * Returns true if $a >= $b + * @throws \LogicException if one of parameters is NAN + */ + public static function isGreaterThanOrEqualTo(float $a, float $b) : bool + { + return self::compare($a, $b) >= 0; + } +} diff --git a/vendor/nette/utils/src/Utils/Helpers.php b/vendor/nette/utils/src/Utils/Helpers.php new file mode 100644 index 0000000000..6e96365397 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Helpers.php @@ -0,0 +1,78 @@ + $max) { + throw new Nette\InvalidArgumentException("Minimum ({$min}) is not less than maximum ({$max})."); + } + return \min(\max($value, $min), $max); + } + /** + * Looks for a string from possibilities that is most similar to value, but not the same (for 8-bit encoding). + * @param string[] $possibilities + */ + public static function getSuggestion(array $possibilities, string $value) : ?string + { + $best = null; + $min = (\strlen($value) / 4 + 1) * 10 + 0.1; + foreach (\array_unique($possibilities) as $item) { + if ($item !== $value && ($len = \levenshtein($item, $value, 10, 11, 10)) < $min) { + $min = $len; + $best = $item; + } + } + return $best; + } +} diff --git a/vendor/nette/utils/src/Utils/Html.php b/vendor/nette/utils/src/Utils/Html.php new file mode 100644 index 0000000000..31b57a129e --- /dev/null +++ b/vendor/nette/utils/src/Utils/Html.php @@ -0,0 +1,744 @@ + element's attributes */ + public $attrs = []; + /** @var bool use XHTML syntax? */ + public static $xhtml = \false; + /** @var array void elements */ + public static $emptyElements = ['img' => 1, 'hr' => 1, 'br' => 1, 'input' => 1, 'meta' => 1, 'area' => 1, 'embed' => 1, 'keygen' => 1, 'source' => 1, 'base' => 1, 'col' => 1, 'link' => 1, 'param' => 1, 'basefont' => 1, 'frame' => 1, 'isindex' => 1, 'wbr' => 1, 'command' => 1, 'track' => 1]; + /** @var array nodes */ + protected $children = []; + /** @var string element's name */ + private $name; + /** @var bool is element empty? */ + private $isEmpty; + /** + * Constructs new HTML element. + * @param array|string $attrs element's attributes or plain text content + * @return static + */ + public static function el(?string $name = null, $attrs = null) + { + $el = new static(); + $parts = \explode(' ', (string) $name, 2); + $el->setName($parts[0]); + if (is_array($attrs)) { + $el->attrs = $attrs; + } elseif ($attrs !== null) { + $el->setText($attrs); + } + if (isset($parts[1])) { + foreach (Strings::matchAll($parts[1] . ' ', '#([a-z0-9:-]+)(?:=(["\'])?(.*?)(?(2)\\2|\\s))?#i') as $m) { + $el->attrs[$m[1]] = $m[3] ?? \true; + } + } + return $el; + } + /** + * Returns an object representing HTML text. + */ + public static function fromHtml(string $html) : self + { + return (new static())->setHtml($html); + } + /** + * Returns an object representing plain text. + */ + public static function fromText(string $text) : self + { + return (new static())->setText($text); + } + /** + * Converts to HTML. + */ + public final function toHtml() : string + { + return $this->render(); + } + /** + * Converts to plain text. + */ + public final function toText() : string + { + return $this->getText(); + } + /** + * Converts given HTML code to plain text. + */ + public static function htmlToText(string $html) : string + { + return \html_entity_decode(\strip_tags($html), \ENT_QUOTES | \ENT_HTML5, 'UTF-8'); + } + /** + * Changes element's name. + * @return static + */ + public final function setName(string $name, ?bool $isEmpty = null) + { + $this->name = $name; + $this->isEmpty = $isEmpty ?? isset(static::$emptyElements[$name]); + return $this; + } + /** + * Returns element's name. + */ + public final function getName() : string + { + return $this->name; + } + /** + * Is element empty? + */ + public final function isEmpty() : bool + { + return $this->isEmpty; + } + /** + * Sets multiple attributes. + * @return static + */ + public function addAttributes(array $attrs) + { + $this->attrs = \array_merge($this->attrs, $attrs); + return $this; + } + /** + * Appends value to element's attribute. + * @param mixed $value + * @param mixed $option + * @return static + */ + public function appendAttribute(string $name, $value, $option = \true) + { + if (is_array($value)) { + $prev = isset($this->attrs[$name]) ? (array) $this->attrs[$name] : []; + $this->attrs[$name] = $value + $prev; + } elseif ((string) $value === '') { + $tmp =& $this->attrs[$name]; + // appending empty value? -> ignore, but ensure it exists + } elseif (!isset($this->attrs[$name]) || is_array($this->attrs[$name])) { + // needs array + $this->attrs[$name][$value] = $option; + } else { + $this->attrs[$name] = [$this->attrs[$name] => \true, $value => $option]; + } + return $this; + } + /** + * Sets element's attribute. + * @param mixed $value + * @return static + */ + public function setAttribute(string $name, $value) + { + $this->attrs[$name] = $value; + return $this; + } + /** + * Returns element's attribute. + * @return mixed + */ + public function getAttribute(string $name) + { + return $this->attrs[$name] ?? null; + } + /** + * Unsets element's attribute. + * @return static + */ + public function removeAttribute(string $name) + { + unset($this->attrs[$name]); + return $this; + } + /** + * Unsets element's attributes. + * @return static + */ + public function removeAttributes(array $attributes) + { + foreach ($attributes as $name) { + unset($this->attrs[$name]); + } + return $this; + } + /** + * Overloaded setter for element's attribute. + * @param mixed $value + */ + public final function __set(string $name, $value) : void + { + $this->attrs[$name] = $value; + } + /** + * Overloaded getter for element's attribute. + * @return mixed + */ + public final function &__get(string $name) + { + return $this->attrs[$name]; + } + /** + * Overloaded tester for element's attribute. + */ + public final function __isset(string $name) : bool + { + return isset($this->attrs[$name]); + } + /** + * Overloaded unsetter for element's attribute. + */ + public final function __unset(string $name) : void + { + unset($this->attrs[$name]); + } + /** + * Overloaded setter for element's attribute. + * @return mixed + */ + public final function __call(string $m, array $args) + { + $p = \substr($m, 0, 3); + if ($p === 'get' || $p === 'set' || $p === 'add') { + $m = \substr($m, 3); + $m[0] = $m[0] | " "; + if ($p === 'get') { + return $this->attrs[$m] ?? null; + } elseif ($p === 'add') { + $args[] = \true; + } + } + if (\count($args) === 0) { + // invalid + } elseif (\count($args) === 1) { + // set + $this->attrs[$m] = $args[0]; + } else { + // add + $this->appendAttribute($m, $args[0], $args[1]); + } + return $this; + } + /** + * Special setter for element's attribute. + * @return static + */ + public final function href(string $path, ?array $query = null) + { + if ($query) { + $query = \http_build_query($query, '', '&'); + if ($query !== '') { + $path .= '?' . $query; + } + } + $this->attrs['href'] = $path; + return $this; + } + /** + * Setter for data-* attributes. Booleans are converted to 'true' resp. 'false'. + * @param mixed $value + * @return static + */ + public function data(string $name, $value = null) + { + if (\func_num_args() === 1) { + $this->attrs['data'] = $name; + } else { + $this->attrs["data-{$name}"] = \is_bool($value) ? \json_encode($value) : $value; + } + return $this; + } + /** + * Sets element's HTML content. + * @param HtmlStringable|string $html + * @return static + */ + public final function setHtml($html) + { + $this->children = [(string) $html]; + return $this; + } + /** + * Returns element's HTML content. + */ + public final function getHtml() : string + { + return \implode('', $this->children); + } + /** + * Sets element's textual content. + * @param HtmlStringable|string|int|float $text + * @return static + */ + public final function setText($text) + { + if (!$text instanceof HtmlStringable) { + $text = \htmlspecialchars((string) $text, \ENT_NOQUOTES, 'UTF-8'); + } + $this->children = [(string) $text]; + return $this; + } + /** + * Returns element's textual content. + */ + public final function getText() : string + { + return self::htmlToText($this->getHtml()); + } + /** + * Adds new element's child. + * @param HtmlStringable|string $child Html node or raw HTML string + * @return static + */ + public final function addHtml($child) + { + return $this->insert(null, $child); + } + /** + * Appends plain-text string to element content. + * @param HtmlStringable|string|int|float $text + * @return static + */ + public function addText($text) + { + if (!$text instanceof HtmlStringable) { + $text = \htmlspecialchars((string) $text, \ENT_NOQUOTES, 'UTF-8'); + } + return $this->insert(null, $text); + } + /** + * Creates and adds a new Html child. + * @param array|string $attrs element's attributes or raw HTML string + * @return static created element + */ + public final function create(string $name, $attrs = null) + { + $this->insert(null, $child = static::el($name, $attrs)); + return $child; + } + /** + * Inserts child node. + * @param HtmlStringable|string $child Html node or raw HTML string + * @return static + */ + public function insert(?int $index, $child, bool $replace = \false) + { + $child = $child instanceof self ? $child : (string) $child; + if ($index === null) { + // append + $this->children[] = $child; + } else { + // insert or replace + \array_splice($this->children, $index, $replace ? 1 : 0, [$child]); + } + return $this; + } + /** + * Inserts (replaces) child node (\ArrayAccess implementation). + * @param int|null $index position or null for appending + * @param Html|string $child Html node or raw HTML string + */ + public final function offsetSet($index, $child) : void + { + $this->insert($index, $child, \true); + } + /** + * Returns child node (\ArrayAccess implementation). + * @param int $index + * @return HtmlStringable|string + */ + #[\ReturnTypeWillChange] + public final function offsetGet($index) + { + return $this->children[$index]; + } + /** + * Exists child node? (\ArrayAccess implementation). + * @param int $index + */ + public final function offsetExists($index) : bool + { + return isset($this->children[$index]); + } + /** + * Removes child node (\ArrayAccess implementation). + * @param int $index + */ + public function offsetUnset($index) : void + { + if (isset($this->children[$index])) { + \array_splice($this->children, $index, 1); + } + } + /** + * Returns children count. + */ + public final function count() : int + { + return \count($this->children); + } + /** + * Removes all children. + */ + public function removeChildren() : void + { + $this->children = []; + } + /** + * Iterates over elements. + * @return \ArrayIterator + */ + public final function getIterator() : \ArrayIterator + { + return new \ArrayIterator($this->children); + } + /** + * Returns all children. + */ + public final function getChildren() : array + { + return $this->children; + } + /** + * Renders element's start tag, content and end tag. + */ + public final function render(?int $indent = null) : string + { + $s = $this->startTag(); + if (!$this->isEmpty) { + // add content + if ($indent !== null) { + $indent++; + } + foreach ($this->children as $child) { + if ($child instanceof self) { + $s .= $child->render($indent); + } else { + $s .= $child; + } + } + // add end tag + $s .= $this->endTag(); + } + if ($indent !== null) { + return "\n" . \str_repeat("\t", $indent - 1) . $s . "\n" . \str_repeat("\t", \max(0, $indent - 2)); + } + return $s; + } + public final function __toString() : string + { + try { + return $this->render(); + } catch (\Throwable $e) { + if (\PHP_VERSION_ID >= 70400) { + throw $e; + } + \trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", \E_USER_ERROR); + return ''; + } + } + /** + * Returns element's start tag. + */ + public final function startTag() : string + { + return $this->name ? '<' . $this->name . $this->attributes() . (static::$xhtml && $this->isEmpty ? ' />' : '>') : ''; + } + /** + * Returns element's end tag. + */ + public final function endTag() : string + { + return $this->name && !$this->isEmpty ? 'name . '>' : ''; + } + /** + * Returns element's attributes. + * @internal + */ + public final function attributes() : string + { + if (!is_array($this->attrs)) { + return ''; + } + $s = ''; + $attrs = $this->attrs; + foreach ($attrs as $key => $value) { + if ($value === null || $value === \false) { + continue; + } elseif ($value === \true) { + if (static::$xhtml) { + $s .= ' ' . $key . '="' . $key . '"'; + } else { + $s .= ' ' . $key; + } + continue; + } elseif (is_array($value)) { + if (\strncmp($key, 'data-', 5) === 0) { + $value = Json::encode($value); + } else { + $tmp = null; + foreach ($value as $k => $v) { + if ($v != null) { + // intentionally ==, skip nulls & empty string + // composite 'style' vs. 'others' + $tmp[] = $v === \true ? $k : (is_string($k) ? $k . ':' . $v : $v); + } + } + if ($tmp === null) { + continue; + } + $value = \implode($key === 'style' || !\strncmp($key, 'on', 2) ? ';' : ' ', $tmp); + } + } elseif (is_float($value)) { + $value = \rtrim(\rtrim(\number_format($value, 10, '.', ''), '0'), '.'); + } else { + $value = (string) $value; + } + $q = \strpos($value, '"') === \false ? '"' : "'"; + $s .= ' ' . $key . '=' . $q . \str_replace(['&', $q, '<'], ['&', $q === '"' ? '"' : ''', self::$xhtml ? '<' : '<'], $value) . (\strpos($value, '`') !== \false && \strpbrk($value, ' <>"\'') === \false ? ' ' : '') . $q; + } + $s = \str_replace('@', '@', $s); + return $s; + } + /** + * Clones all children too. + */ + public function __clone() + { + foreach ($this->children as $key => $value) { + if (is_object($value)) { + $this->children[$key] = clone $value; + } + } + } +} diff --git a/vendor/nette/utils/src/Utils/Image.php b/vendor/nette/utils/src/Utils/Image.php new file mode 100644 index 0000000000..300b127aea --- /dev/null +++ b/vendor/nette/utils/src/Utils/Image.php @@ -0,0 +1,611 @@ + + * $image = Image::fromFile('nette.jpg'); + * $image->resize(150, 100); + * $image->sharpen(); + * $image->send(); + * + * + * @method Image affine(array $affine, array $clip = null) + * @method array affineMatrixConcat(array $m1, array $m2) + * @method array affineMatrixGet(int $type, mixed $options = null) + * @method void alphaBlending(bool $on) + * @method void antialias(bool $on) + * @method void arc($x, $y, $w, $h, $start, $end, $color) + * @method void char(int $font, $x, $y, string $char, $color) + * @method void charUp(int $font, $x, $y, string $char, $color) + * @method int colorAllocate($red, $green, $blue) + * @method int colorAllocateAlpha($red, $green, $blue, $alpha) + * @method int colorAt($x, $y) + * @method int colorClosest($red, $green, $blue) + * @method int colorClosestAlpha($red, $green, $blue, $alpha) + * @method int colorClosestHWB($red, $green, $blue) + * @method void colorDeallocate($color) + * @method int colorExact($red, $green, $blue) + * @method int colorExactAlpha($red, $green, $blue, $alpha) + * @method void colorMatch(Image $image2) + * @method int colorResolve($red, $green, $blue) + * @method int colorResolveAlpha($red, $green, $blue, $alpha) + * @method void colorSet($index, $red, $green, $blue) + * @method array colorsForIndex($index) + * @method int colorsTotal() + * @method int colorTransparent($color = null) + * @method void convolution(array $matrix, float $div, float $offset) + * @method void copy(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH) + * @method void copyMerge(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH, $opacity) + * @method void copyMergeGray(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH, $opacity) + * @method void copyResampled(Image $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) + * @method void copyResized(Image $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) + * @method Image cropAuto(int $mode = -1, float $threshold = .5, int $color = -1) + * @method void ellipse($cx, $cy, $w, $h, $color) + * @method void fill($x, $y, $color) + * @method void filledArc($cx, $cy, $w, $h, $s, $e, $color, $style) + * @method void filledEllipse($cx, $cy, $w, $h, $color) + * @method void filledPolygon(array $points, $numPoints, $color) + * @method void filledRectangle($x1, $y1, $x2, $y2, $color) + * @method void fillToBorder($x, $y, $border, $color) + * @method void filter($filtertype) + * @method void flip(int $mode) + * @method array ftText($size, $angle, $x, $y, $col, string $fontFile, string $text, array $extrainfo = null) + * @method void gammaCorrect(float $inputgamma, float $outputgamma) + * @method array getClip() + * @method int interlace($interlace = null) + * @method bool isTrueColor() + * @method void layerEffect($effect) + * @method void line($x1, $y1, $x2, $y2, $color) + * @method void openPolygon(array $points, int $num_points, int $color) + * @method void paletteCopy(Image $source) + * @method void paletteToTrueColor() + * @method void polygon(array $points, $numPoints, $color) + * @method array psText(string $text, $font, $size, $color, $backgroundColor, $x, $y, $space = null, $tightness = null, float $angle = null, $antialiasSteps = null) + * @method void rectangle($x1, $y1, $x2, $y2, $col) + * @method mixed resolution(int $res_x = null, int $res_y = null) + * @method Image rotate(float $angle, $backgroundColor) + * @method void saveAlpha(bool $saveflag) + * @method Image scale(int $newWidth, int $newHeight = -1, int $mode = IMG_BILINEAR_FIXED) + * @method void setBrush(Image $brush) + * @method void setClip(int $x1, int $y1, int $x2, int $y2) + * @method void setInterpolation(int $method = IMG_BILINEAR_FIXED) + * @method void setPixel($x, $y, $color) + * @method void setStyle(array $style) + * @method void setThickness($thickness) + * @method void setTile(Image $tile) + * @method void string($font, $x, $y, string $s, $col) + * @method void stringUp($font, $x, $y, string $s, $col) + * @method void trueColorToPalette(bool $dither, $ncolors) + * @method array ttfText($size, $angle, $x, $y, $color, string $fontfile, string $text) + * @property-read positive-int $width + * @property-read positive-int $height + * @property-read resource|\GdImage $imageResource + */ +class Image +{ + use Nette\SmartObject; + /** Prevent from getting resized to a bigger size than the original */ + public const SHRINK_ONLY = 0b1; + /** Resizes to a specified width and height without keeping aspect ratio */ + public const STRETCH = 0b10; + /** Resizes to fit into a specified width and height and preserves aspect ratio */ + public const FIT = 0b0; + /** Resizes while bounding the smaller dimension to the specified width or height and preserves aspect ratio */ + public const FILL = 0b100; + /** Resizes to the smallest possible size to completely cover specified width and height and reserves aspect ratio */ + public const EXACT = 0b1000; + /** image types */ + public const JPEG = \IMAGETYPE_JPEG, PNG = \IMAGETYPE_PNG, GIF = \IMAGETYPE_GIF, WEBP = \IMAGETYPE_WEBP, AVIF = 19, BMP = \IMAGETYPE_BMP; + public const EMPTY_GIF = "GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;"; + private const Formats = [self::JPEG => 'jpeg', self::PNG => 'png', self::GIF => 'gif', self::WEBP => 'webp', self::AVIF => 'avif', self::BMP => 'bmp']; + /** @var resource|\GdImage */ + private $image; + /** + * Returns RGB color (0..255) and transparency (0..127). + */ + public static function rgb(int $red, int $green, int $blue, int $transparency = 0) : array + { + return ['red' => \max(0, \min(255, $red)), 'green' => \max(0, \min(255, $green)), 'blue' => \max(0, \min(255, $blue)), 'alpha' => \max(0, \min(127, $transparency))]; + } + /** + * Reads an image from a file and returns its type in $type. + * @throws Nette\NotSupportedException if gd extension is not loaded + * @throws UnknownImageFileException if file not found or file type is not known + * @return static + */ + public static function fromFile(string $file, ?int &$type = null) + { + if (!\extension_loaded('gd')) { + throw new Nette\NotSupportedException('PHP extension GD is not loaded.'); + } + $type = self::detectTypeFromFile($file); + if (!$type) { + throw new UnknownImageFileException(\is_file($file) ? "Unknown type of file '{$file}'." : "File '{$file}' not found."); + } + return self::invokeSafe('imagecreatefrom' . self::Formats[$type], $file, "Unable to open file '{$file}'.", __METHOD__); + } + /** + * Reads an image from a string and returns its type in $type. + * @return static + * @throws Nette\NotSupportedException if gd extension is not loaded + * @throws ImageException + */ + public static function fromString(string $s, ?int &$type = null) + { + if (!\extension_loaded('gd')) { + throw new Nette\NotSupportedException('PHP extension GD is not loaded.'); + } + $type = self::detectTypeFromString($s); + if (!$type) { + throw new UnknownImageFileException('Unknown type of image.'); + } + return self::invokeSafe('imagecreatefromstring', $s, 'Unable to open image from string.', __METHOD__); + } + private static function invokeSafe(string $func, string $arg, string $message, string $callee) : self + { + $errors = []; + $res = Callback::invokeSafe($func, [$arg], function (string $message) use(&$errors) : void { + $errors[] = $message; + }); + if (!$res) { + throw new ImageException($message . ' Errors: ' . \implode(', ', $errors)); + } elseif ($errors) { + \trigger_error($callee . '(): ' . \implode(', ', $errors), \E_USER_WARNING); + } + return new static($res); + } + /** + * Creates a new true color image of the given dimensions. The default color is black. + * @param positive-int $width + * @param positive-int $height + * @return static + * @throws Nette\NotSupportedException if gd extension is not loaded + */ + public static function fromBlank(int $width, int $height, ?array $color = null) + { + if (!\extension_loaded('gd')) { + throw new Nette\NotSupportedException('PHP extension GD is not loaded.'); + } + if ($width < 1 || $height < 1) { + throw new Nette\InvalidArgumentException('Image width and height must be greater than zero.'); + } + $image = \imagecreatetruecolor($width, $height); + if ($color) { + $color += ['alpha' => 0]; + $color = \imagecolorresolvealpha($image, $color['red'], $color['green'], $color['blue'], $color['alpha']); + \imagealphablending($image, \false); + \imagefilledrectangle($image, 0, 0, $width - 1, $height - 1, $color); + \imagealphablending($image, \true); + } + return new static($image); + } + /** + * Returns the type of image from file. + */ + public static function detectTypeFromFile(string $file, &$width = null, &$height = null) : ?int + { + [$width, $height, $type] = @\getimagesize($file); + // @ - files smaller than 12 bytes causes read error + return isset(self::Formats[$type]) ? $type : null; + } + /** + * Returns the type of image from string. + */ + public static function detectTypeFromString(string $s, &$width = null, &$height = null) : ?int + { + [$width, $height, $type] = @\getimagesizefromstring($s); + // @ - strings smaller than 12 bytes causes read error + return isset(self::Formats[$type]) ? $type : null; + } + /** + * Returns the file extension for the given `Image::XXX` constant. + */ + public static function typeToExtension(int $type) : string + { + if (!isset(self::Formats[$type])) { + throw new Nette\InvalidArgumentException("Unsupported image type '{$type}'."); + } + return self::Formats[$type]; + } + /** + * Returns the `Image::XXX` constant for given file extension. + */ + public static function extensionToType(string $extension) : int + { + $extensions = \array_flip(self::Formats) + ['jpg' => self::JPEG]; + $extension = \strtolower($extension); + if (!isset($extensions[$extension])) { + throw new Nette\InvalidArgumentException("Unsupported file extension '{$extension}'."); + } + return $extensions[$extension]; + } + /** + * Returns the mime type for the given `Image::XXX` constant. + */ + public static function typeToMimeType(int $type) : string + { + return 'image/' . self::typeToExtension($type); + } + /** + * Wraps GD image. + * @param resource|\GdImage $image + */ + public function __construct($image) + { + $this->setImageResource($image); + \imagesavealpha($image, \true); + } + /** + * Returns image width. + * @return positive-int + */ + public function getWidth() : int + { + return \imagesx($this->image); + } + /** + * Returns image height. + * @return positive-int + */ + public function getHeight() : int + { + return \imagesy($this->image); + } + /** + * Sets image resource. + * @param resource|\GdImage $image + * @return static + */ + protected function setImageResource($image) + { + if (!$image instanceof \GdImage && !(\is_resource($image) && \get_resource_type($image) === 'gd')) { + throw new Nette\InvalidArgumentException('Image is not valid.'); + } + $this->image = $image; + return $this; + } + /** + * Returns image GD resource. + * @return resource|\GdImage + */ + public function getImageResource() + { + return $this->image; + } + /** + * Scales an image. + * @param int|string|null $width in pixels or percent + * @param int|string|null $height in pixels or percent + * @return static + */ + public function resize($width, $height, int $flags = self::FIT) + { + if ($flags & self::EXACT) { + return $this->resize($width, $height, self::FILL)->crop('50%', '50%', $width, $height); + } + [$newWidth, $newHeight] = static::calculateSize($this->getWidth(), $this->getHeight(), $width, $height, $flags); + if ($newWidth !== $this->getWidth() || $newHeight !== $this->getHeight()) { + // resize + $newImage = static::fromBlank($newWidth, $newHeight, self::rgb(0, 0, 0, 127))->getImageResource(); + \imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $newWidth, $newHeight, $this->getWidth(), $this->getHeight()); + $this->image = $newImage; + } + if ($width < 0 || $height < 0) { + \imageflip($this->image, $width < 0 ? $height < 0 ? \IMG_FLIP_BOTH : \IMG_FLIP_HORIZONTAL : \IMG_FLIP_VERTICAL); + } + return $this; + } + /** + * Calculates dimensions of resized image. + * @param int|string|null $newWidth in pixels or percent + * @param int|string|null $newHeight in pixels or percent + */ + public static function calculateSize(int $srcWidth, int $srcHeight, $newWidth, $newHeight, int $flags = self::FIT) : array + { + if ($newWidth === null) { + } elseif (self::isPercent($newWidth)) { + $newWidth = (int) \round($srcWidth / 100 * \abs($newWidth)); + $percents = \true; + } else { + $newWidth = \abs($newWidth); + } + if ($newHeight === null) { + } elseif (self::isPercent($newHeight)) { + $newHeight = (int) \round($srcHeight / 100 * \abs($newHeight)); + $flags |= empty($percents) ? 0 : self::STRETCH; + } else { + $newHeight = \abs($newHeight); + } + if ($flags & self::STRETCH) { + // non-proportional + if (!$newWidth || !$newHeight) { + throw new Nette\InvalidArgumentException('For stretching must be both width and height specified.'); + } + if ($flags & self::SHRINK_ONLY) { + $newWidth = (int) \round($srcWidth * \min(1, $newWidth / $srcWidth)); + $newHeight = (int) \round($srcHeight * \min(1, $newHeight / $srcHeight)); + } + } else { + // proportional + if (!$newWidth && !$newHeight) { + throw new Nette\InvalidArgumentException('At least width or height must be specified.'); + } + $scale = []; + if ($newWidth > 0) { + // fit width + $scale[] = $newWidth / $srcWidth; + } + if ($newHeight > 0) { + // fit height + $scale[] = $newHeight / $srcHeight; + } + if ($flags & self::FILL) { + $scale = [\max($scale)]; + } + if ($flags & self::SHRINK_ONLY) { + $scale[] = 1; + } + $scale = \min($scale); + $newWidth = (int) \round($srcWidth * $scale); + $newHeight = (int) \round($srcHeight * $scale); + } + return [\max($newWidth, 1), \max($newHeight, 1)]; + } + /** + * Crops image. + * @param int|string $left in pixels or percent + * @param int|string $top in pixels or percent + * @param int|string $width in pixels or percent + * @param int|string $height in pixels or percent + * @return static + */ + public function crop($left, $top, $width, $height) + { + [$r['x'], $r['y'], $r['width'], $r['height']] = static::calculateCutout($this->getWidth(), $this->getHeight(), $left, $top, $width, $height); + if (\gd_info()['GD Version'] === 'bundled (2.1.0 compatible)') { + $this->image = \imagecrop($this->image, $r); + \imagesavealpha($this->image, \true); + } else { + $newImage = static::fromBlank($r['width'], $r['height'], self::RGB(0, 0, 0, 127))->getImageResource(); + \imagecopy($newImage, $this->image, 0, 0, $r['x'], $r['y'], $r['width'], $r['height']); + $this->image = $newImage; + } + return $this; + } + /** + * Calculates dimensions of cutout in image. + * @param int|string $left in pixels or percent + * @param int|string $top in pixels or percent + * @param int|string $newWidth in pixels or percent + * @param int|string $newHeight in pixels or percent + */ + public static function calculateCutout(int $srcWidth, int $srcHeight, $left, $top, $newWidth, $newHeight) : array + { + if (self::isPercent($newWidth)) { + $newWidth = (int) \round($srcWidth / 100 * $newWidth); + } + if (self::isPercent($newHeight)) { + $newHeight = (int) \round($srcHeight / 100 * $newHeight); + } + if (self::isPercent($left)) { + $left = (int) \round(($srcWidth - $newWidth) / 100 * $left); + } + if (self::isPercent($top)) { + $top = (int) \round(($srcHeight - $newHeight) / 100 * $top); + } + if ($left < 0) { + $newWidth += $left; + $left = 0; + } + if ($top < 0) { + $newHeight += $top; + $top = 0; + } + $newWidth = \min($newWidth, $srcWidth - $left); + $newHeight = \min($newHeight, $srcHeight - $top); + return [$left, $top, $newWidth, $newHeight]; + } + /** + * Sharpens image a little bit. + * @return static + */ + public function sharpen() + { + \imageconvolution($this->image, [ + // my magic numbers ;) + [-1, -1, -1], + [-1, 24, -1], + [-1, -1, -1], + ], 16, 0); + return $this; + } + /** + * Puts another image into this image. + * @param int|string $left in pixels or percent + * @param int|string $top in pixels or percent + * @param int<0, 100> $opacity 0..100 + * @return static + */ + public function place(self $image, $left = 0, $top = 0, int $opacity = 100) + { + $opacity = \max(0, \min(100, $opacity)); + if ($opacity === 0) { + return $this; + } + $width = $image->getWidth(); + $height = $image->getHeight(); + if (self::isPercent($left)) { + $left = (int) \round(($this->getWidth() - $width) / 100 * $left); + } + if (self::isPercent($top)) { + $top = (int) \round(($this->getHeight() - $height) / 100 * $top); + } + $output = $input = $image->image; + if ($opacity < 100) { + $tbl = []; + for ($i = 0; $i < 128; $i++) { + $tbl[$i] = \round(127 - (127 - $i) * $opacity / 100); + } + $output = \imagecreatetruecolor($width, $height); + \imagealphablending($output, \false); + if (!$image->isTrueColor()) { + $input = $output; + \imagefilledrectangle($output, 0, 0, $width, $height, \imagecolorallocatealpha($output, 0, 0, 0, 127)); + \imagecopy($output, $image->image, 0, 0, 0, 0, $width, $height); + } + for ($x = 0; $x < $width; $x++) { + for ($y = 0; $y < $height; $y++) { + $c = \imagecolorat($input, $x, $y); + $c = ($c & 0xffffff) + ($tbl[$c >> 24] << 24); + \imagesetpixel($output, $x, $y, $c); + } + } + \imagealphablending($output, \true); + } + \imagecopy($this->image, $output, $left, $top, 0, 0, $width, $height); + return $this; + } + /** + * Saves image to the file. Quality is in the range 0..100 for JPEG (default 85), WEBP (default 80) and AVIF (default 30) and 0..9 for PNG (default 9). + * @throws ImageException + */ + public function save(string $file, ?int $quality = null, ?int $type = null) : void + { + $type = $type ?? self::extensionToType(\pathinfo($file, \PATHINFO_EXTENSION)); + $this->output($type, $quality, $file); + } + /** + * Outputs image to string. Quality is in the range 0..100 for JPEG (default 85), WEBP (default 80) and AVIF (default 30) and 0..9 for PNG (default 9). + */ + public function toString(int $type = self::JPEG, ?int $quality = null) : string + { + return Helpers::capture(function () use($type, $quality) { + $this->output($type, $quality); + }); + } + /** + * Outputs image to string. + */ + public function __toString() : string + { + try { + return $this->toString(); + } catch (\Throwable $e) { + if (\func_num_args() || \PHP_VERSION_ID >= 70400) { + throw $e; + } + \trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", \E_USER_ERROR); + return ''; + } + } + /** + * Outputs image to browser. Quality is in the range 0..100 for JPEG (default 85), WEBP (default 80) and AVIF (default 30) and 0..9 for PNG (default 9). + * @throws ImageException + */ + public function send(int $type = self::JPEG, ?int $quality = null) : void + { + \header('Content-Type: ' . self::typeToMimeType($type)); + $this->output($type, $quality); + } + /** + * Outputs image to browser or file. + * @throws ImageException + */ + private function output(int $type, ?int $quality, ?string $file = null) : void + { + switch ($type) { + case self::JPEG: + $quality = $quality === null ? 85 : \max(0, \min(100, $quality)); + $success = @\imagejpeg($this->image, $file, $quality); + // @ is escalated to exception + break; + case self::PNG: + $quality = $quality === null ? 9 : \max(0, \min(9, $quality)); + $success = @\imagepng($this->image, $file, $quality); + // @ is escalated to exception + break; + case self::GIF: + $success = @\imagegif($this->image, $file); + // @ is escalated to exception + break; + case self::WEBP: + $quality = $quality === null ? 80 : \max(0, \min(100, $quality)); + $success = @\imagewebp($this->image, $file, $quality); + // @ is escalated to exception + break; + case self::AVIF: + $quality = $quality === null ? 30 : \max(0, \min(100, $quality)); + $success = @imageavif($this->image, $file, $quality); + // @ is escalated to exception + break; + case self::BMP: + $success = @\imagebmp($this->image, $file); + // @ is escalated to exception + break; + default: + throw new Nette\InvalidArgumentException("Unsupported image type '{$type}'."); + } + if (!$success) { + throw new ImageException(Helpers::getLastError() ?: 'Unknown error'); + } + } + /** + * Call to undefined method. + * @return mixed + * @throws Nette\MemberAccessException + */ + public function __call(string $name, array $args) + { + $function = 'image' . $name; + if (!\function_exists($function)) { + ObjectHelpers::strictCall(static::class, $name); + } + foreach ($args as $key => $value) { + if ($value instanceof self) { + $args[$key] = $value->getImageResource(); + } elseif (\is_array($value) && isset($value['red'])) { + // rgb + $args[$key] = \imagecolorallocatealpha($this->image, $value['red'], $value['green'], $value['blue'], $value['alpha']) ?: \imagecolorresolvealpha($this->image, $value['red'], $value['green'], $value['blue'], $value['alpha']); + } + } + $res = $function($this->image, ...$args); + return $res instanceof \GdImage || \is_resource($res) && \get_resource_type($res) === 'gd' ? $this->setImageResource($res) : $res; + } + public function __clone() + { + \ob_start(function () { + }); + \imagepng($this->image, null, 0); + $this->setImageResource(\imagecreatefromstring(\ob_get_clean())); + } + /** + * @param int|string $num in pixels or percent + */ + private static function isPercent(&$num) : bool + { + if (\is_string($num) && \substr($num, -1) === '%') { + $num = (float) \substr($num, 0, -1); + return \true; + } elseif (\is_int($num) || $num === (string) (int) $num) { + $num = (int) $num; + return \false; + } + throw new Nette\InvalidArgumentException("Expected dimension in int|string, '{$num}' given."); + } + /** + * Prevents serialization. + */ + public function __sleep() : array + { + throw new Nette\NotSupportedException('You cannot serialize or unserialize ' . self::class . ' instances.'); + } +} diff --git a/vendor/nette/utils/src/Utils/Json.php b/vendor/nette/utils/src/Utils/Json.php new file mode 100644 index 0000000000..c2efd7f23d --- /dev/null +++ b/vendor/nette/utils/src/Utils/Json.php @@ -0,0 +1,49 @@ +getProperties(\ReflectionProperty::IS_PUBLIC), function ($p) { + return !$p->isStatic(); + }), self::parseFullDoc($rc, '~^[ \\t*]*@property(?:-read)?[ \\t]+(?:\\S+[ \\t]+)??\\$(\\w+)~m')), $name); + throw new MemberAccessException("Cannot read an undeclared property {$class}::\${$name}" . ($hint ? ", did you mean \${$hint}?" : '.')); + } + /** + * @return never + * @throws MemberAccessException + */ + public static function strictSet(string $class, string $name) : void + { + $rc = new \ReflectionClass($class); + $hint = self::getSuggestion(\array_merge(\array_filter($rc->getProperties(\ReflectionProperty::IS_PUBLIC), function ($p) { + return !$p->isStatic(); + }), self::parseFullDoc($rc, '~^[ \\t*]*@property(?:-write)?[ \\t]+(?:\\S+[ \\t]+)??\\$(\\w+)~m')), $name); + throw new MemberAccessException("Cannot write to an undeclared property {$class}::\${$name}" . ($hint ? ", did you mean \${$hint}?" : '.')); + } + /** + * @return never + * @throws MemberAccessException + */ + public static function strictCall(string $class, string $method, array $additionalMethods = []) : void + { + $trace = \debug_backtrace(0, 3); + // suppose this method is called from __call() + $context = ($trace[1]['function'] ?? null) === '__call' ? $trace[2]['class'] ?? null : null; + if ($context && \is_a($class, $context, \true) && \method_exists($context, $method)) { + // called parent::$method() + $class = \get_parent_class($context); + } + if (\method_exists($class, $method)) { + // insufficient visibility + $rm = new \ReflectionMethod($class, $method); + $visibility = $rm->isPrivate() ? 'private ' : ($rm->isProtected() ? 'protected ' : ''); + throw new MemberAccessException("Call to {$visibility}method {$class}::{$method}() from " . ($context ? "scope {$context}." : 'global scope.')); + } else { + $hint = self::getSuggestion(\array_merge(\get_class_methods($class), self::parseFullDoc(new \ReflectionClass($class), '~^[ \\t*]*@method[ \\t]+(?:static[ \\t]+)?(?:\\S+[ \\t]+)??(\\w+)\\(~m'), $additionalMethods), $method); + throw new MemberAccessException("Call to undefined method {$class}::{$method}()" . ($hint ? ", did you mean {$hint}()?" : '.')); + } + } + /** + * @return never + * @throws MemberAccessException + */ + public static function strictStaticCall(string $class, string $method) : void + { + $trace = \debug_backtrace(0, 3); + // suppose this method is called from __callStatic() + $context = ($trace[1]['function'] ?? null) === '__callStatic' ? $trace[2]['class'] ?? null : null; + if ($context && \is_a($class, $context, \true) && \method_exists($context, $method)) { + // called parent::$method() + $class = \get_parent_class($context); + } + if (\method_exists($class, $method)) { + // insufficient visibility + $rm = new \ReflectionMethod($class, $method); + $visibility = $rm->isPrivate() ? 'private ' : ($rm->isProtected() ? 'protected ' : ''); + throw new MemberAccessException("Call to {$visibility}method {$class}::{$method}() from " . ($context ? "scope {$context}." : 'global scope.')); + } else { + $hint = self::getSuggestion(\array_filter((new \ReflectionClass($class))->getMethods(\ReflectionMethod::IS_PUBLIC), function ($m) { + return $m->isStatic(); + }), $method); + throw new MemberAccessException("Call to undefined static method {$class}::{$method}()" . ($hint ? ", did you mean {$hint}()?" : '.')); + } + } + /** + * Returns array of magic properties defined by annotation @property. + * @return array of [name => bit mask] + * @internal + */ + public static function getMagicProperties(string $class) : array + { + static $cache; + $props =& $cache[$class]; + if ($props !== null) { + return $props; + } + $rc = new \ReflectionClass($class); + \preg_match_all('~^ [ \\t*]* @property(|-read|-write|-deprecated) [ \\t]+ [^\\s$]+ [ \\t]+ \\$ (\\w+) ()~mx', (string) $rc->getDocComment(), $matches, \PREG_SET_ORDER); + $props = []; + foreach ($matches as [, $type, $name]) { + $uname = \ucfirst($name); + $write = $type !== '-read' && $rc->hasMethod($nm = 'set' . $uname) && ($rm = $rc->getMethod($nm))->name === $nm && !$rm->isPrivate() && !$rm->isStatic(); + $read = $type !== '-write' && ($rc->hasMethod($nm = 'get' . $uname) || $rc->hasMethod($nm = 'is' . $uname)) && ($rm = $rc->getMethod($nm))->name === $nm && !$rm->isPrivate() && !$rm->isStatic(); + if ($read || $write) { + $props[$name] = $read << 0 | ($nm[0] === 'g') << 1 | $rm->returnsReference() << 2 | $write << 3 | ($type === '-deprecated') << 4; + } + } + foreach ($rc->getTraits() as $trait) { + $props += self::getMagicProperties($trait->name); + } + if ($parent = \get_parent_class($class)) { + $props += self::getMagicProperties($parent); + } + return $props; + } + /** + * Finds the best suggestion (for 8-bit encoding). + * @param (\ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionClass|\ReflectionProperty|string)[] $possibilities + * @internal + */ + public static function getSuggestion(array $possibilities, string $value) : ?string + { + $norm = \preg_replace($re = '#^(get|set|has|is|add)(?=[A-Z])#', '+', $value); + $best = null; + $min = (\strlen($value) / 4 + 1) * 10 + 0.1; + foreach (\array_unique($possibilities, \SORT_REGULAR) as $item) { + $item = $item instanceof \Reflector ? $item->name : $item; + if ($item !== $value && (($len = \levenshtein($item, $value, 10, 11, 10)) < $min || ($len = \levenshtein(\preg_replace($re, '*', $item), $norm, 10, 11, 10)) < $min)) { + $min = $len; + $best = $item; + } + } + return $best; + } + private static function parseFullDoc(\ReflectionClass $rc, string $pattern) : array + { + do { + $doc[] = $rc->getDocComment(); + $traits = $rc->getTraits(); + while ($trait = \array_pop($traits)) { + $doc[] = $trait->getDocComment(); + $traits += $trait->getTraits(); + } + } while ($rc = $rc->getParentClass()); + return \preg_match_all($pattern, \implode($doc), $m) ? $m[1] : []; + } + /** + * Checks if the public non-static property exists. + * @return bool|string returns 'event' if the property exists and has event like name + * @internal + */ + public static function hasProperty(string $class, string $name) + { + static $cache; + $prop =& $cache[$class][$name]; + if ($prop === null) { + $prop = \false; + try { + $rp = new \ReflectionProperty($class, $name); + $rp->setAccessible(\true); + if ($rp->isPublic() && !$rp->isStatic()) { + $prop = $name >= 'onA' && $name < 'on_' ? 'event' : \true; + } + } catch (\ReflectionException $e) { + } + } + return $prop; + } +} diff --git a/vendor/nette/utils/src/Utils/ObjectMixin.php b/vendor/nette/utils/src/Utils/ObjectMixin.php new file mode 100644 index 0000000000..c1080cb273 --- /dev/null +++ b/vendor/nette/utils/src/Utils/ObjectMixin.php @@ -0,0 +1,32 @@ + $firstItemOnPage + * @property-read int<0,max> $lastItemOnPage + * @property int $base + * @property-read bool $first + * @property-read bool $last + * @property-read int<0,max>|null $pageCount + * @property positive-int $itemsPerPage + * @property int<0,max>|null $itemCount + * @property-read int<0,max> $offset + * @property-read int<0,max>|null $countdownOffset + * @property-read int<0,max> $length + */ +class Paginator +{ + use Nette\SmartObject; + /** @var int */ + private $base = 1; + /** @var int */ + private $itemsPerPage = 1; + /** @var int */ + private $page = 1; + /** @var int|null */ + private $itemCount; + /** + * Sets current page number. + * @return static + */ + public function setPage(int $page) + { + $this->page = $page; + return $this; + } + /** + * Returns current page number. + */ + public function getPage() : int + { + return $this->base + $this->getPageIndex(); + } + /** + * Returns first page number. + */ + public function getFirstPage() : int + { + return $this->base; + } + /** + * Returns last page number. + */ + public function getLastPage() : ?int + { + return $this->itemCount === null ? null : $this->base + \max(0, $this->getPageCount() - 1); + } + /** + * Returns the sequence number of the first element on the page + * @return int<0, max> + */ + public function getFirstItemOnPage() : int + { + return $this->itemCount !== 0 ? $this->offset + 1 : 0; + } + /** + * Returns the sequence number of the last element on the page + * @return int<0, max> + */ + public function getLastItemOnPage() : int + { + return $this->offset + $this->length; + } + /** + * Sets first page (base) number. + * @return static + */ + public function setBase(int $base) + { + $this->base = $base; + return $this; + } + /** + * Returns first page (base) number. + */ + public function getBase() : int + { + return $this->base; + } + /** + * Returns zero-based page number. + * @return int<0, max> + */ + protected function getPageIndex() : int + { + $index = \max(0, $this->page - $this->base); + return $this->itemCount === null ? $index : \min($index, \max(0, $this->getPageCount() - 1)); + } + /** + * Is the current page the first one? + */ + public function isFirst() : bool + { + return $this->getPageIndex() === 0; + } + /** + * Is the current page the last one? + */ + public function isLast() : bool + { + return $this->itemCount === null ? \false : $this->getPageIndex() >= $this->getPageCount() - 1; + } + /** + * Returns the total number of pages. + * @return int<0, max>|null + */ + public function getPageCount() : ?int + { + return $this->itemCount === null ? null : (int) \ceil($this->itemCount / $this->itemsPerPage); + } + /** + * Sets the number of items to display on a single page. + * @return static + */ + public function setItemsPerPage(int $itemsPerPage) + { + $this->itemsPerPage = \max(1, $itemsPerPage); + return $this; + } + /** + * Returns the number of items to display on a single page. + * @return positive-int + */ + public function getItemsPerPage() : int + { + return $this->itemsPerPage; + } + /** + * Sets the total number of items. + * @return static + */ + public function setItemCount(?int $itemCount = null) + { + $this->itemCount = $itemCount === null ? null : \max(0, $itemCount); + return $this; + } + /** + * Returns the total number of items. + * @return int<0, max>|null + */ + public function getItemCount() : ?int + { + return $this->itemCount; + } + /** + * Returns the absolute index of the first item on current page. + * @return int<0, max> + */ + public function getOffset() : int + { + return $this->getPageIndex() * $this->itemsPerPage; + } + /** + * Returns the absolute index of the first item on current page in countdown paging. + * @return int<0, max>|null + */ + public function getCountdownOffset() : ?int + { + return $this->itemCount === null ? null : \max(0, $this->itemCount - ($this->getPageIndex() + 1) * $this->itemsPerPage); + } + /** + * Returns the number of items on current page. + * @return int<0, max> + */ + public function getLength() : int + { + return $this->itemCount === null ? $this->itemsPerPage : \min($this->itemsPerPage, $this->itemCount - $this->getPageIndex() * $this->itemsPerPage); + } +} diff --git a/vendor/nette/utils/src/Utils/Random.php b/vendor/nette/utils/src/Utils/Random.php new file mode 100644 index 0000000000..43333651a6 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Random.php @@ -0,0 +1,38 @@ +getReturnType() ?? (\PHP_VERSION_ID >= 80100 && $func instanceof \ReflectionMethod ? $func->getTentativeReturnType() : null); + return self::getType($func, $type); + } + /** + * @deprecated + */ + public static function getReturnTypes(\ReflectionFunctionAbstract $func) : array + { + $type = Type::fromReflection($func); + return $type ? $type->getNames() : []; + } + /** + * Returns the type of given parameter and normalizes `self` and `parent` to the actual class names. + * If the parameter does not have a type, it returns null. + * If the parameter has union or intersection type, it throws Nette\InvalidStateException. + * @deprecated use Nette\Utils\Type::fromReflection() + */ + public static function getParameterType(\ReflectionParameter $param) : ?string + { + return self::getType($param, $param->getType()); + } + /** + * @deprecated + */ + public static function getParameterTypes(\ReflectionParameter $param) : array + { + $type = Type::fromReflection($param); + return $type ? $type->getNames() : []; + } + /** + * Returns the type of given property and normalizes `self` and `parent` to the actual class names. + * If the property does not have a type, it returns null. + * If the property has union or intersection type, it throws Nette\InvalidStateException. + * @deprecated use Nette\Utils\Type::fromReflection() + */ + public static function getPropertyType(\ReflectionProperty $prop) : ?string + { + return self::getType($prop, \PHP_VERSION_ID >= 70400 ? \method_exists($prop, 'getType') ? $prop->getType() : null : null); + } + /** + * @deprecated + */ + public static function getPropertyTypes(\ReflectionProperty $prop) : array + { + $type = Type::fromReflection($prop); + return $type ? $type->getNames() : []; + } + /** + * @param \ReflectionFunction|\ReflectionMethod|\ReflectionParameter|\ReflectionProperty $reflection + */ + private static function getType($reflection, ?\ReflectionType $type) : ?string + { + if ($type === null) { + return null; + } elseif ($type instanceof \ReflectionNamedType) { + return Type::resolve($type->getName(), $reflection); + } elseif ($type instanceof \ReflectionUnionType || $type instanceof \ReflectionIntersectionType) { + throw new Nette\InvalidStateException('The ' . self::toString($reflection) . ' is not expected to have a union or intersection type.'); + } else { + throw new Nette\InvalidStateException('Unexpected type of ' . self::toString($reflection)); + } + } + /** + * Returns the default value of parameter. If it is a constant, it returns its value. + * @return mixed + * @throws \ReflectionException If the parameter does not have a default value or the constant cannot be resolved + */ + public static function getParameterDefaultValue(\ReflectionParameter $param) + { + if ($param->isDefaultValueConstant()) { + $const = $orig = $param->getDefaultValueConstantName(); + $pair = \explode('::', $const); + if (isset($pair[1])) { + $pair[0] = Type::resolve($pair[0], $param); + try { + $rcc = new \ReflectionClassConstant($pair[0], $pair[1]); + } catch (\ReflectionException $e) { + $name = self::toString($param); + throw new \ReflectionException("Unable to resolve constant {$orig} used as default value of {$name}.", 0, $e); + } + return $rcc->getValue(); + } elseif (!\defined($const)) { + $const = \substr((string) \strrchr($const, '\\'), 1); + if (!\defined($const)) { + $name = self::toString($param); + throw new \ReflectionException("Unable to resolve constant {$orig} used as default value of {$name}."); + } + } + return \constant($const); + } + return $param->getDefaultValue(); + } + /** + * Returns a reflection of a class or trait that contains a declaration of given property. Property can also be declared in the trait. + */ + public static function getPropertyDeclaringClass(\ReflectionProperty $prop) : \ReflectionClass + { + foreach ($prop->getDeclaringClass()->getTraits() as $trait) { + if ($trait->hasProperty($prop->name) && $trait->getProperty($prop->name)->getDocComment() === $prop->getDocComment()) { + return self::getPropertyDeclaringClass($trait->getProperty($prop->name)); + } + } + return $prop->getDeclaringClass(); + } + /** + * Returns a reflection of a method that contains a declaration of $method. + * Usually, each method is its own declaration, but the body of the method can also be in the trait and under a different name. + */ + public static function getMethodDeclaringMethod(\ReflectionMethod $method) : \ReflectionMethod + { + // file & line guessing as workaround for insufficient PHP reflection + $decl = $method->getDeclaringClass(); + if ($decl->getFileName() === $method->getFileName() && $decl->getStartLine() <= $method->getStartLine() && $decl->getEndLine() >= $method->getEndLine()) { + return $method; + } + $hash = [$method->getFileName(), $method->getStartLine(), $method->getEndLine()]; + if (($alias = $decl->getTraitAliases()[$method->name] ?? null) && ($m = new \ReflectionMethod($alias)) && $hash === [$m->getFileName(), $m->getStartLine(), $m->getEndLine()]) { + return self::getMethodDeclaringMethod($m); + } + foreach ($decl->getTraits() as $trait) { + if ($trait->hasMethod($method->name) && ($m = $trait->getMethod($method->name)) && $hash === [$m->getFileName(), $m->getStartLine(), $m->getEndLine()]) { + return self::getMethodDeclaringMethod($m); + } + } + return $method; + } + /** + * Finds out if reflection has access to PHPdoc comments. Comments may not be available due to the opcode cache. + */ + public static function areCommentsAvailable() : bool + { + static $res; + return $res ?? ($res = (bool) (new \ReflectionMethod(__METHOD__))->getDocComment()); + } + public static function toString(\Reflector $ref) : string + { + if ($ref instanceof \ReflectionClass) { + return $ref->name; + } elseif ($ref instanceof \ReflectionMethod) { + return $ref->getDeclaringClass()->name . '::' . $ref->name . '()'; + } elseif ($ref instanceof \ReflectionFunction) { + return $ref->name . '()'; + } elseif ($ref instanceof \ReflectionProperty) { + return self::getPropertyDeclaringClass($ref)->name . '::$' . $ref->name; + } elseif ($ref instanceof \ReflectionParameter) { + return '$' . $ref->name . ' in ' . self::toString($ref->getDeclaringFunction()); + } else { + throw new Nette\InvalidArgumentException(); + } + } + /** + * Expands the name of the class to full name in the given context of given class. + * Thus, it returns how the PHP parser would understand $name if it were written in the body of the class $context. + * @throws Nette\InvalidArgumentException + */ + public static function expandClassName(string $name, \ReflectionClass $context) : string + { + $lower = \strtolower($name); + if (empty($name)) { + throw new Nette\InvalidArgumentException('Class name must not be empty.'); + } elseif (Validators::isBuiltinType($lower)) { + return $lower; + } elseif ($lower === 'self' || $lower === 'static') { + return $context->name; + } elseif ($lower === 'parent') { + return $context->getParentClass() ? $context->getParentClass()->name : 'parent'; + } elseif ($name[0] === '\\') { + // fully qualified name + return \ltrim($name, '\\'); + } + $uses = self::getUseStatements($context); + $parts = \explode('\\', $name, 2); + if (isset($uses[$parts[0]])) { + $parts[0] = $uses[$parts[0]]; + return \implode('\\', $parts); + } elseif ($context->inNamespace()) { + return $context->getNamespaceName() . '\\' . $name; + } else { + return $name; + } + } + /** @return array of [alias => class] */ + public static function getUseStatements(\ReflectionClass $class) : array + { + if ($class->isAnonymous()) { + throw new Nette\NotImplementedException('Anonymous classes are not supported.'); + } + static $cache = []; + if (!isset($cache[$name = $class->name])) { + if ($class->isInternal()) { + $cache[$name] = []; + } else { + $code = \file_get_contents($class->getFileName()); + $cache = self::parseUseStatements($code, $name) + $cache; + } + } + return $cache[$name]; + } + /** + * Parses PHP code to [class => [alias => class, ...]] + */ + private static function parseUseStatements(string $code, ?string $forClass = null) : array + { + try { + $tokens = \token_get_all($code, \TOKEN_PARSE); + } catch (\ParseError $e) { + \trigger_error($e->getMessage(), \E_USER_NOTICE); + $tokens = []; + } + $namespace = $class = null; + $classLevel = $level = 0; + $res = $uses = []; + $nameTokens = \PHP_VERSION_ID < 80000 ? [\T_STRING, \T_NS_SEPARATOR] : [\T_STRING, \T_NS_SEPARATOR, \T_NAME_QUALIFIED, \T_NAME_FULLY_QUALIFIED]; + while ($token = \current($tokens)) { + \next($tokens); + switch (\is_array($token) ? $token[0] : $token) { + case \T_NAMESPACE: + $namespace = \ltrim(self::fetch($tokens, $nameTokens) . '\\', '\\'); + $uses = []; + break; + case \T_CLASS: + case \T_INTERFACE: + case \T_TRAIT: + case \PHP_VERSION_ID < 80100 ? \T_CLASS : \T_ENUM: + if ($name = self::fetch($tokens, \T_STRING)) { + $class = $namespace . $name; + $classLevel = $level + 1; + $res[$class] = $uses; + if ($class === $forClass) { + return $res; + } + } + break; + case \T_USE: + while (!$class && ($name = self::fetch($tokens, $nameTokens))) { + $name = \ltrim($name, '\\'); + if (self::fetch($tokens, '{')) { + while ($suffix = self::fetch($tokens, $nameTokens)) { + if (self::fetch($tokens, \T_AS)) { + $uses[self::fetch($tokens, \T_STRING)] = $name . $suffix; + } else { + $tmp = \explode('\\', $suffix); + $uses[\end($tmp)] = $name . $suffix; + } + if (!self::fetch($tokens, ',')) { + break; + } + } + } elseif (self::fetch($tokens, \T_AS)) { + $uses[self::fetch($tokens, \T_STRING)] = $name; + } else { + $tmp = \explode('\\', $name); + $uses[\end($tmp)] = $name; + } + if (!self::fetch($tokens, ',')) { + break; + } + } + break; + case \T_CURLY_OPEN: + case \T_DOLLAR_OPEN_CURLY_BRACES: + case '{': + $level++; + break; + case '}': + if ($level === $classLevel) { + $class = $classLevel = 0; + } + $level--; + } + } + return $res; + } + private static function fetch(array &$tokens, $take) : ?string + { + $res = null; + while ($token = \current($tokens)) { + [$token, $s] = \is_array($token) ? $token : [$token, $token]; + if (\in_array($token, (array) $take, \true)) { + $res .= $s; + } elseif (!\in_array($token, [\T_DOC_COMMENT, \T_WHITESPACE, \T_COMMENT], \true)) { + break; + } + \next($tokens); + } + return $res; + } +} diff --git a/vendor/nette/utils/src/Utils/Strings.php b/vendor/nette/utils/src/Utils/Strings.php new file mode 100644 index 0000000000..4b955b1159 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Strings.php @@ -0,0 +1,488 @@ += 0xd800 && $code <= 0xdfff || $code > 0x10ffff) { + throw new Nette\InvalidArgumentException('Code point must be in range 0x0 to 0xD7FF or 0xE000 to 0x10FFFF.'); + } elseif (!\extension_loaded('iconv')) { + throw new Nette\NotSupportedException(__METHOD__ . '() requires ICONV extension that is not loaded.'); + } + return \iconv('UTF-32BE', 'UTF-8//IGNORE', \pack('N', $code)); + } + /** + * Starts the $haystack string with the prefix $needle? + */ + public static function startsWith(string $haystack, string $needle) : bool + { + return \strncmp($haystack, $needle, strlen($needle)) === 0; + } + /** + * Ends the $haystack string with the suffix $needle? + */ + public static function endsWith(string $haystack, string $needle) : bool + { + return $needle === '' || \substr($haystack, -strlen($needle)) === $needle; + } + /** + * Does $haystack contain $needle? + */ + public static function contains(string $haystack, string $needle) : bool + { + return \strpos($haystack, $needle) !== \false; + } + /** + * Returns a part of UTF-8 string specified by starting position and length. If start is negative, + * the returned string will start at the start'th character from the end of string. + */ + public static function substring(string $s, int $start, ?int $length = null) : string + { + if (\function_exists('mb_substr')) { + return \mb_substr($s, $start, $length, 'UTF-8'); + // MB is much faster + } elseif (!\extension_loaded('iconv')) { + throw new Nette\NotSupportedException(__METHOD__ . '() requires extension ICONV or MBSTRING, neither is loaded.'); + } elseif ($length === null) { + $length = self::length($s); + } elseif ($start < 0 && $length < 0) { + $start += self::length($s); + // unifies iconv_substr behavior with mb_substr + } + return \iconv_substr($s, $start, $length, 'UTF-8'); + } + /** + * Removes control characters, normalizes line breaks to `\n`, removes leading and trailing blank lines, + * trims end spaces on lines, normalizes UTF-8 to the normal form of NFC. + */ + public static function normalize(string $s) : string + { + // convert to compressed normal form (NFC) + if (\class_exists('Normalizer', \false) && ($n = \Normalizer::normalize($s, \Normalizer::FORM_C)) !== \false) { + $s = $n; + } + $s = self::normalizeNewLines($s); + // remove control characters; leave \t + \n + $s = self::pcre('preg_replace', ['#[\\x00-\\x08\\x0B-\\x1F\\x7F-\\x9F]+#u', '', $s]); + // right trim + $s = self::pcre('preg_replace', ['#[\\t ]+$#m', '', $s]); + // leading and trailing blank lines + $s = \trim($s, "\n"); + return $s; + } + /** + * Standardize line endings to unix-like. + */ + public static function normalizeNewLines(string $s) : string + { + return \str_replace(["\r\n", "\r"], "\n", $s); + } + /** + * Converts UTF-8 string to ASCII, ie removes diacritics etc. + */ + public static function toAscii(string $s) : string + { + $iconv = \defined('ICONV_IMPL') ? \trim(\ICONV_IMPL, '"\'') : null; + static $transliterator = null; + if ($transliterator === null) { + if (\class_exists('Transliterator', \false)) { + $transliterator = \Transliterator::create('Any-Latin; Latin-ASCII'); + } else { + \trigger_error(__METHOD__ . "(): it is recommended to enable PHP extensions 'intl'.", \E_USER_NOTICE); + $transliterator = \false; + } + } + // remove control characters and check UTF-8 validity + $s = self::pcre('preg_replace', ['#[^\\x09\\x0A\\x0D\\x20-\\x7E\\xA0-\\x{2FF}\\x{370}-\\x{10FFFF}]#u', '', $s]); + // transliteration (by Transliterator and iconv) is not optimal, replace some characters directly + $s = \strtr($s, ["„" => '"', "“" => '"', "”" => '"', "‚" => "'", "‘" => "'", "’" => "'", "°" => '^', "Я" => 'Ya', "я" => 'ya', "Ю" => 'Yu', "ю" => 'yu', "Ä" => 'Ae', "Ö" => 'Oe', "Ü" => 'Ue', "ẞ" => 'Ss', "ä" => 'ae', "ö" => 'oe', "ü" => 'ue', "ß" => 'ss']); + // „ “ ” ‚ ‘ ’ ° Я я Ю ю Ä Ö Ü ẞ ä ö ü ß + if ($iconv !== 'libiconv') { + $s = \strtr($s, ["®" => '(R)', "©" => '(c)', "…" => '...', "«" => '<<', "»" => '>>', "£" => 'lb', "¥" => 'yen', "²" => '^2', "³" => '^3', "µ" => 'u', "¹" => '^1', "º" => 'o', "¿" => '?', "ˊ" => "'", "ˍ" => '_', "˝" => '"', "`" => '', "€" => 'EUR', "™" => 'TM', "℮" => 'e', "←" => '<-', "↑" => '^', "→" => '->', "↓" => 'V', "↔" => '<->']); + // ® © … « » £ ¥ ² ³ µ ¹ º ¿ ˊ ˍ ˝ ` € ™ ℮ ← ↑ → ↓ ↔ + } + if ($transliterator) { + $s = $transliterator->transliterate($s); + // use iconv because The transliterator leaves some characters out of ASCII, eg → ʾ + if ($iconv === 'glibc') { + $s = \strtr($s, '?', "\x01"); + // temporarily hide ? to distinguish them from the garbage that iconv creates + $s = \iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); + $s = \str_replace(['?', "\x01"], ['', '?'], $s); + // remove garbage and restore ? characters + } elseif ($iconv === 'libiconv') { + $s = \iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); + } else { + // null or 'unknown' (#216) + $s = self::pcre('preg_replace', ['#[^\\x00-\\x7F]++#', '', $s]); + // remove non-ascii chars + } + } elseif ($iconv === 'glibc' || $iconv === 'libiconv') { + // temporarily hide these characters to distinguish them from the garbage that iconv creates + $s = \strtr($s, '`\'"^~?', "\x01\x02\x03\x04\x05\x06"); + if ($iconv === 'glibc') { + // glibc implementation is very limited. transliterate into Windows-1250 and then into ASCII, so most Eastern European characters are preserved + $s = \iconv('UTF-8', 'WINDOWS-1250//TRANSLIT//IGNORE', $s); + $s = \strtr($s, "\xa5\xa3\xbc\x8c\xa7\x8a\xaa\x8d\x8f\x8e\xaf\xb9\xb3\xbe\x9c\x9a\xba\x9d\x9f\x9e\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\x96\xa0\x8b\x97\x9b\xa6\xad\xb7", 'ALLSSSSTZZZallssstzzzRAAAALCCCEEEEIIDDNNOOOOxRUUUUYTsraaaalccceeeeiiddnnooooruuuuyt- <->|-.'); + $s = self::pcre('preg_replace', ['#[^\\x00-\\x7F]++#', '', $s]); + } else { + $s = \iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); + } + // remove garbage that iconv creates during transliteration (eg Ý -> Y') + $s = \str_replace(['`', "'", '"', '^', '~', '?'], '', $s); + // restore temporarily hidden characters + $s = \strtr($s, "\x01\x02\x03\x04\x05\x06", '`\'"^~?'); + } else { + $s = self::pcre('preg_replace', ['#[^\\x00-\\x7F]++#', '', $s]); + // remove non-ascii chars + } + return $s; + } + /** + * Modifies the UTF-8 string to the form used in the URL, ie removes diacritics and replaces all characters + * except letters of the English alphabet and numbers with a hyphens. + */ + public static function webalize(string $s, ?string $charlist = null, bool $lower = \true) : string + { + $s = self::toAscii($s); + if ($lower) { + $s = \strtolower($s); + } + $s = self::pcre('preg_replace', ['#[^a-z0-9' . ($charlist !== null ? \preg_quote($charlist, '#') : '') . ']+#i', '-', $s]); + $s = \trim($s, '-'); + return $s; + } + /** + * Truncates a UTF-8 string to given maximal length, while trying not to split whole words. Only if the string is truncated, + * an ellipsis (or something else set with third argument) is appended to the string. + */ + public static function truncate(string $s, int $maxLen, string $append = "…") : string + { + if (self::length($s) > $maxLen) { + $maxLen -= self::length($append); + if ($maxLen < 1) { + return $append; + } elseif ($matches = self::match($s, '#^.{1,' . $maxLen . '}(?=[\\s\\x00-/:-@\\[-`{-~])#us')) { + return $matches[0] . $append; + } else { + return self::substring($s, 0, $maxLen) . $append; + } + } + return $s; + } + /** + * Indents a multiline text from the left. Second argument sets how many indentation chars should be used, + * while the indent itself is the third argument (*tab* by default). + */ + public static function indent(string $s, int $level = 1, string $chars = "\t") : string + { + if ($level > 0) { + $s = self::replace($s, '#(?:^|[\\r\\n]+)(?=[^\\r\\n])#', '$0' . \str_repeat($chars, $level)); + } + return $s; + } + /** + * Converts all characters of UTF-8 string to lower case. + */ + public static function lower(string $s) : string + { + return \mb_strtolower($s, 'UTF-8'); + } + /** + * Converts the first character of a UTF-8 string to lower case and leaves the other characters unchanged. + */ + public static function firstLower(string $s) : string + { + return self::lower(self::substring($s, 0, 1)) . self::substring($s, 1); + } + /** + * Converts all characters of a UTF-8 string to upper case. + */ + public static function upper(string $s) : string + { + return \mb_strtoupper($s, 'UTF-8'); + } + /** + * Converts the first character of a UTF-8 string to upper case and leaves the other characters unchanged. + */ + public static function firstUpper(string $s) : string + { + return self::upper(self::substring($s, 0, 1)) . self::substring($s, 1); + } + /** + * Converts the first character of every word of a UTF-8 string to upper case and the others to lower case. + */ + public static function capitalize(string $s) : string + { + return \mb_convert_case($s, \MB_CASE_TITLE, 'UTF-8'); + } + /** + * Compares two UTF-8 strings or their parts, without taking character case into account. If length is null, whole strings are compared, + * if it is negative, the corresponding number of characters from the end of the strings is compared, + * otherwise the appropriate number of characters from the beginning is compared. + */ + public static function compare(string $left, string $right, ?int $length = null) : bool + { + if (\class_exists('Normalizer', \false)) { + $left = \Normalizer::normalize($left, \Normalizer::FORM_D); + // form NFD is faster + $right = \Normalizer::normalize($right, \Normalizer::FORM_D); + // form NFD is faster + } + if ($length < 0) { + $left = self::substring($left, $length, -$length); + $right = self::substring($right, $length, -$length); + } elseif ($length !== null) { + $left = self::substring($left, 0, $length); + $right = self::substring($right, 0, $length); + } + return self::lower($left) === self::lower($right); + } + /** + * Finds the common prefix of strings or returns empty string if the prefix was not found. + * @param string[] $strings + */ + public static function findPrefix(array $strings) : string + { + $first = \array_shift($strings); + for ($i = 0; $i < strlen($first); $i++) { + foreach ($strings as $s) { + if (!isset($s[$i]) || $first[$i] !== $s[$i]) { + while ($i && $first[$i - 1] >= "\x80" && $first[$i] >= "\x80" && $first[$i] < "\xc0") { + $i--; + } + return \substr($first, 0, $i); + } + } + } + return $first; + } + /** + * Returns number of characters (not bytes) in UTF-8 string. + * That is the number of Unicode code points which may differ from the number of graphemes. + */ + public static function length(string $s) : int + { + return \function_exists('mb_strlen') ? \mb_strlen($s, 'UTF-8') : strlen(\utf8_decode($s)); + } + /** + * Removes all left and right side spaces (or the characters passed as second argument) from a UTF-8 encoded string. + */ + public static function trim(string $s, string $charlist = self::TRIM_CHARACTERS) : string + { + $charlist = \preg_quote($charlist, '#'); + return self::replace($s, '#^[' . $charlist . ']+|[' . $charlist . ']+$#Du', ''); + } + /** + * Pads a UTF-8 string to given length by prepending the $pad string to the beginning. + * @param non-empty-string $pad + */ + public static function padLeft(string $s, int $length, string $pad = ' ') : string + { + $length = \max(0, $length - self::length($s)); + $padLen = self::length($pad); + return \str_repeat($pad, (int) ($length / $padLen)) . self::substring($pad, 0, $length % $padLen) . $s; + } + /** + * Pads UTF-8 string to given length by appending the $pad string to the end. + * @param non-empty-string $pad + */ + public static function padRight(string $s, int $length, string $pad = ' ') : string + { + $length = \max(0, $length - self::length($s)); + $padLen = self::length($pad); + return $s . \str_repeat($pad, (int) ($length / $padLen)) . self::substring($pad, 0, $length % $padLen); + } + /** + * Reverses UTF-8 string. + */ + public static function reverse(string $s) : string + { + if (!\extension_loaded('iconv')) { + throw new Nette\NotSupportedException(__METHOD__ . '() requires ICONV extension that is not loaded.'); + } + return \iconv('UTF-32LE', 'UTF-8', \strrev(\iconv('UTF-8', 'UTF-32BE', $s))); + } + /** + * Returns part of $haystack before $nth occurence of $needle or returns null if the needle was not found. + * Negative value means searching from the end. + */ + public static function before(string $haystack, string $needle, int $nth = 1) : ?string + { + $pos = self::pos($haystack, $needle, $nth); + return $pos === null ? null : \substr($haystack, 0, $pos); + } + /** + * Returns part of $haystack after $nth occurence of $needle or returns null if the needle was not found. + * Negative value means searching from the end. + */ + public static function after(string $haystack, string $needle, int $nth = 1) : ?string + { + $pos = self::pos($haystack, $needle, $nth); + return $pos === null ? null : \substr($haystack, $pos + strlen($needle)); + } + /** + * Returns position in characters of $nth occurence of $needle in $haystack or null if the $needle was not found. + * Negative value of `$nth` means searching from the end. + */ + public static function indexOf(string $haystack, string $needle, int $nth = 1) : ?int + { + $pos = self::pos($haystack, $needle, $nth); + return $pos === null ? null : self::length(\substr($haystack, 0, $pos)); + } + /** + * Returns position in characters of $nth occurence of $needle in $haystack or null if the needle was not found. + */ + private static function pos(string $haystack, string $needle, int $nth = 1) : ?int + { + if (!$nth) { + return null; + } elseif ($nth > 0) { + if ($needle === '') { + return 0; + } + $pos = 0; + while (($pos = \strpos($haystack, $needle, $pos)) !== \false && --$nth) { + $pos++; + } + } else { + $len = strlen($haystack); + if ($needle === '') { + return $len; + } elseif ($len === 0) { + return null; + } + $pos = $len - 1; + while (($pos = \strrpos($haystack, $needle, $pos - $len)) !== \false && ++$nth) { + $pos--; + } + } + return Helpers::falseToNull($pos); + } + /** + * Splits a string into array by the regular expression. Parenthesized expression in the delimiter are captured. + * Parameter $flags can be any combination of PREG_SPLIT_NO_EMPTY and PREG_OFFSET_CAPTURE flags. + */ + public static function split( + string $subject, + /** + * @language + */ + string $pattern, + int $flags = 0 + ) : array + { + return self::pcre('preg_split', [$pattern, $subject, -1, $flags | \PREG_SPLIT_DELIM_CAPTURE]); + } + /** + * Checks if given string matches a regular expression pattern and returns an array with first found match and each subpattern. + * Parameter $flags can be any combination of PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL flags. + */ + public static function match( + string $subject, + /** + * @language + */ + string $pattern, + int $flags = 0, + int $offset = 0 + ) : ?array + { + if ($offset > strlen($subject)) { + return null; + } + return self::pcre('preg_match', [$pattern, $subject, &$m, $flags, $offset]) ? $m : null; + } + /** + * Finds all occurrences matching regular expression pattern and returns a two-dimensional array. Result is array of matches (ie uses by default PREG_SET_ORDER). + * Parameter $flags can be any combination of PREG_OFFSET_CAPTURE, PREG_UNMATCHED_AS_NULL and PREG_PATTERN_ORDER flags. + */ + public static function matchAll( + string $subject, + /** + * @language + */ + string $pattern, + int $flags = 0, + int $offset = 0 + ) : array + { + if ($offset > strlen($subject)) { + return []; + } + self::pcre('preg_match_all', [$pattern, $subject, &$m, $flags & \PREG_PATTERN_ORDER ? $flags : $flags | \PREG_SET_ORDER, $offset]); + return $m; + } + /** + * Replaces all occurrences matching regular expression $pattern which can be string or array in the form `pattern => replacement`. + * @param string|array $pattern + * @param string|callable $replacement + */ + public static function replace( + string $subject, + /** + * @language + */ + $pattern, + $replacement = '', + int $limit = -1 + ) : string + { + if (is_object($replacement) || is_array($replacement)) { + if (!\is_callable($replacement, \false, $textual)) { + throw new Nette\InvalidStateException("Callback '{$textual}' is not callable."); + } + return self::pcre('preg_replace_callback', [$pattern, $replacement, $subject, $limit]); + } elseif (is_array($pattern) && \is_string(\key($pattern))) { + $replacement = \array_values($pattern); + $pattern = \array_keys($pattern); + } + return self::pcre('preg_replace', [$pattern, $replacement, $subject, $limit]); + } + /** @internal */ + public static function pcre(string $func, array $args) + { + $res = Callback::invokeSafe($func, $args, function (string $message) use($args) : void { + // compile-time error, not detectable by preg_last_error + throw new RegexpException($message . ' in pattern: ' . \implode(' or ', (array) $args[0])); + }); + if (($code = \preg_last_error()) && ($res === null || !\in_array($func, ['preg_filter', 'preg_replace_callback', 'preg_replace'], \true))) { + throw new RegexpException((RegexpException::MESSAGES[$code] ?? 'Unknown error') . ' (pattern: ' . \implode(' or ', (array) $args[0]) . ')', $code); + } + return $res; + } +} diff --git a/vendor/nette/utils/src/Utils/Type.php b/vendor/nette/utils/src/Utils/Type.php new file mode 100644 index 0000000000..88eaa29116 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Type.php @@ -0,0 +1,212 @@ + */ + private $types; + /** @var bool */ + private $simple; + /** @var string |, & */ + private $kind; + /** + * Creates a Type object based on reflection. Resolves self, static and parent to the actual class name. + * If the subject has no type, it returns null. + * @param \ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionProperty $reflection + */ + public static function fromReflection($reflection) : ?self + { + if ($reflection instanceof \ReflectionProperty && \PHP_VERSION_ID < 70400) { + return null; + } elseif ($reflection instanceof \ReflectionMethod) { + $type = $reflection->getReturnType() ?? (\PHP_VERSION_ID >= 80100 ? $reflection->getTentativeReturnType() : null); + } else { + $type = $reflection instanceof \ReflectionFunctionAbstract ? $reflection->getReturnType() : $reflection->getType(); + } + return $type ? self::fromReflectionType($type, $reflection, \true) : null; + } + private static function fromReflectionType(\ReflectionType $type, $of, bool $asObject) + { + if ($type instanceof \ReflectionNamedType) { + $name = self::resolve($type->getName(), $of); + return $asObject ? new self($type->allowsNull() && $name !== 'mixed' ? [$name, 'null'] : [$name]) : $name; + } elseif ($type instanceof \ReflectionUnionType || $type instanceof \ReflectionIntersectionType) { + return new self(\array_map(function ($t) use($of) { + return self::fromReflectionType($t, $of, \false); + }, $type->getTypes()), $type instanceof \ReflectionUnionType ? '|' : '&'); + } else { + throw new Nette\InvalidStateException('Unexpected type of ' . Reflection::toString($of)); + } + } + /** + * Creates the Type object according to the text notation. + */ + public static function fromString(string $type) : self + { + if (!Validators::isTypeDeclaration($type)) { + throw new Nette\InvalidArgumentException("Invalid type '{$type}'."); + } + if ($type[0] === '?') { + return new self([\substr($type, 1), 'null']); + } + $unions = []; + foreach (\explode('|', $type) as $part) { + $part = \explode('&', \trim($part, '()')); + $unions[] = \count($part) === 1 ? $part[0] : new self($part, '&'); + } + return \count($unions) === 1 && $unions[0] instanceof self ? $unions[0] : new self($unions); + } + /** + * Resolves 'self', 'static' and 'parent' to the actual class name. + * @param \ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionProperty $of + */ + public static function resolve(string $type, $of) : string + { + $lower = \strtolower($type); + if ($of instanceof \ReflectionFunction) { + return $type; + } elseif ($lower === 'self' || $lower === 'static') { + return $of->getDeclaringClass()->name; + } elseif ($lower === 'parent' && $of->getDeclaringClass()->getParentClass()) { + return $of->getDeclaringClass()->getParentClass()->name; + } else { + return $type; + } + } + private function __construct(array $types, string $kind = '|') + { + $o = \array_search('null', $types, \true); + if ($o !== \false) { + // null as last + \array_splice($types, $o, 1); + $types[] = 'null'; + } + $this->types = $types; + $this->simple = \is_string($types[0]) && ($types[1] ?? 'null') === 'null'; + $this->kind = \count($types) > 1 ? $kind : ''; + } + public function __toString() : string + { + $multi = \count($this->types) > 1; + if ($this->simple) { + return ($multi ? '?' : '') . $this->types[0]; + } + $res = []; + foreach ($this->types as $type) { + $res[] = $type instanceof self && $multi ? "({$type})" : $type; + } + return \implode($this->kind, $res); + } + /** + * Returns the array of subtypes that make up the compound type as strings. + * @return array + */ + public function getNames() : array + { + return \array_map(function ($t) { + return $t instanceof self ? $t->getNames() : $t; + }, $this->types); + } + /** + * Returns the array of subtypes that make up the compound type as Type objects: + * @return self[] + */ + public function getTypes() : array + { + return \array_map(function ($t) { + return $t instanceof self ? $t : new self([$t]); + }, $this->types); + } + /** + * Returns the type name for simple types, otherwise null. + */ + public function getSingleName() : ?string + { + return $this->simple ? $this->types[0] : null; + } + /** + * Returns true whether it is a union type. + */ + public function isUnion() : bool + { + return $this->kind === '|'; + } + /** + * Returns true whether it is an intersection type. + */ + public function isIntersection() : bool + { + return $this->kind === '&'; + } + /** + * Returns true whether it is a simple type. Single nullable types are also considered to be simple types. + */ + public function isSimple() : bool + { + return $this->simple; + } + /** @deprecated use isSimple() */ + public function isSingle() : bool + { + return $this->simple; + } + /** + * Returns true whether the type is both a simple and a PHP built-in type. + */ + public function isBuiltin() : bool + { + return $this->simple && Validators::isBuiltinType($this->types[0]); + } + /** + * Returns true whether the type is both a simple and a class name. + */ + public function isClass() : bool + { + return $this->simple && !Validators::isBuiltinType($this->types[0]); + } + /** + * Determines if type is special class name self/parent/static. + */ + public function isClassKeyword() : bool + { + return $this->simple && Validators::isClassKeyword($this->types[0]); + } + /** + * Verifies type compatibility. For example, it checks if a value of a certain type could be passed as a parameter. + */ + public function allows(string $subtype) : bool + { + if ($this->types === ['mixed']) { + return \true; + } + $subtype = self::fromString($subtype); + return $subtype->isUnion() ? Arrays::every($subtype->types, function ($t) { + return $this->allows2($t instanceof self ? $t->types : [$t]); + }) : $this->allows2($subtype->types); + } + private function allows2(array $subtypes) : bool + { + return $this->isUnion() ? Arrays::some($this->types, function ($t) use($subtypes) { + return $this->allows3($t instanceof self ? $t->types : [$t], $subtypes); + }) : $this->allows3($this->types, $subtypes); + } + private function allows3(array $types, array $subtypes) : bool + { + return Arrays::every($types, function ($type) use($subtypes) { + $builtin = Validators::isBuiltinType($type); + return Arrays::some($subtypes, function ($subtype) use($type, $builtin) { + return $builtin ? \strcasecmp($type, $subtype) === 0 : \is_a($subtype, $type, \true); + }); + }); + } +} diff --git a/vendor/nette/utils/src/Utils/Validators.php b/vendor/nette/utils/src/Utils/Validators.php new file mode 100644 index 0000000000..ddda53f25d --- /dev/null +++ b/vendor/nette/utils/src/Utils/Validators.php @@ -0,0 +1,341 @@ + 1, 'int' => 1, 'float' => 1, 'bool' => 1, 'array' => 1, 'object' => 1, 'callable' => 1, 'iterable' => 1, 'void' => 1, 'null' => 1, 'mixed' => 1, 'false' => 1, 'never' => 1, 'true' => 1]; + /** @var array */ + protected static $validators = [ + // PHP types + 'array' => 'is_array', + 'bool' => 'is_bool', + 'boolean' => 'is_bool', + 'float' => 'is_float', + 'int' => 'is_int', + 'integer' => 'is_int', + 'null' => 'is_null', + 'object' => 'is_object', + 'resource' => 'is_resource', + 'scalar' => 'is_scalar', + 'string' => 'is_string', + // pseudo-types + 'callable' => [self::class, 'isCallable'], + 'iterable' => 'is_iterable', + 'list' => [Arrays::class, 'isList'], + 'mixed' => [self::class, 'isMixed'], + 'none' => [self::class, 'isNone'], + 'number' => [self::class, 'isNumber'], + 'numeric' => [self::class, 'isNumeric'], + 'numericint' => [self::class, 'isNumericInt'], + // string patterns + 'alnum' => 'ctype_alnum', + 'alpha' => 'ctype_alpha', + 'digit' => 'ctype_digit', + 'lower' => 'ctype_lower', + 'pattern' => null, + 'space' => 'ctype_space', + 'unicode' => [self::class, 'isUnicode'], + 'upper' => 'ctype_upper', + 'xdigit' => 'ctype_xdigit', + // syntax validation + 'email' => [self::class, 'isEmail'], + 'identifier' => [self::class, 'isPhpIdentifier'], + 'uri' => [self::class, 'isUri'], + 'url' => [self::class, 'isUrl'], + // environment validation + 'class' => 'class_exists', + 'interface' => 'interface_exists', + 'directory' => 'is_dir', + 'file' => 'is_file', + 'type' => [self::class, 'isType'], + ]; + /** @var array */ + protected static $counters = ['string' => 'strlen', 'unicode' => [Strings::class, 'length'], 'array' => 'count', 'list' => 'count', 'alnum' => 'strlen', 'alpha' => 'strlen', 'digit' => 'strlen', 'lower' => 'strlen', 'space' => 'strlen', 'upper' => 'strlen', 'xdigit' => 'strlen']; + /** + * Verifies that the value is of expected types separated by pipe. + * @param mixed $value + * @throws AssertionException + */ + public static function assert($value, string $expected, string $label = 'variable') : void + { + if (!static::is($value, $expected)) { + $expected = \str_replace(['|', ':'], [' or ', ' in range '], $expected); + $translate = ['boolean' => 'bool', 'integer' => 'int', 'double' => 'float', 'NULL' => 'null']; + $type = $translate[\gettype($value)] ?? \gettype($value); + if (\is_int($value) || \is_float($value) || \is_string($value) && \strlen($value) < 40) { + $type .= ' ' . \var_export($value, \true); + } elseif (\is_object($value)) { + $type .= ' ' . \get_class($value); + } + throw new AssertionException("The {$label} expects to be {$expected}, {$type} given."); + } + } + /** + * Verifies that element $key in array is of expected types separated by pipe. + * @param mixed[] $array + * @param int|string $key + * @throws AssertionException + */ + public static function assertField(array $array, $key, ?string $expected = null, string $label = "item '%' in array") : void + { + if (!\array_key_exists($key, $array)) { + throw new AssertionException('Missing ' . \str_replace('%', $key, $label) . '.'); + } elseif ($expected) { + static::assert($array[$key], $expected, \str_replace('%', $key, $label)); + } + } + /** + * Verifies that the value is of expected types separated by pipe. + * @param mixed $value + */ + public static function is($value, string $expected) : bool + { + foreach (\explode('|', $expected) as $item) { + if (\substr($item, -2) === '[]') { + if (\is_iterable($value) && self::everyIs($value, \substr($item, 0, -2))) { + return \true; + } + continue; + } elseif (\substr($item, 0, 1) === '?') { + $item = \substr($item, 1); + if ($value === null) { + return \true; + } + } + [$type] = $item = \explode(':', $item, 2); + if (isset(static::$validators[$type])) { + try { + if (!static::$validators[$type]($value)) { + continue; + } + } catch (\TypeError $e) { + continue; + } + } elseif ($type === 'pattern') { + if (Strings::match($value, '|^' . ($item[1] ?? '') . '$|D')) { + return \true; + } + continue; + } elseif (!$value instanceof $type) { + continue; + } + if (isset($item[1])) { + $length = $value; + if (isset(static::$counters[$type])) { + $length = static::$counters[$type]($value); + } + $range = \explode('..', $item[1]); + if (!isset($range[1])) { + $range[1] = $range[0]; + } + if ($range[0] !== '' && $length < $range[0] || $range[1] !== '' && $length > $range[1]) { + continue; + } + } + return \true; + } + return \false; + } + /** + * Finds whether all values are of expected types separated by pipe. + * @param mixed[] $values + */ + public static function everyIs(iterable $values, string $expected) : bool + { + foreach ($values as $value) { + if (!static::is($value, $expected)) { + return \false; + } + } + return \true; + } + /** + * Checks if the value is an integer or a float. + * @param mixed $value + */ + public static function isNumber($value) : bool + { + return \is_int($value) || \is_float($value); + } + /** + * Checks if the value is an integer or a integer written in a string. + * @param mixed $value + */ + public static function isNumericInt($value) : bool + { + return \is_int($value) || \is_string($value) && \preg_match('#^[+-]?[0-9]+$#D', $value); + } + /** + * Checks if the value is a number or a number written in a string. + * @param mixed $value + */ + public static function isNumeric($value) : bool + { + return \is_float($value) || \is_int($value) || \is_string($value) && \preg_match('#^[+-]?([0-9]++\\.?[0-9]*|\\.[0-9]+)$#D', $value); + } + /** + * Checks if the value is a syntactically correct callback. + * @param mixed $value + */ + public static function isCallable($value) : bool + { + return $value && \is_callable($value, \true); + } + /** + * Checks if the value is a valid UTF-8 string. + * @param mixed $value + */ + public static function isUnicode($value) : bool + { + return \is_string($value) && \preg_match('##u', $value); + } + /** + * Checks if the value is 0, '', false or null. + * @param mixed $value + */ + public static function isNone($value) : bool + { + return $value == null; + // intentionally == + } + /** @internal */ + public static function isMixed() : bool + { + return \true; + } + /** + * Checks if a variable is a zero-based integer indexed array. + * @param mixed $value + * @deprecated use Nette\Utils\Arrays::isList + * @return ($value is list ? true : false) + */ + public static function isList($value) : bool + { + return Arrays::isList($value); + } + /** + * Checks if the value is in the given range [min, max], where the upper or lower limit can be omitted (null). + * Numbers, strings and DateTime objects can be compared. + * @param mixed $value + */ + public static function isInRange($value, array $range) : bool + { + if ($value === null || !(isset($range[0]) || isset($range[1]))) { + return \false; + } + $limit = $range[0] ?? $range[1]; + if (\is_string($limit)) { + $value = (string) $value; + } elseif ($limit instanceof \DateTimeInterface) { + if (!$value instanceof \DateTimeInterface) { + return \false; + } + } elseif (\is_numeric($value)) { + $value *= 1; + } else { + return \false; + } + return (!isset($range[0]) || $value >= $range[0]) && (!isset($range[1]) || $value <= $range[1]); + } + /** + * Checks if the value is a valid email address. It does not verify that the domain actually exists, only the syntax is verified. + */ + public static function isEmail(string $value) : bool + { + $atom = "[-a-z0-9!#\$%&'*+/=?^_`{|}~]"; + // RFC 5322 unquoted characters in local-part + $alpha = "a-z\x80-\xff"; + // superset of IDN + return (bool) \preg_match(<< \\? (? [a-zA-Z_\x7f-\xff][\w\x7f-\xff]*) (\\ (?&name))* ) | + (? (?&type) (& (?&type))+ ) | + (? (?&type) | \( (?&intersection) \) ) (\| (?&upart))+ + )$~xAD +XX +, $type); + } +} diff --git a/vendor/nette/utils/src/Utils/exceptions.php b/vendor/nette/utils/src/Utils/exceptions.php new file mode 100644 index 0000000000..85635e2fe2 --- /dev/null +++ b/vendor/nette/utils/src/Utils/exceptions.php @@ -0,0 +1,40 @@ + 'Internal error', \PREG_BACKTRACK_LIMIT_ERROR => 'Backtrack limit was exhausted', \PREG_RECURSION_LIMIT_ERROR => 'Recursion limit was exhausted', \PREG_BAD_UTF8_ERROR => 'Malformed UTF-8 data', \PREG_BAD_UTF8_OFFSET_ERROR => 'Offset didn\'t correspond to the begin of a valid UTF-8 code point', 6 => 'Failed due to limited JIT stack space']; +} +/** + * The exception that indicates assertion error. + */ +class AssertionException extends \Exception +{ +} diff --git a/vendor/nette/utils/src/compatibility.php b/vendor/nette/utils/src/compatibility.php new file mode 100644 index 0000000000..1f4fe54cc7 --- /dev/null +++ b/vendor/nette/utils/src/compatibility.php @@ -0,0 +1,28 @@ + 3.0.0-alpha.1` + + +## [2.0.0] - 23.06.2018 + +Changes to public API: + +- `PreReleaseSuffix::construct()`: optional parameter `$number` removed +- `PreReleaseSuffix::isGreaterThan()`: introduced +- `Version::hasPreReleaseSuffix()`: introduced + +### Added + +- [#11](https://github.com/phar-io/version/issues/11): Added support for pre-release version suffixes. Supported values are: + - `dev` + - `beta` (also abbreviated form `b`) + - `rc` + - `alpha` (also abbreviated form `a`) + - `patch` (also abbreviated form `p`) + + All values can be followed by a number, e.g. `beta3`. + + When comparing versions, the pre-release suffix is taken into account. Example: +`1.5.0 > 1.5.0-beta1 > 1.5.0-alpha3 > 1.5.0-alpha2 > 1.5.0-dev11` + +### Changed + +- reorganized the source directories + +### Fixed + +- [#10](https://github.com/phar-io/version/issues/10): Version numbers containing +a numeric suffix as seen in Debian packages are now supported. + + +[3.1.0]: https://github.com/phar-io/version/compare/3.0.4...3.1.0 +[3.0.4]: https://github.com/phar-io/version/compare/3.0.3...3.0.4 +[3.0.3]: https://github.com/phar-io/version/compare/3.0.2...3.0.3 +[3.0.2]: https://github.com/phar-io/version/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/phar-io/version/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/phar-io/version/compare/2.0.1...3.0.0 +[2.0.1]: https://github.com/phar-io/version/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/phar-io/version/compare/1.0.1...2.0.0 diff --git a/vendor/phar-io/version/LICENSE b/vendor/phar-io/version/LICENSE new file mode 100644 index 0000000000..ce32758a80 --- /dev/null +++ b/vendor/phar-io/version/LICENSE @@ -0,0 +1,29 @@ +Copyright (c) 2016-2017 Arne Blankerts , Sebastian Heuer and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/phar-io/version/README.md b/vendor/phar-io/version/README.md new file mode 100644 index 0000000000..76e6e98579 --- /dev/null +++ b/vendor/phar-io/version/README.md @@ -0,0 +1,61 @@ +# Version + +Library for handling version information and constraints + +[![Build Status](https://travis-ci.org/phar-io/version.svg?branch=master)](https://travis-ci.org/phar-io/version) + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phar-io/version + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev phar-io/version + +## Version constraints + +A Version constraint describes a range of versions or a discrete version number. The format of version numbers follows the schema of [semantic versioning](http://semver.org): `..`. A constraint might contain an operator that describes the range. + +Beside the typical mathematical operators like `<=`, `>=`, there are two special operators: + +*Caret operator*: `^1.0` +can be written as `>=1.0.0 <2.0.0` and read as »every Version within major version `1`«. + +*Tilde operator*: `~1.0.0` +can be written as `>=1.0.0 <1.1.0` and read as »every version within minor version `1.1`. The behavior of tilde operator depends on whether a patch level version is provided or not. If no patch level is provided, tilde operator behaves like the caret operator: `~1.0` is identical to `^1.0`. + +## Usage examples + +Parsing version constraints and check discrete versions for compliance: + +```php + +use PharIo\Version\Version; +use PharIo\Version\VersionConstraintParser; + +$parser = new VersionConstraintParser(); +$caret_constraint = $parser->parse( '^7.0' ); + +$caret_constraint->complies( new Version( '7.0.17' ) ); // true +$caret_constraint->complies( new Version( '7.1.0' ) ); // true +$caret_constraint->complies( new Version( '6.4.34' ) ); // false + +$tilde_constraint = $parser->parse( '~1.1.0' ); + +$tilde_constraint->complies( new Version( '1.1.4' ) ); // true +$tilde_constraint->complies( new Version( '1.2.0' ) ); // false +``` + +As of version 2.0.0, pre-release labels are supported and taken into account when comparing versions: + +```php + +$leftVersion = new PharIo\Version\Version('3.0.0-alpha.1'); +$rightVersion = new PharIo\Version\Version('3.0.0-alpha.2'); + +$leftVersion->isGreaterThan($rightVersion); // false +$rightVersion->isGreaterThan($leftVersion); // true + +``` diff --git a/vendor/phar-io/version/composer.json b/vendor/phar-io/version/composer.json new file mode 100644 index 0000000000..9e521b2fb0 --- /dev/null +++ b/vendor/phar-io/version/composer.json @@ -0,0 +1,33 @@ +{ + "name": "phar-io\/version", + "description": "Library for handling version information and constraints", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "support": { + "issues": "https:\/\/github.com\/phar-io\/version\/issues" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "autoload": { + "classmap": [ + "src\/" + ] + } +} \ No newline at end of file diff --git a/vendor/phar-io/version/src/BuildMetaData.php b/vendor/phar-io/version/src/BuildMetaData.php new file mode 100644 index 0000000000..28217b81b0 --- /dev/null +++ b/vendor/phar-io/version/src/BuildMetaData.php @@ -0,0 +1,30 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class BuildMetaData +{ + /** @var string */ + private $value; + public function __construct(string $value) + { + $this->value = $value; + } + public function asString() : string + { + return $this->value; + } + public function equals(\PharIo\Version\BuildMetaData $other) : bool + { + return $this->asString() === $other->asString(); + } +} diff --git a/vendor/phar-io/version/src/PreReleaseSuffix.php b/vendor/phar-io/version/src/PreReleaseSuffix.php new file mode 100644 index 0000000000..366c93c950 --- /dev/null +++ b/vendor/phar-io/version/src/PreReleaseSuffix.php @@ -0,0 +1,64 @@ + 0, 'a' => 1, 'alpha' => 1, 'b' => 2, 'beta' => 2, 'rc' => 3, 'p' => 4, 'pl' => 4, 'patch' => 4]; + /** @var string */ + private $value; + /** @var int */ + private $valueScore; + /** @var int */ + private $number = 0; + /** @var string */ + private $full; + /** + * @throws InvalidPreReleaseSuffixException + */ + public function __construct(string $value) + { + $this->parseValue($value); + } + public function asString() : string + { + return $this->full; + } + public function getValue() : string + { + return $this->value; + } + public function getNumber() : ?int + { + return $this->number; + } + public function isGreaterThan(\PharIo\Version\PreReleaseSuffix $suffix) : bool + { + if ($this->valueScore > $suffix->valueScore) { + return \true; + } + if ($this->valueScore < $suffix->valueScore) { + return \false; + } + return $this->getNumber() > $suffix->getNumber(); + } + private function mapValueToScore(string $value) : int + { + $value = \strtolower($value); + return self::valueScoreMap[$value]; + } + private function parseValue(string $value) : void + { + $regex = '/-?((dev|beta|b|rc|alpha|a|patch|p|pl)\\.?(\\d*)).*$/i'; + if (\preg_match($regex, $value, $matches) !== 1) { + throw new \PharIo\Version\InvalidPreReleaseSuffixException(\sprintf('Invalid label %s', $value)); + } + $this->full = $matches[1]; + $this->value = $matches[2]; + if ($matches[3] !== '') { + $this->number = (int) $matches[3]; + } + $this->valueScore = $this->mapValueToScore($matches[2]); + } +} diff --git a/vendor/phar-io/version/src/Version.php b/vendor/phar-io/version/src/Version.php new file mode 100644 index 0000000000..780726b3a9 --- /dev/null +++ b/vendor/phar-io/version/src/Version.php @@ -0,0 +1,178 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class Version +{ + /** @var string */ + private $originalVersionString; + /** @var VersionNumber */ + private $major; + /** @var VersionNumber */ + private $minor; + /** @var VersionNumber */ + private $patch; + /** @var null|PreReleaseSuffix */ + private $preReleaseSuffix; + /** @var null|BuildMetaData */ + private $buildMetadata; + public function __construct(string $versionString) + { + $this->ensureVersionStringIsValid($versionString); + $this->originalVersionString = $versionString; + } + /** + * @throws NoPreReleaseSuffixException + */ + public function getPreReleaseSuffix() : \PharIo\Version\PreReleaseSuffix + { + if ($this->preReleaseSuffix === null) { + throw new \PharIo\Version\NoPreReleaseSuffixException('No pre-release suffix set'); + } + return $this->preReleaseSuffix; + } + public function getOriginalString() : string + { + return $this->originalVersionString; + } + public function getVersionString() : string + { + $str = \sprintf('%d.%d.%d', $this->getMajor()->getValue() ?? 0, $this->getMinor()->getValue() ?? 0, $this->getPatch()->getValue() ?? 0); + if (!$this->hasPreReleaseSuffix()) { + return $str; + } + return $str . '-' . $this->getPreReleaseSuffix()->asString(); + } + public function hasPreReleaseSuffix() : bool + { + return $this->preReleaseSuffix !== null; + } + public function equals(\PharIo\Version\Version $other) : bool + { + if ($this->getVersionString() !== $other->getVersionString()) { + return \false; + } + if ($this->hasBuildMetaData() !== $other->hasBuildMetaData()) { + return \false; + } + if ($this->hasBuildMetaData() && $other->hasBuildMetaData() && !$this->getBuildMetaData()->equals($other->getBuildMetaData())) { + return \false; + } + return \true; + } + public function isGreaterThan(\PharIo\Version\Version $version) : bool + { + if ($version->getMajor()->getValue() > $this->getMajor()->getValue()) { + return \false; + } + if ($version->getMajor()->getValue() < $this->getMajor()->getValue()) { + return \true; + } + if ($version->getMinor()->getValue() > $this->getMinor()->getValue()) { + return \false; + } + if ($version->getMinor()->getValue() < $this->getMinor()->getValue()) { + return \true; + } + if ($version->getPatch()->getValue() > $this->getPatch()->getValue()) { + return \false; + } + if ($version->getPatch()->getValue() < $this->getPatch()->getValue()) { + return \true; + } + if (!$version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) { + return \false; + } + if ($version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) { + return \true; + } + if (!$version->hasPreReleaseSuffix() && $this->hasPreReleaseSuffix()) { + return \false; + } + return $this->getPreReleaseSuffix()->isGreaterThan($version->getPreReleaseSuffix()); + } + public function getMajor() : \PharIo\Version\VersionNumber + { + return $this->major; + } + public function getMinor() : \PharIo\Version\VersionNumber + { + return $this->minor; + } + public function getPatch() : \PharIo\Version\VersionNumber + { + return $this->patch; + } + /** + * @psalm-assert-if-true BuildMetaData $this->buildMetadata + * @psalm-assert-if-true BuildMetaData $this->getBuildMetaData() + */ + public function hasBuildMetaData() : bool + { + return $this->buildMetadata !== null; + } + /** + * @throws NoBuildMetaDataException + */ + public function getBuildMetaData() : \PharIo\Version\BuildMetaData + { + if (!$this->hasBuildMetaData()) { + throw new \PharIo\Version\NoBuildMetaDataException('No build metadata set'); + } + return $this->buildMetadata; + } + /** + * @param string[] $matches + * + * @throws InvalidPreReleaseSuffixException + */ + private function parseVersion(array $matches) : void + { + $this->major = new \PharIo\Version\VersionNumber((int) $matches['Major']); + $this->minor = new \PharIo\Version\VersionNumber((int) $matches['Minor']); + $this->patch = isset($matches['Patch']) ? new \PharIo\Version\VersionNumber((int) $matches['Patch']) : new \PharIo\Version\VersionNumber(0); + if (isset($matches['PreReleaseSuffix']) && $matches['PreReleaseSuffix'] !== '') { + $this->preReleaseSuffix = new \PharIo\Version\PreReleaseSuffix($matches['PreReleaseSuffix']); + } + if (isset($matches['BuildMetadata'])) { + $this->buildMetadata = new \PharIo\Version\BuildMetaData($matches['BuildMetadata']); + } + } + /** + * @param string $version + * + * @throws InvalidVersionException + */ + private function ensureVersionStringIsValid($version) : void + { + $regex = '/^v? + (?P0|[1-9]\\d*) + \\. + (?P0|[1-9]\\d*) + (\\. + (?P0|[1-9]\\d*) + )? + (?: + - + (?(?:(dev|beta|b|rc|alpha|a|patch|p|pl)\\.?\\d*)) + )? + (?: + \\+ + (?P[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-@]+)*) + )? + $/xi'; + if (\preg_match($regex, $version, $matches) !== 1) { + throw new \PharIo\Version\InvalidVersionException(\sprintf("Version string '%s' does not follow SemVer semantics", $version)); + } + $this->parseVersion($matches); + } +} diff --git a/vendor/phar-io/version/src/VersionConstraintParser.php b/vendor/phar-io/version/src/VersionConstraintParser.php new file mode 100644 index 0000000000..e2c38cf706 --- /dev/null +++ b/vendor/phar-io/version/src/VersionConstraintParser.php @@ -0,0 +1,73 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class VersionConstraintParser +{ + /** + * @throws UnsupportedVersionConstraintException + */ + public function parse(string $value) : \PharIo\Version\VersionConstraint + { + if (\strpos($value, '|') !== \false) { + return $this->handleOrGroup($value); + } + if (!\preg_match('/^[\\^~*]?v?[\\d.*]+(?:-.*)?$/i', $value)) { + throw new \PharIo\Version\UnsupportedVersionConstraintException(\sprintf('Version constraint %s is not supported.', $value)); + } + switch ($value[0]) { + case '~': + return $this->handleTildeOperator($value); + case '^': + return $this->handleCaretOperator($value); + } + $constraint = new \PharIo\Version\VersionConstraintValue($value); + if ($constraint->getMajor()->isAny()) { + return new \PharIo\Version\AnyVersionConstraint(); + } + if ($constraint->getMinor()->isAny()) { + return new \PharIo\Version\SpecificMajorVersionConstraint($constraint->getVersionString(), $constraint->getMajor()->getValue() ?? 0); + } + if ($constraint->getPatch()->isAny()) { + return new \PharIo\Version\SpecificMajorAndMinorVersionConstraint($constraint->getVersionString(), $constraint->getMajor()->getValue() ?? 0, $constraint->getMinor()->getValue() ?? 0); + } + return new \PharIo\Version\ExactVersionConstraint($constraint->getVersionString()); + } + private function handleOrGroup(string $value) : \PharIo\Version\OrVersionConstraintGroup + { + $constraints = []; + foreach (\preg_split('{\\s*\\|\\|?\\s*}', \trim($value)) as $groupSegment) { + $constraints[] = $this->parse(\trim($groupSegment)); + } + return new \PharIo\Version\OrVersionConstraintGroup($value, $constraints); + } + private function handleTildeOperator(string $value) : \PharIo\Version\AndVersionConstraintGroup + { + $constraintValue = new \PharIo\Version\VersionConstraintValue(\substr($value, 1)); + if ($constraintValue->getPatch()->isAny()) { + return $this->handleCaretOperator($value); + } + $constraints = [new \PharIo\Version\GreaterThanOrEqualToVersionConstraint($value, new \PharIo\Version\Version(\substr($value, 1))), new \PharIo\Version\SpecificMajorAndMinorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0, $constraintValue->getMinor()->getValue() ?? 0)]; + return new \PharIo\Version\AndVersionConstraintGroup($value, $constraints); + } + private function handleCaretOperator(string $value) : \PharIo\Version\AndVersionConstraintGroup + { + $constraintValue = new \PharIo\Version\VersionConstraintValue(\substr($value, 1)); + $constraints = [new \PharIo\Version\GreaterThanOrEqualToVersionConstraint($value, new \PharIo\Version\Version(\substr($value, 1)))]; + if ($constraintValue->getMajor()->getValue() === 0) { + $constraints[] = new \PharIo\Version\SpecificMajorAndMinorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0, $constraintValue->getMinor()->getValue() ?? 0); + } else { + $constraints[] = new \PharIo\Version\SpecificMajorVersionConstraint($value, $constraintValue->getMajor()->getValue() ?? 0); + } + return new \PharIo\Version\AndVersionConstraintGroup($value, $constraints); + } +} diff --git a/vendor/phar-io/version/src/VersionConstraintValue.php b/vendor/phar-io/version/src/VersionConstraintValue.php new file mode 100644 index 0000000000..8c7eebd796 --- /dev/null +++ b/vendor/phar-io/version/src/VersionConstraintValue.php @@ -0,0 +1,82 @@ +versionString = $versionString; + $this->parseVersion($versionString); + } + public function getLabel() : string + { + return $this->label; + } + public function getBuildMetaData() : string + { + return $this->buildMetaData; + } + public function getVersionString() : string + { + return $this->versionString; + } + public function getMajor() : \PharIo\Version\VersionNumber + { + return $this->major; + } + public function getMinor() : \PharIo\Version\VersionNumber + { + return $this->minor; + } + public function getPatch() : \PharIo\Version\VersionNumber + { + return $this->patch; + } + private function parseVersion(string $versionString) : void + { + $this->extractBuildMetaData($versionString); + $this->extractLabel($versionString); + $this->stripPotentialVPrefix($versionString); + $versionSegments = \explode('.', $versionString); + $this->major = new \PharIo\Version\VersionNumber(\is_numeric($versionSegments[0]) ? (int) $versionSegments[0] : null); + $minorValue = isset($versionSegments[1]) && \is_numeric($versionSegments[1]) ? (int) $versionSegments[1] : null; + $patchValue = isset($versionSegments[2]) && \is_numeric($versionSegments[2]) ? (int) $versionSegments[2] : null; + $this->minor = new \PharIo\Version\VersionNumber($minorValue); + $this->patch = new \PharIo\Version\VersionNumber($patchValue); + } + private function extractBuildMetaData(string &$versionString) : void + { + if (\preg_match('/\\+(.*)/', $versionString, $matches) === 1) { + $this->buildMetaData = $matches[1]; + $versionString = \str_replace($matches[0], '', $versionString); + } + } + private function extractLabel(string &$versionString) : void + { + if (\preg_match('/-(.*)/', $versionString, $matches) === 1) { + $this->label = $matches[1]; + $versionString = \str_replace($matches[0], '', $versionString); + } + } + private function stripPotentialVPrefix(string &$versionString) : void + { + if ($versionString[0] !== 'v') { + return; + } + $versionString = \substr($versionString, 1); + } +} diff --git a/vendor/phar-io/version/src/VersionNumber.php b/vendor/phar-io/version/src/VersionNumber.php new file mode 100644 index 0000000000..dc1dec64f8 --- /dev/null +++ b/vendor/phar-io/version/src/VersionNumber.php @@ -0,0 +1,30 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class VersionNumber +{ + /** @var ?int */ + private $value; + public function __construct(?int $value) + { + $this->value = $value; + } + public function isAny() : bool + { + return $this->value === null; + } + public function getValue() : ?int + { + return $this->value; + } +} diff --git a/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php b/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php new file mode 100644 index 0000000000..6b60e69362 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php @@ -0,0 +1,26 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +abstract class AbstractVersionConstraint implements \PharIo\Version\VersionConstraint +{ + /** @var string */ + private $originalValue; + public function __construct(string $originalValue) + { + $this->originalValue = $originalValue; + } + public function asString() : string + { + return $this->originalValue; + } +} diff --git a/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php b/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php new file mode 100644 index 0000000000..f1101f7344 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php @@ -0,0 +1,35 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class AndVersionConstraintGroup extends \PharIo\Version\AbstractVersionConstraint +{ + /** @var VersionConstraint[] */ + private $constraints = []; + /** + * @param VersionConstraint[] $constraints + */ + public function __construct(string $originalValue, array $constraints) + { + parent::__construct($originalValue); + $this->constraints = $constraints; + } + public function complies(\PharIo\Version\Version $version) : bool + { + foreach ($this->constraints as $constraint) { + if (!$constraint->complies($version)) { + return \false; + } + } + return \true; + } +} diff --git a/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php b/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php new file mode 100644 index 0000000000..8155cfab81 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php @@ -0,0 +1,24 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class AnyVersionConstraint implements \PharIo\Version\VersionConstraint +{ + public function complies(\PharIo\Version\Version $version) : bool + { + return \true; + } + public function asString() : string + { + return '*'; + } +} diff --git a/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php b/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php new file mode 100644 index 0000000000..3e3171726f --- /dev/null +++ b/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php @@ -0,0 +1,24 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class ExactVersionConstraint extends \PharIo\Version\AbstractVersionConstraint +{ + public function complies(\PharIo\Version\Version $version) : bool + { + $other = $version->getVersionString(); + if ($version->hasBuildMetaData()) { + $other .= '+' . $version->getBuildMetaData()->asString(); + } + return $this->asString() === $other; + } +} diff --git a/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php b/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php new file mode 100644 index 0000000000..764b9b4e42 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php @@ -0,0 +1,27 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class GreaterThanOrEqualToVersionConstraint extends \PharIo\Version\AbstractVersionConstraint +{ + /** @var Version */ + private $minimalVersion; + public function __construct(string $originalValue, \PharIo\Version\Version $minimalVersion) + { + parent::__construct($originalValue); + $this->minimalVersion = $minimalVersion; + } + public function complies(\PharIo\Version\Version $version) : bool + { + return $version->getVersionString() === $this->minimalVersion->getVersionString() || $version->isGreaterThan($this->minimalVersion); + } +} diff --git a/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php b/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php new file mode 100644 index 0000000000..b35381e443 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php @@ -0,0 +1,36 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class OrVersionConstraintGroup extends \PharIo\Version\AbstractVersionConstraint +{ + /** @var VersionConstraint[] */ + private $constraints = []; + /** + * @param string $originalValue + * @param VersionConstraint[] $constraints + */ + public function __construct($originalValue, array $constraints) + { + parent::__construct($originalValue); + $this->constraints = $constraints; + } + public function complies(\PharIo\Version\Version $version) : bool + { + foreach ($this->constraints as $constraint) { + if ($constraint->complies($version)) { + return \true; + } + } + return \false; + } +} diff --git a/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php b/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php new file mode 100644 index 0000000000..4e319ef16e --- /dev/null +++ b/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php @@ -0,0 +1,33 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class SpecificMajorAndMinorVersionConstraint extends \PharIo\Version\AbstractVersionConstraint +{ + /** @var int */ + private $major; + /** @var int */ + private $minor; + public function __construct(string $originalValue, int $major, int $minor) + { + parent::__construct($originalValue); + $this->major = $major; + $this->minor = $minor; + } + public function complies(\PharIo\Version\Version $version) : bool + { + if ($version->getMajor()->getValue() !== $this->major) { + return \false; + } + return $version->getMinor()->getValue() === $this->minor; + } +} diff --git a/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php b/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php new file mode 100644 index 0000000000..bf4f64f03e --- /dev/null +++ b/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php @@ -0,0 +1,27 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +class SpecificMajorVersionConstraint extends \PharIo\Version\AbstractVersionConstraint +{ + /** @var int */ + private $major; + public function __construct(string $originalValue, int $major) + { + parent::__construct($originalValue); + $this->major = $major; + } + public function complies(\PharIo\Version\Version $version) : bool + { + return $version->getMajor()->getValue() === $this->major; + } +} diff --git a/vendor/phar-io/version/src/constraints/VersionConstraint.php b/vendor/phar-io/version/src/constraints/VersionConstraint.php new file mode 100644 index 0000000000..e2e24a9993 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/VersionConstraint.php @@ -0,0 +1,18 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +interface VersionConstraint +{ + public function complies(\PharIo\Version\Version $version) : bool; + public function asString() : string; +} diff --git a/vendor/phar-io/version/src/exceptions/Exception.php b/vendor/phar-io/version/src/exceptions/Exception.php new file mode 100644 index 0000000000..3afcc964cf --- /dev/null +++ b/vendor/phar-io/version/src/exceptions/Exception.php @@ -0,0 +1,17 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +use Throwable; +interface Exception extends Throwable +{ +} diff --git a/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php b/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php new file mode 100644 index 0000000000..0becbab34d --- /dev/null +++ b/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php @@ -0,0 +1,8 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PharIo\Version; + +final class UnsupportedVersionConstraintException extends \RuntimeException implements \PharIo\Version\Exception +{ +} diff --git a/vendor/psr/container/LICENSE b/vendor/psr/container/LICENSE new file mode 100644 index 0000000000..2877a4894e --- /dev/null +++ b/vendor/psr/container/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-2016 container-interop +Copyright (c) 2016 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/psr/container/README.md b/vendor/psr/container/README.md new file mode 100644 index 0000000000..1b9d9e5708 --- /dev/null +++ b/vendor/psr/container/README.md @@ -0,0 +1,13 @@ +Container interface +============== + +This repository holds all interfaces related to [PSR-11 (Container Interface)][psr-url]. + +Note that this is not a Container implementation of its own. It is merely abstractions that describe the components of a Dependency Injection Container. + +The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist. + +[psr-url]: https://www.php-fig.org/psr/psr-11/ +[package-url]: https://packagist.org/packages/psr/container +[implementation-url]: https://packagist.org/providers/psr/container-implementation + diff --git a/vendor/psr/container/composer.json b/vendor/psr/container/composer.json new file mode 100644 index 0000000000..f58e234bee --- /dev/null +++ b/vendor/psr/container/composer.json @@ -0,0 +1,33 @@ +{ + "name": "psr\/container", + "type": "library", + "description": "Common Container Interface (PHP FIG PSR-11)", + "keywords": [ + "psr", + "psr-11", + "container", + "container-interop", + "container-interface" + ], + "homepage": "https:\/\/github.com\/php-fig\/container", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https:\/\/www.php-fig.org\/" + } + ], + "require": { + "php": ">=7.4.0" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Psr\\Container\\": "src\/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + } +} \ No newline at end of file diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php new file mode 100644 index 0000000000..050d9e62f6 --- /dev/null +++ b/vendor/psr/container/src/ContainerExceptionInterface.php @@ -0,0 +1,11 @@ +=7.3` + +## [4.0.2] - 2020-06-30 + +### Added + +* This component is now supported on PHP 8 + +## [4.0.1] - 2020-05-08 + +### Fixed + +* [#99](https://github.com/sebastianbergmann/diff/pull/99): Regression in unified diff output of identical strings + +## [4.0.0] - 2020-02-07 + +### Removed + +* Removed support for PHP 7.1 and PHP 7.2 + +## [3.0.2] - 2019-02-04 + +### Changed + +* `Chunk::setLines()` now ensures that the `$lines` array only contains `Line` objects + +## [3.0.1] - 2018-06-10 + +### Fixed + +* Removed `"minimum-stability": "dev",` from `composer.json` + +## [3.0.0] - 2018-02-01 + +* The `StrictUnifiedDiffOutputBuilder` implementation of the `DiffOutputBuilderInterface` was added + +### Changed + +* The default `DiffOutputBuilderInterface` implementation now generates context lines (unchanged lines) + +### Removed + +* Removed support for PHP 7.0 + +### Fixed + +* [#70](https://github.com/sebastianbergmann/diff/issues/70): Diffing of arrays no longer works + +## [2.0.1] - 2017-08-03 + +### Fixed + +* [#66](https://github.com/sebastianbergmann/diff/pull/66): Restored backwards compatibility for PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3 + +## [2.0.0] - 2017-07-11 [YANKED] + +### Added + +* [#64](https://github.com/sebastianbergmann/diff/pull/64): Show line numbers for chunks of a diff + +### Removed + +* This component is no longer supported on PHP 5.6 + +[5.0.3]: https://github.com/sebastianbergmann/diff/compare/5.0.2...5.0.3 +[5.0.2]: https://github.com/sebastianbergmann/diff/compare/5.0.1...5.0.2 +[5.0.1]: https://github.com/sebastianbergmann/diff/compare/5.0.0...5.0.1 +[5.0.0]: https://github.com/sebastianbergmann/diff/compare/4.0.4...5.0.0 +[4.0.4]: https://github.com/sebastianbergmann/diff/compare/4.0.3...4.0.4 +[4.0.3]: https://github.com/sebastianbergmann/diff/compare/4.0.2...4.0.3 +[4.0.2]: https://github.com/sebastianbergmann/diff/compare/4.0.1...4.0.2 +[4.0.1]: https://github.com/sebastianbergmann/diff/compare/4.0.0...4.0.1 +[4.0.0]: https://github.com/sebastianbergmann/diff/compare/3.0.2...4.0.0 +[3.0.2]: https://github.com/sebastianbergmann/diff/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/diff/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/diff/compare/2.0...3.0.0 +[2.0.1]: https://github.com/sebastianbergmann/diff/compare/c341c98ce083db77f896a0aa64f5ee7652915970...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/diff/compare/1.4...c341c98ce083db77f896a0aa64f5ee7652915970 diff --git a/vendor/sebastian/diff/LICENSE b/vendor/sebastian/diff/LICENSE new file mode 100644 index 0000000000..a453252d52 --- /dev/null +++ b/vendor/sebastian/diff/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2002-2023, Sebastian Bergmann +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/sebastian/diff/README.md b/vendor/sebastian/diff/README.md new file mode 100644 index 0000000000..539dc59ede --- /dev/null +++ b/vendor/sebastian/diff/README.md @@ -0,0 +1,206 @@ +[![Latest Stable Version](https://poser.pugx.org/sebastian/diff/v/stable.png)](https://packagist.org/packages/sebastian/diff) +[![CI Status](https://github.com/sebastianbergmann/diff/workflows/CI/badge.svg)](https://github.com/sebastianbergmann/diff/actions) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/diff/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/diff) +[![codecov](https://codecov.io/gh/sebastianbergmann/diff/branch/main/graph/badge.svg)](https://codecov.io/gh/sebastianbergmann/diff) + +# sebastian/diff + +Diff implementation for PHP, factored out of PHPUnit into a stand-alone component. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + +``` +composer require sebastian/diff +``` + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + +``` +composer require --dev sebastian/diff +``` + +### Usage + +#### Generating diff + +The `Differ` class can be used to generate a textual representation of the difference between two strings: + +```php +diff('foo', 'bar'); +``` + +The code above yields the output below: +```diff +--- Original ++++ New +@@ @@ +-foo ++bar +``` + +There are three output builders available in this package: + +#### UnifiedDiffOutputBuilder + +This is default builder, which generates the output close to udiff and is used by PHPUnit. + +```php +diff('foo', 'bar'); +``` + +#### StrictUnifiedDiffOutputBuilder + +Generates (strict) Unified diff's (unidiffs) with hunks, +similar to `diff -u` and compatible with `patch` and `git apply`. + +```php + true, // ranges of length one are rendered with the trailing `,1` + 'commonLineThreshold' => 6, // number of same lines before ending a new hunk and creating a new one (if needed) + 'contextLines' => 3, // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3 + 'fromFile' => '', + 'fromFileDate' => null, + 'toFile' => '', + 'toFileDate' => null, +]); + +$differ = new Differ($builder); +print $differ->diff('foo', 'bar'); +``` + +#### DiffOnlyOutputBuilder + +Output only the lines that differ. + +```php +diff('foo', 'bar'); +``` + +#### DiffOutputBuilderInterface + +You can pass any output builder to the `Differ` class as longs as it implements the `DiffOutputBuilderInterface`. + +#### Parsing diff + +The `Parser` class can be used to parse a unified diff into an object graph: + +```php +use SebastianBergmann\Diff\Parser; +use SebastianBergmann\Git; + +$git = new Git('/usr/local/src/money'); + +$diff = $git->getDiff( + '948a1a07768d8edd10dcefa8315c1cbeffb31833', + 'c07a373d2399f3e686234c4f7f088d635eb9641b' +); + +$parser = new Parser; + +print_r($parser->parse($diff)); +``` + +The code above yields the output below: + + Array + ( + [0] => SebastianBergmann\Diff\Diff Object + ( + [from:SebastianBergmann\Diff\Diff:private] => a/tests/MoneyTest.php + [to:SebastianBergmann\Diff\Diff:private] => b/tests/MoneyTest.php + [chunks:SebastianBergmann\Diff\Diff:private] => Array + ( + [0] => SebastianBergmann\Diff\Chunk Object + ( + [start:SebastianBergmann\Diff\Chunk:private] => 87 + [startRange:SebastianBergmann\Diff\Chunk:private] => 7 + [end:SebastianBergmann\Diff\Chunk:private] => 87 + [endRange:SebastianBergmann\Diff\Chunk:private] => 7 + [lines:SebastianBergmann\Diff\Chunk:private] => Array + ( + [0] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::add + ) + + [1] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::newMoney + ) + + [2] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => */ + ) + + [3] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 2 + [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyWithSameCurrencyObjectCanBeAdded() + ) + + [4] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 1 + [content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyObjectWithSameCurrencyCanBeAdded() + ) + + [5] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => { + ) + + [6] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => $a = new Money(1, new Currency('EUR')); + ) + + [7] => SebastianBergmann\Diff\Line Object + ( + [type:SebastianBergmann\Diff\Line:private] => 3 + [content:SebastianBergmann\Diff\Line:private] => $b = new Money(2, new Currency('EUR')); + ) + ) + ) + ) + ) + ) + +Note: If the chunk size is 0 lines, i.e., `getStartRange()` or `getEndRange()` return 0, the number of line returned by `getStart()` or `getEnd()` is one lower than one would expect. It is the line number after which the chunk should be inserted or deleted; in all other cases, it gives the first line number of the replaced range of lines. diff --git a/vendor/sebastian/diff/SECURITY.md b/vendor/sebastian/diff/SECURITY.md new file mode 100644 index 0000000000..d88ff0019a --- /dev/null +++ b/vendor/sebastian/diff/SECURITY.md @@ -0,0 +1,30 @@ +# Security Policy + +If you believe you have found a security vulnerability in the library that is developed in this repository, please report it to us through coordinated disclosure. + +**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.** + +Instead, please email `sebastian@phpunit.de`. + +Please include as much of the information listed below as you can to help us better understand and resolve the issue: + +* The type of issue +* Full paths of source file(s) related to the manifestation of the issue +* The location of the affected source code (tag/branch/commit or direct URL) +* Any special configuration required to reproduce the issue +* Step-by-step instructions to reproduce the issue +* Proof-of-concept or exploit code (if possible) +* Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +## Web Context + +The library that is developed in this repository was either extracted from [PHPUnit](https://github.com/sebastianbergmann/phpunit) or developed specifically as a dependency for PHPUnit. + +The library is developed with a focus on development environments and the command-line. No specific testing or hardening with regard to using the library in an HTTP or web context or with untrusted input data is performed. The library might also contain functionality that intentionally exposes internal application data for debugging purposes. + +If the library is used in a web application, the application developer is responsible for filtering inputs or escaping outputs as necessary and for verifying that the used functionality is safe for use within the intended context. + +Vulnerabilities specific to the use outside a development context will be fixed as applicable, provided that the fix does not have an averse effect on the primary use case for development purposes. + diff --git a/vendor/sebastian/diff/composer.json b/vendor/sebastian/diff/composer.json new file mode 100644 index 0000000000..acc5769f7e --- /dev/null +++ b/vendor/sebastian/diff/composer.json @@ -0,0 +1,56 @@ +{ + "name": "sebastian\/diff", + "description": "Diff implementation", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "homepage": "https:\/\/github.com\/sebastianbergmann\/diff", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "support": { + "issues": "https:\/\/github.com\/sebastianbergmann\/diff\/issues", + "security": "https:\/\/github.com\/sebastianbergmann\/diff\/security\/policy" + }, + "prefer-stable": true, + "config": { + "platform": { + "php": "8.1.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit\/phpunit": "^10.0", + "symfony\/process": "^4.2 || ^5" + }, + "autoload": { + "classmap": [ + "src\/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests\/" + ] + }, + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + } +} \ No newline at end of file diff --git a/vendor/sebastian/diff/src/Chunk.php b/vendor/sebastian/diff/src/Chunk.php new file mode 100644 index 0000000000..b7d5d6cd73 --- /dev/null +++ b/vendor/sebastian/diff/src/Chunk.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +final class Chunk +{ + /** + * @var int + */ + private $start; + /** + * @var int + */ + private $startRange; + /** + * @var int + */ + private $end; + /** + * @var int + */ + private $endRange; + /** + * @var mixed[] + */ + private $lines; + public function __construct(int $start = 0, int $startRange = 1, int $end = 0, int $endRange = 1, array $lines = []) + { + $this->start = $start; + $this->startRange = $startRange; + $this->end = $end; + $this->endRange = $endRange; + $this->lines = $lines; + } + public function getStart() : int + { + return $this->start; + } + public function getStartRange() : int + { + return $this->startRange; + } + public function getEnd() : int + { + return $this->end; + } + public function getEndRange() : int + { + return $this->endRange; + } + /** + * @psalm-return list + */ + public function getLines() : array + { + return $this->lines; + } + /** + * @psalm-param list $lines + */ + public function setLines(array $lines) : void + { + foreach ($lines as $line) { + if (!$line instanceof Line) { + throw new InvalidArgumentException(); + } + } + $this->lines = $lines; + } +} diff --git a/vendor/sebastian/diff/src/Diff.php b/vendor/sebastian/diff/src/Diff.php new file mode 100644 index 0000000000..5bdb025a2c --- /dev/null +++ b/vendor/sebastian/diff/src/Diff.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +final class Diff +{ + /** + * @var string + */ + private $from; + /** + * @var string + */ + private $to; + /** + * @psalm-var list + * @var mixed[] + */ + private $chunks; + /** + * @psalm-param list $chunks + */ + public function __construct(string $from, string $to, array $chunks = []) + { + $this->from = $from; + $this->to = $to; + $this->chunks = $chunks; + } + public function getFrom() : string + { + return $this->from; + } + public function getTo() : string + { + return $this->to; + } + /** + * @psalm-return list + */ + public function getChunks() : array + { + return $this->chunks; + } + /** + * @psalm-param list $chunks + */ + public function setChunks(array $chunks) : void + { + $this->chunks = $chunks; + } +} diff --git a/vendor/sebastian/diff/src/Differ.php b/vendor/sebastian/diff/src/Differ.php new file mode 100644 index 0000000000..6d178e5bed --- /dev/null +++ b/vendor/sebastian/diff/src/Differ.php @@ -0,0 +1,206 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +use const PHP_INT_SIZE; +use const PREG_SPLIT_DELIM_CAPTURE; +use const PREG_SPLIT_NO_EMPTY; +use function array_shift; +use function array_unshift; +use function array_values; +use function count; +use function current; +use function end; +use function is_string; +use function key; +use function min; +use function preg_split; +use function prev; +use function reset; +use function str_ends_with; +use function substr; +use MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Output\DiffOutputBuilderInterface; +final class Differ +{ + public const OLD = 0; + public const ADDED = 1; + public const REMOVED = 2; + public const DIFF_LINE_END_WARNING = 3; + public const NO_LINE_END_EOF_WARNING = 4; + /** + * @var \SebastianBergmann\Diff\Output\DiffOutputBuilderInterface + */ + private $outputBuilder; + public function __construct(DiffOutputBuilderInterface $outputBuilder) + { + $this->outputBuilder = $outputBuilder; + } + /** + * @param mixed[]|string $from + * @param mixed[]|string $to + */ + public function diff($from, $to, LongestCommonSubsequenceCalculator $lcs = null) : string + { + $diff = $this->diffToArray($from, $to, $lcs); + return $this->outputBuilder->getDiff($diff); + } + /** + * @param mixed[]|string $from + * @param mixed[]|string $to + */ + public function diffToArray($from, $to, LongestCommonSubsequenceCalculator $lcs = null) : array + { + if (is_string($from)) { + $from = $this->splitStringByLines($from); + } + if (is_string($to)) { + $to = $this->splitStringByLines($to); + } + [$from, $to, $start, $end] = self::getArrayDiffParted($from, $to); + if ($lcs === null) { + $lcs = $this->selectLcsImplementation($from, $to); + } + $common = $lcs->calculate(array_values($from), array_values($to)); + $diff = []; + foreach ($start as $token) { + $diff[] = [$token, self::OLD]; + } + reset($from); + reset($to); + foreach ($common as $token) { + while (($fromToken = reset($from)) !== $token) { + $diff[] = [array_shift($from), self::REMOVED]; + } + while (($toToken = reset($to)) !== $token) { + $diff[] = [array_shift($to), self::ADDED]; + } + $diff[] = [$token, self::OLD]; + array_shift($from); + array_shift($to); + } + while (($token = array_shift($from)) !== null) { + $diff[] = [$token, self::REMOVED]; + } + while (($token = array_shift($to)) !== null) { + $diff[] = [$token, self::ADDED]; + } + foreach ($end as $token) { + $diff[] = [$token, self::OLD]; + } + if ($this->detectUnmatchedLineEndings($diff)) { + array_unshift($diff, ["#Warning: Strings contain different line endings!\n", self::DIFF_LINE_END_WARNING]); + } + return $diff; + } + private function splitStringByLines(string $input) : array + { + return preg_split('/(.*\\R)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + } + private function selectLcsImplementation(array $from, array $to) : LongestCommonSubsequenceCalculator + { + // We do not want to use the time-efficient implementation if its memory + // footprint will probably exceed this value. Note that the footprint + // calculation is only an estimation for the matrix and the LCS method + // will typically allocate a bit more memory than this. + $memoryLimit = 100 * 1024 * 1024; + if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) { + return new MemoryEfficientLongestCommonSubsequenceCalculator(); + } + return new TimeEfficientLongestCommonSubsequenceCalculator(); + } + /** + * @return float|int + */ + private function calculateEstimatedFootprint(array $from, array $to) + { + $itemSize = PHP_INT_SIZE === 4 ? 76 : 144; + return $itemSize * min(count($from), count($to)) ** 2; + } + private function detectUnmatchedLineEndings(array $diff) : bool + { + $newLineBreaks = ['' => \true]; + $oldLineBreaks = ['' => \true]; + foreach ($diff as $entry) { + if (self::OLD === $entry[1]) { + $ln = $this->getLinebreak($entry[0]); + $oldLineBreaks[$ln] = \true; + $newLineBreaks[$ln] = \true; + } elseif (self::ADDED === $entry[1]) { + $newLineBreaks[$this->getLinebreak($entry[0])] = \true; + } elseif (self::REMOVED === $entry[1]) { + $oldLineBreaks[$this->getLinebreak($entry[0])] = \true; + } + } + // if either input or output is a single line without breaks than no warning should be raised + if (['' => \true] === $newLineBreaks || ['' => \true] === $oldLineBreaks) { + return \false; + } + // two-way compare + foreach ($newLineBreaks as $break => $set) { + if (!isset($oldLineBreaks[$break])) { + return \true; + } + } + foreach ($oldLineBreaks as $break => $set) { + if (!isset($newLineBreaks[$break])) { + return \true; + } + } + return \false; + } + private function getLinebreak($line) : string + { + if (!is_string($line)) { + return ''; + } + $lc = substr($line, -1); + if ("\r" === $lc) { + return "\r"; + } + if ("\n" !== $lc) { + return ''; + } + if (\substr_compare($line, "\r\n", -\strlen("\r\n")) === 0) { + return "\r\n"; + } + return "\n"; + } + private static function getArrayDiffParted(array &$from, array &$to) : array + { + $start = []; + $end = []; + reset($to); + foreach ($from as $k => $v) { + $toK = key($to); + if ($toK === $k && $v === $to[$k]) { + $start[$k] = $v; + unset($from[$k], $to[$k]); + } else { + break; + } + } + end($from); + end($to); + do { + $fromK = key($from); + $toK = key($to); + if (null === $fromK || null === $toK || current($from) !== current($to)) { + break; + } + prev($from); + prev($to); + $end = [$fromK => $from[$fromK]] + $end; + unset($from[$fromK], $to[$toK]); + } while (\true); + return [$from, $to, $start, $end]; + } +} diff --git a/vendor/sebastian/diff/src/Exception/ConfigurationException.php b/vendor/sebastian/diff/src/Exception/ConfigurationException.php new file mode 100644 index 0000000000..1c082cb3e1 --- /dev/null +++ b/vendor/sebastian/diff/src/Exception/ConfigurationException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +use function gettype; +use function is_object; +use function sprintf; +use Exception; +final class ConfigurationException extends InvalidArgumentException +{ + public function __construct(string $option, string $expected, $value, int $code = 0, Exception $previous = null) + { + parent::__construct(sprintf('Option "%s" must be %s, got "%s".', $option, $expected, is_object($value) ? \get_class($value) : (null === $value ? '' : gettype($value) . '#' . $value)), $code, $previous); + } +} diff --git a/vendor/sebastian/diff/src/Exception/Exception.php b/vendor/sebastian/diff/src/Exception/Exception.php new file mode 100644 index 0000000000..7e37673d09 --- /dev/null +++ b/vendor/sebastian/diff/src/Exception/Exception.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +use Throwable; +interface Exception extends Throwable +{ +} diff --git a/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php b/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000..ff181086fb --- /dev/null +++ b/vendor/sebastian/diff/src/Exception/InvalidArgumentException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/vendor/sebastian/diff/src/Line.php b/vendor/sebastian/diff/src/Line.php new file mode 100644 index 0000000000..8660c2d502 --- /dev/null +++ b/vendor/sebastian/diff/src/Line.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +final class Line +{ + public const ADDED = 1; + public const REMOVED = 2; + public const UNCHANGED = 3; + /** + * @var int + */ + private $type; + /** + * @var string + */ + private $content; + public function __construct(int $type = self::UNCHANGED, string $content = '') + { + $this->type = $type; + $this->content = $content; + } + public function getContent() : string + { + return $this->content; + } + public function getType() : int + { + return $this->type; + } +} diff --git a/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php new file mode 100644 index 0000000000..b33beaa7aa --- /dev/null +++ b/vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +interface LongestCommonSubsequenceCalculator +{ + /** + * Calculates the longest common subsequence of two arrays. + */ + public function calculate(array $from, array $to) : array; +} diff --git a/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php new file mode 100644 index 0000000000..9634fde66e --- /dev/null +++ b/vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +use function array_fill; +use function array_merge; +use function array_reverse; +use function array_slice; +use function count; +use function in_array; +use function max; +final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator +{ + /** + * @inheritDoc + */ + public function calculate(array $from, array $to) : array + { + $cFrom = count($from); + $cTo = count($to); + if ($cFrom === 0) { + return []; + } + if ($cFrom === 1) { + if (in_array($from[0], $to, \true)) { + return [$from[0]]; + } + return []; + } + $i = (int) ($cFrom / 2); + $fromStart = array_slice($from, 0, $i); + $fromEnd = array_slice($from, $i); + $llB = $this->length($fromStart, $to); + $llE = $this->length(array_reverse($fromEnd), array_reverse($to)); + $jMax = 0; + $max = 0; + for ($j = 0; $j <= $cTo; $j++) { + $m = $llB[$j] + $llE[$cTo - $j]; + if ($m >= $max) { + $max = $m; + $jMax = $j; + } + } + $toStart = array_slice($to, 0, $jMax); + $toEnd = array_slice($to, $jMax); + return array_merge($this->calculate($fromStart, $toStart), $this->calculate($fromEnd, $toEnd)); + } + private function length(array $from, array $to) : array + { + $current = array_fill(0, count($to) + 1, 0); + $cFrom = count($from); + $cTo = count($to); + for ($i = 0; $i < $cFrom; $i++) { + $prev = $current; + for ($j = 0; $j < $cTo; $j++) { + if ($from[$i] === $to[$j]) { + $current[$j + 1] = $prev[$j] + 1; + } else { + // don't use max() to avoid function call overhead + if ($current[$j] > $prev[$j + 1]) { + $current[$j + 1] = $current[$j]; + } else { + $current[$j + 1] = $prev[$j + 1]; + } + } + } + } + return $current; + } +} diff --git a/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php b/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php new file mode 100644 index 0000000000..dc71cb05bd --- /dev/null +++ b/vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Output; + +use function count; +abstract class AbstractChunkOutputBuilder implements DiffOutputBuilderInterface +{ + /** + * Takes input of the diff array and returns the common parts. + * Iterates through diff line by line. + */ + protected function getCommonChunks(array $diff, int $lineThreshold = 5) : array + { + $diffSize = count($diff); + $capturing = \false; + $chunkStart = 0; + $chunkSize = 0; + $commonChunks = []; + for ($i = 0; $i < $diffSize; $i++) { + if ($diff[$i][1] === 0) { + if ($capturing === \false) { + $capturing = \true; + $chunkStart = $i; + $chunkSize = 0; + } else { + $chunkSize++; + } + } elseif ($capturing !== \false) { + if ($chunkSize >= $lineThreshold) { + $commonChunks[$chunkStart] = $chunkStart + $chunkSize; + } + $capturing = \false; + } + } + if ($capturing !== \false && $chunkSize >= $lineThreshold) { + $commonChunks[$chunkStart] = $chunkStart + $chunkSize; + } + return $commonChunks; + } +} diff --git a/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php b/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php new file mode 100644 index 0000000000..20daf38bef --- /dev/null +++ b/vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Output; + +use function fclose; +use function fopen; +use function fwrite; +use function str_ends_with; +use function stream_get_contents; +use function substr; +use MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Differ; +/** + * Builds a diff string representation in a loose unified diff format + * listing only changes lines. Does not include line numbers. + */ +final class DiffOnlyOutputBuilder implements DiffOutputBuilderInterface +{ + /** + * @var string + */ + private $header; + public function __construct(string $header = "--- Original\n+++ New\n") + { + $this->header = $header; + } + public function getDiff(array $diff) : string + { + $buffer = fopen('php://memory', 'r+b'); + if ('' !== $this->header) { + fwrite($buffer, $this->header); + if (\substr_compare($this->header, "\n", -\strlen("\n")) !== 0) { + fwrite($buffer, "\n"); + } + } + foreach ($diff as $diffEntry) { + if ($diffEntry[1] === Differ::ADDED) { + fwrite($buffer, '+' . $diffEntry[0]); + } elseif ($diffEntry[1] === Differ::REMOVED) { + fwrite($buffer, '-' . $diffEntry[0]); + } elseif ($diffEntry[1] === Differ::DIFF_LINE_END_WARNING) { + fwrite($buffer, ' ' . $diffEntry[0]); + continue; + // Warnings should not be tested for line break, it will always be there + } else { + /* Not changed (old) 0 */ + continue; + // we didn't write the not-changed line, so do not add a line break either + } + $lc = substr($diffEntry[0], -1); + if ($lc !== "\n" && $lc !== "\r") { + fwrite($buffer, "\n"); + // \No newline at end of file + } + } + $diff = stream_get_contents($buffer, -1, 0); + fclose($buffer); + return $diff; + } +} diff --git a/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php b/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php new file mode 100644 index 0000000000..7e294303b0 --- /dev/null +++ b/vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Output; + +/** + * Defines how an output builder should take a generated + * diff array and return a string representation of that diff. + */ +interface DiffOutputBuilderInterface +{ + public function getDiff(array $diff) : string; +} diff --git a/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php b/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php new file mode 100644 index 0000000000..43fe2f5c56 --- /dev/null +++ b/vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php @@ -0,0 +1,252 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Output; + +use function array_merge; +use function array_splice; +use function count; +use function fclose; +use function fopen; +use function fwrite; +use function is_bool; +use function is_int; +use function is_string; +use function max; +use function min; +use function sprintf; +use function stream_get_contents; +use function substr; +use MonorepoBuilderPrefix202310\SebastianBergmann\Diff\ConfigurationException; +use MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Differ; +/** + * Strict Unified diff output builder. + * + * Generates (strict) Unified diff's (unidiffs) with hunks. + */ +final class StrictUnifiedDiffOutputBuilder implements DiffOutputBuilderInterface +{ + /** + * @var mixed[] + */ + private static $default = [ + 'collapseRanges' => \true, + // ranges of length one are rendered with the trailing `,1` + 'commonLineThreshold' => 6, + // number of same lines before ending a new hunk and creating a new one (if needed) + 'contextLines' => 3, + // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3 + 'fromFile' => null, + 'fromFileDate' => null, + 'toFile' => null, + 'toFileDate' => null, + ]; + /** + * @var bool + */ + private $changed; + /** + * @var bool + */ + private $collapseRanges; + /** + * @psalm-var positive-int + * @var int + */ + private $commonLineThreshold; + /** + * @var string + */ + private $header; + /** + * @psalm-var positive-int + * @var int + */ + private $contextLines; + public function __construct(array $options = []) + { + $options = array_merge(self::$default, $options); + if (!is_bool($options['collapseRanges'])) { + throw new ConfigurationException('collapseRanges', 'a bool', $options['collapseRanges']); + } + if (!is_int($options['contextLines']) || $options['contextLines'] < 0) { + throw new ConfigurationException('contextLines', 'an int >= 0', $options['contextLines']); + } + if (!is_int($options['commonLineThreshold']) || $options['commonLineThreshold'] <= 0) { + throw new ConfigurationException('commonLineThreshold', 'an int > 0', $options['commonLineThreshold']); + } + $this->assertString($options, 'fromFile'); + $this->assertString($options, 'toFile'); + $this->assertStringOrNull($options, 'fromFileDate'); + $this->assertStringOrNull($options, 'toFileDate'); + $this->header = sprintf("--- %s%s\n+++ %s%s\n", $options['fromFile'], null === $options['fromFileDate'] ? '' : "\t" . $options['fromFileDate'], $options['toFile'], null === $options['toFileDate'] ? '' : "\t" . $options['toFileDate']); + $this->collapseRanges = $options['collapseRanges']; + $this->commonLineThreshold = $options['commonLineThreshold']; + $this->contextLines = $options['contextLines']; + } + public function getDiff(array $diff) : string + { + if (0 === count($diff)) { + return ''; + } + $this->changed = \false; + $buffer = fopen('php://memory', 'r+b'); + fwrite($buffer, $this->header); + $this->writeDiffHunks($buffer, $diff); + if (!$this->changed) { + fclose($buffer); + return ''; + } + $diff = stream_get_contents($buffer, -1, 0); + fclose($buffer); + // If the last char is not a linebreak: add it. + // This might happen when both the `from` and `to` do not have a trailing linebreak + $last = substr($diff, -1); + return "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff; + } + private function writeDiffHunks($output, array $diff) : void + { + // detect "No newline at end of file" and insert into `$diff` if needed + $upperLimit = count($diff); + if (0 === $diff[$upperLimit - 1][1]) { + $lc = substr($diff[$upperLimit - 1][0], -1); + if ("\n" !== $lc) { + array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + } else { + // search back for the last `+` and `-` line, + // check if it has a trailing linebreak, else add a warning under it + $toFind = [1 => \true, 2 => \true]; + for ($i = $upperLimit - 1; $i >= 0; $i--) { + if (isset($toFind[$diff[$i][1]])) { + unset($toFind[$diff[$i][1]]); + $lc = substr($diff[$i][0], -1); + if ("\n" !== $lc) { + array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + if (!count($toFind)) { + break; + } + } + } + } + // write hunks to output buffer + $cutOff = max($this->commonLineThreshold, $this->contextLines); + $hunkCapture = \false; + $sameCount = $toRange = $fromRange = 0; + $toStart = $fromStart = 1; + $i = 0; + /** @var int $i */ + foreach ($diff as $i => $entry) { + if (0 === $entry[1]) { + // same + if (\false === $hunkCapture) { + $fromStart++; + $toStart++; + continue; + } + $sameCount++; + $toRange++; + $fromRange++; + if ($sameCount === $cutOff) { + $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines; + // note: $contextEndOffset = $this->contextLines; + // + // because we never go beyond the end of the diff. + // with the cutoff/contextlines here the follow is never true; + // + // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) { + // $contextEndOffset = count($diff) - 1; + // } + // + // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop + $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output); + $fromStart += $fromRange; + $toStart += $toRange; + $hunkCapture = \false; + $sameCount = $toRange = $fromRange = 0; + } + continue; + } + $sameCount = 0; + if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) { + continue; + } + $this->changed = \true; + if (\false === $hunkCapture) { + $hunkCapture = $i; + } + if (Differ::ADDED === $entry[1]) { + // added + $toRange++; + } + if (Differ::REMOVED === $entry[1]) { + // removed + $fromRange++; + } + } + if (\false === $hunkCapture) { + return; + } + // we end here when cutoff (commonLineThreshold) was not reached, but we were capturing a hunk, + // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold + $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines; + // prevent trying to write out more common lines than there are in the diff _and_ + // do not write more than configured through the context lines + $contextEndOffset = min($sameCount, $this->contextLines); + $fromRange -= $sameCount; + $toRange -= $sameCount; + $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output); + } + private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output) : void + { + fwrite($output, '@@ -' . $fromStart); + if (!$this->collapseRanges || 1 !== $fromRange) { + fwrite($output, ',' . $fromRange); + } + fwrite($output, ' +' . $toStart); + if (!$this->collapseRanges || 1 !== $toRange) { + fwrite($output, ',' . $toRange); + } + fwrite($output, " @@\n"); + for ($i = $diffStartIndex; $i < $diffEndIndex; $i++) { + if ($diff[$i][1] === Differ::ADDED) { + $this->changed = \true; + fwrite($output, '+' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::REMOVED) { + $this->changed = \true; + fwrite($output, '-' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::OLD) { + fwrite($output, ' ' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) { + $this->changed = \true; + fwrite($output, $diff[$i][0]); + } + //} elseif ($diff[$i][1] === Differ::DIFF_LINE_END_WARNING) { // custom comment inserted by PHPUnit/diff package + // skip + //} else { + // unknown/invalid + //} + } + } + private function assertString(array $options, string $option) : void + { + if (!is_string($options[$option])) { + throw new ConfigurationException($option, 'a string', $options[$option]); + } + } + private function assertStringOrNull(array $options, string $option) : void + { + if (null !== $options[$option] && !is_string($options[$option])) { + throw new ConfigurationException($option, 'a string or ', $options[$option]); + } + } +} diff --git a/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php b/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php new file mode 100644 index 0000000000..9c6c24149e --- /dev/null +++ b/vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php @@ -0,0 +1,198 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Output; + +use function array_splice; +use function count; +use function fclose; +use function fopen; +use function fwrite; +use function max; +use function min; +use function str_ends_with; +use function stream_get_contents; +use function strlen; +use function substr; +use MonorepoBuilderPrefix202310\SebastianBergmann\Diff\Differ; +/** + * Builds a diff string representation in unified diff format in chunks. + */ +final class UnifiedDiffOutputBuilder extends AbstractChunkOutputBuilder +{ + /** + * @var bool + */ + private $collapseRanges = \true; + /** + * @var int + */ + private $commonLineThreshold = 6; + /** + * @psalm-var positive-int + * @var int + */ + private $contextLines = 3; + /** + * @var string + */ + private $header; + /** + * @var bool + */ + private $addLineNumbers; + public function __construct(string $header = "--- Original\n+++ New\n", bool $addLineNumbers = \false) + { + $this->header = $header; + $this->addLineNumbers = $addLineNumbers; + } + public function getDiff(array $diff) : string + { + $buffer = fopen('php://memory', 'r+b'); + if ('' !== $this->header) { + fwrite($buffer, $this->header); + if (\substr_compare($this->header, "\n", -strlen("\n")) !== 0) { + fwrite($buffer, "\n"); + } + } + if (0 !== count($diff)) { + $this->writeDiffHunks($buffer, $diff); + } + $diff = stream_get_contents($buffer, -1, 0); + fclose($buffer); + // If the diff is non-empty and last char is not a linebreak: add it. + // This might happen when both the `from` and `to` do not have a trailing linebreak + $last = substr($diff, -1); + return 0 !== strlen($diff) && "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff; + } + private function writeDiffHunks($output, array $diff) : void + { + // detect "No newline at end of file" and insert into `$diff` if needed + $upperLimit = count($diff); + if (0 === $diff[$upperLimit - 1][1]) { + $lc = substr($diff[$upperLimit - 1][0], -1); + if ("\n" !== $lc) { + array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + } else { + // search back for the last `+` and `-` line, + // check if it has trailing linebreak, else add a warning under it + $toFind = [1 => \true, 2 => \true]; + for ($i = $upperLimit - 1; $i >= 0; $i--) { + if (isset($toFind[$diff[$i][1]])) { + unset($toFind[$diff[$i][1]]); + $lc = substr($diff[$i][0], -1); + if ("\n" !== $lc) { + array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]); + } + if (!count($toFind)) { + break; + } + } + } + } + // write hunks to output buffer + $cutOff = max($this->commonLineThreshold, $this->contextLines); + $hunkCapture = \false; + $sameCount = $toRange = $fromRange = 0; + $toStart = $fromStart = 1; + $i = 0; + /** @var int $i */ + foreach ($diff as $i => $entry) { + if (0 === $entry[1]) { + // same + if (\false === $hunkCapture) { + $fromStart++; + $toStart++; + continue; + } + $sameCount++; + $toRange++; + $fromRange++; + if ($sameCount === $cutOff) { + $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines; + // note: $contextEndOffset = $this->contextLines; + // + // because we never go beyond the end of the diff. + // with the cutoff/contextlines here the follow is never true; + // + // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) { + // $contextEndOffset = count($diff) - 1; + // } + // + // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop + $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output); + $fromStart += $fromRange; + $toStart += $toRange; + $hunkCapture = \false; + $sameCount = $toRange = $fromRange = 0; + } + continue; + } + $sameCount = 0; + if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) { + continue; + } + if (\false === $hunkCapture) { + $hunkCapture = $i; + } + if (Differ::ADDED === $entry[1]) { + $toRange++; + } + if (Differ::REMOVED === $entry[1]) { + $fromRange++; + } + } + if (\false === $hunkCapture) { + return; + } + // we end here when cutoff (commonLineThreshold) was not reached, but we were capturing a hunk, + // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold + $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines; + // prevent trying to write out more common lines than there are in the diff _and_ + // do not write more than configured through the context lines + $contextEndOffset = min($sameCount, $this->contextLines); + $fromRange -= $sameCount; + $toRange -= $sameCount; + $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output); + } + private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output) : void + { + if ($this->addLineNumbers) { + fwrite($output, '@@ -' . $fromStart); + if (!$this->collapseRanges || 1 !== $fromRange) { + fwrite($output, ',' . $fromRange); + } + fwrite($output, ' +' . $toStart); + if (!$this->collapseRanges || 1 !== $toRange) { + fwrite($output, ',' . $toRange); + } + fwrite($output, " @@\n"); + } else { + fwrite($output, "@@ @@\n"); + } + for ($i = $diffStartIndex; $i < $diffEndIndex; $i++) { + if ($diff[$i][1] === Differ::ADDED) { + fwrite($output, '+' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::REMOVED) { + fwrite($output, '-' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::OLD) { + fwrite($output, ' ' . $diff[$i][0]); + } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) { + fwrite($output, "\n"); + // $diff[$i][0] + } else { + /* Not changed (old) Differ::OLD or Warning Differ::DIFF_LINE_END_WARNING */ + fwrite($output, ' ' . $diff[$i][0]); + } + } + } +} diff --git a/vendor/sebastian/diff/src/Parser.php b/vendor/sebastian/diff/src/Parser.php new file mode 100644 index 0000000000..edfc9e5c7e --- /dev/null +++ b/vendor/sebastian/diff/src/Parser.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +use function array_pop; +use function count; +use function max; +use function preg_match; +use function preg_split; +/** + * Unified diff parser. + */ +final class Parser +{ + /** + * @return Diff[] + */ + public function parse(string $string) : array + { + $lines = preg_split('(\\r\\n|\\r|\\n)', $string); + if (!empty($lines) && $lines[count($lines) - 1] === '') { + array_pop($lines); + } + $lineCount = count($lines); + $diffs = []; + $diff = null; + $collected = []; + for ($i = 0; $i < $lineCount; $i++) { + if (preg_match('#^---\\h+"?(?P[^\\v\\t"]+)#', $lines[$i], $fromMatch) && preg_match('#^\\+\\+\\+\\h+"?(?P[^\\v\\t"]+)#', $lines[$i + 1], $toMatch)) { + if ($diff !== null) { + $this->parseFileDiff($diff, $collected); + $diffs[] = $diff; + $collected = []; + } + $diff = new Diff($fromMatch['file'], $toMatch['file']); + $i++; + } else { + if (preg_match('/^(?:diff --git |index [\\da-f.]+|[+-]{3} [ab])/', $lines[$i])) { + continue; + } + $collected[] = $lines[$i]; + } + } + if ($diff !== null && count($collected)) { + $this->parseFileDiff($diff, $collected); + $diffs[] = $diff; + } + return $diffs; + } + private function parseFileDiff(Diff $diff, array $lines) : void + { + $chunks = []; + $chunk = null; + $diffLines = []; + foreach ($lines as $line) { + if (preg_match('/^@@\\s+-(?P\\d+)(?:,\\s*(?P\\d+))?\\s+\\+(?P\\d+)(?:,\\s*(?P\\d+))?\\s+@@/', $line, $match, \PREG_UNMATCHED_AS_NULL)) { + $chunk = new Chunk((int) $match['start'], isset($match['startrange']) ? max(0, (int) $match['startrange']) : 1, (int) $match['end'], isset($match['endrange']) ? max(0, (int) $match['endrange']) : 1); + $chunks[] = $chunk; + $diffLines = []; + continue; + } + if (preg_match('/^(?P[+ -])?(?P.*)/', $line, $match)) { + $type = Line::UNCHANGED; + if ($match['type'] === '+') { + $type = Line::ADDED; + } elseif ($match['type'] === '-') { + $type = Line::REMOVED; + } + $diffLines[] = new Line($type, $match['line']); + ($nullsafeVariable1 = $chunk) ? $nullsafeVariable1->setLines($diffLines) : null; + } + } + $diff->setChunks($chunks); + } +} diff --git a/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php b/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php new file mode 100644 index 0000000000..065537b893 --- /dev/null +++ b/vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\SebastianBergmann\Diff; + +use function array_reverse; +use function count; +use function max; +use SplFixedArray; +final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator +{ + /** + * @inheritDoc + */ + public function calculate(array $from, array $to) : array + { + $common = []; + $fromLength = count($from); + $toLength = count($to); + $width = $fromLength + 1; + $matrix = new SplFixedArray($width * ($toLength + 1)); + for ($i = 0; $i <= $fromLength; $i++) { + $matrix[$i] = 0; + } + for ($j = 0; $j <= $toLength; $j++) { + $matrix[$j * $width] = 0; + } + for ($i = 1; $i <= $fromLength; $i++) { + for ($j = 1; $j <= $toLength; $j++) { + $o = $j * $width + $i; + // don't use max() to avoid function call overhead + $firstOrLast = $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0; + if ($matrix[$o - 1] > $matrix[$o - $width]) { + if ($firstOrLast > $matrix[$o - 1]) { + $matrix[$o] = $firstOrLast; + } else { + $matrix[$o] = $matrix[$o - 1]; + } + } else { + if ($firstOrLast > $matrix[$o - $width]) { + $matrix[$o] = $firstOrLast; + } else { + $matrix[$o] = $matrix[$o - $width]; + } + } + } + } + $i = $fromLength; + $j = $toLength; + while ($i > 0 && $j > 0) { + if ($from[$i - 1] === $to[$j - 1]) { + $common[] = $from[$i - 1]; + $i--; + $j--; + } else { + $o = $j * $width + $i; + if ($matrix[$o - $width] > $matrix[$o - 1]) { + $j--; + } else { + $i--; + } + } + } + return array_reverse($common); + } +} diff --git a/vendor/symfony/config/Builder/ClassBuilder.php b/vendor/symfony/config/Builder/ClassBuilder.php new file mode 100644 index 0000000000..41803c07c0 --- /dev/null +++ b/vendor/symfony/config/Builder/ClassBuilder.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder; + +/** + * Build PHP classes to generate config. + * + * @internal + * + * @author Tobias Nyholm + */ +class ClassBuilder +{ + /** + * @var string + */ + private $namespace; + /** + * @var string + */ + private $name; + /** @var Property[] */ + private $properties = []; + /** @var Method[] */ + private $methods = []; + /** + * @var mixed[] + */ + private $require = []; + /** + * @var mixed[] + */ + private $use = []; + /** + * @var mixed[] + */ + private $implements = []; + /** + * @var bool + */ + private $allowExtraKeys = \false; + public function __construct(string $namespace, string $name) + { + $this->namespace = $namespace; + $this->name = \ucfirst($this->camelCase($name)) . 'Config'; + } + public function getDirectory() : string + { + return \str_replace('\\', \DIRECTORY_SEPARATOR, $this->namespace); + } + public function getFilename() : string + { + return $this->name . '.php'; + } + public function build() : string + { + $rootPath = \explode(\DIRECTORY_SEPARATOR, $this->getDirectory()); + $require = ''; + foreach ($this->require as $class) { + // figure out relative path. + $path = \explode(\DIRECTORY_SEPARATOR, $class->getDirectory()); + $path[] = $class->getFilename(); + foreach ($rootPath as $key => $value) { + if ($path[$key] !== $value) { + break; + } + unset($path[$key]); + } + $require .= \sprintf('require_once __DIR__.\\DIRECTORY_SEPARATOR.\'%s\';', \implode('\'.\\DIRECTORY_SEPARATOR.\'', $path)) . "\n"; + } + $use = $require ? "\n" : ''; + foreach (\array_keys($this->use) as $statement) { + $use .= \sprintf('use %s;', $statement) . "\n"; + } + $implements = [] === $this->implements ? '' : 'implements ' . \implode(', ', $this->implements); + $body = ''; + foreach ($this->properties as $property) { + $body .= ' ' . $property->getContent() . "\n"; + } + foreach ($this->methods as $method) { + $lines = \explode("\n", $method->getContent()); + foreach ($lines as $line) { + $body .= ($line ? ' ' . $line : '') . "\n"; + } + } + $content = \strtr(' $this->namespace, 'REQUIRE' => $require, 'USE' => $use, 'CLASS' => $this->getName(), 'IMPLEMENTS' => $implements, 'BODY' => $body]); + return $content; + } + public function addRequire(self $class) : void + { + $this->require[] = $class; + } + public function addUse(string $class) : void + { + $this->use[$class] = \true; + } + public function addImplements(string $interface) : void + { + $this->implements[] = '\\' . \ltrim($interface, '\\'); + } + public function addMethod(string $name, string $body, array $params = []) : void + { + $this->methods[] = new Method(\strtr($body, ['NAME' => $this->camelCase($name)] + $params)); + } + public function addProperty(string $name, string $classType = null, string $defaultValue = null) : Property + { + $property = new Property($name, '_' !== $name[0] ? $this->camelCase($name) : $name); + if (null !== $classType) { + $property->setType($classType); + } + $this->properties[] = $property; + $defaultValue = null !== $defaultValue ? \sprintf(' = %s', $defaultValue) : ''; + $property->setContent(\sprintf('private $%s%s;', $property->getName(), $defaultValue)); + return $property; + } + public function getProperties() : array + { + return $this->properties; + } + private function camelCase(string $input) : string + { + $output = \lcfirst(\str_replace(' ', '', \ucwords(\str_replace('_', ' ', $input)))); + return \preg_replace('#\\W#', '', $output); + } + public function getName() : string + { + return $this->name; + } + public function getNamespace() : string + { + return $this->namespace; + } + public function getFqcn() : string + { + return '\\' . $this->namespace . '\\' . $this->name; + } + public function setAllowExtraKeys(bool $allowExtraKeys) : void + { + $this->allowExtraKeys = $allowExtraKeys; + } + public function shouldAllowExtraKeys() : bool + { + return $this->allowExtraKeys; + } +} diff --git a/vendor/symfony/config/Builder/ConfigBuilderGenerator.php b/vendor/symfony/config/Builder/ConfigBuilderGenerator.php new file mode 100644 index 0000000000..9a7aa05f90 --- /dev/null +++ b/vendor/symfony/config/Builder/ConfigBuilderGenerator.php @@ -0,0 +1,506 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ArrayNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BaseNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BooleanNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder\ExprBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\EnumNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\FloatNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\IntegerNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\NodeInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\PrototypedArrayNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\VariableNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\ParamConfigurator; +/** + * Generate ConfigBuilders to help create valid config. + * + * @author Tobias Nyholm + */ +class ConfigBuilderGenerator implements ConfigBuilderGeneratorInterface +{ + /** + * @var ClassBuilder[] + */ + private $classes = []; + /** + * @var string + */ + private $outputDir; + public function __construct(string $outputDir) + { + $this->outputDir = $outputDir; + } + /** + * @return \Closure that will return the root config class + */ + public function build(ConfigurationInterface $configuration) : \Closure + { + $this->classes = []; + $rootNode = $configuration->getConfigTreeBuilder()->buildTree(); + $rootClass = new ClassBuilder('MonorepoBuilderPrefix202310\\Symfony\\Config', $rootNode->getName()); + $path = $this->getFullPath($rootClass); + if (!\is_file($path)) { + // Generate the class if the file not exists + $this->classes[] = $rootClass; + $this->buildNode($rootNode, $rootClass, $this->getSubNamespace($rootClass)); + $rootClass->addImplements(ConfigBuilderInterface::class); + $rootClass->addMethod('getExtensionAlias', ' +public function NAME(): string +{ + return \'ALIAS\'; +}', ['ALIAS' => $rootNode->getPath()]); + $this->writeClasses(); + } + return function () use($path, $rootClass) { + require_once $path; + $className = $rootClass->getFqcn(); + return new $className(); + }; + } + private function getFullPath(ClassBuilder $class) : string + { + $directory = $this->outputDir . \DIRECTORY_SEPARATOR . $class->getDirectory(); + if (!\is_dir($directory)) { + @\mkdir($directory, 0777, \true); + } + return $directory . \DIRECTORY_SEPARATOR . $class->getFilename(); + } + private function writeClasses() : void + { + foreach ($this->classes as $class) { + $this->buildConstructor($class); + $this->buildToArray($class); + if ($class->getProperties()) { + $class->addProperty('_usedProperties', null, '[]'); + } + $this->buildSetExtraKey($class); + \file_put_contents($this->getFullPath($class), $class->build()); + } + $this->classes = []; + } + private function buildNode(NodeInterface $node, ClassBuilder $class, string $namespace) : void + { + if (!$node instanceof ArrayNode) { + throw new \LogicException('The node was expected to be an ArrayNode. This Configuration includes an edge case not supported yet.'); + } + foreach ($node->getChildren() as $child) { + switch (\true) { + case $child instanceof ScalarNode: + $this->handleScalarNode($child, $class); + break; + case $child instanceof PrototypedArrayNode: + $this->handlePrototypedArrayNode($child, $class, $namespace); + break; + case $child instanceof VariableNode: + $this->handleVariableNode($child, $class); + break; + case $child instanceof ArrayNode: + $this->handleArrayNode($child, $class, $namespace); + break; + default: + throw new \RuntimeException(\sprintf('Unknown node "%s".', \get_class($child))); + } + } + } + private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $namespace) : void + { + $childClass = new ClassBuilder($namespace, $node->getName()); + $childClass->setAllowExtraKeys($node->shouldIgnoreExtraKeys()); + $class->addRequire($childClass); + $this->classes[] = $childClass; + $hasNormalizationClosures = $this->hasNormalizationClosures($node); + $comment = $this->getComment($node); + if ($hasNormalizationClosures) { + $comment = \sprintf(" * @template TValue\n * @param TValue \$value\n%s", $comment); + $comment .= \sprintf(' * @return %s|$this' . "\n", $childClass->getFqcn()); + $comment .= \sprintf(' * @psalm-return (TValue is array ? %s : static)' . "\n ", $childClass->getFqcn()); + } + if ('' !== $comment) { + $comment = "/**\n{$comment}*/\n"; + } + $property = $class->addProperty($node->getName(), $this->getType($childClass->getFqcn(), $hasNormalizationClosures)); + $nodeTypes = $this->getParameterTypes($node); + $body = $hasNormalizationClosures ? ' +COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static +{ + if (!\\is_array($value)) { + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY = $value; + + return $this; + } + + if (!$this->PROPERTY instanceof CLASS) { + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY = new CLASS($value); + } elseif (0 < \\func_num_args()) { + throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\'); + } + + return $this->PROPERTY; +}' : ' +COMMENTpublic function NAME(array $value = []): CLASS +{ + if (null === $this->PROPERTY) { + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY = new CLASS($value); + } elseif (0 < \\func_num_args()) { + throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\'); + } + + return $this->PROPERTY; +}'; + $class->addUse(InvalidConfigurationException::class); + $class->addMethod($node->getName(), $body, ['COMMENT' => $comment, 'PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn(), 'PARAM_TYPE' => \in_array('mixed', $nodeTypes, \true) ? 'mixed' : \implode('|', $nodeTypes)]); + $this->buildNode($node, $childClass, $this->getSubNamespace($childClass)); + } + private function handleVariableNode(VariableNode $node, ClassBuilder $class) : void + { + $comment = $this->getComment($node); + $property = $class->addProperty($node->getName()); + $class->addUse(ParamConfigurator::class); + $body = ' +/** +COMMENT * + * @return $this + */ +public function NAME(mixed $valueDEFAULT): static +{ + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY = $value; + + return $this; +}'; + $class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'COMMENT' => $comment, 'DEFAULT' => $node->hasDefaultValue() ? ' = ' . \var_export($node->getDefaultValue(), \true) : '']); + } + private function handlePrototypedArrayNode(PrototypedArrayNode $node, ClassBuilder $class, string $namespace) : void + { + $name = $this->getSingularName($node); + $prototype = $node->getPrototype(); + $methodName = $name; + $hasNormalizationClosures = $this->hasNormalizationClosures($node) || $this->hasNormalizationClosures($prototype); + $nodeParameterTypes = $this->getParameterTypes($node); + $prototypeParameterTypes = $this->getParameterTypes($prototype); + if (!$prototype instanceof ArrayNode || $prototype instanceof PrototypedArrayNode && $prototype->getPrototype() instanceof ScalarNode) { + $class->addUse(ParamConfigurator::class); + $property = $class->addProperty($node->getName()); + if (null === ($key = $node->getKeyAttribute())) { + // This is an array of values; don't use singular name + $nodeTypesWithoutArray = \array_filter($nodeParameterTypes, static function ($type) { + return 'array' !== $type; + }); + $body = ' +/** + * @param ParamConfigurator|listEXTRA_TYPE $value + * + * @return $this + */ +public function NAME(PARAM_TYPE $value): static +{ + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY = $value; + + return $this; +}'; + $class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'PROTOTYPE_TYPE' => \implode('|', $prototypeParameterTypes), 'EXTRA_TYPE' => $nodeTypesWithoutArray ? '|' . \implode('|', $nodeTypesWithoutArray) : '', 'PARAM_TYPE' => \in_array('mixed', $nodeParameterTypes, \true) ? 'mixed' : 'ParamConfigurator|' . \implode('|', $nodeParameterTypes)]); + } else { + $body = ' +/** + * @return $this + */ +public function NAME(string $VAR, TYPE $VALUE): static +{ + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY[$VAR] = $VALUE; + + return $this; +}'; + $class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'TYPE' => \in_array('mixed', $prototypeParameterTypes, \true) ? 'mixed' : 'ParamConfigurator|' . \implode('|', $prototypeParameterTypes), 'VAR' => '' === $key ? 'key' : $key, 'VALUE' => 'value' === $key ? 'data' : 'value']); + } + return; + } + $childClass = new ClassBuilder($namespace, $name); + if ($prototype instanceof ArrayNode) { + $childClass->setAllowExtraKeys($prototype->shouldIgnoreExtraKeys()); + } + $class->addRequire($childClass); + $this->classes[] = $childClass; + $property = $class->addProperty($node->getName(), $this->getType($childClass->getFqcn() . '[]', $hasNormalizationClosures)); + $comment = $this->getComment($node); + if ($hasNormalizationClosures) { + $comment = \sprintf(" * @template TValue\n * @param TValue \$value\n%s", $comment); + $comment .= \sprintf(' * @return %s|$this' . "\n", $childClass->getFqcn()); + $comment .= \sprintf(' * @psalm-return (TValue is array ? %s : static)' . "\n ", $childClass->getFqcn()); + } + if ('' !== $comment) { + $comment = "/**\n{$comment}*/\n"; + } + if (null === ($key = $node->getKeyAttribute())) { + $body = $hasNormalizationClosures ? ' +COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static +{ + $this->_usedProperties[\'PROPERTY\'] = true; + if (!\\is_array($value)) { + $this->PROPERTY[] = $value; + + return $this; + } + + return $this->PROPERTY[] = new CLASS($value); +}' : ' +COMMENTpublic function NAME(array $value = []): CLASS +{ + $this->_usedProperties[\'PROPERTY\'] = true; + + return $this->PROPERTY[] = new CLASS($value); +}'; + $class->addMethod($methodName, $body, ['COMMENT' => $comment, 'PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn(), 'PARAM_TYPE' => \in_array('mixed', $nodeParameterTypes, \true) ? 'mixed' : \implode('|', $nodeParameterTypes)]); + } else { + $body = $hasNormalizationClosures ? ' +COMMENTpublic function NAME(string $VAR, PARAM_TYPE $VALUE = []): CLASS|static +{ + if (!\\is_array($VALUE)) { + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY[$VAR] = $VALUE; + + return $this; + } + + if (!isset($this->PROPERTY[$VAR]) || !$this->PROPERTY[$VAR] instanceof CLASS) { + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY[$VAR] = new CLASS($VALUE); + } elseif (1 < \\func_num_args()) { + throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\'); + } + + return $this->PROPERTY[$VAR]; +}' : ' +COMMENTpublic function NAME(string $VAR, array $VALUE = []): CLASS +{ + if (!isset($this->PROPERTY[$VAR])) { + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY[$VAR] = new CLASS($VALUE); + } elseif (1 < \\func_num_args()) { + throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\'); + } + + return $this->PROPERTY[$VAR]; +}'; + $class->addUse(InvalidConfigurationException::class); + $class->addMethod($methodName, \str_replace('$value', '$VAR', $body), ['COMMENT' => $comment, 'PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn(), 'VAR' => '' === $key ? 'key' : $key, 'VALUE' => 'value' === $key ? 'data' : 'value', 'PARAM_TYPE' => \in_array('mixed', $prototypeParameterTypes, \true) ? 'mixed' : \implode('|', $prototypeParameterTypes)]); + } + $this->buildNode($prototype, $childClass, $namespace . '\\' . $childClass->getName()); + } + private function handleScalarNode(ScalarNode $node, ClassBuilder $class) : void + { + $comment = $this->getComment($node); + $property = $class->addProperty($node->getName()); + $class->addUse(ParamConfigurator::class); + $body = ' +/** +COMMENT * @return $this + */ +public function NAME($value): static +{ + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY = $value; + + return $this; +}'; + $class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'COMMENT' => $comment]); + } + private function getParameterTypes(NodeInterface $node) : array + { + $paramTypes = []; + if ($node instanceof BaseNode) { + $types = $node->getNormalizedTypes(); + if (\in_array(ExprBuilder::TYPE_ANY, $types, \true)) { + $paramTypes[] = 'mixed'; + } + if (\in_array(ExprBuilder::TYPE_STRING, $types, \true)) { + $paramTypes[] = 'string'; + } + } + if ($node instanceof BooleanNode) { + $paramTypes[] = 'bool'; + } elseif ($node instanceof IntegerNode) { + $paramTypes[] = 'int'; + } elseif ($node instanceof FloatNode) { + $paramTypes[] = 'float'; + } elseif ($node instanceof EnumNode) { + $paramTypes[] = 'mixed'; + } elseif ($node instanceof ArrayNode) { + $paramTypes[] = 'array'; + } elseif ($node instanceof VariableNode) { + $paramTypes[] = 'mixed'; + } + return \array_unique($paramTypes); + } + private function getComment(BaseNode $node) : string + { + $comment = ''; + if ('' !== ($info = (string) $node->getInfo())) { + $comment .= ' * ' . $info . "\n"; + } + if (!$node instanceof ArrayNode) { + foreach ((array) ($node->getExample() ?? []) as $example) { + $comment .= ' * @example ' . $example . "\n"; + } + if ('' !== ($default = $node->getDefaultValue())) { + $comment .= ' * @default ' . (null === $default ? 'null' : \var_export($default, \true)) . "\n"; + } + if ($node instanceof EnumNode) { + $comment .= \sprintf(' * @param ParamConfigurator|%s $value', \implode('|', \array_unique(\array_map(function ($a) { + return !$a instanceof \UnitEnum ? \var_export($a, \true) : '\\' . \ltrim(\var_export($a, \true), '\\'); + }, $node->getValues())))) . "\n"; + } else { + $parameterTypes = $this->getParameterTypes($node); + $comment .= ' * @param ParamConfigurator|' . \implode('|', $parameterTypes) . ' $value' . "\n"; + } + } else { + foreach ((array) ($node->getExample() ?? []) as $example) { + $comment .= ' * @example ' . \json_encode($example) . "\n"; + } + if ($node->hasDefaultValue() && [] != ($default = $node->getDefaultValue())) { + $comment .= ' * @default ' . \json_encode($default) . "\n"; + } + } + if ($node->isDeprecated()) { + $comment .= ' * @deprecated ' . $node->getDeprecation($node->getName(), $node->getParent()->getName())['message'] . "\n"; + } + return $comment; + } + /** + * Pick a good singular name. + */ + private function getSingularName(PrototypedArrayNode $node) : string + { + $name = $node->getName(); + if (\substr_compare($name, 's', -\strlen('s')) !== 0) { + return $name; + } + $parent = $node->getParent(); + $mappings = $parent instanceof ArrayNode ? $parent->getXmlRemappings() : []; + foreach ($mappings as $map) { + if ($map[1] === $name) { + $name = $map[0]; + break; + } + } + return $name; + } + private function buildToArray(ClassBuilder $class) : void + { + $body = '$output = [];'; + foreach ($class->getProperties() as $p) { + $code = '$this->PROPERTY'; + if (null !== $p->getType()) { + if ($p->isArray()) { + $code = $p->areScalarsAllowed() ? 'array_map(function ($v) { return $v instanceof CLASS ? $v->toArray() : $v; }, $this->PROPERTY)' : 'array_map(function ($v) { return $v->toArray(); }, $this->PROPERTY)'; + } else { + $code = $p->areScalarsAllowed() ? '$this->PROPERTY instanceof CLASS ? $this->PROPERTY->toArray() : $this->PROPERTY' : '$this->PROPERTY->toArray()'; + } + } + $body .= \strtr(' + if (isset($this->_usedProperties[\'PROPERTY\'])) { + $output[\'ORG_NAME\'] = ' . $code . '; + }', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName(), 'CLASS' => $p->getType()]); + } + $extraKeys = $class->shouldAllowExtraKeys() ? ' + $this->_extraKeys' : ''; + $class->addMethod('toArray', ' +public function NAME(): array +{ + ' . $body . ' + + return $output' . $extraKeys . '; +}'); + } + private function buildConstructor(ClassBuilder $class) : void + { + $body = ''; + foreach ($class->getProperties() as $p) { + $code = '$value[\'ORG_NAME\']'; + if (null !== $p->getType()) { + if ($p->isArray()) { + $code = $p->areScalarsAllowed() ? 'array_map(function ($v) { return \\is_array($v) ? new ' . $p->getType() . '($v) : $v; }, $value[\'ORG_NAME\'])' : 'array_map(function ($v) { return new ' . $p->getType() . '($v); }, $value[\'ORG_NAME\'])'; + } else { + $code = $p->areScalarsAllowed() ? '\\is_array($value[\'ORG_NAME\']) ? new ' . $p->getType() . '($value[\'ORG_NAME\']) : $value[\'ORG_NAME\']' : 'new ' . $p->getType() . '($value[\'ORG_NAME\'])'; + } + } + $body .= \strtr(' + if (array_key_exists(\'ORG_NAME\', $value)) { + $this->_usedProperties[\'PROPERTY\'] = true; + $this->PROPERTY = ' . $code . '; + unset($value[\'ORG_NAME\']); + } +', ['PROPERTY' => $p->getName(), 'ORG_NAME' => $p->getOriginalName()]); + } + if ($class->shouldAllowExtraKeys()) { + $body .= ' + $this->_extraKeys = $value; +'; + } else { + $body .= ' + if ([] !== $value) { + throw new InvalidConfigurationException(sprintf(\'The following keys are not supported by "%s": \', __CLASS__).implode(\', \', array_keys($value))); + }'; + $class->addUse(InvalidConfigurationException::class); + } + $class->addMethod('__construct', ' +public function __construct(array $value = []) +{' . $body . ' +}'); + } + private function buildSetExtraKey(ClassBuilder $class) : void + { + if (!$class->shouldAllowExtraKeys()) { + return; + } + $class->addUse(ParamConfigurator::class); + $class->addProperty('_extraKeys'); + $class->addMethod('set', ' +/** + * @param ParamConfigurator|mixed $value + * + * @return $this + */ +public function NAME(string $key, mixed $value): static +{ + $this->_extraKeys[$key] = $value; + + return $this; +}'); + } + private function getSubNamespace(ClassBuilder $rootClass) : string + { + return \sprintf('%s\\%s', $rootClass->getNamespace(), \substr($rootClass->getName(), 0, -6)); + } + private function hasNormalizationClosures(NodeInterface $node) : bool + { + try { + $r = new \ReflectionProperty($node, 'normalizationClosures'); + $r->setAccessible(\true); + } catch (\ReflectionException $exception) { + return \false; + } + $r->setAccessible(\true); + return [] !== $r->getValue($node); + } + private function getType(string $classType, bool $hasNormalizationClosures) : string + { + return $classType . ($hasNormalizationClosures ? '|scalar' : ''); + } +} diff --git a/vendor/symfony/config/Builder/ConfigBuilderGeneratorInterface.php b/vendor/symfony/config/Builder/ConfigBuilderGeneratorInterface.php new file mode 100644 index 0000000000..68e8774abc --- /dev/null +++ b/vendor/symfony/config/Builder/ConfigBuilderGeneratorInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +/** + * Generates ConfigBuilders to help create valid config. + * + * @author Tobias Nyholm + */ +interface ConfigBuilderGeneratorInterface +{ + /** + * @return \Closure that will return the root config class + */ + public function build(ConfigurationInterface $configuration) : \Closure; +} diff --git a/vendor/symfony/config/Builder/ConfigBuilderInterface.php b/vendor/symfony/config/Builder/ConfigBuilderInterface.php new file mode 100644 index 0000000000..44be23cd3b --- /dev/null +++ b/vendor/symfony/config/Builder/ConfigBuilderInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder; + +/** + * A ConfigBuilder provides helper methods to build a large complex array. + * + * @author Tobias Nyholm + */ +interface ConfigBuilderInterface +{ + /** + * Gets all configuration represented as an array. + */ + public function toArray() : array; + /** + * Gets the alias for the extension which config we are building. + */ + public function getExtensionAlias() : string; +} diff --git a/vendor/symfony/config/Builder/Method.php b/vendor/symfony/config/Builder/Method.php new file mode 100644 index 0000000000..dd13ac07ba --- /dev/null +++ b/vendor/symfony/config/Builder/Method.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder; + +/** + * Represents a method when building classes. + * + * @internal + * + * @author Tobias Nyholm + */ +class Method +{ + /** + * @var string + */ + private $content; + public function __construct(string $content) + { + $this->content = $content; + } + public function getContent() : string + { + return $this->content; + } +} diff --git a/vendor/symfony/config/Builder/Property.php b/vendor/symfony/config/Builder/Property.php new file mode 100644 index 0000000000..a91f681ee2 --- /dev/null +++ b/vendor/symfony/config/Builder/Property.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder; + +/** + * Represents a property when building classes. + * + * @internal + * + * @author Tobias Nyholm + */ +class Property +{ + /** + * @var string + */ + private $name; + /** + * @var string + */ + private $originalName; + /** + * @var bool + */ + private $array = \false; + /** + * @var bool + */ + private $scalarsAllowed = \false; + /** + * @var string|null + */ + private $type; + /** + * @var string|null + */ + private $content; + public function __construct(string $originalName, string $name) + { + $this->name = $name; + $this->originalName = $originalName; + } + public function getName() : string + { + return $this->name; + } + public function getOriginalName() : string + { + return $this->originalName; + } + public function setType(string $type) : void + { + $this->array = \false; + $this->type = $type; + if (\substr_compare($type, '|scalar', -\strlen('|scalar')) === 0) { + $this->scalarsAllowed = \true; + $this->type = $type = \substr($type, 0, -7); + } + if (\substr_compare($type, '[]', -\strlen('[]')) === 0) { + $this->array = \true; + $this->type = \substr($type, 0, -2); + } + } + public function getType() : ?string + { + return $this->type; + } + public function getContent() : ?string + { + return $this->content; + } + public function setContent(string $content) : void + { + $this->content = $content; + } + public function isArray() : bool + { + return $this->array; + } + public function areScalarsAllowed() : bool + { + return $this->scalarsAllowed; + } +} diff --git a/vendor/symfony/config/CHANGELOG.md b/vendor/symfony/config/CHANGELOG.md new file mode 100644 index 0000000000..094d5abba0 --- /dev/null +++ b/vendor/symfony/config/CHANGELOG.md @@ -0,0 +1,153 @@ +CHANGELOG +========= + +6.3 +--- + + * Allow enum values in `EnumNode` + +6.2 +--- + + * Deprecate calling `NodeBuilder::setParent()` without any arguments + * Add a more accurate typehint in generated PHP config + +6.1 +--- + + * Allow using environment variables in `EnumNode` + * Add Node's information in generated Config + * Add `DefinitionFileLoader` class to load a TreeBuilder definition from an external file + * Add `DefinitionConfigurator` helper + +6.0 +--- + + * Remove `BaseNode::getDeprecationMessage()` + +5.3.0 +----- + + * Add support for generating `ConfigBuilder` for extensions + +5.1.0 +----- + + * updated the signature of method `NodeDefinition::setDeprecated()` to `NodeDefinition::setDeprecation(string $package, string $version, string $message)` + * updated the signature of method `BaseNode::setDeprecated()` to `BaseNode::setDeprecation(string $package, string $version, string $message)` + * deprecated passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node + * deprecated `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead + +5.0.0 +----- + + * Dropped support for constructing a `TreeBuilder` without passing root node information. + * Removed the `root()` method in `TreeBuilder`, pass the root node information to the constructor instead + * Added method `getChildNodeDefinitions()` to ParentNodeDefinitionInterface + * Removed `FileLoaderLoadException`, use `LoaderLoadException` instead + +4.4.0 +----- + + * added a way to exclude patterns of resources from being imported by the `import()` method + +4.3.0 +----- + + * deprecated using environment variables with `cannotBeEmpty()` if the value is validated with `validate()` + * made `Resource\*` classes final and not implement `Serializable` anymore + * deprecated the `root()` method in `TreeBuilder`, pass the root node information to the constructor instead + +4.2.0 +----- + + * deprecated constructing a `TreeBuilder` without passing root node information + * renamed `FileLoaderLoadException` to `LoaderLoadException` + +4.1.0 +----- + + * added `setPathSeparator` method to `NodeBuilder` class + * added third `$pathSeparator` constructor argument to `BaseNode` + * the `Processor` class has been made final + +4.0.0 +----- + + * removed `ConfigCachePass` + +3.4.0 +----- + + * added `setDeprecated()` method to indicate a deprecated node + * added `XmlUtils::parse()` method to parse an XML string + * deprecated `ConfigCachePass` + +3.3.0 +----- + + * added `ReflectionClassResource` class + * added second `$exists` constructor argument to `ClassExistenceResource` + * made `ClassExistenceResource` work with interfaces and traits + * added `ConfigCachePass` (originally in FrameworkBundle) + * added `castToArray()` helper to turn any config value into an array + +3.0.0 +----- + + * removed `ReferenceDumper` class + * removed the `ResourceInterface::isFresh()` method + * removed `BCResourceInterfaceChecker` class + * removed `ResourceInterface::getResource()` method + +2.8.0 +----- + +The edge case of defining just one value for nodes of type Enum is now allowed: + +```php +$rootNode + ->children() + ->enumNode('variable') + ->values(['value']) + ->end() + ->end() +; +``` + +Before: `InvalidArgumentException` (variable must contain at least two +distinct elements). +After: the code will work as expected and it will restrict the values of the +`variable` option to just `value`. + + * deprecated the `ResourceInterface::isFresh()` method. If you implement custom resource types and they + can be validated that way, make them implement the new `SelfCheckingResourceInterface`. + * deprecated the getResource() method in ResourceInterface. You can still call this method + on concrete classes implementing the interface, but it does not make sense at the interface + level as you need to know about the particular type of resource at hand to understand the + semantics of the returned value. + +2.7.0 +----- + + * added `ConfigCacheInterface`, `ConfigCacheFactoryInterface` and a basic `ConfigCacheFactory` + implementation to delegate creation of ConfigCache instances + +2.2.0 +----- + + * added `ArrayNodeDefinition::canBeEnabled()` and `ArrayNodeDefinition::canBeDisabled()` + to ease configuration when some sections are respectively disabled / enabled + by default. + * added a `normalizeKeys()` method for array nodes (to avoid key normalization) + * added numerical type handling for config definitions + * added convenience methods for optional configuration sections to `ArrayNodeDefinition` + * added a utils class for XML manipulations + +2.1.0 +----- + + * added a way to add documentation on configuration + * implemented `Serializable` on resources + * `LoaderResolverInterface` is now used instead of `LoaderResolver` for type + hinting diff --git a/vendor/symfony/config/ConfigCache.php b/vendor/symfony/config/ConfigCache.php new file mode 100644 index 0000000000..af8de0bab9 --- /dev/null +++ b/vendor/symfony/config/ConfigCache.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\SelfCheckingResourceChecker; +/** + * ConfigCache caches arbitrary content in files on disk. + * + * When in debug mode, those metadata resources that implement + * \Symfony\Component\Config\Resource\SelfCheckingResourceInterface will + * be used to check cache freshness. + * + * @author Fabien Potencier + * @author Matthias Pigulla + */ +class ConfigCache extends ResourceCheckerConfigCache +{ + /** + * @var bool + */ + private $debug; + /** + * @param string $file The absolute cache path + * @param bool $debug Whether debugging is enabled or not + */ + public function __construct(string $file, bool $debug) + { + $this->debug = $debug; + $checkers = []; + if (\true === $this->debug) { + $checkers = [new SelfCheckingResourceChecker()]; + } + parent::__construct($file, $checkers); + } + /** + * Checks if the cache is still fresh. + * + * This implementation always returns true when debug is off and the + * cache file exists. + */ + public function isFresh() : bool + { + if (!$this->debug && \is_file($this->getPath())) { + return \true; + } + return parent::isFresh(); + } +} diff --git a/vendor/symfony/config/ConfigCacheFactory.php b/vendor/symfony/config/ConfigCacheFactory.php new file mode 100644 index 0000000000..6ecb1d8419 --- /dev/null +++ b/vendor/symfony/config/ConfigCacheFactory.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +/** + * Basic implementation of ConfigCacheFactoryInterface that + * creates an instance of the default ConfigCache. + * + * This factory and/or cache do not support cache validation + * by means of ResourceChecker instances (that is, service-based). + * + * @author Matthias Pigulla + */ +class ConfigCacheFactory implements ConfigCacheFactoryInterface +{ + /** + * @var bool + */ + private $debug; + /** + * @param bool $debug The debug flag to pass to ConfigCache + */ + public function __construct(bool $debug) + { + $this->debug = $debug; + } + public function cache(string $file, callable $callback) : ConfigCacheInterface + { + $cache = new ConfigCache($file, $this->debug); + if (!$cache->isFresh()) { + $callback($cache); + } + return $cache; + } +} diff --git a/vendor/symfony/config/ConfigCacheFactoryInterface.php b/vendor/symfony/config/ConfigCacheFactoryInterface.php new file mode 100644 index 0000000000..733392fb41 --- /dev/null +++ b/vendor/symfony/config/ConfigCacheFactoryInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +/** + * Interface for a ConfigCache factory. This factory creates + * an instance of ConfigCacheInterface and initializes the + * cache if necessary. + * + * @author Matthias Pigulla + */ +interface ConfigCacheFactoryInterface +{ + /** + * Creates a cache instance and (re-)initializes it if necessary. + * + * @param string $file The absolute cache file path + * @param callable $callable The callable to be executed when the cache needs to be filled (i. e. is not fresh). The cache will be passed as the only parameter to this callback + */ + public function cache(string $file, callable $callable) : ConfigCacheInterface; +} diff --git a/vendor/symfony/config/ConfigCacheInterface.php b/vendor/symfony/config/ConfigCacheInterface.php new file mode 100644 index 0000000000..77596ed004 --- /dev/null +++ b/vendor/symfony/config/ConfigCacheInterface.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ResourceInterface; +/** + * Interface for ConfigCache. + * + * @author Matthias Pigulla + */ +interface ConfigCacheInterface +{ + /** + * Gets the cache file path. + */ + public function getPath() : string; + /** + * Checks if the cache is still fresh. + * + * This check should take the metadata passed to the write() method into consideration. + */ + public function isFresh() : bool; + /** + * Writes the given content into the cache file. Metadata will be stored + * independently and can be used to check cache freshness at a later time. + * + * @param string $content The content to write into the cache + * @param ResourceInterface[]|null $metadata An array of ResourceInterface instances + * + * @return void + * + * @throws \RuntimeException When the cache file cannot be written + */ + public function write(string $content, array $metadata = null); +} diff --git a/vendor/symfony/config/Definition/ArrayNode.php b/vendor/symfony/config/Definition/ArrayNode.php new file mode 100644 index 0000000000..4c9fdd369d --- /dev/null +++ b/vendor/symfony/config/Definition/ArrayNode.php @@ -0,0 +1,359 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidTypeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\UnsetKeyException; +/** + * Represents an Array node in the config tree. + * + * @author Johannes M. Schmitt + */ +class ArrayNode extends BaseNode implements PrototypeNodeInterface +{ + protected $xmlRemappings = []; + protected $children = []; + protected $allowFalse = \false; + protected $allowNewKeys = \true; + protected $addIfNotSet = \false; + protected $performDeepMerging = \true; + protected $ignoreExtraKeys = \false; + protected $removeExtraKeys = \true; + protected $normalizeKeys = \true; + /** + * @return void + */ + public function setNormalizeKeys(bool $normalizeKeys) + { + $this->normalizeKeys = $normalizeKeys; + } + /** + * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML. + * After running this method, all keys are normalized to foo_bar. + * + * If you have a mixed key like foo-bar_moo, it will not be altered. + * The key will also not be altered if the target key already exists. + * @param mixed $value + * @return mixed + */ + protected function preNormalize($value) + { + if (!$this->normalizeKeys || !\is_array($value)) { + return $value; + } + $normalized = []; + foreach ($value as $k => $v) { + if (\strpos($k, '-') !== \false && \strpos($k, '_') === \false && !\array_key_exists($normalizedKey = \str_replace('-', '_', $k), $value)) { + $normalized[$normalizedKey] = $v; + } else { + $normalized[$k] = $v; + } + } + return $normalized; + } + /** + * Retrieves the children of this node. + * + * @return array + */ + public function getChildren() : array + { + return $this->children; + } + /** + * Sets the xml remappings that should be performed. + * + * @param array $remappings An array of the form [[string, string]] + * + * @return void + */ + public function setXmlRemappings(array $remappings) + { + $this->xmlRemappings = $remappings; + } + /** + * Gets the xml remappings that should be performed. + * + * @return array an array of the form [[string, string]] + */ + public function getXmlRemappings() : array + { + return $this->xmlRemappings; + } + /** + * Sets whether to add default values for this array if it has not been + * defined in any of the configuration files. + * + * @return void + */ + public function setAddIfNotSet(bool $boolean) + { + $this->addIfNotSet = $boolean; + } + /** + * Sets whether false is allowed as value indicating that the array should be unset. + * + * @return void + */ + public function setAllowFalse(bool $allow) + { + $this->allowFalse = $allow; + } + /** + * Sets whether new keys can be defined in subsequent configurations. + * + * @return void + */ + public function setAllowNewKeys(bool $allow) + { + $this->allowNewKeys = $allow; + } + /** + * Sets if deep merging should occur. + * + * @return void + */ + public function setPerformDeepMerging(bool $boolean) + { + $this->performDeepMerging = $boolean; + } + /** + * Whether extra keys should just be ignored without an exception. + * + * @param bool $boolean To allow extra keys + * @param bool $remove To remove extra keys + * + * @return void + */ + public function setIgnoreExtraKeys(bool $boolean, bool $remove = \true) + { + $this->ignoreExtraKeys = $boolean; + $this->removeExtraKeys = $this->ignoreExtraKeys && $remove; + } + /** + * Returns true when extra keys should be ignored without an exception. + */ + public function shouldIgnoreExtraKeys() : bool + { + return $this->ignoreExtraKeys; + } + /** + * @return void + */ + public function setName(string $name) + { + $this->name = $name; + } + public function hasDefaultValue() : bool + { + return $this->addIfNotSet; + } + /** + * @return mixed + */ + public function getDefaultValue() + { + if (!$this->hasDefaultValue()) { + throw new \RuntimeException(\sprintf('The node at path "%s" has no default value.', $this->getPath())); + } + $defaults = []; + foreach ($this->children as $name => $child) { + if ($child->hasDefaultValue()) { + $defaults[$name] = $child->getDefaultValue(); + } + } + return $defaults; + } + /** + * Adds a child node. + * + * @return void + * + * @throws \InvalidArgumentException when the child node has no name + * @throws \InvalidArgumentException when the child node's name is not unique + */ + public function addChild(NodeInterface $node) + { + $name = $node->getName(); + if ('' === $name) { + throw new \InvalidArgumentException('Child nodes must be named.'); + } + if (isset($this->children[$name])) { + throw new \InvalidArgumentException(\sprintf('A child node named "%s" already exists.', $name)); + } + $this->children[$name] = $node; + } + /** + * @throws UnsetKeyException + * @throws InvalidConfigurationException if the node doesn't have enough children + * @param mixed $value + * @return mixed + */ + protected function finalizeValue($value) + { + if (\false === $value) { + throw new UnsetKeyException(\sprintf('Unsetting key for path "%s", value: %s.', $this->getPath(), \json_encode($value))); + } + foreach ($this->children as $name => $child) { + if (!\array_key_exists($name, $value)) { + if ($child->isRequired()) { + $message = \sprintf('The child config "%s" under "%s" must be configured', $name, $this->getPath()); + if ($child->getInfo()) { + $message .= \sprintf(': %s', $child->getInfo()); + } else { + $message .= '.'; + } + $ex = new InvalidConfigurationException($message); + $ex->setPath($this->getPath()); + throw $ex; + } + if ($child->hasDefaultValue()) { + $value[$name] = $child->getDefaultValue(); + } + continue; + } + if ($child->isDeprecated()) { + $deprecation = $child->getDeprecation($name, $this->getPath()); + trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']); + } + try { + $value[$name] = $child->finalize($value[$name]); + } catch (UnsetKeyException $exception) { + unset($value[$name]); + } + } + return $value; + } + /** + * @return void + * @param mixed $value + */ + protected function validateType($value) + { + if (!\is_array($value) && (!$this->allowFalse || \false !== $value)) { + $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "array", but got "%s"', $this->getPath(), \get_debug_type($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + throw $ex; + } + } + /** + * @throws InvalidConfigurationException + * @param mixed $value + * @return mixed + */ + protected function normalizeValue($value) + { + if (\false === $value) { + return $value; + } + $value = $this->remapXml($value); + $normalized = []; + foreach ($value as $name => $val) { + if (isset($this->children[$name])) { + try { + $normalized[$name] = $this->children[$name]->normalize($val); + } catch (UnsetKeyException $exception) { + } + unset($value[$name]); + } elseif (!$this->removeExtraKeys) { + $normalized[$name] = $val; + } + } + // if extra fields are present, throw exception + if (\count($value) && !$this->ignoreExtraKeys) { + $proposals = \array_keys($this->children); + \sort($proposals); + $guesses = []; + foreach (\array_keys($value) as $subject) { + $minScore = \INF; + foreach ($proposals as $proposal) { + $distance = \levenshtein($subject, $proposal); + if ($distance <= $minScore && $distance < 3) { + $guesses[$proposal] = $distance; + $minScore = $distance; + } + } + } + $msg = \sprintf('Unrecognized option%s "%s" under "%s"', 1 === \count($value) ? '' : 's', \implode(', ', \array_keys($value)), $this->getPath()); + if (\count($guesses)) { + \asort($guesses); + $msg .= \sprintf('. Did you mean "%s"?', \implode('", "', \array_keys($guesses))); + } else { + $msg .= \sprintf('. Available option%s %s "%s".', 1 === \count($proposals) ? '' : 's', 1 === \count($proposals) ? 'is' : 'are', \implode('", "', $proposals)); + } + $ex = new InvalidConfigurationException($msg); + $ex->setPath($this->getPath()); + throw $ex; + } + return $normalized; + } + /** + * Remaps multiple singular values to a single plural value. + */ + protected function remapXml(array $value) : array + { + foreach ($this->xmlRemappings as [$singular, $plural]) { + if (!isset($value[$singular])) { + continue; + } + $value[$plural] = Processor::normalizeConfig($value, $singular, $plural); + unset($value[$singular]); + } + return $value; + } + /** + * @throws InvalidConfigurationException + * @throws \RuntimeException + * @param mixed $leftSide + * @param mixed $rightSide + * @return mixed + */ + protected function mergeValues($leftSide, $rightSide) + { + if (\false === $rightSide) { + // if this is still false after the last config has been merged the + // finalization pass will take care of removing this key entirely + return \false; + } + if (\false === $leftSide || !$this->performDeepMerging) { + return $rightSide; + } + foreach ($rightSide as $k => $v) { + // no conflict + if (!\array_key_exists($k, $leftSide)) { + if (!$this->allowNewKeys) { + $ex = new InvalidConfigurationException(\sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file. If you are trying to overwrite an element, make sure you redefine it with the same name.', $this->getPath())); + $ex->setPath($this->getPath()); + throw $ex; + } + $leftSide[$k] = $v; + continue; + } + if (!isset($this->children[$k])) { + if (!$this->ignoreExtraKeys || $this->removeExtraKeys) { + throw new \RuntimeException('merge() expects a normalized config array.'); + } + $leftSide[$k] = $v; + continue; + } + $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v); + } + return $leftSide; + } + protected function allowPlaceholders() : bool + { + return \false; + } +} diff --git a/vendor/symfony/config/Definition/BaseNode.php b/vendor/symfony/config/Definition/BaseNode.php new file mode 100644 index 0000000000..9ae2ebc533 --- /dev/null +++ b/vendor/symfony/config/Definition/BaseNode.php @@ -0,0 +1,501 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\Exception; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidTypeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\UnsetKeyException; +/** + * The base node class. + * + * @author Johannes M. Schmitt + */ +abstract class BaseNode implements NodeInterface +{ + public const DEFAULT_PATH_SEPARATOR = '.'; + /** + * @var mixed[] + */ + private static $placeholderUniquePrefixes = []; + /** + * @var mixed[] + */ + private static $placeholders = []; + protected $name; + protected $parent; + protected $normalizationClosures = []; + protected $normalizedTypes = []; + protected $finalValidationClosures = []; + protected $allowOverwrite = \true; + protected $required = \false; + protected $deprecation = []; + protected $equivalentValues = []; + protected $attributes = []; + protected $pathSeparator; + /** + * @var mixed + */ + private $handlingPlaceholder = null; + /** + * @throws \InvalidArgumentException if the name contains a period + */ + public function __construct(?string $name, NodeInterface $parent = null, string $pathSeparator = self::DEFAULT_PATH_SEPARATOR) + { + if (\strpos($name = (string) $name, $pathSeparator) !== \false) { + throw new \InvalidArgumentException('The name must not contain ".' . $pathSeparator . '".'); + } + $this->name = $name; + $this->parent = $parent; + $this->pathSeparator = $pathSeparator; + } + /** + * Register possible (dummy) values for a dynamic placeholder value. + * + * Matching configuration values will be processed with a provided value, one by one. After a provided value is + * successfully processed the configuration value is returned as is, thus preserving the placeholder. + * + * @internal + */ + public static function setPlaceholder(string $placeholder, array $values) : void + { + if (!$values) { + throw new \InvalidArgumentException('At least one value must be provided.'); + } + self::$placeholders[$placeholder] = $values; + } + /** + * Adds a common prefix for dynamic placeholder values. + * + * Matching configuration values will be skipped from being processed and are returned as is, thus preserving the + * placeholder. An exact match provided by {@see setPlaceholder()} might take precedence. + * + * @internal + */ + public static function setPlaceholderUniquePrefix(string $prefix) : void + { + self::$placeholderUniquePrefixes[] = $prefix; + } + /** + * Resets all current placeholders available. + * + * @internal + */ + public static function resetPlaceholders() : void + { + self::$placeholderUniquePrefixes = []; + self::$placeholders = []; + } + /** + * @return void + * @param mixed $value + */ + public function setAttribute(string $key, $value) + { + $this->attributes[$key] = $value; + } + /** + * @param mixed $default + * @return mixed + */ + public function getAttribute(string $key, $default = null) + { + return $this->attributes[$key] ?? $default; + } + public function hasAttribute(string $key) : bool + { + return isset($this->attributes[$key]); + } + public function getAttributes() : array + { + return $this->attributes; + } + /** + * @return void + */ + public function setAttributes(array $attributes) + { + $this->attributes = $attributes; + } + /** + * @return void + */ + public function removeAttribute(string $key) + { + unset($this->attributes[$key]); + } + /** + * Sets an info message. + * + * @return void + */ + public function setInfo(string $info) + { + $this->setAttribute('info', $info); + } + /** + * Returns info message. + */ + public function getInfo() : ?string + { + return $this->getAttribute('info'); + } + /** + * Sets the example configuration for this node. + * + * @return void + * @param string|mixed[] $example + */ + public function setExample($example) + { + $this->setAttribute('example', $example); + } + /** + * Retrieves the example configuration for this node. + * @return string|mixed[]|null + */ + public function getExample() + { + return $this->getAttribute('example'); + } + /** + * Adds an equivalent value. + * + * @return void + * @param mixed $originalValue + * @param mixed $equivalentValue + */ + public function addEquivalentValue($originalValue, $equivalentValue) + { + $this->equivalentValues[] = [$originalValue, $equivalentValue]; + } + /** + * Set this node as required. + * + * @return void + */ + public function setRequired(bool $boolean) + { + $this->required = $boolean; + } + /** + * Sets this node as deprecated. + * + * You can use %node% and %path% placeholders in your message to display, + * respectively, the node name and its complete path. + * + * @param string $package The name of the composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message the deprecation message to use + * + * @return void + */ + public function setDeprecated(string $package, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.') + { + $this->deprecation = ['package' => $package, 'version' => $version, 'message' => $message]; + } + /** + * Sets if this node can be overridden. + * + * @return void + */ + public function setAllowOverwrite(bool $allow) + { + $this->allowOverwrite = $allow; + } + /** + * Sets the closures used for normalization. + * + * @param \Closure[] $closures An array of Closures used for normalization + * + * @return void + */ + public function setNormalizationClosures(array $closures) + { + $this->normalizationClosures = $closures; + } + /** + * Sets the list of types supported by normalization. + * + * see ExprBuilder::TYPE_* constants. + * + * @return void + */ + public function setNormalizedTypes(array $types) + { + $this->normalizedTypes = $types; + } + /** + * Gets the list of types supported by normalization. + * + * see ExprBuilder::TYPE_* constants. + */ + public function getNormalizedTypes() : array + { + return $this->normalizedTypes; + } + /** + * Sets the closures used for final validation. + * + * @param \Closure[] $closures An array of Closures used for final validation + * + * @return void + */ + public function setFinalValidationClosures(array $closures) + { + $this->finalValidationClosures = $closures; + } + public function isRequired() : bool + { + return $this->required; + } + /** + * Checks if this node is deprecated. + */ + public function isDeprecated() : bool + { + return (bool) $this->deprecation; + } + /** + * @param string $node The configuration node name + * @param string $path The path of the node + */ + public function getDeprecation(string $node, string $path) : array + { + return ['package' => $this->deprecation['package'], 'version' => $this->deprecation['version'], 'message' => \strtr($this->deprecation['message'], ['%node%' => $node, '%path%' => $path])]; + } + public function getName() : string + { + return $this->name; + } + public function getPath() : string + { + if (null !== $this->parent) { + return $this->parent->getPath() . $this->pathSeparator . $this->name; + } + return $this->name; + } + /** + * @param mixed $leftSide + * @param mixed $rightSide + * @return mixed + */ + public final function merge($leftSide, $rightSide) + { + if (!$this->allowOverwrite) { + throw new ForbiddenOverwriteException(\sprintf('Configuration path "%s" cannot be overwritten. You have to define all options for this path, and any of its sub-paths in one configuration section.', $this->getPath())); + } + if ($leftSide !== ($leftPlaceholders = self::resolvePlaceholderValue($leftSide))) { + foreach ($leftPlaceholders as $leftPlaceholder) { + $this->handlingPlaceholder = $leftSide; + try { + $this->merge($leftPlaceholder, $rightSide); + } finally { + $this->handlingPlaceholder = null; + } + } + return $rightSide; + } + if ($rightSide !== ($rightPlaceholders = self::resolvePlaceholderValue($rightSide))) { + foreach ($rightPlaceholders as $rightPlaceholder) { + $this->handlingPlaceholder = $rightSide; + try { + $this->merge($leftSide, $rightPlaceholder); + } finally { + $this->handlingPlaceholder = null; + } + } + return $rightSide; + } + $this->doValidateType($leftSide); + $this->doValidateType($rightSide); + return $this->mergeValues($leftSide, $rightSide); + } + /** + * @param mixed $value + * @return mixed + */ + public final function normalize($value) + { + $value = $this->preNormalize($value); + // run custom normalization closures + foreach ($this->normalizationClosures as $closure) { + $value = $closure($value); + } + // resolve placeholder value + if ($value !== ($placeholders = self::resolvePlaceholderValue($value))) { + foreach ($placeholders as $placeholder) { + $this->handlingPlaceholder = $value; + try { + $this->normalize($placeholder); + } finally { + $this->handlingPlaceholder = null; + } + } + return $value; + } + // replace value with their equivalent + foreach ($this->equivalentValues as $data) { + if ($data[0] === $value) { + $value = $data[1]; + } + } + // validate type + $this->doValidateType($value); + // normalize value + return $this->normalizeValue($value); + } + /** + * Normalizes the value before any other normalization is applied. + * @param mixed $value + * @return mixed + */ + protected function preNormalize($value) + { + return $value; + } + /** + * Returns parent node for this node. + */ + public function getParent() : ?NodeInterface + { + return $this->parent; + } + /** + * @param mixed $value + * @return mixed + */ + public final function finalize($value) + { + if ($value !== ($placeholders = self::resolvePlaceholderValue($value))) { + foreach ($placeholders as $placeholder) { + $this->handlingPlaceholder = $value; + try { + $this->finalize($placeholder); + } finally { + $this->handlingPlaceholder = null; + } + } + return $value; + } + $this->doValidateType($value); + $value = $this->finalizeValue($value); + // Perform validation on the final value if a closure has been set. + // The closure is also allowed to return another value. + foreach ($this->finalValidationClosures as $closure) { + try { + $value = $closure($value); + } catch (Exception $e) { + if ($e instanceof UnsetKeyException && null !== $this->handlingPlaceholder) { + continue; + } + throw $e; + } catch (\Exception $e) { + throw new InvalidConfigurationException(\sprintf('Invalid configuration for path "%s": ', $this->getPath()) . $e->getMessage(), $e->getCode(), $e); + } + } + return $value; + } + /** + * Validates the type of a Node. + * + * @return void + * + * @throws InvalidTypeException when the value is invalid + * @param mixed $value + */ + protected abstract function validateType($value); + /** + * Normalizes the value. + * @param mixed $value + * @return mixed + */ + protected abstract function normalizeValue($value); + /** + * Merges two values together. + * @param mixed $leftSide + * @param mixed $rightSide + * @return mixed + */ + protected abstract function mergeValues($leftSide, $rightSide); + /** + * Finalizes a value. + * @param mixed $value + * @return mixed + */ + protected abstract function finalizeValue($value); + /** + * Tests if placeholder values are allowed for this node. + */ + protected function allowPlaceholders() : bool + { + return \true; + } + /** + * Tests if a placeholder is being handled currently. + */ + protected function isHandlingPlaceholder() : bool + { + return null !== $this->handlingPlaceholder; + } + /** + * Gets allowed dynamic types for this node. + */ + protected function getValidPlaceholderTypes() : array + { + return []; + } + /** + * @param mixed $value + * @return mixed + */ + private static function resolvePlaceholderValue($value) + { + if (\is_string($value)) { + if (isset(self::$placeholders[$value])) { + return self::$placeholders[$value]; + } + foreach (self::$placeholderUniquePrefixes as $placeholderUniquePrefix) { + if (\strncmp($value, $placeholderUniquePrefix, \strlen($placeholderUniquePrefix)) === 0) { + return []; + } + } + } + return $value; + } + /** + * @param mixed $value + */ + private function doValidateType($value) : void + { + if (null !== $this->handlingPlaceholder && !$this->allowPlaceholders()) { + $e = new InvalidTypeException(\sprintf('A dynamic value is not compatible with a "%s" node type at path "%s".', static::class, $this->getPath())); + $e->setPath($this->getPath()); + throw $e; + } + if (null === $this->handlingPlaceholder || null === $value) { + $this->validateType($value); + return; + } + $knownTypes = \array_keys(self::$placeholders[$this->handlingPlaceholder]); + $validTypes = $this->getValidPlaceholderTypes(); + if ($validTypes && \array_diff($knownTypes, $validTypes)) { + $e = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected %s, but got %s.', $this->getPath(), 1 === \count($validTypes) ? '"' . \reset($validTypes) . '"' : 'one of "' . \implode('", "', $validTypes) . '"', 1 === \count($knownTypes) ? '"' . \reset($knownTypes) . '"' : 'one of "' . \implode('", "', $knownTypes) . '"')); + if ($hint = $this->getInfo()) { + $e->addHint($hint); + } + $e->setPath($this->getPath()); + throw $e; + } + $this->validateType($value); + } +} diff --git a/vendor/symfony/config/Definition/BooleanNode.php b/vendor/symfony/config/Definition/BooleanNode.php new file mode 100644 index 0000000000..2504e822bc --- /dev/null +++ b/vendor/symfony/config/Definition/BooleanNode.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidTypeException; +/** + * This node represents a Boolean value in the config tree. + * + * @author Johannes M. Schmitt + */ +class BooleanNode extends ScalarNode +{ + /** + * @return void + * @param mixed $value + */ + protected function validateType($value) + { + if (!\is_bool($value)) { + $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "bool", but got "%s".', $this->getPath(), \get_debug_type($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + throw $ex; + } + } + /** + * @param mixed $value + */ + protected function isValueEmpty($value) : bool + { + // a boolean value cannot be empty + return \false; + } + protected function getValidPlaceholderTypes() : array + { + return ['bool']; + } +} diff --git a/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php b/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php new file mode 100644 index 0000000000..82760d02ba --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php @@ -0,0 +1,421 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ArrayNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\NodeInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\PrototypedArrayNode; +/** + * This class provides a fluent interface for defining an array node. + * + * @author Johannes M. Schmitt + */ +class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface +{ + protected $performDeepMerging = \true; + protected $ignoreExtraKeys = \false; + protected $removeExtraKeys = \true; + protected $children = []; + protected $prototype; + protected $atLeastOne = \false; + protected $allowNewKeys = \true; + protected $key; + protected $removeKeyItem; + protected $addDefaults = \false; + protected $addDefaultChildren = \false; + protected $nodeBuilder; + protected $normalizeKeys = \true; + public function __construct(?string $name, NodeParentInterface $parent = null) + { + parent::__construct($name, $parent); + $this->nullEquivalent = []; + $this->trueEquivalent = []; + } + /** + * @return void + */ + public function setBuilder(NodeBuilder $builder) + { + $this->nodeBuilder = $builder; + } + public function children() : NodeBuilder + { + return $this->getNodeBuilder(); + } + /** + * Sets a prototype for child nodes. + */ + public function prototype(string $type) : NodeDefinition + { + return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this); + } + public function variablePrototype() : VariableNodeDefinition + { + return $this->prototype('variable'); + } + public function scalarPrototype() : ScalarNodeDefinition + { + return $this->prototype('scalar'); + } + public function booleanPrototype() : BooleanNodeDefinition + { + return $this->prototype('boolean'); + } + public function integerPrototype() : IntegerNodeDefinition + { + return $this->prototype('integer'); + } + public function floatPrototype() : FloatNodeDefinition + { + return $this->prototype('float'); + } + public function arrayPrototype() : self + { + return $this->prototype('array'); + } + public function enumPrototype() : EnumNodeDefinition + { + return $this->prototype('enum'); + } + /** + * Adds the default value if the node is not set in the configuration. + * + * This method is applicable to concrete nodes only (not to prototype nodes). + * If this function has been called and the node is not set during the finalization + * phase, it's default value will be derived from its children default values. + * + * @return $this + */ + public function addDefaultsIfNotSet() + { + $this->addDefaults = \true; + return $this; + } + /** + * Adds children with a default value when none are defined. + * + * This method is applicable to prototype nodes only. + * + * @param int|string|mixed[] $children The number of children|The child name|The children names to be added + * + * @return $this + */ + public function addDefaultChildrenIfNoneSet($children = null) + { + $this->addDefaultChildren = $children; + return $this; + } + /** + * Requires the node to have at least one element. + * + * This method is applicable to prototype nodes only. + * + * @return $this + */ + public function requiresAtLeastOneElement() + { + $this->atLeastOne = \true; + return $this; + } + /** + * Disallows adding news keys in a subsequent configuration. + * + * If used all keys have to be defined in the same configuration file. + * + * @return $this + */ + public function disallowNewKeysInSubsequentConfigs() + { + $this->allowNewKeys = \false; + return $this; + } + /** + * Sets a normalization rule for XML configurations. + * + * @param string $singular The key to remap + * @param string|null $plural The plural of the key for irregular plurals + * + * @return $this + */ + public function fixXmlConfig(string $singular, string $plural = null) + { + $this->normalization()->remap($singular, $plural); + return $this; + } + /** + * Sets the attribute which value is to be used as key. + * + * This is useful when you have an indexed array that should be an + * associative array. You can select an item from within the array + * to be the key of the particular item. For example, if "id" is the + * "key", then: + * + * [ + * ['id' => 'my_name', 'foo' => 'bar'], + * ]; + * + * becomes + * + * [ + * 'my_name' => ['foo' => 'bar'], + * ]; + * + * If you'd like "'id' => 'my_name'" to still be present in the resulting + * array, then you can set the second argument of this method to false. + * + * This method is applicable to prototype nodes only. + * + * @param string $name The name of the key + * @param bool $removeKeyItem Whether or not the key item should be removed + * + * @return $this + */ + public function useAttributeAsKey(string $name, bool $removeKeyItem = \true) + { + $this->key = $name; + $this->removeKeyItem = $removeKeyItem; + return $this; + } + /** + * Sets whether the node can be unset. + * + * @return $this + */ + public function canBeUnset(bool $allow = \true) + { + $this->merge()->allowUnset($allow); + return $this; + } + /** + * Adds an "enabled" boolean to enable the current section. + * + * By default, the section is disabled. If any configuration is specified then + * the node will be automatically enabled: + * + * enableableArrayNode: {enabled: true, ...} # The config is enabled & default values get overridden + * enableableArrayNode: ~ # The config is enabled & use the default values + * enableableArrayNode: true # The config is enabled & use the default values + * enableableArrayNode: {other: value, ...} # The config is enabled & default values get overridden + * enableableArrayNode: {enabled: false, ...} # The config is disabled + * enableableArrayNode: false # The config is disabled + * + * @return $this + */ + public function canBeEnabled() + { + $this->addDefaultsIfNotSet()->treatFalseLike(['enabled' => \false])->treatTrueLike(['enabled' => \true])->treatNullLike(['enabled' => \true])->beforeNormalization()->ifArray()->then(function (array $v) { + $v['enabled'] = $v['enabled'] ?? \true; + return $v; + })->end()->children()->booleanNode('enabled')->defaultFalse(); + return $this; + } + /** + * Adds an "enabled" boolean to enable the current section. + * + * By default, the section is enabled. + * + * @return $this + */ + public function canBeDisabled() + { + $this->addDefaultsIfNotSet()->treatFalseLike(['enabled' => \false])->treatTrueLike(['enabled' => \true])->treatNullLike(['enabled' => \true])->children()->booleanNode('enabled')->defaultTrue(); + return $this; + } + /** + * Disables the deep merging of the node. + * + * @return $this + */ + public function performNoDeepMerging() + { + $this->performDeepMerging = \false; + return $this; + } + /** + * Allows extra config keys to be specified under an array without + * throwing an exception. + * + * Those config values are ignored and removed from the resulting + * array. This should be used only in special cases where you want + * to send an entire configuration array through a special tree that + * processes only part of the array. + * + * @param bool $remove Whether to remove the extra keys + * + * @return $this + */ + public function ignoreExtraKeys(bool $remove = \true) + { + $this->ignoreExtraKeys = \true; + $this->removeExtraKeys = $remove; + return $this; + } + /** + * Sets whether to enable key normalization. + * + * @return $this + */ + public function normalizeKeys(bool $bool) + { + $this->normalizeKeys = $bool; + return $this; + } + /** + * @return static + */ + public function append(NodeDefinition $node) + { + $this->children[$node->name] = $node->setParent($this); + return $this; + } + /** + * Returns a node builder to be used to add children and prototype. + */ + protected function getNodeBuilder() : NodeBuilder + { + $this->nodeBuilder = $this->nodeBuilder ?? new NodeBuilder(); + return $this->nodeBuilder->setParent($this); + } + protected function createNode() : NodeInterface + { + if (null === $this->prototype) { + $node = new ArrayNode($this->name, $this->parent, $this->pathSeparator); + $this->validateConcreteNode($node); + $node->setAddIfNotSet($this->addDefaults); + foreach ($this->children as $child) { + $child->parent = $node; + $node->addChild($child->getNode()); + } + } else { + $node = new PrototypedArrayNode($this->name, $this->parent, $this->pathSeparator); + $this->validatePrototypeNode($node); + if (null !== $this->key) { + $node->setKeyAttribute($this->key, $this->removeKeyItem); + } + if (\true === $this->atLeastOne || \false === $this->allowEmptyValue) { + $node->setMinNumberOfElements(1); + } + if ($this->default) { + if (!\is_array($this->defaultValue)) { + throw new \InvalidArgumentException(\sprintf('%s: the default value of an array node has to be an array.', $node->getPath())); + } + $node->setDefaultValue($this->defaultValue); + } + if (\false !== $this->addDefaultChildren) { + $node->setAddChildrenIfNoneSet($this->addDefaultChildren); + if ($this->prototype instanceof static && null === $this->prototype->prototype) { + $this->prototype->addDefaultsIfNotSet(); + } + } + $this->prototype->parent = $node; + $node->setPrototype($this->prototype->getNode()); + } + $node->setAllowNewKeys($this->allowNewKeys); + $node->addEquivalentValue(null, $this->nullEquivalent); + $node->addEquivalentValue(\true, $this->trueEquivalent); + $node->addEquivalentValue(\false, $this->falseEquivalent); + $node->setPerformDeepMerging($this->performDeepMerging); + $node->setRequired($this->required); + $node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys); + $node->setNormalizeKeys($this->normalizeKeys); + if ($this->deprecation) { + $node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']); + } + if (null !== $this->normalization) { + $node->setNormalizationClosures($this->normalization->before); + $node->setNormalizedTypes($this->normalization->declaredTypes); + $node->setXmlRemappings($this->normalization->remappings); + } + if (null !== $this->merge) { + $node->setAllowOverwrite($this->merge->allowOverwrite); + $node->setAllowFalse($this->merge->allowFalse); + } + if (null !== $this->validation) { + $node->setFinalValidationClosures($this->validation->rules); + } + return $node; + } + /** + * Validate the configuration of a concrete node. + * + * @return void + * + * @throws InvalidDefinitionException + */ + protected function validateConcreteNode(ArrayNode $node) + { + $path = $node->getPath(); + if (null !== $this->key) { + throw new InvalidDefinitionException(\sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s".', $path)); + } + if (\false === $this->allowEmptyValue) { + throw new InvalidDefinitionException(\sprintf('->cannotBeEmpty() is not applicable to concrete nodes at path "%s".', $path)); + } + if (\true === $this->atLeastOne) { + throw new InvalidDefinitionException(\sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s".', $path)); + } + if ($this->default) { + throw new InvalidDefinitionException(\sprintf('->defaultValue() is not applicable to concrete nodes at path "%s".', $path)); + } + if (\false !== $this->addDefaultChildren) { + throw new InvalidDefinitionException(\sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s".', $path)); + } + } + /** + * Validate the configuration of a prototype node. + * + * @return void + * + * @throws InvalidDefinitionException + */ + protected function validatePrototypeNode(PrototypedArrayNode $node) + { + $path = $node->getPath(); + if ($this->addDefaults) { + throw new InvalidDefinitionException(\sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s".', $path)); + } + if (\false !== $this->addDefaultChildren) { + if ($this->default) { + throw new InvalidDefinitionException(\sprintf('A default value and default children might not be used together at path "%s".', $path)); + } + if (null !== $this->key && (null === $this->addDefaultChildren || \is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) { + throw new InvalidDefinitionException(\sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s".', $path)); + } + if (null === $this->key && (\is_string($this->addDefaultChildren) || \is_array($this->addDefaultChildren))) { + throw new InvalidDefinitionException(\sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s".', $path)); + } + } + } + /** + * @return NodeDefinition[] + */ + public function getChildNodeDefinitions() : array + { + return $this->children; + } + /** + * Finds a node defined by the given $nodePath. + * + * @param string $nodePath The path of the node to find. e.g "doctrine.orm.mappings" + */ + public function find(string $nodePath) : NodeDefinition + { + $firstPathSegment = \false === ($pathSeparatorPos = \strpos($nodePath, $this->pathSeparator)) ? $nodePath : \substr($nodePath, 0, $pathSeparatorPos); + if (null === ($node = $this->children[$firstPathSegment] ?? null)) { + throw new \RuntimeException(\sprintf('Node with name "%s" does not exist in the current node "%s".', $firstPathSegment, $this->name)); + } + if (\false === $pathSeparatorPos) { + return $node; + } + return $node->find(\substr($nodePath, $pathSeparatorPos + \strlen($this->pathSeparator))); + } +} diff --git a/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php b/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php new file mode 100644 index 0000000000..95c9bc75de --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BooleanNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +class BooleanNodeDefinition extends ScalarNodeDefinition +{ + public function __construct(?string $name, NodeParentInterface $parent = null) + { + parent::__construct($name, $parent); + $this->nullEquivalent = \true; + } + /** + * Instantiate a Node. + */ + protected function instantiateNode() : \MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode + { + return new BooleanNode($this->name, $this->parent, $this->pathSeparator); + } + /** + * @throws InvalidDefinitionException + * @return static + */ + public function cannotBeEmpty() + { + throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to BooleanNodeDefinition.'); + } +} diff --git a/vendor/symfony/config/Definition/Builder/BuilderAwareInterface.php b/vendor/symfony/config/Definition/Builder/BuilderAwareInterface.php new file mode 100644 index 0000000000..161b6a48f0 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/BuilderAwareInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +/** + * An interface that can be implemented by nodes which build other nodes. + * + * @author Roland Franssen + */ +interface BuilderAwareInterface +{ + /** + * Sets a custom children builder. + * + * @return void + */ + public function setBuilder(NodeBuilder $builder); +} diff --git a/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php b/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php new file mode 100644 index 0000000000..9081bcffd5 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\EnumNode; +/** + * Enum Node Definition. + * + * @author Johannes M. Schmitt + */ +class EnumNodeDefinition extends ScalarNodeDefinition +{ + /** + * @var mixed[] + */ + private $values; + /** + * @return $this + */ + public function values(array $values) + { + if (!$values) { + throw new \InvalidArgumentException('->values() must be called with at least one value.'); + } + $this->values = $values; + return $this; + } + /** + * Instantiate a Node. + * + * @throws \RuntimeException + */ + protected function instantiateNode() : \MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode + { + if (!isset($this->values)) { + throw new \RuntimeException('You must call ->values() on enum nodes.'); + } + return new EnumNode($this->name, $this->parent, $this->values, $this->pathSeparator); + } +} diff --git a/vendor/symfony/config/Definition/Builder/ExprBuilder.php b/vendor/symfony/config/Definition/Builder/ExprBuilder.php new file mode 100644 index 0000000000..9f67c095cc --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/ExprBuilder.php @@ -0,0 +1,239 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\UnsetKeyException; +/** + * This class builds an if expression. + * + * @author Johannes M. Schmitt + * @author Christophe Coevoet + */ +class ExprBuilder +{ + public const TYPE_ANY = 'any'; + public const TYPE_STRING = 'string'; + public const TYPE_NULL = 'null'; + public const TYPE_ARRAY = 'array'; + protected $node; + public $allowedTypes; + public $ifPart; + public $thenPart; + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + /** + * Marks the expression as being always used. + * + * @return $this + */ + public function always(\Closure $then = null) + { + $this->ifPart = static function () { + return \true; + }; + $this->allowedTypes = self::TYPE_ANY; + if (null !== $then) { + $this->thenPart = $then; + } + return $this; + } + /** + * Sets a closure to use as tests. + * + * The default one tests if the value is true. + * + * @return $this + */ + public function ifTrue(\Closure $closure = null) + { + $this->ifPart = $closure ?? static function ($v) { + return \true === $v; + }; + $this->allowedTypes = self::TYPE_ANY; + return $this; + } + /** + * Tests if the value is a string. + * + * @return $this + */ + public function ifString() + { + $this->ifPart = \Closure::fromCallable('is_string'); + $this->allowedTypes = self::TYPE_STRING; + return $this; + } + /** + * Tests if the value is null. + * + * @return $this + */ + public function ifNull() + { + $this->ifPart = \Closure::fromCallable('is_null'); + $this->allowedTypes = self::TYPE_NULL; + return $this; + } + /** + * Tests if the value is empty. + * + * @return $this + */ + public function ifEmpty() + { + $this->ifPart = static function ($v) { + return empty($v); + }; + $this->allowedTypes = self::TYPE_ANY; + return $this; + } + /** + * Tests if the value is an array. + * + * @return $this + */ + public function ifArray() + { + $this->ifPart = \Closure::fromCallable('is_array'); + $this->allowedTypes = self::TYPE_ARRAY; + return $this; + } + /** + * Tests if the value is in an array. + * + * @return $this + */ + public function ifInArray(array $array) + { + $this->ifPart = static function ($v) use($array) { + return \in_array($v, $array, \true); + }; + $this->allowedTypes = self::TYPE_ANY; + return $this; + } + /** + * Tests if the value is not in an array. + * + * @return $this + */ + public function ifNotInArray(array $array) + { + $this->ifPart = static function ($v) use($array) { + return !\in_array($v, $array, \true); + }; + $this->allowedTypes = self::TYPE_ANY; + return $this; + } + /** + * Transforms variables of any type into an array. + * + * @return $this + */ + public function castToArray() + { + $this->ifPart = static function ($v) { + return !\is_array($v); + }; + $this->allowedTypes = self::TYPE_ANY; + $this->thenPart = static function ($v) { + return [$v]; + }; + return $this; + } + /** + * Sets the closure to run if the test pass. + * + * @return $this + */ + public function then(\Closure $closure) + { + $this->thenPart = $closure; + return $this; + } + /** + * Sets a closure returning an empty array. + * + * @return $this + */ + public function thenEmptyArray() + { + $this->thenPart = static function () { + return []; + }; + return $this; + } + /** + * Sets a closure marking the value as invalid at processing time. + * + * if you want to add the value of the node in your message just use a %s placeholder. + * + * @return $this + * + * @throws \InvalidArgumentException + */ + public function thenInvalid(string $message) + { + $this->thenPart = static function ($v) use($message) { + throw new \InvalidArgumentException(\sprintf($message, \json_encode($v))); + }; + return $this; + } + /** + * Sets a closure unsetting this key of the array at processing time. + * + * @return $this + * + * @throws UnsetKeyException + */ + public function thenUnset() + { + $this->thenPart = static function () { + throw new UnsetKeyException('Unsetting key.'); + }; + return $this; + } + /** + * Returns the related node. + * + * @throws \RuntimeException + * @return \Symfony\Component\Config\Definition\Builder\NodeDefinition|\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\VariableNodeDefinition + */ + public function end() + { + if (null === $this->ifPart) { + throw new \RuntimeException('You must specify an if part.'); + } + if (null === $this->thenPart) { + throw new \RuntimeException('You must specify a then part.'); + } + return $this->node; + } + /** + * Builds the expressions. + * + * @param ExprBuilder[] $expressions An array of ExprBuilder instances to build + */ + public static function buildExpressions(array $expressions) : array + { + foreach ($expressions as $k => $expr) { + if ($expr instanceof self) { + $if = $expr->ifPart; + $then = $expr->thenPart; + $expressions[$k] = static function ($v) use($if, $then) { + return $if($v) ? $then($v) : $v; + }; + } + } + return $expressions; + } +} diff --git a/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php b/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php new file mode 100644 index 0000000000..66271b3d01 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\FloatNode; +/** + * This class provides a fluent interface for defining a float node. + * + * @author Jeanmonod David + */ +class FloatNodeDefinition extends NumericNodeDefinition +{ + /** + * Instantiates a Node. + */ + protected function instantiateNode() : \MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode + { + return new FloatNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator); + } +} diff --git a/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php b/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php new file mode 100644 index 0000000000..7700f95692 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\IntegerNode; +/** + * This class provides a fluent interface for defining an integer node. + * + * @author Jeanmonod David + */ +class IntegerNodeDefinition extends NumericNodeDefinition +{ + /** + * Instantiates a Node. + */ + protected function instantiateNode() : \MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode + { + return new IntegerNode($this->name, $this->parent, $this->min, $this->max, $this->pathSeparator); + } +} diff --git a/vendor/symfony/config/Definition/Builder/MergeBuilder.php b/vendor/symfony/config/Definition/Builder/MergeBuilder.php new file mode 100644 index 0000000000..7bdcab2dcf --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/MergeBuilder.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +/** + * This class builds merge conditions. + * + * @author Johannes M. Schmitt + */ +class MergeBuilder +{ + protected $node; + public $allowFalse = \false; + public $allowOverwrite = \true; + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + /** + * Sets whether the node can be unset. + * + * @return $this + */ + public function allowUnset(bool $allow = \true) + { + $this->allowFalse = $allow; + return $this; + } + /** + * Sets whether the node can be overwritten. + * + * @return $this + */ + public function denyOverwrite(bool $deny = \true) + { + $this->allowOverwrite = !$deny; + return $this; + } + /** + * Returns the related node. + * @return \Symfony\Component\Config\Definition\Builder\NodeDefinition|\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\VariableNodeDefinition + */ + public function end() + { + return $this->node; + } +} diff --git a/vendor/symfony/config/Definition/Builder/NodeBuilder.php b/vendor/symfony/config/Definition/Builder/NodeBuilder.php new file mode 100644 index 0000000000..5c52411dee --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/NodeBuilder.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +/** + * This class provides a fluent interface for building a node. + * + * @author Johannes M. Schmitt + */ +class NodeBuilder implements NodeParentInterface +{ + protected $parent; + protected $nodeMapping; + public function __construct() + { + $this->nodeMapping = ['variable' => VariableNodeDefinition::class, 'scalar' => ScalarNodeDefinition::class, 'boolean' => BooleanNodeDefinition::class, 'integer' => IntegerNodeDefinition::class, 'float' => FloatNodeDefinition::class, 'array' => ArrayNodeDefinition::class, 'enum' => EnumNodeDefinition::class]; + } + /** + * Set the parent node. + * + * @return $this + */ + public function setParent(ParentNodeDefinitionInterface $parent = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/form', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + $this->parent = $parent; + return $this; + } + /** + * Creates a child array node. + */ + public function arrayNode(string $name) : ArrayNodeDefinition + { + return $this->node($name, 'array'); + } + /** + * Creates a child scalar node. + */ + public function scalarNode(string $name) : ScalarNodeDefinition + { + return $this->node($name, 'scalar'); + } + /** + * Creates a child Boolean node. + */ + public function booleanNode(string $name) : BooleanNodeDefinition + { + return $this->node($name, 'boolean'); + } + /** + * Creates a child integer node. + */ + public function integerNode(string $name) : IntegerNodeDefinition + { + return $this->node($name, 'integer'); + } + /** + * Creates a child float node. + */ + public function floatNode(string $name) : FloatNodeDefinition + { + return $this->node($name, 'float'); + } + /** + * Creates a child EnumNode. + */ + public function enumNode(string $name) : EnumNodeDefinition + { + return $this->node($name, 'enum'); + } + /** + * Creates a child variable node. + */ + public function variableNode(string $name) : VariableNodeDefinition + { + return $this->node($name, 'variable'); + } + /** + * Returns the parent node. + * + * @return NodeDefinition&ParentNodeDefinitionInterface + */ + public function end() + { + return $this->parent; + } + /** + * Creates a child node. + * + * @throws \RuntimeException When the node type is not registered + * @throws \RuntimeException When the node class is not found + */ + public function node(?string $name, string $type) : NodeDefinition + { + $class = $this->getNodeClass($type); + $node = new $class($name); + $this->append($node); + return $node; + } + /** + * Appends a node definition. + * + * Usage: + * + * $node = new ArrayNodeDefinition('name') + * ->children() + * ->scalarNode('foo')->end() + * ->scalarNode('baz')->end() + * ->append($this->getBarNodeDefinition()) + * ->end() + * ; + * + * @return $this + */ + public function append(NodeDefinition $node) + { + if ($node instanceof BuilderAwareInterface) { + $builder = clone $this; + $builder->setParent(null); + $node->setBuilder($builder); + } + if (null !== $this->parent) { + $this->parent->append($node); + // Make this builder the node parent to allow for a fluid interface + $node->setParent($this); + } + return $this; + } + /** + * Adds or overrides a node Type. + * + * @param string $type The name of the type + * @param string $class The fully qualified name the node definition class + * + * @return $this + */ + public function setNodeClass(string $type, string $class) + { + $this->nodeMapping[\strtolower($type)] = $class; + return $this; + } + /** + * Returns the class name of the node definition. + * + * @throws \RuntimeException When the node type is not registered + * @throws \RuntimeException When the node class is not found + */ + protected function getNodeClass(string $type) : string + { + $type = \strtolower($type); + if (!isset($this->nodeMapping[$type])) { + throw new \RuntimeException(\sprintf('The node type "%s" is not registered.', $type)); + } + $class = $this->nodeMapping[$type]; + if (!\class_exists($class)) { + throw new \RuntimeException(\sprintf('The node class "%s" does not exist.', $class)); + } + return $class; + } +} diff --git a/vendor/symfony/config/Definition/Builder/NodeDefinition.php b/vendor/symfony/config/Definition/Builder/NodeDefinition.php new file mode 100644 index 0000000000..9603009cbb --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/NodeDefinition.php @@ -0,0 +1,296 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BaseNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\NodeInterface; +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +abstract class NodeDefinition implements NodeParentInterface +{ + protected $name; + protected $normalization; + protected $validation; + protected $defaultValue; + protected $default = \false; + protected $required = \false; + protected $deprecation = []; + protected $merge; + protected $allowEmptyValue = \true; + protected $nullEquivalent; + protected $trueEquivalent = \true; + protected $falseEquivalent = \false; + protected $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR; + protected $parent; + protected $attributes = []; + public function __construct(?string $name, NodeParentInterface $parent = null) + { + $this->parent = $parent; + $this->name = $name; + } + /** + * Sets the parent node. + * + * @return $this + */ + public function setParent(NodeParentInterface $parent) + { + $this->parent = $parent; + return $this; + } + /** + * Sets info message. + * + * @return $this + */ + public function info(string $info) + { + return $this->attribute('info', $info); + } + /** + * Sets example configuration. + * + * @return $this + * @param string|mixed[] $example + */ + public function example($example) + { + return $this->attribute('example', $example); + } + /** + * Sets an attribute on the node. + * + * @return $this + * @param mixed $value + */ + public function attribute(string $key, $value) + { + $this->attributes[$key] = $value; + return $this; + } + /** + * Returns the parent node. + * @return \Symfony\Component\Config\Definition\Builder\NodeParentInterface|\Symfony\Component\Config\Definition\Builder\NodeBuilder|\Symfony\Component\Config\Definition\Builder\NodeDefinition|\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\VariableNodeDefinition|null + */ + public function end() + { + return $this->parent; + } + /** + * Creates the node. + */ + public function getNode(bool $forceRootNode = \false) : NodeInterface + { + if ($forceRootNode) { + $this->parent = null; + } + if (null !== $this->normalization) { + $allowedTypes = []; + foreach ($this->normalization->before as $expr) { + $allowedTypes[] = $expr->allowedTypes; + } + $allowedTypes = \array_unique($allowedTypes); + $this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before); + $this->normalization->declaredTypes = $allowedTypes; + } + if (null !== $this->validation) { + $this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules); + } + $node = $this->createNode(); + if ($node instanceof BaseNode) { + $node->setAttributes($this->attributes); + } + return $node; + } + /** + * Sets the default value. + * + * @return $this + * @param mixed $value + */ + public function defaultValue($value) + { + $this->default = \true; + $this->defaultValue = $value; + return $this; + } + /** + * Sets the node as required. + * + * @return $this + */ + public function isRequired() + { + $this->required = \true; + return $this; + } + /** + * Sets the node as deprecated. + * + * @param string $package The name of the composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message the deprecation message to use + * + * You can use %node% and %path% placeholders in your message to display, + * respectively, the node name and its complete path + * + * @return $this + */ + public function setDeprecated(string $package, string $version, string $message = 'The child node "%node%" at path "%path%" is deprecated.') + { + $this->deprecation = ['package' => $package, 'version' => $version, 'message' => $message]; + return $this; + } + /** + * Sets the equivalent value used when the node contains null. + * + * @return $this + * @param mixed $value + */ + public function treatNullLike($value) + { + $this->nullEquivalent = $value; + return $this; + } + /** + * Sets the equivalent value used when the node contains true. + * + * @return $this + * @param mixed $value + */ + public function treatTrueLike($value) + { + $this->trueEquivalent = $value; + return $this; + } + /** + * Sets the equivalent value used when the node contains false. + * + * @return $this + * @param mixed $value + */ + public function treatFalseLike($value) + { + $this->falseEquivalent = $value; + return $this; + } + /** + * Sets null as the default value. + * + * @return $this + */ + public function defaultNull() + { + return $this->defaultValue(null); + } + /** + * Sets true as the default value. + * + * @return $this + */ + public function defaultTrue() + { + return $this->defaultValue(\true); + } + /** + * Sets false as the default value. + * + * @return $this + */ + public function defaultFalse() + { + return $this->defaultValue(\false); + } + /** + * Sets an expression to run before the normalization. + */ + public function beforeNormalization() : ExprBuilder + { + return $this->normalization()->before(); + } + /** + * Denies the node value being empty. + * + * @return $this + */ + public function cannotBeEmpty() + { + $this->allowEmptyValue = \false; + return $this; + } + /** + * Sets an expression to run for the validation. + * + * The expression receives the value of the node and must return it. It can + * modify it. + * An exception should be thrown when the node is not valid. + */ + public function validate() : ExprBuilder + { + return $this->validation()->rule(); + } + /** + * Sets whether the node can be overwritten. + * + * @return $this + */ + public function cannotBeOverwritten(bool $deny = \true) + { + $this->merge()->denyOverwrite($deny); + return $this; + } + /** + * Gets the builder for validation rules. + */ + protected function validation() : ValidationBuilder + { + return $this->validation = $this->validation ?? new ValidationBuilder($this); + } + /** + * Gets the builder for merging rules. + */ + protected function merge() : MergeBuilder + { + return $this->merge = $this->merge ?? new MergeBuilder($this); + } + /** + * Gets the builder for normalization rules. + */ + protected function normalization() : NormalizationBuilder + { + return $this->normalization = $this->normalization ?? new NormalizationBuilder($this); + } + /** + * Instantiate and configure the node according to this definition. + * + * @throws InvalidDefinitionException When the definition is invalid + */ + protected abstract function createNode() : NodeInterface; + /** + * Set PathSeparator to use. + * + * @return $this + */ + public function setPathSeparator(string $separator) + { + if ($this instanceof ParentNodeDefinitionInterface) { + foreach ($this->getChildNodeDefinitions() as $child) { + $child->setPathSeparator($separator); + } + } + $this->pathSeparator = $separator; + return $this; + } +} diff --git a/vendor/symfony/config/Definition/Builder/NodeParentInterface.php b/vendor/symfony/config/Definition/Builder/NodeParentInterface.php new file mode 100644 index 0000000000..ee5b87b7b7 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/NodeParentInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +/** + * An interface that must be implemented by all node parents. + * + * @author Victor Berchet + */ +interface NodeParentInterface +{ +} diff --git a/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php b/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php new file mode 100644 index 0000000000..d932ffd482 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +/** + * This class builds normalization conditions. + * + * @author Johannes M. Schmitt + */ +class NormalizationBuilder +{ + protected $node; + public $before = []; + public $declaredTypes = []; + public $remappings = []; + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + /** + * Registers a key to remap to its plural form. + * + * @param string $key The key to remap + * @param string|null $plural The plural of the key in case of irregular plural + * + * @return $this + */ + public function remap(string $key, string $plural = null) + { + $this->remappings[] = [$key, null === $plural ? $key . 's' : $plural]; + return $this; + } + /** + * Registers a closure to run before the normalization or an expression builder to build it if null is provided. + * + * @return ExprBuilder|$this + */ + public function before(\Closure $closure = null) + { + if (null !== $closure) { + $this->before[] = $closure; + return $this; + } + return $this->before[] = new ExprBuilder($this->node); + } +} diff --git a/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php b/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php new file mode 100644 index 0000000000..23cc073f36 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; +/** + * Abstract class that contains common code of integer and float node definitions. + * + * @author David Jeanmonod + */ +abstract class NumericNodeDefinition extends ScalarNodeDefinition +{ + protected $min; + protected $max; + /** + * Ensures that the value is smaller than the given reference. + * + * @return $this + * + * @throws \InvalidArgumentException when the constraint is inconsistent + * @param int|float $max + */ + public function max($max) + { + if (isset($this->min) && $this->min > $max) { + throw new \InvalidArgumentException(\sprintf('You cannot define a max(%s) as you already have a min(%s).', $max, $this->min)); + } + $this->max = $max; + return $this; + } + /** + * Ensures that the value is bigger than the given reference. + * + * @return $this + * + * @throws \InvalidArgumentException when the constraint is inconsistent + * @param int|float $min + */ + public function min($min) + { + if (isset($this->max) && $this->max < $min) { + throw new \InvalidArgumentException(\sprintf('You cannot define a min(%s) as you already have a max(%s).', $min, $this->max)); + } + $this->min = $min; + return $this; + } + /** + * @throws InvalidDefinitionException + * @return static + */ + public function cannotBeEmpty() + { + throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to NumericNodeDefinition.'); + } +} diff --git a/vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php b/vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php new file mode 100644 index 0000000000..2fdfffda3b --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +/** + * An interface that must be implemented by nodes which can have children. + * + * @author Victor Berchet + */ +interface ParentNodeDefinitionInterface extends BuilderAwareInterface +{ + /** + * Returns a builder to add children nodes. + */ + public function children() : NodeBuilder; + /** + * Appends a node definition. + * + * Usage: + * + * $node = $parentNode + * ->children() + * ->scalarNode('foo')->end() + * ->scalarNode('baz')->end() + * ->append($this->getBarNodeDefinition()) + * ->end() + * ; + * + * @return $this + */ + public function append(NodeDefinition $node); + /** + * Gets the child node definitions. + * + * @return NodeDefinition[] + */ + public function getChildNodeDefinitions() : array; +} diff --git a/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php b/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php new file mode 100644 index 0000000000..ae9e4f1b5b --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode; +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +class ScalarNodeDefinition extends VariableNodeDefinition +{ + /** + * Instantiate a Node. + */ + protected function instantiateNode() : \MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\VariableNode + { + return new ScalarNode($this->name, $this->parent, $this->pathSeparator); + } +} diff --git a/vendor/symfony/config/Definition/Builder/TreeBuilder.php b/vendor/symfony/config/Definition/Builder/TreeBuilder.php new file mode 100644 index 0000000000..a3030b377c --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/TreeBuilder.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\NodeInterface; +/** + * This is the entry class for building a config tree. + * + * @author Johannes M. Schmitt + */ +class TreeBuilder implements NodeParentInterface +{ + protected $tree; + protected $root; + public function __construct(string $name, string $type = 'array', NodeBuilder $builder = null) + { + $builder = $builder ?? new NodeBuilder(); + $this->root = $builder->node($name, $type)->setParent($this); + } + /** + * @return NodeDefinition|ArrayNodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array') + */ + public function getRootNode() + { + return $this->root; + } + /** + * Builds the tree. + * + * @throws \RuntimeException + */ + public function buildTree() : NodeInterface + { + if (null !== $this->tree) { + return $this->tree; + } + return $this->tree = $this->root->getNode(\true); + } + /** + * @return void + */ + public function setPathSeparator(string $separator) + { + // unset last built as changing path separator changes all nodes + $this->tree = null; + $this->root->setPathSeparator($separator); + } +} diff --git a/vendor/symfony/config/Definition/Builder/ValidationBuilder.php b/vendor/symfony/config/Definition/Builder/ValidationBuilder.php new file mode 100644 index 0000000000..13bc5494da --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/ValidationBuilder.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +/** + * This class builds validation conditions. + * + * @author Christophe Coevoet + */ +class ValidationBuilder +{ + protected $node; + public $rules = []; + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + /** + * Registers a closure to run as normalization or an expression builder to build it if null is provided. + * + * @return ExprBuilder|$this + */ + public function rule(\Closure $closure = null) + { + if (null !== $closure) { + $this->rules[] = $closure; + return $this; + } + return $this->rules[] = new ExprBuilder($this->node); + } +} diff --git a/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php b/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php new file mode 100644 index 0000000000..520196f905 --- /dev/null +++ b/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\NodeInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\VariableNode; +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +class VariableNodeDefinition extends NodeDefinition +{ + /** + * Instantiate a Node. + */ + protected function instantiateNode() : VariableNode + { + return new VariableNode($this->name, $this->parent, $this->pathSeparator); + } + protected function createNode() : NodeInterface + { + $node = $this->instantiateNode(); + if (null !== $this->normalization) { + $node->setNormalizationClosures($this->normalization->before); + } + if (null !== $this->merge) { + $node->setAllowOverwrite($this->merge->allowOverwrite); + } + if (\true === $this->default) { + $node->setDefaultValue($this->defaultValue); + } + $node->setAllowEmptyValue($this->allowEmptyValue); + $node->addEquivalentValue(null, $this->nullEquivalent); + $node->addEquivalentValue(\true, $this->trueEquivalent); + $node->addEquivalentValue(\false, $this->falseEquivalent); + $node->setRequired($this->required); + if ($this->deprecation) { + $node->setDeprecated($this->deprecation['package'], $this->deprecation['version'], $this->deprecation['message']); + } + if (null !== $this->validation) { + $node->setFinalValidationClosures($this->validation->rules); + } + return $node; + } +} diff --git a/vendor/symfony/config/Definition/ConfigurableInterface.php b/vendor/symfony/config/Definition/ConfigurableInterface.php new file mode 100644 index 0000000000..699bd14127 --- /dev/null +++ b/vendor/symfony/config/Definition/ConfigurableInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; +/** + * @author Yonel Ceruto + */ +interface ConfigurableInterface +{ + /** + * Generates the configuration tree builder. + */ + public function configure(DefinitionConfigurator $definition) : void; +} diff --git a/vendor/symfony/config/Definition/Configuration.php b/vendor/symfony/config/Definition/Configuration.php new file mode 100644 index 0000000000..69ea66ca53 --- /dev/null +++ b/vendor/symfony/config/Definition/Configuration.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder\TreeBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Loader\DefinitionFileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\FileLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * @author Yonel Ceruto + * + * @final + */ +class Configuration implements ConfigurationInterface +{ + /** + * @var \Symfony\Component\Config\Definition\ConfigurableInterface + */ + private $subject; + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder|null + */ + private $container; + /** + * @var string + */ + private $alias; + public function __construct(ConfigurableInterface $subject, ?ContainerBuilder $container, string $alias) + { + $this->subject = $subject; + $this->container = $container; + $this->alias = $alias; + } + public function getConfigTreeBuilder() : TreeBuilder + { + $treeBuilder = new TreeBuilder($this->alias); + $file = (new \ReflectionObject($this->subject))->getFileName(); + $loader = new DefinitionFileLoader($treeBuilder, new FileLocator(\dirname($file)), $this->container); + $configurator = new DefinitionConfigurator($treeBuilder, $loader, $file, $file); + $this->subject->configure($configurator); + return $treeBuilder; + } +} diff --git a/vendor/symfony/config/Definition/ConfigurationInterface.php b/vendor/symfony/config/Definition/ConfigurationInterface.php new file mode 100644 index 0000000000..a29a2fc5c6 --- /dev/null +++ b/vendor/symfony/config/Definition/ConfigurationInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder\TreeBuilder; +/** + * Configuration interface. + * + * @author Victor Berchet + */ +interface ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return TreeBuilder + */ + public function getConfigTreeBuilder(); +} diff --git a/vendor/symfony/config/Definition/Configurator/DefinitionConfigurator.php b/vendor/symfony/config/Definition/Configurator/DefinitionConfigurator.php new file mode 100644 index 0000000000..58693252bc --- /dev/null +++ b/vendor/symfony/config/Definition/Configurator/DefinitionConfigurator.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder\NodeDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder\TreeBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Loader\DefinitionFileLoader; +/** + * @author Yonel Ceruto + */ +class DefinitionConfigurator +{ + /** + * @var \Symfony\Component\Config\Definition\Builder\TreeBuilder + */ + private $treeBuilder; + /** + * @var \Symfony\Component\Config\Definition\Loader\DefinitionFileLoader + */ + private $loader; + /** + * @var string + */ + private $path; + /** + * @var string + */ + private $file; + public function __construct(TreeBuilder $treeBuilder, DefinitionFileLoader $loader, string $path, string $file) + { + $this->treeBuilder = $treeBuilder; + $this->loader = $loader; + $this->path = $path; + $this->file = $file; + } + public function import(string $resource, string $type = null, bool $ignoreErrors = \false) : void + { + $this->loader->setCurrentDir(\dirname($this->path)); + $this->loader->import($resource, $type, $ignoreErrors, $this->file); + } + /** + * @return \Symfony\Component\Config\Definition\Builder\NodeDefinition|\Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition + */ + public function rootNode() + { + return $this->treeBuilder->getRootNode(); + } + public function setPathSeparator(string $separator) : void + { + $this->treeBuilder->setPathSeparator($separator); + } +} diff --git a/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php b/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php new file mode 100644 index 0000000000..1c37266e61 --- /dev/null +++ b/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php @@ -0,0 +1,262 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Dumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ArrayNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BaseNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BooleanNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\EnumNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\FloatNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\IntegerNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\NodeInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\PrototypedArrayNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode; +/** + * Dumps an XML reference configuration for the given configuration/node instance. + * + * @author Wouter J + */ +class XmlReferenceDumper +{ + /** + * @var string|null + */ + private $reference; + /** + * @return string + */ + public function dump(ConfigurationInterface $configuration, string $namespace = null) + { + return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace); + } + /** + * @return string + */ + public function dumpNode(NodeInterface $node, string $namespace = null) + { + $this->reference = ''; + $this->writeNode($node, 0, \true, $namespace); + $ref = $this->reference; + $this->reference = null; + return $ref; + } + private function writeNode(NodeInterface $node, int $depth = 0, bool $root = \false, string $namespace = null) : void + { + $rootName = $root ? 'config' : $node->getName(); + $rootNamespace = $namespace ?: ($root ? 'http://example.org/schema/dic/' . $node->getName() : null); + // xml remapping + if ($node->getParent()) { + $remapping = \array_filter($node->getParent()->getXmlRemappings(), function (array $mapping) use($rootName) { + return $rootName === $mapping[1]; + }); + if (\count($remapping)) { + [$singular] = \current($remapping); + $rootName = $singular; + } + } + $rootName = \str_replace('_', '-', $rootName); + $rootAttributes = []; + $rootAttributeComments = []; + $rootChildren = []; + $rootComments = []; + if ($node instanceof ArrayNode) { + $children = $node->getChildren(); + // comments about the root node + if ($rootInfo = $node->getInfo()) { + $rootComments[] = $rootInfo; + } + if ($rootNamespace) { + $rootComments[] = 'Namespace: ' . $rootNamespace; + } + // render prototyped nodes + if ($node instanceof PrototypedArrayNode) { + $prototype = $node->getPrototype(); + $info = 'prototype'; + if (null !== $prototype->getInfo()) { + $info .= ': ' . $prototype->getInfo(); + } + \array_unshift($rootComments, $info); + if ($key = $node->getKeyAttribute()) { + $rootAttributes[$key] = \str_replace('-', ' ', $rootName) . ' ' . $key; + } + if ($prototype instanceof PrototypedArrayNode) { + $prototype->setName($key ?? ''); + $children = [$key => $prototype]; + } elseif ($prototype instanceof ArrayNode) { + $children = $prototype->getChildren(); + } else { + if ($prototype->hasDefaultValue()) { + $prototypeValue = $prototype->getDefaultValue(); + } else { + switch (\get_class($prototype)) { + case ScalarNode::class: + $prototypeValue = 'scalar value'; + break; + case FloatNode::class: + case IntegerNode::class: + $prototypeValue = 'numeric value'; + break; + case BooleanNode::class: + $prototypeValue = 'true|false'; + break; + case EnumNode::class: + $prototypeValue = $prototype->getPermissibleValues('|'); + break; + default: + $prototypeValue = 'value'; + break; + } + } + } + } + // get attributes and elements + foreach ($children as $child) { + if ($child instanceof ArrayNode) { + // get elements + $rootChildren[] = $child; + continue; + } + // get attributes + // metadata + $name = \str_replace('_', '-', $child->getName()); + $value = '%%%%not_defined%%%%'; + // use a string which isn't used in the normal world + // comments + $comments = []; + if ($child instanceof BaseNode && ($info = $child->getInfo())) { + $comments[] = $info; + } + if ($child instanceof BaseNode && ($example = $child->getExample())) { + $comments[] = 'Example: ' . (\is_array($example) ? \implode(', ', $example) : $example); + } + if ($child->isRequired()) { + $comments[] = 'Required'; + } + if ($child instanceof BaseNode && $child->isDeprecated()) { + $deprecation = $child->getDeprecation($child->getName(), $node->getPath()); + $comments[] = \sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '') . $deprecation['message']); + } + if ($child instanceof EnumNode) { + $comments[] = 'One of ' . $child->getPermissibleValues('; '); + } + if (\count($comments)) { + $rootAttributeComments[$name] = \implode(";\n", $comments); + } + // default values + if ($child->hasDefaultValue()) { + $value = $child->getDefaultValue(); + } + // append attribute + $rootAttributes[$name] = $value; + } + } + // render comments + // root node comment + if (\count($rootComments)) { + foreach ($rootComments as $comment) { + $this->writeLine('', $depth); + } + } + // attribute comments + if (\count($rootAttributeComments)) { + foreach ($rootAttributeComments as $attrName => $comment) { + $commentDepth = $depth + 4 + \strlen($attrName) + 2; + $commentLines = \explode("\n", $comment); + $multiline = \count($commentLines) > 1; + $comment = \implode(\PHP_EOL . \str_repeat(' ', $commentDepth), $commentLines); + if ($multiline) { + $this->writeLine('', $depth); + } else { + $this->writeLine('', $depth); + } + } + } + // render start tag + attributes + $rootIsVariablePrototype = isset($prototypeValue); + $rootIsEmptyTag = 0 === \count($rootChildren) && !$rootIsVariablePrototype; + $rootOpenTag = '<' . $rootName; + if (1 >= ($attributesCount = \count($rootAttributes))) { + if (1 === $attributesCount) { + $rootOpenTag .= \sprintf(' %s="%s"', \current(\array_keys($rootAttributes)), $this->writeValue(\current($rootAttributes))); + } + $rootOpenTag .= $rootIsEmptyTag ? ' />' : '>'; + if ($rootIsVariablePrototype) { + $rootOpenTag .= $prototypeValue . ''; + } + $this->writeLine($rootOpenTag, $depth); + } else { + $this->writeLine($rootOpenTag, $depth); + $i = 1; + foreach ($rootAttributes as $attrName => $attrValue) { + $attr = \sprintf('%s="%s"', $attrName, $this->writeValue($attrValue)); + $this->writeLine($attr, $depth + 4); + if ($attributesCount === $i++) { + $this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth); + if ($rootIsVariablePrototype) { + $rootOpenTag .= $prototypeValue . ''; + } + } + } + } + // render children tags + foreach ($rootChildren as $child) { + $this->writeLine(''); + $this->writeNode($child, $depth + 4); + } + // render end tag + if (!$rootIsEmptyTag && !$rootIsVariablePrototype) { + $this->writeLine(''); + $rootEndTag = ''; + $this->writeLine($rootEndTag, $depth); + } + } + /** + * Outputs a single config reference line. + */ + private function writeLine(string $text, int $indent = 0) : void + { + $indent = \strlen($text) + $indent; + $format = '%' . $indent . 's'; + $this->reference .= \sprintf($format, $text) . \PHP_EOL; + } + /** + * Renders the string conversion of the value. + * @param mixed $value + */ + private function writeValue($value) : string + { + if ('%%%%not_defined%%%%' === $value) { + return ''; + } + if (\is_string($value) || \is_numeric($value)) { + return $value; + } + if (\false === $value) { + return 'false'; + } + if (\true === $value) { + return 'true'; + } + if (null === $value) { + return 'null'; + } + if (empty($value)) { + return ''; + } + if (\is_array($value)) { + return \implode(',', $value); + } + return ''; + } +} diff --git a/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php b/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php new file mode 100644 index 0000000000..ac42d91be9 --- /dev/null +++ b/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php @@ -0,0 +1,232 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Dumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ArrayNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BaseNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\EnumNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\NodeInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\PrototypedArrayNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ScalarNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\VariableNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Inline; +/** + * Dumps a Yaml reference configuration for the given configuration/node instance. + * + * @author Kevin Bond + */ +class YamlReferenceDumper +{ + /** + * @var string|null + */ + private $reference; + /** + * @return string + */ + public function dump(ConfigurationInterface $configuration) + { + return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree()); + } + /** + * @return string + */ + public function dumpAtPath(ConfigurationInterface $configuration, string $path) + { + $rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree(); + foreach (\explode('.', $path) as $step) { + if (!$node instanceof ArrayNode) { + throw new \UnexpectedValueException(\sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path)); + } + /** @var NodeInterface[] $children */ + $children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren(); + foreach ($children as $child) { + if ($child->getName() === $step) { + $node = $child; + continue 2; + } + } + throw new \UnexpectedValueException(\sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path)); + } + return $this->dumpNode($node); + } + /** + * @return string + */ + public function dumpNode(NodeInterface $node) + { + $this->reference = ''; + $this->writeNode($node); + $ref = $this->reference; + $this->reference = null; + return $ref; + } + private function writeNode(NodeInterface $node, NodeInterface $parentNode = null, int $depth = 0, bool $prototypedArray = \false) : void + { + $comments = []; + $default = ''; + $defaultArray = null; + $children = null; + $example = null; + if ($node instanceof BaseNode) { + $example = $node->getExample(); + } + // defaults + if ($node instanceof ArrayNode) { + $children = $node->getChildren(); + if ($node instanceof PrototypedArrayNode) { + $children = $this->getPrototypeChildren($node); + } + if (!$children) { + if ($node->hasDefaultValue() && \count($defaultArray = $node->getDefaultValue())) { + $default = ''; + } elseif (!\is_array($example)) { + $default = '[]'; + } + } + } elseif ($node instanceof EnumNode) { + $comments[] = 'One of ' . $node->getPermissibleValues('; '); + $default = $node->hasDefaultValue() ? Inline::dump($node->getDefaultValue()) : '~'; + } elseif (VariableNode::class === \get_class($node) && \is_array($example)) { + // If there is an array example, we are sure we dont need to print a default value + $default = ''; + } else { + $default = '~'; + if ($node->hasDefaultValue()) { + $default = $node->getDefaultValue(); + if (\is_array($default)) { + if (\count($defaultArray = $node->getDefaultValue())) { + $default = ''; + } elseif (!\is_array($example)) { + $default = '[]'; + } + } else { + $default = Inline::dump($default); + } + } + } + // required? + if ($node->isRequired()) { + $comments[] = 'Required'; + } + // deprecated? + if ($node instanceof BaseNode && $node->isDeprecated()) { + $deprecation = $node->getDeprecation($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath()); + $comments[] = \sprintf('Deprecated (%s)', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '') . $deprecation['message']); + } + // example + if ($example && !\is_array($example)) { + $comments[] = 'Example: ' . Inline::dump($example); + } + $default = '' != (string) $default ? ' ' . $default : ''; + $comments = \count($comments) ? '# ' . \implode(', ', $comments) : ''; + $key = $prototypedArray ? '-' : $node->getName() . ':'; + $text = \rtrim(\sprintf('%-21s%s %s', $key, $default, $comments), ' '); + if ($node instanceof BaseNode && ($info = $node->getInfo())) { + $this->writeLine(''); + // indenting multi-line info + $info = \str_replace("\n", \sprintf("\n%" . $depth * 4 . 's# ', ' '), $info); + $this->writeLine('# ' . $info, $depth * 4); + } + $this->writeLine($text, $depth * 4); + // output defaults + if ($defaultArray) { + $this->writeLine(''); + $message = \count($defaultArray) > 1 ? 'Defaults' : 'Default'; + $this->writeLine('# ' . $message . ':', $depth * 4 + 4); + $this->writeArray($defaultArray, $depth + 1); + } + if (\is_array($example)) { + $this->writeLine(''); + $message = \count($example) > 1 ? 'Examples' : 'Example'; + $this->writeLine('# ' . $message . ':', $depth * 4 + 4); + $this->writeArray(\array_map(\Closure::fromCallable([Inline::class, 'dump']), $example), $depth + 1); + } + if ($children) { + foreach ($children as $childNode) { + $this->writeNode($childNode, $node, $depth + 1, $node instanceof PrototypedArrayNode && !$node->getKeyAttribute()); + } + } + } + /** + * Outputs a single config reference line. + */ + private function writeLine(string $text, int $indent = 0) : void + { + $indent = \strlen($text) + $indent; + $format = '%' . $indent . 's'; + $this->reference .= \sprintf($format, $text) . "\n"; + } + private function writeArray(array $array, int $depth) : void + { + $arrayIsListFunction = function (array $array) : bool { + if (\function_exists('array_is_list')) { + return \array_is_list($array); + } + if ($array === []) { + return \true; + } + $current_key = 0; + foreach ($array as $key => $noop) { + if ($key !== $current_key) { + return \false; + } + ++$current_key; + } + return \true; + }; + $isIndexed = $arrayIsListFunction($array); + foreach ($array as $key => $value) { + if (\is_array($value)) { + $val = ''; + } else { + $val = $value; + } + if ($isIndexed) { + $this->writeLine('- ' . $val, $depth * 4); + } else { + $this->writeLine(\sprintf('%-20s %s', $key . ':', $val), $depth * 4); + } + if (\is_array($value)) { + $this->writeArray($value, $depth + 1); + } + } + } + private function getPrototypeChildren(PrototypedArrayNode $node) : array + { + $prototype = $node->getPrototype(); + $key = $node->getKeyAttribute(); + // Do not expand prototype if it isn't an array node nor uses attribute as key + if (!$key && !$prototype instanceof ArrayNode) { + return $node->getChildren(); + } + if ($prototype instanceof ArrayNode) { + $keyNode = new ArrayNode($key, $node); + $children = $prototype->getChildren(); + if ($prototype instanceof PrototypedArrayNode && $prototype->getKeyAttribute()) { + $children = $this->getPrototypeChildren($prototype); + } + // add children + foreach ($children as $childNode) { + $keyNode->addChild($childNode); + } + } else { + $keyNode = new ScalarNode($key, $node); + } + $info = 'Prototype'; + if (null !== $prototype->getInfo()) { + $info .= ': ' . $prototype->getInfo(); + } + $keyNode->setInfo($info); + return [$key => $keyNode]; + } +} diff --git a/vendor/symfony/config/Definition/EnumNode.php b/vendor/symfony/config/Definition/EnumNode.php new file mode 100644 index 0000000000..77bd9b2105 --- /dev/null +++ b/vendor/symfony/config/Definition/EnumNode.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +/** + * Node which only allows a finite set of values. + * + * @author Johannes M. Schmitt + */ +class EnumNode extends ScalarNode +{ + /** + * @var mixed[] + */ + private $values; + public function __construct(?string $name, NodeInterface $parent = null, array $values = [], string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR) + { + if (!$values) { + throw new \InvalidArgumentException('$values must contain at least one element.'); + } + foreach ($values as $value) { + if (null === $value || \is_scalar($value)) { + continue; + } + if (!$value instanceof \UnitEnum) { + throw new \InvalidArgumentException(\sprintf('"%s" only supports scalar, enum, or null values, "%s" given.', __CLASS__, \get_debug_type($value))); + } + if (\get_class($value) !== ($enumClass = $enumClass ?? \get_class($value))) { + throw new \InvalidArgumentException(\sprintf('"%s" only supports one type of enum, "%s" and "%s" passed.', __CLASS__, $enumClass, \get_class($value))); + } + } + parent::__construct($name, $parent, $pathSeparator); + $this->values = $values; + } + /** + * @return array + */ + public function getValues() + { + return $this->values; + } + /** + * @internal + */ + public function getPermissibleValues(string $separator) : string + { + return \implode($separator, \array_unique(\array_map(static function ($value) : string { + if (!$value instanceof \UnitEnum) { + return \json_encode($value); + } + return \ltrim(\var_export($value, \true), '\\'); + }, $this->values))); + } + /** + * @return void + * @param mixed $value + */ + protected function validateType($value) + { + if ($value instanceof \UnitEnum) { + return; + } + parent::validateType($value); + } + /** + * @param mixed $value + * @return mixed + */ + protected function finalizeValue($value) + { + $value = parent::finalizeValue($value); + if (!\in_array($value, $this->values, \true)) { + $ex = new InvalidConfigurationException(\sprintf('The value %s is not allowed for path "%s". Permissible values: %s', \json_encode($value), $this->getPath(), $this->getPermissibleValues(', '))); + $ex->setPath($this->getPath()); + throw $ex; + } + return $value; + } +} diff --git a/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php b/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php new file mode 100644 index 0000000000..1c4cf51db2 --- /dev/null +++ b/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception; + +/** + * This exception is thrown whenever the key of an array is not unique. This can + * only be the case if the configuration is coming from an XML file. + * + * @author Johannes M. Schmitt + */ +class DuplicateKeyException extends InvalidConfigurationException +{ +} diff --git a/vendor/symfony/config/Definition/Exception/Exception.php b/vendor/symfony/config/Definition/Exception/Exception.php new file mode 100644 index 0000000000..40634ee9b8 --- /dev/null +++ b/vendor/symfony/config/Definition/Exception/Exception.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception; + +/** + * Base exception for all configuration exceptions. + * + * @author Johannes M. Schmitt + */ +class Exception extends \RuntimeException +{ +} diff --git a/vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php b/vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php new file mode 100644 index 0000000000..7780ab9e1e --- /dev/null +++ b/vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception; + +/** + * This exception is thrown when a configuration path is overwritten from a + * subsequent configuration file, but the entry node specifically forbids this. + * + * @author Johannes M. Schmitt + */ +class ForbiddenOverwriteException extends InvalidConfigurationException +{ +} diff --git a/vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php b/vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php new file mode 100644 index 0000000000..8c7044a5f6 --- /dev/null +++ b/vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception; + +/** + * A very general exception which can be thrown whenever non of the more specific + * exceptions is suitable. + * + * @author Johannes M. Schmitt + */ +class InvalidConfigurationException extends Exception +{ + /** + * @var string|null + */ + private $path; + /** + * @var bool + */ + private $containsHints = \false; + /** + * @return void + */ + public function setPath(string $path) + { + $this->path = $path; + } + public function getPath() : ?string + { + return $this->path; + } + /** + * Adds extra information that is suffixed to the original exception message. + * + * @return void + */ + public function addHint(string $hint) + { + if (!$this->containsHints) { + $this->message .= "\nHint: " . $hint; + $this->containsHints = \true; + } else { + $this->message .= ', ' . $hint; + } + } +} diff --git a/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php b/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php new file mode 100644 index 0000000000..ac304abab6 --- /dev/null +++ b/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception; + +/** + * Thrown when an error is detected in a node Definition. + * + * @author Victor Berchet + */ +class InvalidDefinitionException extends Exception +{ +} diff --git a/vendor/symfony/config/Definition/Exception/InvalidTypeException.php b/vendor/symfony/config/Definition/Exception/InvalidTypeException.php new file mode 100644 index 0000000000..782535530c --- /dev/null +++ b/vendor/symfony/config/Definition/Exception/InvalidTypeException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception; + +/** + * This exception is thrown if an invalid type is encountered. + * + * @author Johannes M. Schmitt + */ +class InvalidTypeException extends InvalidConfigurationException +{ +} diff --git a/vendor/symfony/config/Definition/Exception/UnsetKeyException.php b/vendor/symfony/config/Definition/Exception/UnsetKeyException.php new file mode 100644 index 0000000000..ae8669f2ac --- /dev/null +++ b/vendor/symfony/config/Definition/Exception/UnsetKeyException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception; + +/** + * This exception is usually not encountered by the end-user, but only used + * internally to signal the parent scope to unset a key. + * + * @author Johannes M. Schmitt + */ +class UnsetKeyException extends Exception +{ +} diff --git a/vendor/symfony/config/Definition/FloatNode.php b/vendor/symfony/config/Definition/FloatNode.php new file mode 100644 index 0000000000..15fa26e094 --- /dev/null +++ b/vendor/symfony/config/Definition/FloatNode.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidTypeException; +/** + * This node represents a float value in the config tree. + * + * @author Jeanmonod David + */ +class FloatNode extends NumericNode +{ + /** + * @return void + * @param mixed $value + */ + protected function validateType($value) + { + // Integers are also accepted, we just cast them + if (\is_int($value)) { + $value = (float) $value; + } + if (!\is_float($value)) { + $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "float", but got "%s".', $this->getPath(), \get_debug_type($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + throw $ex; + } + } + protected function getValidPlaceholderTypes() : array + { + return ['float']; + } +} diff --git a/vendor/symfony/config/Definition/IntegerNode.php b/vendor/symfony/config/Definition/IntegerNode.php new file mode 100644 index 0000000000..09719db2d6 --- /dev/null +++ b/vendor/symfony/config/Definition/IntegerNode.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidTypeException; +/** + * This node represents an integer value in the config tree. + * + * @author Jeanmonod David + */ +class IntegerNode extends NumericNode +{ + /** + * @return void + * @param mixed $value + */ + protected function validateType($value) + { + if (!\is_int($value)) { + $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "int", but got "%s".', $this->getPath(), \get_debug_type($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + throw $ex; + } + } + protected function getValidPlaceholderTypes() : array + { + return ['int']; + } +} diff --git a/vendor/symfony/config/Definition/Loader/DefinitionFileLoader.php b/vendor/symfony/config/Definition/Loader/DefinitionFileLoader.php new file mode 100644 index 0000000000..1fdff61a03 --- /dev/null +++ b/vendor/symfony/config/Definition/Loader/DefinitionFileLoader.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Builder\TreeBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\FileLocatorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\FileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * DefinitionFileLoader loads config definitions from a PHP file. + * + * The PHP file is required. + * + * @author Yonel Ceruto + */ +class DefinitionFileLoader extends FileLoader +{ + /** + * @var \Symfony\Component\Config\Definition\Builder\TreeBuilder + */ + private $treeBuilder; + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder|null + */ + private $container; + public function __construct(TreeBuilder $treeBuilder, FileLocatorInterface $locator, ?ContainerBuilder $container = null) + { + $this->treeBuilder = $treeBuilder; + $this->container = $container; + parent::__construct($locator); + } + /** + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + // the loader variable is exposed to the included file below + $loader = $this; + $path = $this->locator->locate($resource); + $this->setCurrentDir(\dirname($path)); + ($nullsafeVariable1 = $this->container) ? $nullsafeVariable1->fileExists($path) : null; + // the closure forbids access to the private scope in the included file + $load = \Closure::bind(static function ($file) use($loader) { + return include $file; + }, null, ProtectedDefinitionFileLoader::class); + $callback = $load($path); + if (\is_object($callback) && \is_callable($callback)) { + $this->executeCallback($callback, new DefinitionConfigurator($this->treeBuilder, $this, $path, $resource), $path); + } + return null; + } + /** + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + if (!\is_string($resource)) { + return \false; + } + if (null === $type && 'php' === \pathinfo($resource, \PATHINFO_EXTENSION)) { + return \true; + } + return 'php' === $type; + } + private function executeCallback(callable $callback, DefinitionConfigurator $configurator, string $path) : void + { + $callback = \Closure::fromCallable($callback); + $arguments = []; + $r = new \ReflectionFunction($callback); + foreach ($r->getParameters() as $parameter) { + $reflectionType = $parameter->getType(); + if (!$reflectionType instanceof \ReflectionNamedType) { + throw new \InvalidArgumentException(\sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s").', $parameter->getName(), $path, DefinitionConfigurator::class)); + } + switch ($reflectionType->getName()) { + case DefinitionConfigurator::class: + $arguments[] = $configurator; + break; + case TreeBuilder::class: + $arguments[] = $this->treeBuilder; + break; + case FileLoader::class: + case self::class: + $arguments[] = $this; + break; + } + } + $callback(...$arguments); + } +} +/** + * @internal + */ +final class ProtectedDefinitionFileLoader extends DefinitionFileLoader +{ +} diff --git a/vendor/symfony/config/Definition/NodeInterface.php b/vendor/symfony/config/Definition/NodeInterface.php new file mode 100644 index 0000000000..9baf8d7b57 --- /dev/null +++ b/vendor/symfony/config/Definition/NodeInterface.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidTypeException; +/** + * Common Interface among all nodes. + * + * In most cases, it is better to inherit from BaseNode instead of implementing + * this interface yourself. + * + * @author Johannes M. Schmitt + */ +interface NodeInterface +{ + /** + * Returns the name of the node. + */ + public function getName() : string; + /** + * Returns the path of the node. + */ + public function getPath() : string; + /** + * Returns true when the node is required. + */ + public function isRequired() : bool; + /** + * Returns true when the node has a default value. + */ + public function hasDefaultValue() : bool; + /** + * Returns the default value of the node. + * + * @throws \RuntimeException if the node has no default value + * @return mixed + */ + public function getDefaultValue(); + /** + * Normalizes a value. + * + * @throws InvalidTypeException if the value type is invalid + * @param mixed $value + * @return mixed + */ + public function normalize($value); + /** + * Merges two values together. + * + * @throws ForbiddenOverwriteException if the configuration path cannot be overwritten + * @throws InvalidTypeException if the value type is invalid + * @param mixed $leftSide + * @param mixed $rightSide + * @return mixed + */ + public function merge($leftSide, $rightSide); + /** + * Finalizes a value. + * + * @throws InvalidTypeException if the value type is invalid + * @throws InvalidConfigurationException if the value is invalid configuration + * @param mixed $value + * @return mixed + */ + public function finalize($value); +} diff --git a/vendor/symfony/config/Definition/NumericNode.php b/vendor/symfony/config/Definition/NumericNode.php new file mode 100644 index 0000000000..6a4d3d1b78 --- /dev/null +++ b/vendor/symfony/config/Definition/NumericNode.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +/** + * This node represents a numeric value in the config tree. + * + * @author David Jeanmonod + */ +class NumericNode extends ScalarNode +{ + protected $min; + protected $max; + /** + * @param int|float $min + * @param int|float $max + */ + public function __construct(?string $name, NodeInterface $parent = null, $min = null, $max = null, string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR) + { + parent::__construct($name, $parent, $pathSeparator); + $this->min = $min; + $this->max = $max; + } + /** + * @param mixed $value + * @return mixed + */ + protected function finalizeValue($value) + { + $value = parent::finalizeValue($value); + $errorMsg = null; + if (isset($this->min) && $value < $this->min) { + $errorMsg = \sprintf('The value %s is too small for path "%s". Should be greater than or equal to %s', $value, $this->getPath(), $this->min); + } + if (isset($this->max) && $value > $this->max) { + $errorMsg = \sprintf('The value %s is too big for path "%s". Should be less than or equal to %s', $value, $this->getPath(), $this->max); + } + if (isset($errorMsg)) { + $ex = new InvalidConfigurationException($errorMsg); + $ex->setPath($this->getPath()); + throw $ex; + } + return $value; + } + /** + * @param mixed $value + */ + protected function isValueEmpty($value) : bool + { + // a numeric value cannot be empty + return \false; + } +} diff --git a/vendor/symfony/config/Definition/Processor.php b/vendor/symfony/config/Definition/Processor.php new file mode 100644 index 0000000000..00da8bf0c5 --- /dev/null +++ b/vendor/symfony/config/Definition/Processor.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +/** + * This class is the entry point for config normalization/merging/finalization. + * + * @author Johannes M. Schmitt + * + * @final + */ +class Processor +{ + /** + * Processes an array of configurations. + * + * @param array $configs An array of configuration items to process + */ + public function process(NodeInterface $configTree, array $configs) : array + { + $currentConfig = []; + foreach ($configs as $config) { + $config = $configTree->normalize($config); + $currentConfig = $configTree->merge($currentConfig, $config); + } + return $configTree->finalize($currentConfig); + } + /** + * Processes an array of configurations. + * + * @param array $configs An array of configuration items to process + */ + public function processConfiguration(ConfigurationInterface $configuration, array $configs) : array + { + return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs); + } + /** + * Normalizes a configuration entry. + * + * This method returns a normalize configuration array for a given key + * to remove the differences due to the original format (YAML and XML mainly). + * + * Here is an example. + * + * The configuration in XML: + * + * twig.extension.foo + * twig.extension.bar + * + * And the same configuration in YAML: + * + * extensions: ['twig.extension.foo', 'twig.extension.bar'] + * + * @param array $config A config array + * @param string $key The key to normalize + * @param string|null $plural The plural form of the key if it is irregular + */ + public static function normalizeConfig(array $config, string $key, string $plural = null) : array + { + $plural = $plural ?? $key . 's'; + if (isset($config[$plural])) { + return $config[$plural]; + } + if (isset($config[$key])) { + if (\is_string($config[$key]) || !\is_int(\key($config[$key]))) { + // only one + return [$config[$key]]; + } + return $config[$key]; + } + return []; + } +} diff --git a/vendor/symfony/config/Definition/PrototypeNodeInterface.php b/vendor/symfony/config/Definition/PrototypeNodeInterface.php new file mode 100644 index 0000000000..5a3534e871 --- /dev/null +++ b/vendor/symfony/config/Definition/PrototypeNodeInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +/** + * This interface must be implemented by nodes which can be used as prototypes. + * + * @author Johannes M. Schmitt + */ +interface PrototypeNodeInterface extends NodeInterface +{ + /** + * Sets the name of the node. + * + * @return void + */ + public function setName(string $name); +} diff --git a/vendor/symfony/config/Definition/PrototypedArrayNode.php b/vendor/symfony/config/Definition/PrototypedArrayNode.php new file mode 100644 index 0000000000..4cc6dc89e9 --- /dev/null +++ b/vendor/symfony/config/Definition/PrototypedArrayNode.php @@ -0,0 +1,348 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\DuplicateKeyException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\Exception; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\UnsetKeyException; +/** + * Represents a prototyped Array node in the config tree. + * + * @author Johannes M. Schmitt + */ +class PrototypedArrayNode extends ArrayNode +{ + protected $prototype; + protected $keyAttribute; + protected $removeKeyAttribute = \false; + protected $minNumberOfElements = 0; + protected $defaultValue = []; + protected $defaultChildren; + /** + * @var NodeInterface[] An array of the prototypes of the simplified value children + */ + private $valuePrototypes = []; + /** + * Sets the minimum number of elements that a prototype based node must + * contain. By default this is zero, meaning no elements. + * + * @return void + */ + public function setMinNumberOfElements(int $number) + { + $this->minNumberOfElements = $number; + } + /** + * Sets the attribute which value is to be used as key. + * + * This is useful when you have an indexed array that should be an + * associative array. You can select an item from within the array + * to be the key of the particular item. For example, if "id" is the + * "key", then: + * + * [ + * ['id' => 'my_name', 'foo' => 'bar'], + * ]; + * + * becomes + * + * [ + * 'my_name' => ['foo' => 'bar'], + * ]; + * + * If you'd like "'id' => 'my_name'" to still be present in the resulting + * array, then you can set the second argument of this method to false. + * + * @param string $attribute The name of the attribute which value is to be used as a key + * @param bool $remove Whether or not to remove the key + * + * @return void + */ + public function setKeyAttribute(string $attribute, bool $remove = \true) + { + $this->keyAttribute = $attribute; + $this->removeKeyAttribute = $remove; + } + /** + * Retrieves the name of the attribute which value should be used as key. + */ + public function getKeyAttribute() : ?string + { + return $this->keyAttribute; + } + /** + * Sets the default value of this node. + * + * @return void + */ + public function setDefaultValue(array $value) + { + $this->defaultValue = $value; + } + public function hasDefaultValue() : bool + { + return \true; + } + /** + * Adds default children when none are set. + * + * @param int|string|array|null $children The number of children|The child name|The children names to be added + * + * @return void + */ + public function setAddChildrenIfNoneSet($children = ['defaults']) + { + if (null === $children) { + $this->defaultChildren = ['defaults']; + } else { + $this->defaultChildren = \is_int($children) && $children > 0 ? \range(1, $children) : (array) $children; + } + } + /** + * The default value could be either explicited or derived from the prototype + * default value. + * @return mixed + */ + public function getDefaultValue() + { + if (null !== $this->defaultChildren) { + $default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : []; + $defaults = []; + foreach (\array_values($this->defaultChildren) as $i => $name) { + $defaults[null === $this->keyAttribute ? $i : $name] = $default; + } + return $defaults; + } + return $this->defaultValue; + } + /** + * Sets the node prototype. + * + * @return void + */ + public function setPrototype(PrototypeNodeInterface $node) + { + $this->prototype = $node; + } + /** + * Retrieves the prototype. + */ + public function getPrototype() : PrototypeNodeInterface + { + return $this->prototype; + } + /** + * Disable adding concrete children for prototyped nodes. + * + * @return never + * + * @throws Exception + */ + public function addChild(NodeInterface $node) + { + throw new Exception('A prototyped array node cannot have concrete children.'); + } + /** + * @param mixed $value + * @return mixed + */ + protected function finalizeValue($value) + { + if (\false === $value) { + throw new UnsetKeyException(\sprintf('Unsetting key for path "%s", value: %s.', $this->getPath(), \json_encode($value))); + } + foreach ($value as $k => $v) { + $prototype = $this->getPrototypeForChild($k); + try { + $value[$k] = $prototype->finalize($v); + } catch (UnsetKeyException $exception) { + unset($value[$k]); + } + } + if (\count($value) < $this->minNumberOfElements) { + $ex = new InvalidConfigurationException(\sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements)); + $ex->setPath($this->getPath()); + throw $ex; + } + return $value; + } + /** + * @throws DuplicateKeyException + * @param mixed $value + * @return mixed + */ + protected function normalizeValue($value) + { + if (\false === $value) { + return $value; + } + $value = $this->remapXml($value); + $arrayIsListFunction = function (array $array) : bool { + if (\function_exists('array_is_list')) { + return \array_is_list($array); + } + if ($array === []) { + return \true; + } + $current_key = 0; + foreach ($array as $key => $noop) { + if ($key !== $current_key) { + return \false; + } + ++$current_key; + } + return \true; + }; + $isList = $arrayIsListFunction($value); + $normalized = []; + foreach ($value as $k => $v) { + if (null !== $this->keyAttribute && \is_array($v)) { + if (!isset($v[$this->keyAttribute]) && \is_int($k) && $isList) { + $ex = new InvalidConfigurationException(\sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath())); + $ex->setPath($this->getPath()); + throw $ex; + } elseif (isset($v[$this->keyAttribute])) { + $k = $v[$this->keyAttribute]; + if (\is_float($k)) { + $k = \var_export($k, \true); + } + // remove the key attribute when required + if ($this->removeKeyAttribute) { + unset($v[$this->keyAttribute]); + } + // if only "value" is left + if (\array_keys($v) === ['value']) { + $v = $v['value']; + if ($this->prototype instanceof ArrayNode && ($children = $this->prototype->getChildren()) && \array_key_exists('value', $children)) { + $valuePrototype = \current($this->valuePrototypes) ?: clone $children['value']; + $valuePrototype->parent = $this; + $originalClosures = $this->prototype->normalizationClosures; + if (\is_array($originalClosures)) { + $valuePrototypeClosures = $valuePrototype->normalizationClosures; + $valuePrototype->normalizationClosures = \is_array($valuePrototypeClosures) ? \array_merge($originalClosures, $valuePrototypeClosures) : $originalClosures; + } + $this->valuePrototypes[$k] = $valuePrototype; + } + } + } + if (\array_key_exists($k, $normalized)) { + $ex = new DuplicateKeyException(\sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath())); + $ex->setPath($this->getPath()); + throw $ex; + } + } + $prototype = $this->getPrototypeForChild($k); + if (null !== $this->keyAttribute || !$isList) { + $normalized[$k] = $prototype->normalize($v); + } else { + $normalized[] = $prototype->normalize($v); + } + } + return $normalized; + } + /** + * @param mixed $leftSide + * @param mixed $rightSide + * @return mixed + */ + protected function mergeValues($leftSide, $rightSide) + { + if (\false === $rightSide) { + // if this is still false after the last config has been merged the + // finalization pass will take care of removing this key entirely + return \false; + } + if (\false === $leftSide || !$this->performDeepMerging) { + return $rightSide; + } + $arrayIsListFunction = function (array $array) : bool { + if (\function_exists('array_is_list')) { + return \array_is_list($array); + } + if ($array === []) { + return \true; + } + $current_key = 0; + foreach ($array as $key => $noop) { + if ($key !== $current_key) { + return \false; + } + ++$current_key; + } + return \true; + }; + $isList = $arrayIsListFunction($rightSide); + foreach ($rightSide as $k => $v) { + // prototype, and key is irrelevant there are no named keys, append the element + if (null === $this->keyAttribute && $isList) { + $leftSide[] = $v; + continue; + } + // no conflict + if (!\array_key_exists($k, $leftSide)) { + if (!$this->allowNewKeys) { + $ex = new InvalidConfigurationException(\sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file.', $this->getPath())); + $ex->setPath($this->getPath()); + throw $ex; + } + $leftSide[$k] = $v; + continue; + } + $prototype = $this->getPrototypeForChild($k); + $leftSide[$k] = $prototype->merge($leftSide[$k], $v); + } + return $leftSide; + } + /** + * Returns a prototype for the child node that is associated to $key in the value array. + * For general child nodes, this will be $this->prototype. + * But if $this->removeKeyAttribute is true and there are only two keys in the child node: + * one is same as this->keyAttribute and the other is 'value', then the prototype will be different. + * + * For example, assume $this->keyAttribute is 'name' and the value array is as follows: + * + * [ + * [ + * 'name' => 'name001', + * 'value' => 'value001' + * ] + * ] + * + * Now, the key is 0 and the child node is: + * + * [ + * 'name' => 'name001', + * 'value' => 'value001' + * ] + * + * When normalizing the value array, the 'name' element will removed from the child node + * and its value becomes the new key of the child node: + * + * [ + * 'name001' => ['value' => 'value001'] + * ] + * + * Now only 'value' element is left in the child node which can be further simplified into a string: + * + * ['name001' => 'value001'] + * + * Now, the key becomes 'name001' and the child node becomes 'value001' and + * the prototype of child node 'name001' should be a ScalarNode instead of an ArrayNode instance. + * @return mixed + */ + private function getPrototypeForChild(string $key) + { + $prototype = $this->valuePrototypes[$key] ?? $this->prototype; + $prototype->setName($key); + return $prototype; + } +} diff --git a/vendor/symfony/config/Definition/ScalarNode.php b/vendor/symfony/config/Definition/ScalarNode.php new file mode 100644 index 0000000000..5e07ec23ff --- /dev/null +++ b/vendor/symfony/config/Definition/ScalarNode.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidTypeException; +/** + * This node represents a scalar value in the config tree. + * + * The following values are considered scalars: + * * booleans + * * strings + * * null + * * integers + * * floats + * + * @author Johannes M. Schmitt + */ +class ScalarNode extends VariableNode +{ + /** + * @return void + * @param mixed $value + */ + protected function validateType($value) + { + if (!\is_scalar($value) && null !== $value) { + $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "scalar", but got "%s".', $this->getPath(), \get_debug_type($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + throw $ex; + } + } + /** + * @param mixed $value + */ + protected function isValueEmpty($value) : bool + { + // assume environment variables are never empty (which in practice is likely to be true during runtime) + // not doing so breaks many configs that are valid today + if ($this->isHandlingPlaceholder()) { + return \false; + } + return null === $value || '' === $value; + } + protected function getValidPlaceholderTypes() : array + { + return ['bool', 'int', 'float', 'string']; + } +} diff --git a/vendor/symfony/config/Definition/VariableNode.php b/vendor/symfony/config/Definition/VariableNode.php new file mode 100644 index 0000000000..1c13042c0e --- /dev/null +++ b/vendor/symfony/config/Definition/VariableNode.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +/** + * This node represents a value of variable type in the config tree. + * + * This node is intended for values of arbitrary type. + * Any PHP type is accepted as a value. + * + * @author Jeremy Mikola + */ +class VariableNode extends BaseNode implements PrototypeNodeInterface +{ + protected $defaultValueSet = \false; + protected $defaultValue; + protected $allowEmptyValue = \true; + /** + * @return void + * @param mixed $value + */ + public function setDefaultValue($value) + { + $this->defaultValueSet = \true; + $this->defaultValue = $value; + } + public function hasDefaultValue() : bool + { + return $this->defaultValueSet; + } + /** + * @return mixed + */ + public function getDefaultValue() + { + $v = $this->defaultValue; + return $v instanceof \Closure ? $v() : $v; + } + /** + * Sets if this node is allowed to have an empty value. + * + * @param bool $boolean True if this entity will accept empty values + * + * @return void + */ + public function setAllowEmptyValue(bool $boolean) + { + $this->allowEmptyValue = $boolean; + } + /** + * @return void + */ + public function setName(string $name) + { + $this->name = $name; + } + /** + * @return void + * @param mixed $value + */ + protected function validateType($value) + { + } + /** + * @param mixed $value + * @return mixed + */ + protected function finalizeValue($value) + { + // deny environment variables only when using custom validators + // this avoids ever passing an empty value to final validation closures + if (!$this->allowEmptyValue && $this->isHandlingPlaceholder() && $this->finalValidationClosures) { + $e = new InvalidConfigurationException(\sprintf('The path "%s" cannot contain an environment variable when empty values are not allowed by definition and are validated.', $this->getPath())); + if ($hint = $this->getInfo()) { + $e->addHint($hint); + } + $e->setPath($this->getPath()); + throw $e; + } + if (!$this->allowEmptyValue && $this->isValueEmpty($value)) { + $ex = new InvalidConfigurationException(\sprintf('The path "%s" cannot contain an empty value, but got %s.', $this->getPath(), \json_encode($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + throw $ex; + } + return $value; + } + /** + * @param mixed $value + * @return mixed + */ + protected function normalizeValue($value) + { + return $value; + } + /** + * @param mixed $leftSide + * @param mixed $rightSide + * @return mixed + */ + protected function mergeValues($leftSide, $rightSide) + { + return $rightSide; + } + /** + * Evaluates if the given value is to be treated as empty. + * + * By default, PHP's empty() function is used to test for emptiness. This + * method may be overridden by subtypes to better match their understanding + * of empty data. + * + * @see finalizeValue() + * @param mixed $value + */ + protected function isValueEmpty($value) : bool + { + return empty($value); + } +} diff --git a/vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php b/vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php new file mode 100644 index 0000000000..40c60dfd95 --- /dev/null +++ b/vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception; + +/** + * Exception class for when a circular reference is detected when importing resources. + * + * @author Fabien Potencier + */ +class FileLoaderImportCircularReferenceException extends LoaderLoadException +{ + public function __construct(array $resources, int $code = 0, \Throwable $previous = null) + { + $message = \sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), \implode('" > "', $resources), $resources[0]); + \Exception::__construct($message, $code, $previous); + } +} diff --git a/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php b/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php new file mode 100644 index 0000000000..417e643d5f --- /dev/null +++ b/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception; + +/** + * File locator exception if a file does not exist. + * + * @author Leo Feyer + */ +class FileLocatorFileNotFoundException extends \InvalidArgumentException +{ + /** + * @var mixed[] + */ + private $paths; + public function __construct(string $message = '', int $code = 0, \Throwable $previous = null, array $paths = []) + { + parent::__construct($message, $code, $previous); + $this->paths = $paths; + } + /** + * @return array + */ + public function getPaths() + { + return $this->paths; + } +} diff --git a/vendor/symfony/config/Exception/LoaderLoadException.php b/vendor/symfony/config/Exception/LoaderLoadException.php new file mode 100644 index 0000000000..dca83d5931 --- /dev/null +++ b/vendor/symfony/config/Exception/LoaderLoadException.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception; + +/** + * Exception class for when a resource cannot be loaded or imported. + * + * @author Ryan Weaver + */ +class LoaderLoadException extends \Exception +{ + /** + * @param mixed $resource The resource that could not be imported + * @param string|null $sourceResource The original resource importing the new resource + * @param int $code The error code + * @param \Throwable|null $previous A previous exception + * @param string|null $type The type of resource + */ + public function __construct($resource, string $sourceResource = null, int $code = 0, \Throwable $previous = null, string $type = null) + { + if (!\is_string($resource)) { + try { + $resource = \json_encode($resource, 0); + } catch (\JsonException $exception) { + $resource = \sprintf('resource of type "%s"', \get_debug_type($resource)); + } + } + $message = ''; + if ($previous) { + // Include the previous exception, to help the user see what might be the underlying cause + // Trim the trailing period of the previous message. We only want 1 period remove so no rtrim... + if (\substr_compare($previous->getMessage(), '.', -\strlen('.')) === 0) { + $trimmedMessage = \substr($previous->getMessage(), 0, -1); + $message .= \sprintf('%s', $trimmedMessage) . ' in '; + } else { + $message .= \sprintf('%s', $previous->getMessage()) . ' in '; + } + $message .= $resource . ' '; + // show tweaked trace to complete the human readable sentence + if (null === $sourceResource) { + $message .= \sprintf('(which is loaded in resource "%s")', $resource); + } else { + $message .= \sprintf('(which is being imported from "%s")', $sourceResource); + } + $message .= '.'; + // if there's no previous message, present it the default way + } elseif (null === $sourceResource) { + $message .= \sprintf('Cannot load resource "%s".', $resource); + } else { + $message .= \sprintf('Cannot import resource "%s" from "%s".', $resource, $sourceResource); + } + // Is the resource located inside a bundle? + if ('@' === $resource[0]) { + $parts = \explode(\DIRECTORY_SEPARATOR, $resource); + $bundle = \substr($parts[0], 1); + $message .= \sprintf(' Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle); + $message .= \sprintf(' If the bundle is registered, make sure the bundle path "%s" is not empty.', $resource); + } elseif (null !== $type) { + $message .= \sprintf(' Make sure there is a loader supporting the "%s" type.', $type); + } + parent::__construct($message, $code, $previous); + } + /** + * @return string + * @param mixed $var + */ + protected function varToString($var) + { + if (\is_object($var)) { + return \sprintf('Object(%s)', \get_class($var)); + } + if (\is_array($var)) { + $a = []; + foreach ($var as $k => $v) { + $a[] = \sprintf('%s => %s', $k, $this->varToString($v)); + } + return \sprintf('Array(%s)', \implode(', ', $a)); + } + if (\is_resource($var)) { + return \sprintf('Resource(%s)', \get_resource_type($var)); + } + if (null === $var) { + return 'null'; + } + if (\false === $var) { + return 'false'; + } + if (\true === $var) { + return 'true'; + } + return (string) $var; + } +} diff --git a/vendor/symfony/config/FileLocator.php b/vendor/symfony/config/FileLocator.php new file mode 100644 index 0000000000..70dd285284 --- /dev/null +++ b/vendor/symfony/config/FileLocator.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; +/** + * FileLocator uses an array of pre-defined paths to find files. + * + * @author Fabien Potencier + */ +class FileLocator implements FileLocatorInterface +{ + protected $paths; + /** + * @param string|string[] $paths A path or an array of paths where to look for resources + */ + public function __construct($paths = []) + { + $this->paths = (array) $paths; + } + /** + * @return string|array + */ + public function locate(string $name, string $currentPath = null, bool $first = \true) + { + if ('' === $name) { + throw new \InvalidArgumentException('An empty file name is not valid to be located.'); + } + if ($this->isAbsolutePath($name)) { + if (!\file_exists($name)) { + throw new FileLocatorFileNotFoundException(\sprintf('The file "%s" does not exist.', $name), 0, null, [$name]); + } + return $name; + } + $paths = $this->paths; + if (null !== $currentPath) { + \array_unshift($paths, $currentPath); + } + $paths = \array_unique($paths); + $filepaths = $notfound = []; + foreach ($paths as $path) { + if (@\file_exists($file = $path . \DIRECTORY_SEPARATOR . $name)) { + if (\true === $first) { + return $file; + } + $filepaths[] = $file; + } else { + $notfound[] = $file; + } + } + if (!$filepaths) { + throw new FileLocatorFileNotFoundException(\sprintf('The file "%s" does not exist (in: "%s").', $name, \implode('", "', $paths)), 0, null, $notfound); + } + return $filepaths; + } + /** + * Returns whether the file path is an absolute path. + */ + private function isAbsolutePath(string $file) : bool + { + if ('/' === $file[0] || '\\' === $file[0] || \strlen($file) > 3 && \ctype_alpha($file[0]) && ':' === $file[1] && ('\\' === $file[2] || '/' === $file[2]) || null !== \parse_url($file, \PHP_URL_SCHEME)) { + return \true; + } + return \false; + } +} diff --git a/vendor/symfony/config/FileLocatorInterface.php b/vendor/symfony/config/FileLocatorInterface.php new file mode 100644 index 0000000000..ddaaa1e76c --- /dev/null +++ b/vendor/symfony/config/FileLocatorInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; +/** + * @author Fabien Potencier + */ +interface FileLocatorInterface +{ + /** + * Returns a full path for a given file name. + * + * @param string $name The file name to locate + * @param string|null $currentPath The current path + * @param bool $first Whether to return the first occurrence or an array of filenames + * + * @return string|array The full path to the file or an array of file paths + * + * @throws \InvalidArgumentException If $name is empty + * @throws FileLocatorFileNotFoundException If a file is not found + */ + public function locate(string $name, string $currentPath = null, bool $first = \true); +} diff --git a/vendor/symfony/config/LICENSE b/vendor/symfony/config/LICENSE new file mode 100644 index 0000000000..0138f8f071 --- /dev/null +++ b/vendor/symfony/config/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/config/Loader/DelegatingLoader.php b/vendor/symfony/config/Loader/DelegatingLoader.php new file mode 100644 index 0000000000..bd4d714f27 --- /dev/null +++ b/vendor/symfony/config/Loader/DelegatingLoader.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\LoaderLoadException; +/** + * DelegatingLoader delegates loading to other loaders using a loader resolver. + * + * This loader acts as an array of LoaderInterface objects - each having + * a chance to load a given resource (handled by the resolver) + * + * @author Fabien Potencier + */ +class DelegatingLoader extends Loader +{ + public function __construct(LoaderResolverInterface $resolver) + { + $this->resolver = $resolver; + } + /** + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + if (\false === ($loader = $this->resolver->resolve($resource, $type))) { + throw new LoaderLoadException($resource, null, 0, null, $type); + } + return $loader->load($resource, $type); + } + /** + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + return \false !== $this->resolver->resolve($resource, $type); + } +} diff --git a/vendor/symfony/config/Loader/DirectoryAwareLoaderInterface.php b/vendor/symfony/config/Loader/DirectoryAwareLoaderInterface.php new file mode 100644 index 0000000000..ed78498eb3 --- /dev/null +++ b/vendor/symfony/config/Loader/DirectoryAwareLoaderInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +/** + * A loader that can be scoped to a given filesystem directory. + * + * @author Alexander M. Turek + */ +interface DirectoryAwareLoaderInterface +{ + /** + * @return static + */ + public function forDirectory(string $currentDirectory); +} diff --git a/vendor/symfony/config/Loader/FileLoader.php b/vendor/symfony/config/Loader/FileLoader.php new file mode 100644 index 0000000000..e64ea78ad9 --- /dev/null +++ b/vendor/symfony/config/Loader/FileLoader.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\LoaderLoadException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\FileLocatorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\FileExistenceResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\GlobResource; +/** + * FileLoader is the abstract class used by all built-in loaders that are file based. + * + * @author Fabien Potencier + */ +abstract class FileLoader extends Loader +{ + protected static $loading = []; + protected $locator; + /** + * @var string|null + */ + private $currentDir; + public function __construct(FileLocatorInterface $locator, string $env = null) + { + $this->locator = $locator; + parent::__construct($env); + } + /** + * Sets the current directory. + * + * @return void + */ + public function setCurrentDir(string $dir) + { + $this->currentDir = $dir; + } + /** + * Returns the file locator used by this loader. + */ + public function getLocator() : FileLocatorInterface + { + return $this->locator; + } + /** + * Imports a resource. + * + * @param mixed $resource A Resource + * @param string|null $type The resource type or null if unknown + * @param bool $ignoreErrors Whether to ignore import errors or not + * @param string|null $sourceResource The original resource importing the new resource + * @param string|mixed[] $exclude Glob patterns to exclude from the import + * + * @return mixed + * + * @throws LoaderLoadException + * @throws FileLoaderImportCircularReferenceException + * @throws FileLocatorFileNotFoundException + */ + public function import($resource, string $type = null, bool $ignoreErrors = \false, string $sourceResource = null, $exclude = null) + { + if (\is_string($resource) && \strlen($resource) !== ($i = \strcspn($resource, '*?{[')) && \strpos($resource, "\n") === \false) { + $excluded = []; + foreach ((array) $exclude as $pattern) { + foreach ($this->glob($pattern, \true, $_, \false, \true) as $path => $info) { + // normalize Windows slashes and remove trailing slashes + $excluded[\rtrim(\str_replace('\\', '/', $path), '/')] = \true; + } + } + $ret = []; + $isSubpath = 0 !== $i && \strpos(\substr($resource, 0, $i), '/') !== \false; + foreach ($this->glob($resource, \false, $_, $ignoreErrors || !$isSubpath, \false, $excluded) as $path => $info) { + if (null !== ($res = $this->doImport($path, 'glob' === $type ? null : $type, $ignoreErrors, $sourceResource))) { + $ret[] = $res; + } + $isSubpath = \true; + } + if ($isSubpath) { + return isset($ret[1]) ? $ret : $ret[0] ?? null; + } + } + return $this->doImport($resource, $type, $ignoreErrors, $sourceResource); + } + /** + * @internal + * @param mixed[]|\Symfony\Component\Config\Resource\GlobResource $resource + */ + protected function glob(string $pattern, bool $recursive, &$resource = null, bool $ignoreErrors = \false, bool $forExclusion = \false, array $excluded = []) : iterable + { + if (\strlen($pattern) === ($i = \strcspn($pattern, '*?{['))) { + $prefix = $pattern; + $pattern = ''; + } elseif (0 === $i || \strpos(\substr($pattern, 0, $i), '/') === \false) { + $prefix = '.'; + $pattern = '/' . $pattern; + } else { + $prefix = \dirname(\substr($pattern, 0, 1 + $i)); + $pattern = \substr($pattern, \strlen($prefix)); + } + try { + $prefix = $this->locator->locate($prefix, $this->currentDir, \true); + } catch (FileLocatorFileNotFoundException $e) { + if (!$ignoreErrors) { + throw $e; + } + $resource = []; + foreach ($e->getPaths() as $path) { + $resource[] = new FileExistenceResource($path); + } + return; + } + $resource = new GlobResource($prefix, $pattern, $recursive, $forExclusion, $excluded); + yield from $resource; + } + /** + * @param mixed $resource + * @return mixed + */ + private function doImport($resource, string $type = null, bool $ignoreErrors = \false, string $sourceResource = null) + { + try { + $loader = $this->resolve($resource, $type); + if ($loader instanceof DirectoryAwareLoaderInterface) { + $loader = $loader->forDirectory($this->currentDir); + } + if (!$loader instanceof self) { + return $loader->load($resource, $type); + } + if (null !== $this->currentDir) { + $resource = $loader->getLocator()->locate($resource, $this->currentDir, \false); + } + $resources = \is_array($resource) ? $resource : [$resource]; + for ($i = 0; $i < ($resourcesCount = \count($resources)); ++$i) { + if (isset(self::$loading[$resources[$i]])) { + if ($i == $resourcesCount - 1) { + throw new FileLoaderImportCircularReferenceException(\array_keys(self::$loading)); + } + } else { + $resource = $resources[$i]; + break; + } + } + self::$loading[$resource] = \true; + try { + $ret = $loader->load($resource, $type); + } finally { + unset(self::$loading[$resource]); + } + return $ret; + } catch (FileLoaderImportCircularReferenceException $e) { + throw $e; + } catch (\Exception $e) { + if (!$ignoreErrors) { + // prevent embedded imports from nesting multiple exceptions + if ($e instanceof LoaderLoadException) { + throw $e; + } + throw new LoaderLoadException($resource, $sourceResource, 0, $e, $type); + } + } + return null; + } +} diff --git a/vendor/symfony/config/Loader/GlobFileLoader.php b/vendor/symfony/config/Loader/GlobFileLoader.php new file mode 100644 index 0000000000..814d8f98f6 --- /dev/null +++ b/vendor/symfony/config/Loader/GlobFileLoader.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +/** + * GlobFileLoader loads files from a glob pattern. + * + * @author Fabien Potencier + */ +class GlobFileLoader extends FileLoader +{ + /** + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + return $this->import($resource); + } + /** + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + return 'glob' === $type; + } +} diff --git a/vendor/symfony/config/Loader/Loader.php b/vendor/symfony/config/Loader/Loader.php new file mode 100644 index 0000000000..235a385ea6 --- /dev/null +++ b/vendor/symfony/config/Loader/Loader.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\LoaderLoadException; +/** + * Loader is the abstract class used by all built-in loaders. + * + * @author Fabien Potencier + */ +abstract class Loader implements LoaderInterface +{ + protected $resolver; + protected $env; + public function __construct(string $env = null) + { + $this->env = $env; + } + public function getResolver() : LoaderResolverInterface + { + return $this->resolver; + } + /** + * @return void + */ + public function setResolver(LoaderResolverInterface $resolver) + { + $this->resolver = $resolver; + } + /** + * Imports a resource. + * + * @return mixed + * @param mixed $resource + */ + public function import($resource, string $type = null) + { + return $this->resolve($resource, $type)->load($resource, $type); + } + /** + * Finds a loader able to load an imported resource. + * + * @throws LoaderLoadException If no loader is found + * @param mixed $resource + */ + public function resolve($resource, string $type = null) : LoaderInterface + { + if ($this->supports($resource, $type)) { + return $this; + } + $loader = null === $this->resolver ? \false : $this->resolver->resolve($resource, $type); + if (\false === $loader) { + throw new LoaderLoadException($resource, null, 0, null, $type); + } + return $loader; + } +} diff --git a/vendor/symfony/config/Loader/LoaderInterface.php b/vendor/symfony/config/Loader/LoaderInterface.php new file mode 100644 index 0000000000..c8e9821ed9 --- /dev/null +++ b/vendor/symfony/config/Loader/LoaderInterface.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +/** + * LoaderInterface is the interface implemented by all loader classes. + * + * @author Fabien Potencier + */ +interface LoaderInterface +{ + /** + * Loads a resource. + * + * @return mixed + * + * @throws \Exception If something went wrong + * @param mixed $resource + */ + public function load($resource, string $type = null); + /** + * Returns whether this class supports the given resource. + * + * @param mixed $resource A resource + * + * @return bool + */ + public function supports($resource, string $type = null); + /** + * Gets the loader resolver. + * + * @return LoaderResolverInterface + */ + public function getResolver(); + /** + * Sets the loader resolver. + * + * @return void + */ + public function setResolver(LoaderResolverInterface $resolver); +} diff --git a/vendor/symfony/config/Loader/LoaderResolver.php b/vendor/symfony/config/Loader/LoaderResolver.php new file mode 100644 index 0000000000..3144fdc9e9 --- /dev/null +++ b/vendor/symfony/config/Loader/LoaderResolver.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +/** + * LoaderResolver selects a loader for a given resource. + * + * A resource can be anything (e.g. a full path to a config file or a Closure). + * Each loader determines whether it can load a resource and how. + * + * @author Fabien Potencier + */ +class LoaderResolver implements LoaderResolverInterface +{ + /** + * @var LoaderInterface[] An array of LoaderInterface objects + */ + private $loaders = []; + /** + * @param LoaderInterface[] $loaders An array of loaders + */ + public function __construct(array $loaders = []) + { + foreach ($loaders as $loader) { + $this->addLoader($loader); + } + } + /** + * @return \Symfony\Component\Config\Loader\LoaderInterface|false + * @param mixed $resource + */ + public function resolve($resource, string $type = null) + { + foreach ($this->loaders as $loader) { + if ($loader->supports($resource, $type)) { + return $loader; + } + } + return \false; + } + /** + * @return void + */ + public function addLoader(LoaderInterface $loader) + { + $this->loaders[] = $loader; + $loader->setResolver($this); + } + /** + * Returns the registered loaders. + * + * @return LoaderInterface[] + */ + public function getLoaders() : array + { + return $this->loaders; + } +} diff --git a/vendor/symfony/config/Loader/LoaderResolverInterface.php b/vendor/symfony/config/Loader/LoaderResolverInterface.php new file mode 100644 index 0000000000..9b9b1cd551 --- /dev/null +++ b/vendor/symfony/config/Loader/LoaderResolverInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +/** + * LoaderResolverInterface selects a loader for a given resource. + * + * @author Fabien Potencier + */ +interface LoaderResolverInterface +{ + /** + * Returns a loader able to load the resource. + * + * @param string|null $type The resource type or null if unknown + * @return \Symfony\Component\Config\Loader\LoaderInterface|false + * @param mixed $resource + */ + public function resolve($resource, string $type = null); +} diff --git a/vendor/symfony/config/Loader/ParamConfigurator.php b/vendor/symfony/config/Loader/ParamConfigurator.php new file mode 100644 index 0000000000..fa6f188e18 --- /dev/null +++ b/vendor/symfony/config/Loader/ParamConfigurator.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader; + +/** + * Placeholder for a parameter. + * + * @author Tobias Nyholm + */ +class ParamConfigurator +{ + /** + * @var string + */ + private $name; + public function __construct(string $name) + { + $this->name = $name; + } + public function __toString() : string + { + return '%' . $this->name . '%'; + } +} diff --git a/vendor/symfony/config/README.md b/vendor/symfony/config/README.md new file mode 100644 index 0000000000..10c2ddd058 --- /dev/null +++ b/vendor/symfony/config/README.md @@ -0,0 +1,15 @@ +Config Component +================ + +The Config component helps find, load, combine, autofill and validate +configuration values of any kind, whatever their source may be (YAML, XML, INI +files, or for instance a database). + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/config.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/config/Resource/ClassExistenceResource.php b/vendor/symfony/config/Resource/ClassExistenceResource.php new file mode 100644 index 0000000000..abee01f01b --- /dev/null +++ b/vendor/symfony/config/Resource/ClassExistenceResource.php @@ -0,0 +1,206 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +/** + * ClassExistenceResource represents a class existence. + * Freshness is only evaluated against resource existence. + * + * The resource must be a fully-qualified class name. + * + * @author Fabien Potencier + * + * @final + */ +class ClassExistenceResource implements SelfCheckingResourceInterface +{ + /** + * @var string + */ + private $resource; + /** + * @var mixed[]|null + */ + private $exists; + /** + * @var int + */ + private static $autoloadLevel = 0; + /** + * @var string|null + */ + private static $autoloadedClass; + /** + * @var mixed[] + */ + private static $existsCache = []; + /** + * @param string $resource The fully-qualified class name + * @param bool|null $exists Boolean when the existence check has already been done + */ + public function __construct(string $resource, bool $exists = null) + { + $this->resource = $resource; + if (null !== $exists) { + $this->exists = [$exists, null]; + } + } + public function __toString() : string + { + return $this->resource; + } + public function getResource() : string + { + return $this->resource; + } + /** + * @throws \ReflectionException when a parent class/interface/trait is not found + */ + public function isFresh(int $timestamp) : bool + { + $loaded = \class_exists($this->resource, \false) || \interface_exists($this->resource, \false) || \trait_exists($this->resource, \false); + if (null !== ($exists =& self::$existsCache[$this->resource])) { + if ($loaded) { + $exists = [\true, null]; + } elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) { + throw new \ReflectionException($exists[1]); + } + } elseif ([\false, null] === ($exists = [$loaded, null])) { + if (!self::$autoloadLevel++) { + \spl_autoload_register(__CLASS__ . '::throwOnRequiredClass'); + } + $autoloadedClass = self::$autoloadedClass; + self::$autoloadedClass = \ltrim($this->resource, '\\'); + try { + $exists[0] = \class_exists($this->resource) || \interface_exists($this->resource, \false) || \trait_exists($this->resource, \false); + } catch (\Exception $e) { + $exists[1] = $e->getMessage(); + try { + self::throwOnRequiredClass($this->resource, $e); + } catch (\ReflectionException $e) { + if (0 >= $timestamp) { + throw $e; + } + } + } catch (\Throwable $e) { + $exists[1] = $e->getMessage(); + throw $e; + } finally { + self::$autoloadedClass = $autoloadedClass; + if (!--self::$autoloadLevel) { + \spl_autoload_unregister(__CLASS__ . '::throwOnRequiredClass'); + } + } + } + $this->exists = $this->exists ?? $exists; + return $this->exists[0] xor !$exists[0]; + } + /** + * @internal + */ + public function __sleep() : array + { + if (null === $this->exists) { + $this->isFresh(0); + } + return ['resource', 'exists']; + } + /** + * @internal + */ + public function __wakeup() + { + if (\is_bool($this->exists)) { + $this->exists = [$this->exists, null]; + } + } + /** + * Throws a reflection exception when the passed class does not exist but is required. + * + * A class is considered "not required" when it's loaded as part of a "class_exists" or similar check. + * + * This function can be used as an autoload function to throw a reflection + * exception if the class was not found by previous autoload functions. + * + * A previous exception can be passed. In this case, the class is considered as being + * required totally, so if it doesn't exist, a reflection exception is always thrown. + * If it exists, the previous exception is rethrown. + * + * @throws \ReflectionException + * + * @internal + */ + public static function throwOnRequiredClass(string $class, \Exception $previous = null) : void + { + // If the passed class is the resource being checked, we shouldn't throw. + if (null === $previous && self::$autoloadedClass === $class) { + return; + } + if (\class_exists($class, \false) || \interface_exists($class, \false) || \trait_exists($class, \false)) { + if (null !== $previous) { + throw $previous; + } + return; + } + if ($previous instanceof \ReflectionException) { + throw $previous; + } + $message = \sprintf('Class "%s" not found.', $class); + if ($class !== (self::$autoloadedClass ?? $class)) { + $message = \substr_replace($message, \sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0); + } + if (null !== $previous) { + $message = $previous->getMessage(); + } + $e = new \ReflectionException($message, 0, $previous); + if (null !== $previous) { + throw $e; + } + $trace = \debug_backtrace(); + $autoloadFrame = ['function' => 'spl_autoload_call', 'args' => [$class]]; + if (isset($trace[1])) { + $callerFrame = $trace[1]; + $i = 2; + } elseif (\false !== ($i = \array_search($autoloadFrame, $trace, \true))) { + $callerFrame = $trace[++$i]; + } else { + throw $e; + } + if (isset($callerFrame['function']) && !isset($callerFrame['class'])) { + switch ($callerFrame['function']) { + case 'get_class_methods': + case 'get_class_vars': + case 'get_parent_class': + case 'is_a': + case 'is_subclass_of': + case 'class_exists': + case 'class_implements': + case 'class_parents': + case 'trait_exists': + case 'defined': + case 'interface_exists': + case 'method_exists': + case 'property_exists': + case 'is_callable': + return; + } + $props = ['file' => $callerFrame['file'] ?? null, 'line' => $callerFrame['line'] ?? null, 'trace' => \array_slice($trace, 1 + $i)]; + foreach ($props as $p => $v) { + if (null !== $v) { + $r = new \ReflectionProperty(\Exception::class, $p); + $r->setAccessible(\true); + $r->setValue($e, $v); + } + } + } + throw $e; + } +} diff --git a/vendor/symfony/config/Resource/ComposerResource.php b/vendor/symfony/config/Resource/ComposerResource.php new file mode 100644 index 0000000000..7b9d1f7f42 --- /dev/null +++ b/vendor/symfony/config/Resource/ComposerResource.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +/** + * ComposerResource tracks the PHP version and Composer dependencies. + * + * @author Nicolas Grekas + * + * @final + */ +class ComposerResource implements SelfCheckingResourceInterface +{ + /** + * @var mixed[] + */ + private $vendors; + /** + * @var mixed[] + */ + private static $runtimeVendors; + public function __construct() + { + self::refresh(); + $this->vendors = self::$runtimeVendors; + } + public function getVendors() : array + { + return \array_keys($this->vendors); + } + public function __toString() : string + { + return __CLASS__; + } + public function isFresh(int $timestamp) : bool + { + self::refresh(); + return \array_values(self::$runtimeVendors) === \array_values($this->vendors); + } + private static function refresh() : void + { + self::$runtimeVendors = []; + foreach (\get_declared_classes() as $class) { + if ('C' === $class[0] && \strncmp($class, 'ComposerAutoloaderInit', \strlen('ComposerAutoloaderInit')) === 0) { + $r = new \ReflectionClass($class); + $v = \dirname($r->getFileName(), 2); + if (\is_file($v . '/composer/installed.json')) { + self::$runtimeVendors[$v] = @\filemtime($v . '/composer/installed.json'); + } + } + } + } +} diff --git a/vendor/symfony/config/Resource/DirectoryResource.php b/vendor/symfony/config/Resource/DirectoryResource.php new file mode 100644 index 0000000000..2c28a8cd57 --- /dev/null +++ b/vendor/symfony/config/Resource/DirectoryResource.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +/** + * DirectoryResource represents a resources stored in a subdirectory tree. + * + * @author Fabien Potencier + * + * @final + */ +class DirectoryResource implements SelfCheckingResourceInterface +{ + /** + * @var string + */ + private $resource; + /** + * @var string|null + */ + private $pattern; + /** + * @param string $resource The file path to the resource + * @param string|null $pattern A pattern to restrict monitored files + * + * @throws \InvalidArgumentException + */ + public function __construct(string $resource, string $pattern = null) + { + $resolvedResource = \realpath($resource) ?: (\file_exists($resource) ? $resource : \false); + $this->pattern = $pattern; + if (\false === $resolvedResource || !\is_dir($resolvedResource)) { + throw new \InvalidArgumentException(\sprintf('The directory "%s" does not exist.', $resource)); + } + $this->resource = $resolvedResource; + } + public function __toString() : string + { + return \hash('xxh128', \serialize([$this->resource, $this->pattern])); + } + public function getResource() : string + { + return $this->resource; + } + public function getPattern() : ?string + { + return $this->pattern; + } + public function isFresh(int $timestamp) : bool + { + if (!\is_dir($this->resource)) { + return \false; + } + if ($timestamp < \filemtime($this->resource)) { + return \false; + } + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) { + // if regex filtering is enabled only check matching files + if ($this->pattern && $file->isFile() && !\preg_match($this->pattern, $file->getBasename())) { + continue; + } + // always monitor directories for changes, except the .. entries + // (otherwise deleted files wouldn't get detected) + if ($file->isDir() && \substr_compare($file, '/..', -\strlen('/..')) === 0) { + continue; + } + // for broken links + try { + $fileMTime = $file->getMTime(); + } catch (\RuntimeException $exception) { + continue; + } + // early return if a file's mtime exceeds the passed timestamp + if ($timestamp < $fileMTime) { + return \false; + } + } + return \true; + } +} diff --git a/vendor/symfony/config/Resource/FileExistenceResource.php b/vendor/symfony/config/Resource/FileExistenceResource.php new file mode 100644 index 0000000000..089862fe20 --- /dev/null +++ b/vendor/symfony/config/Resource/FileExistenceResource.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +/** + * FileExistenceResource represents a resource stored on the filesystem. + * Freshness is only evaluated against resource creation or deletion. + * + * The resource can be a file or a directory. + * + * @author Charles-Henri Bruyand + * + * @final + */ +class FileExistenceResource implements SelfCheckingResourceInterface +{ + /** + * @var string + */ + private $resource; + /** + * @var bool + */ + private $exists; + /** + * @param string $resource The file path to the resource + */ + public function __construct(string $resource) + { + $this->resource = $resource; + $this->exists = \file_exists($resource); + } + public function __toString() : string + { + return $this->resource; + } + public function getResource() : string + { + return $this->resource; + } + public function isFresh(int $timestamp) : bool + { + return \file_exists($this->resource) === $this->exists; + } +} diff --git a/vendor/symfony/config/Resource/FileResource.php b/vendor/symfony/config/Resource/FileResource.php new file mode 100644 index 0000000000..b2dfc02458 --- /dev/null +++ b/vendor/symfony/config/Resource/FileResource.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +/** + * FileResource represents a resource stored on the filesystem. + * + * The resource can be a file or a directory. + * + * @author Fabien Potencier + * + * @final + */ +class FileResource implements SelfCheckingResourceInterface +{ + /** + * @var string + */ + private $resource; + /** + * @param string $resource The file path to the resource + * + * @throws \InvalidArgumentException + */ + public function __construct(string $resource) + { + $resolvedResource = \realpath($resource) ?: (\file_exists($resource) ? $resource : \false); + if (\false === $resolvedResource) { + throw new \InvalidArgumentException(\sprintf('The file "%s" does not exist.', $resource)); + } + $this->resource = $resolvedResource; + } + public function __toString() : string + { + return $this->resource; + } + /** + * Returns the canonicalized, absolute path to the resource. + */ + public function getResource() : string + { + return $this->resource; + } + public function isFresh(int $timestamp) : bool + { + return \false !== ($filemtime = @\filemtime($this->resource)) && $filemtime <= $timestamp; + } +} diff --git a/vendor/symfony/config/Resource/GlobResource.php b/vendor/symfony/config/Resource/GlobResource.php new file mode 100644 index 0000000000..18859990bb --- /dev/null +++ b/vendor/symfony/config/Resource/GlobResource.php @@ -0,0 +1,227 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Finder; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Glob; +/** + * GlobResource represents a set of resources stored on the filesystem. + * + * Only existence/removal is tracked (not mtimes.) + * + * @author Nicolas Grekas + * + * @final + * + * @implements \IteratorAggregate + */ +class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface +{ + /** + * @var string + */ + private $prefix; + /** + * @var string + */ + private $pattern; + /** + * @var bool + */ + private $recursive; + /** + * @var string + */ + private $hash; + /** + * @var bool + */ + private $forExclusion; + /** + * @var mixed[] + */ + private $excludedPrefixes; + /** + * @var int + */ + private $globBrace; + /** + * @param string $prefix A directory prefix + * @param string $pattern A glob pattern + * @param bool $recursive Whether directories should be scanned recursively or not + * + * @throws \InvalidArgumentException + */ + public function __construct(string $prefix, string $pattern, bool $recursive, bool $forExclusion = \false, array $excludedPrefixes = []) + { + \ksort($excludedPrefixes); + $resolvedPrefix = \realpath($prefix) ?: (\file_exists($prefix) ? $prefix : \false); + $this->pattern = $pattern; + $this->recursive = $recursive; + $this->forExclusion = $forExclusion; + $this->excludedPrefixes = $excludedPrefixes; + $this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0; + if (\false === $resolvedPrefix) { + throw new \InvalidArgumentException(\sprintf('The path "%s" does not exist.', $prefix)); + } + $this->prefix = $resolvedPrefix; + } + public function getPrefix() : string + { + return $this->prefix; + } + public function __toString() : string + { + return 'glob.' . $this->prefix . (int) $this->recursive . $this->pattern . (int) $this->forExclusion . \implode("\x00", $this->excludedPrefixes); + } + public function isFresh(int $timestamp) : bool + { + $hash = $this->computeHash(); + $this->hash = $this->hash ?? $hash; + return $this->hash === $hash; + } + /** + * @internal + */ + public function __sleep() : array + { + $this->hash = $this->hash ?? $this->computeHash(); + return ['prefix', 'pattern', 'recursive', 'hash', 'forExclusion', 'excludedPrefixes']; + } + /** + * @internal + */ + public function __wakeup() : void + { + $this->globBrace = \defined('GLOB_BRACE') ? \GLOB_BRACE : 0; + } + public function getIterator() : \Traversable + { + if (!$this->recursive && '' === $this->pattern || !\file_exists($this->prefix)) { + return; + } + if (\is_file($prefix = \str_replace('\\', '/', $this->prefix))) { + $prefix = \dirname($prefix); + $pattern = \basename($prefix) . $this->pattern; + } else { + $pattern = $this->pattern; + } + if (\class_exists(Finder::class)) { + $regex = Glob::toRegex($pattern); + if ($this->recursive) { + $regex = \substr_replace($regex, '(/|$)', -2, 1); + } + } else { + $regex = null; + } + $prefixLen = \strlen($prefix); + $paths = null; + if ('' === $this->pattern && \is_file($this->prefix)) { + $paths = [$this->prefix => null]; + } elseif (\strncmp($this->prefix, 'phar://', \strlen('phar://')) !== 0 && (null !== $regex || \strpos($this->pattern, '/**/') === \false)) { + if (\strpos($this->pattern, '/**/') === \false && ($this->globBrace || \strpos($this->pattern, '{') === \false)) { + $paths = \array_fill_keys(\glob($this->prefix . $this->pattern, \GLOB_NOSORT | $this->globBrace), null); + } elseif (\strpos($this->pattern, '\\') === \false || !\preg_match('/\\\\[,{}]/', $this->pattern)) { + $paths = []; + foreach ($this->expandGlob($this->pattern) as $p) { + if (\false !== ($i = \strpos($p, '/**/'))) { + $p = \substr_replace($p, '/*', $i); + } + $paths += \array_fill_keys(\glob($this->prefix . $p, \GLOB_NOSORT), \false !== $i ? $regex : null); + } + } + } + if (null !== $paths) { + \uksort($paths, 'strnatcmp'); + foreach ($paths as $path => $regex) { + if ($this->excludedPrefixes) { + $normalizedPath = \str_replace('\\', '/', $path); + do { + if (isset($this->excludedPrefixes[$dirPath = $normalizedPath])) { + continue 2; + } + } while ($prefix !== $dirPath && $dirPath !== ($normalizedPath = \dirname($dirPath))); + } + if ((null === $regex || \preg_match($regex, \substr(\str_replace('\\', '/', $path), $prefixLen))) && \is_file($path)) { + (yield $path => new \SplFileInfo($path)); + } + if (!\is_dir($path)) { + continue; + } + if ($this->forExclusion && (null === $regex || \preg_match($regex, \substr(\str_replace('\\', '/', $path), $prefixLen)))) { + (yield $path => new \SplFileInfo($path)); + continue; + } + if (!($this->recursive || null !== $regex) || isset($this->excludedPrefixes[\str_replace('\\', '/', $path)])) { + continue; + } + $files = \iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveCallbackFilterIterator(new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS), function (\SplFileInfo $file, $path) use($regex, $prefixLen) { + return !isset($this->excludedPrefixes[$path = \str_replace('\\', '/', $path)]) && (null === $regex || \preg_match($regex, \substr($path, $prefixLen)) || $file->isDir()) && '.' !== $file->getBasename()[0]; + }), \RecursiveIteratorIterator::LEAVES_ONLY)); + \uksort($files, 'strnatcmp'); + foreach ($files as $path => $info) { + if ($info->isFile()) { + (yield $path => $info); + } + } + } + return; + } + if (!\class_exists(Finder::class)) { + throw new \LogicException('Extended glob patterns cannot be used as the Finder component is not installed. Try running "composer require symfony/finder".'); + } + yield from (new Finder())->followLinks()->filter(function (\SplFileInfo $info) use($regex, $prefixLen, $prefix) { + $normalizedPath = \str_replace('\\', '/', $info->getPathname()); + if (!\preg_match($regex, \substr($normalizedPath, $prefixLen)) || !$info->isFile()) { + return \false; + } + if ($this->excludedPrefixes) { + do { + if (isset($this->excludedPrefixes[$dirPath = $normalizedPath])) { + return \false; + } + } while ($prefix !== $dirPath && $dirPath !== ($normalizedPath = \dirname($dirPath))); + } + })->sortByName()->in($prefix); + } + private function computeHash() : string + { + $hash = \hash_init('xxh128'); + foreach ($this->getIterator() as $path => $info) { + \hash_update($hash, $path . "\n"); + } + return \hash_final($hash); + } + private function expandGlob(string $pattern) : array + { + $segments = \preg_split('/\\{([^{}]*+)\\}/', $pattern, -1, \PREG_SPLIT_DELIM_CAPTURE); + $paths = [$segments[0]]; + $patterns = []; + for ($i = 1; $i < \count($segments); $i += 2) { + $patterns = []; + foreach (\explode(',', $segments[$i]) as $s) { + foreach ($paths as $p) { + $patterns[] = $p . $s . $segments[1 + $i]; + } + } + $paths = $patterns; + } + $j = 0; + foreach ($patterns as $i => $p) { + if (\strpos($p, '{') !== \false) { + $p = $this->expandGlob($p); + \array_splice($paths, $i + $j, 1, $p); + $j += \count($p) - 1; + } + } + return $paths; + } +} diff --git a/vendor/symfony/config/Resource/ReflectionClassResource.php b/vendor/symfony/config/Resource/ReflectionClassResource.php new file mode 100644 index 0000000000..3952ba3d99 --- /dev/null +++ b/vendor/symfony/config/Resource/ReflectionClassResource.php @@ -0,0 +1,191 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +use MonorepoBuilderPrefix202310\Symfony\Component\EventDispatcher\EventSubscriberInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Messenger\Handler\MessageSubscriberInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceSubscriberInterface; +/** + * @author Nicolas Grekas + * + * @final + */ +class ReflectionClassResource implements SelfCheckingResourceInterface +{ + /** + * @var mixed[] + */ + private $files = []; + /** + * @var string + */ + private $className; + /** + * @var \ReflectionClass + */ + private $classReflector; + /** + * @var mixed[] + */ + private $excludedVendors = []; + /** + * @var string + */ + private $hash; + public function __construct(\ReflectionClass $classReflector, array $excludedVendors = []) + { + $this->className = $classReflector->name; + $this->classReflector = $classReflector; + $this->excludedVendors = $excludedVendors; + } + public function isFresh(int $timestamp) : bool + { + if (!isset($this->hash)) { + $this->hash = $this->computeHash(); + $this->loadFiles($this->classReflector); + } + foreach ($this->files as $file => $v) { + if (\false === ($filemtime = @\filemtime($file))) { + return \false; + } + if ($filemtime > $timestamp) { + return $this->hash === $this->computeHash(); + } + } + return \true; + } + public function __toString() : string + { + return 'reflection.' . $this->className; + } + /** + * @internal + */ + public function __sleep() : array + { + if (!isset($this->hash)) { + $this->hash = $this->computeHash(); + $this->loadFiles($this->classReflector); + } + return ['files', 'className', 'hash']; + } + private function loadFiles(\ReflectionClass $class) : void + { + foreach ($class->getInterfaces() as $v) { + $this->loadFiles($v); + } + do { + $file = $class->getFileName(); + if (\false !== $file && \is_file($file)) { + foreach ($this->excludedVendors as $vendor) { + if (\strncmp($file, $vendor, \strlen($vendor)) === 0 && \false !== \strpbrk(\substr($file, \strlen($vendor), 1), '/' . \DIRECTORY_SEPARATOR)) { + $file = \false; + break; + } + } + if ($file) { + $this->files[$file] = null; + } + } + foreach ($class->getTraits() as $v) { + $this->loadFiles($v); + } + } while ($class = $class->getParentClass()); + } + private function computeHash() : string + { + try { + $this->classReflector = $this->classReflector ?? new \ReflectionClass($this->className); + } catch (\ReflectionException $exception) { + // the class does not exist anymore + return \false; + } + $hash = \hash_init('xxh128'); + foreach ($this->generateSignature($this->classReflector) as $info) { + \hash_update($hash, $info); + } + return \hash_final($hash); + } + private function generateSignature(\ReflectionClass $class) : iterable + { + $attributes = []; + foreach (\method_exists($class, 'getAttributes') ? $class->getAttributes() : [] as $a) { + $attributes[] = [$a->getName(), (string) $a]; + } + (yield \print_r($attributes, \true)); + $attributes = []; + (yield $class->getDocComment()); + (yield (int) $class->isFinal()); + (yield (int) $class->isAbstract()); + if ($class->isTrait()) { + (yield \print_r(\class_uses($class->name), \true)); + } else { + (yield \print_r(\class_parents($class->name), \true)); + (yield \print_r(\class_implements($class->name), \true)); + (yield \print_r($class->getConstants(), \true)); + } + if (!$class->isInterface()) { + $defaults = $class->getDefaultProperties(); + foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $p) { + foreach (\method_exists($p, 'getAttributes') ? $p->getAttributes() : [] as $a) { + $attributes[] = [$a->getName(), (string) $a]; + } + (yield \print_r($attributes, \true)); + $attributes = []; + (yield $p->getDocComment()); + (yield $p->isDefault() ? '' : ''); + (yield $p->isPublic() ? 'public' : 'protected'); + (yield $p->isStatic() ? 'static' : ''); + (yield '$' . $p->name); + (yield \print_r(isset($defaults[$p->name]) && !\is_object($defaults[$p->name]) ? $defaults[$p->name] : null, \true)); + } + } + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { + foreach (\method_exists($m, 'getAttributes') ? $m->getAttributes() : [] as $a) { + $attributes[] = [$a->getName(), (string) $a]; + } + (yield \print_r($attributes, \true)); + $attributes = []; + $defaults = []; + foreach ($m->getParameters() as $p) { + foreach (\method_exists($p, 'getAttributes') ? $p->getAttributes() : [] as $a) { + $attributes[] = [$a->getName(), (string) $a]; + } + (yield \print_r($attributes, \true)); + $attributes = []; + if (!$p->isDefaultValueAvailable()) { + $defaults[$p->name] = null; + continue; + } + $defaults[$p->name] = (string) $p; + } + (yield \preg_replace('/^ @@.*/m', '', $m)); + (yield \print_r($defaults, \true)); + } + if ($class->isAbstract() || $class->isInterface() || $class->isTrait()) { + return; + } + if (\interface_exists(EventSubscriberInterface::class, \false) && $class->isSubclassOf(EventSubscriberInterface::class)) { + (yield EventSubscriberInterface::class); + (yield \print_r($class->name::getSubscribedEvents(), \true)); + } + if (\interface_exists(MessageSubscriberInterface::class, \false) && $class->isSubclassOf(MessageSubscriberInterface::class)) { + (yield MessageSubscriberInterface::class); + foreach ($class->name::getHandledMessages() as $key => $value) { + (yield $key . \print_r($value, \true)); + } + } + if (\interface_exists(ServiceSubscriberInterface::class, \false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) { + (yield ServiceSubscriberInterface::class); + (yield \print_r($class->name::getSubscribedServices(), \true)); + } + } +} diff --git a/vendor/symfony/config/Resource/ResourceInterface.php b/vendor/symfony/config/Resource/ResourceInterface.php new file mode 100644 index 0000000000..dcbff4a11c --- /dev/null +++ b/vendor/symfony/config/Resource/ResourceInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +/** + * ResourceInterface is the interface that must be implemented by all Resource classes. + * + * @author Fabien Potencier + */ +interface ResourceInterface +{ + /** + * Returns a string representation of the Resource. + * + * This method is necessary to allow for resource de-duplication, for example by means + * of array_unique(). The string returned need not have a particular meaning, but has + * to be identical for different ResourceInterface instances referring to the same + * resource; and it should be unlikely to collide with that of other, unrelated + * resource instances. + */ + public function __toString() : string; +} diff --git a/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php b/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php new file mode 100644 index 0000000000..879132af42 --- /dev/null +++ b/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\ResourceCheckerInterface; +/** + * Resource checker for instances of SelfCheckingResourceInterface. + * + * As these resources perform the actual check themselves, we can provide + * this class as a standard way of validating them. + * + * @author Matthias Pigulla + */ +class SelfCheckingResourceChecker implements ResourceCheckerInterface +{ + // Common shared cache, because this checker can be used in different + // situations. For example, when using the full stack framework, the router + // and the container have their own cache. But they may check the very same + // resources + /** + * @var mixed[] + */ + private static $cache = []; + public function supports(ResourceInterface $metadata) : bool + { + return $metadata instanceof SelfCheckingResourceInterface; + } + /** + * @param SelfCheckingResourceInterface $resource + */ + public function isFresh(ResourceInterface $resource, int $timestamp) : bool + { + $key = "{$resource}:{$timestamp}"; + return self::$cache[$key] = self::$cache[$key] ?? $resource->isFresh($timestamp); + } +} diff --git a/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php b/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php new file mode 100644 index 0000000000..9689679455 --- /dev/null +++ b/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource; + +/** + * Interface for Resources that can check for freshness autonomously, + * without special support from external services. + * + * @author Matthias Pigulla + */ +interface SelfCheckingResourceInterface extends ResourceInterface +{ + /** + * Returns true if the resource has not been updated since the given timestamp. + * + * @param int $timestamp The last time the resource was loaded + */ + public function isFresh(int $timestamp) : bool; +} diff --git a/vendor/symfony/config/ResourceCheckerConfigCache.php b/vendor/symfony/config/ResourceCheckerConfigCache.php new file mode 100644 index 0000000000..a1e09fbe49 --- /dev/null +++ b/vendor/symfony/config/ResourceCheckerConfigCache.php @@ -0,0 +1,166 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ResourceInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception\IOException; +use MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Filesystem; +/** + * ResourceCheckerConfigCache uses instances of ResourceCheckerInterface + * to check whether cached data is still fresh. + * + * @author Matthias Pigulla + */ +class ResourceCheckerConfigCache implements ConfigCacheInterface +{ + /** + * @var string + */ + private $file; + /** + * @var iterable + */ + private $resourceCheckers; + /** + * @param string $file The absolute cache path + * @param iterable $resourceCheckers The ResourceCheckers to use for the freshness check + */ + public function __construct(string $file, iterable $resourceCheckers = []) + { + $this->file = $file; + $this->resourceCheckers = $resourceCheckers; + } + public function getPath() : string + { + return $this->file; + } + /** + * Checks if the cache is still fresh. + * + * This implementation will make a decision solely based on the ResourceCheckers + * passed in the constructor. + * + * The first ResourceChecker that supports a given resource is considered authoritative. + * Resources with no matching ResourceChecker will silently be ignored and considered fresh. + */ + public function isFresh() : bool + { + if (!\is_file($this->file)) { + return \false; + } + if ($this->resourceCheckers instanceof \Traversable && !$this->resourceCheckers instanceof \Countable) { + $this->resourceCheckers = \iterator_to_array($this->resourceCheckers); + } + if (!\count($this->resourceCheckers)) { + return \true; + // shortcut - if we don't have any checkers we don't need to bother with the meta file at all + } + $metadata = $this->getMetaFile(); + if (!\is_file($metadata)) { + return \false; + } + $meta = $this->safelyUnserialize($metadata); + if (\false === $meta) { + return \false; + } + $time = \filemtime($this->file); + foreach ($meta as $resource) { + foreach ($this->resourceCheckers as $checker) { + if (!$checker->supports($resource)) { + continue; + // next checker + } + if ($checker->isFresh($resource, $time)) { + break; + // no need to further check this resource + } + return \false; + // cache is stale + } + // no suitable checker found, ignore this resource + } + return \true; + } + /** + * Writes cache. + * + * @param string $content The content to write in the cache + * @param ResourceInterface[] $metadata An array of metadata + * + * @return void + * + * @throws \RuntimeException When cache file can't be written + */ + public function write(string $content, array $metadata = null) + { + $mode = 0666; + $umask = \umask(); + $filesystem = new Filesystem(); + $filesystem->dumpFile($this->file, $content); + try { + $filesystem->chmod($this->file, $mode, $umask); + } catch (IOException $exception) { + // discard chmod failure (some filesystem may not support it) + } + if (null !== $metadata) { + $filesystem->dumpFile($this->getMetaFile(), \serialize($metadata)); + try { + $filesystem->chmod($this->getMetaFile(), $mode, $umask); + } catch (IOException $exception) { + // discard chmod failure (some filesystem may not support it) + } + } + if (\function_exists('opcache_invalidate') && \filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL)) { + @\opcache_invalidate($this->file, \true); + } + } + /** + * Gets the meta file path. + */ + private function getMetaFile() : string + { + return $this->file . '.meta'; + } + /** + * @return mixed + */ + private function safelyUnserialize(string $file) + { + $meta = \false; + $content = \file_get_contents($file); + $signalingException = new \UnexpectedValueException(); + $prevUnserializeHandler = \ini_set('unserialize_callback_func', self::class . '::handleUnserializeCallback'); + $prevErrorHandler = \set_error_handler(function ($type, $msg, $file, $line, $context = []) use(&$prevErrorHandler, $signalingException) { + if (__FILE__ === $file) { + throw $signalingException; + } + return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : \false; + }); + try { + $meta = \unserialize($content); + } catch (\Throwable $e) { + if ($e !== $signalingException) { + throw $e; + } + } finally { + \restore_error_handler(); + \ini_set('unserialize_callback_func', $prevUnserializeHandler); + } + return $meta; + } + /** + * @internal + */ + public static function handleUnserializeCallback(string $class) : void + { + \trigger_error('Class not found: ' . $class); + } +} diff --git a/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php b/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php new file mode 100644 index 0000000000..6bf570e7f5 --- /dev/null +++ b/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +/** + * A ConfigCacheFactory implementation that validates the + * cache with an arbitrary set of ResourceCheckers. + * + * @author Matthias Pigulla + */ +class ResourceCheckerConfigCacheFactory implements ConfigCacheFactoryInterface +{ + /** + * @var iterable + */ + private $resourceCheckers = []; + /** + * @param iterable $resourceCheckers + */ + public function __construct(iterable $resourceCheckers = []) + { + $this->resourceCheckers = $resourceCheckers; + } + public function cache(string $file, callable $callable) : ConfigCacheInterface + { + $cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers); + if (!$cache->isFresh()) { + $callable($cache); + } + return $cache; + } +} diff --git a/vendor/symfony/config/ResourceCheckerInterface.php b/vendor/symfony/config/ResourceCheckerInterface.php new file mode 100644 index 0000000000..7033181992 --- /dev/null +++ b/vendor/symfony/config/ResourceCheckerInterface.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ResourceInterface; +/** + * Interface for ResourceCheckers. + * + * When a ResourceCheckerConfigCache instance is checked for freshness, all its associated + * metadata resources are passed to ResourceCheckers. The ResourceCheckers + * can then inspect the resources and decide whether the cache can be considered + * fresh or not. + * + * @author Matthias Pigulla + * @author Benjamin Klotz + */ +interface ResourceCheckerInterface +{ + /** + * Queries the ResourceChecker whether it can validate a given + * resource or not. + * + * @return bool + */ + public function supports(ResourceInterface $metadata); + /** + * Validates the resource. + * + * @param int $timestamp The timestamp at which the cache associated with this resource was created + * + * @return bool + */ + public function isFresh(ResourceInterface $resource, int $timestamp); +} diff --git a/vendor/symfony/config/Util/Exception/InvalidXmlException.php b/vendor/symfony/config/Util/Exception/InvalidXmlException.php new file mode 100644 index 0000000000..d5cadd50fd --- /dev/null +++ b/vendor/symfony/config/Util/Exception/InvalidXmlException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Util\Exception; + +/** + * Exception class for when XML parsing with an XSD schema file path or a callable validator produces errors unrelated + * to the actual XML parsing. + * + * @author Ole Rößner + */ +class InvalidXmlException extends XmlParsingException +{ +} diff --git a/vendor/symfony/config/Util/Exception/XmlParsingException.php b/vendor/symfony/config/Util/Exception/XmlParsingException.php new file mode 100644 index 0000000000..0545ced39d --- /dev/null +++ b/vendor/symfony/config/Util/Exception/XmlParsingException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Util\Exception; + +/** + * Exception class for when XML cannot be parsed properly. + * + * @author Ole Rößner + */ +class XmlParsingException extends \InvalidArgumentException +{ +} diff --git a/vendor/symfony/config/Util/XmlUtils.php b/vendor/symfony/config/Util/XmlUtils.php new file mode 100644 index 0000000000..971c698725 --- /dev/null +++ b/vendor/symfony/config/Util/XmlUtils.php @@ -0,0 +1,235 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Config\Util; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Util\Exception\InvalidXmlException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Util\Exception\XmlParsingException; +/** + * XMLUtils is a bunch of utility methods to XML operations. + * + * This class contains static methods only and is not meant to be instantiated. + * + * @author Fabien Potencier + * @author Martin Hasoň + * @author Ole Rößner + */ +class XmlUtils +{ + /** + * This class should not be instantiated. + */ + private function __construct() + { + } + /** + * Parses an XML string. + * + * @param string $content An XML string + * @param string|callable $schemaOrCallable An XSD schema file path, a callable, or null to disable validation + * + * @throws XmlParsingException When parsing of XML file returns error + * @throws InvalidXmlException When parsing of XML with schema or callable produces any errors unrelated to the XML parsing itself + * @throws \RuntimeException When DOM extension is missing + */ + public static function parse(string $content, $schemaOrCallable = null) : \DOMDocument + { + if (!\extension_loaded('dom')) { + throw new \LogicException('Extension DOM is required.'); + } + $internalErrors = \libxml_use_internal_errors(\true); + \libxml_clear_errors(); + $dom = new \DOMDocument(); + $dom->validateOnParse = \true; + if (!$dom->loadXML($content, \LIBXML_NONET | \LIBXML_COMPACT)) { + throw new XmlParsingException(\implode("\n", static::getXmlErrors($internalErrors))); + } + $dom->normalizeDocument(); + \libxml_use_internal_errors($internalErrors); + foreach ($dom->childNodes as $child) { + if (\XML_DOCUMENT_TYPE_NODE === $child->nodeType) { + throw new XmlParsingException('Document types are not allowed.'); + } + } + if (null !== $schemaOrCallable) { + $internalErrors = \libxml_use_internal_errors(\true); + \libxml_clear_errors(); + $e = null; + if (\is_callable($schemaOrCallable)) { + try { + $valid = $schemaOrCallable($dom, $internalErrors); + } catch (\Exception $e) { + $valid = \false; + } + } elseif (\is_file($schemaOrCallable)) { + $schemaSource = \file_get_contents((string) $schemaOrCallable); + $valid = @$dom->schemaValidateSource($schemaSource); + } else { + \libxml_use_internal_errors($internalErrors); + throw new XmlParsingException(\sprintf('Invalid XSD file: "%s".', $schemaOrCallable)); + } + if (!$valid) { + $messages = static::getXmlErrors($internalErrors); + if (!$messages) { + throw new InvalidXmlException('The XML is not valid.', 0, $e); + } + throw new XmlParsingException(\implode("\n", $messages), 0, $e); + } + } + \libxml_clear_errors(); + \libxml_use_internal_errors($internalErrors); + return $dom; + } + /** + * Loads an XML file. + * + * @param string $file An XML file path + * @param string|callable $schemaOrCallable An XSD schema file path, a callable, or null to disable validation + * + * @throws \InvalidArgumentException When loading of XML file returns error + * @throws XmlParsingException When XML parsing returns any errors + * @throws \RuntimeException When DOM extension is missing + */ + public static function loadFile(string $file, $schemaOrCallable = null) : \DOMDocument + { + if (!\is_file($file)) { + throw new \InvalidArgumentException(\sprintf('Resource "%s" is not a file.', $file)); + } + if (!\is_readable($file)) { + throw new \InvalidArgumentException(\sprintf('File "%s" is not readable.', $file)); + } + $content = @\file_get_contents($file); + if ('' === \trim($content)) { + throw new \InvalidArgumentException(\sprintf('File "%s" does not contain valid XML, it is empty.', $file)); + } + try { + return static::parse($content, $schemaOrCallable); + } catch (InvalidXmlException $e) { + throw new XmlParsingException(\sprintf('The XML file "%s" is not valid.', $file), 0, $e->getPrevious()); + } + } + /** + * Converts a \DOMElement object to a PHP array. + * + * The following rules applies during the conversion: + * + * * Each tag is converted to a key value or an array + * if there is more than one "value" + * + * * The content of a tag is set under a "value" key (bar) + * if the tag also has some nested tags + * + * * The attributes are converted to keys () + * + * * The nested-tags are converted to keys (bar) + * + * @param \DOMElement $element A \DOMElement instance + * @param bool $checkPrefix Check prefix in an element or an attribute name + * @return mixed + */ + public static function convertDomElementToArray(\DOMElement $element, bool $checkPrefix = \true) + { + $prefix = (string) $element->prefix; + $empty = \true; + $config = []; + foreach ($element->attributes as $name => $node) { + if ($checkPrefix && !\in_array((string) $node->prefix, ['', $prefix], \true)) { + continue; + } + $config[$name] = static::phpize($node->value); + $empty = \false; + } + $nodeValue = \false; + foreach ($element->childNodes as $node) { + if ($node instanceof \DOMText) { + if ('' !== \trim($node->nodeValue)) { + $nodeValue = \trim($node->nodeValue); + $empty = \false; + } + } elseif ($checkPrefix && $prefix != (string) $node->prefix) { + continue; + } elseif (!$node instanceof \DOMComment) { + $value = static::convertDomElementToArray($node, $checkPrefix); + $key = $node->localName; + if (isset($config[$key])) { + if (!\is_array($config[$key]) || !\is_int(\key($config[$key]))) { + $config[$key] = [$config[$key]]; + } + $config[$key][] = $value; + } else { + $config[$key] = $value; + } + $empty = \false; + } + } + if (\false !== $nodeValue) { + $value = static::phpize($nodeValue); + if (\count($config)) { + $config['value'] = $value; + } else { + $config = $value; + } + } + return !$empty ? $config : null; + } + /** + * Converts an xml value to a PHP type. + * @param string|\Stringable $value + * @return mixed + */ + public static function phpize($value) + { + $value = (string) $value; + $lowercaseValue = \strtolower($value); + switch (\true) { + case 'null' === $lowercaseValue: + return null; + case \ctype_digit($value): + case isset($value[1]) && '-' === $value[0] && \ctype_digit(\substr($value, 1)): + $raw = $value; + $cast = (int) $value; + return self::isOctal($value) ? \intval($value, 8) : ($raw === (string) $cast ? $cast : $raw); + case 'true' === $lowercaseValue: + return \true; + case 'false' === $lowercaseValue: + return \false; + case isset($value[1]) && '0b' == $value[0] . $value[1] && \preg_match('/^0b[01]*$/', $value): + return \bindec($value); + case \is_numeric($value): + return '0x' === $value[0] . $value[1] ? \hexdec($value) : (float) $value; + case \preg_match('/^0x[0-9a-f]++$/i', $value): + return \hexdec($value); + case \preg_match('/^[+-]?[0-9]+(\\.[0-9]+)?$/', $value): + return (float) $value; + default: + return $value; + } + } + /** + * @return array + */ + protected static function getXmlErrors(bool $internalErrors) + { + $errors = []; + foreach (\libxml_get_errors() as $error) { + $errors[] = \sprintf('[%s %s] %s (in %s - line %d, column %d)', \LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', $error->code, \trim($error->message), $error->file ?: 'n/a', $error->line, $error->column); + } + \libxml_clear_errors(); + \libxml_use_internal_errors($internalErrors); + return $errors; + } + private static function isOctal(string $str) : bool + { + if ('-' === $str[0]) { + $str = \substr($str, 1); + } + return $str === '0' . \decoct(\intval($str, 8)); + } +} diff --git a/vendor/symfony/config/composer.json b/vendor/symfony/config/composer.json new file mode 100644 index 0000000000..349ea880aa --- /dev/null +++ b/vendor/symfony/config/composer.json @@ -0,0 +1,44 @@ +{ + "name": "symfony\/config", + "type": "library", + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "keywords": [], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1", + "symfony\/deprecation-contracts": "^2.5|^3", + "symfony\/filesystem": "^5.4|^6.0", + "symfony\/polyfill-ctype": "~1.8" + }, + "require-dev": { + "symfony\/event-dispatcher": "^5.4|^6.0", + "symfony\/finder": "^5.4|^6.0", + "symfony\/messenger": "^5.4|^6.0", + "symfony\/service-contracts": "^2.5|^3", + "symfony\/yaml": "^5.4|^6.0" + }, + "conflict": { + "symfony\/finder": "<5.4", + "symfony\/service-contracts": "<2.5" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/vendor/symfony/console/Application.php b/vendor/symfony/console/Application.php new file mode 100644 index 0000000000..6061d187dd --- /dev/null +++ b/vendor/symfony/console/Application.php @@ -0,0 +1,1147 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\CompleteCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\DumpCompletionCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\HelpCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\LazyCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\ListCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\SignalableCommandInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\CommandLoader\CommandLoaderInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Suggestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleCommandEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleErrorEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleSignalEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleTerminateEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\CommandNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\NamespaceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\DebugFormatterHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\DescriptorHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\FormatterHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\Helper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\HelperSet; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\ProcessHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\QuestionHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\ArgvInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\ArrayInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputAwareInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\SignalRegistry\SignalRegistry; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Style\SymfonyStyle; +use MonorepoBuilderPrefix202310\Symfony\Component\ErrorHandler\ErrorHandler; +use MonorepoBuilderPrefix202310\Symfony\Contracts\EventDispatcher\EventDispatcherInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ResetInterface; +/** + * An Application is the container for a collection of commands. + * + * It is the main entry point of a Console application. + * + * This class is optimized for a standard CLI environment. + * + * Usage: + * + * $app = new Application('myapp', '1.0 (stable)'); + * $app->add(new SimpleCommand()); + * $app->run(); + * + * @author Fabien Potencier + */ +class Application implements ResetInterface +{ + /** + * @var mixed[] + */ + private $commands = []; + /** + * @var bool + */ + private $wantHelps = \false; + /** + * @var \Symfony\Component\Console\Command\Command|null + */ + private $runningCommand; + /** + * @var string + */ + private $name; + /** + * @var string + */ + private $version; + /** + * @var \Symfony\Component\Console\CommandLoader\CommandLoaderInterface|null + */ + private $commandLoader; + /** + * @var bool + */ + private $catchExceptions = \true; + /** + * @var bool + */ + private $autoExit = \true; + /** + * @var \Symfony\Component\Console\Input\InputDefinition + */ + private $definition; + /** + * @var \Symfony\Component\Console\Helper\HelperSet + */ + private $helperSet; + /** + * @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface|null + */ + private $dispatcher; + /** + * @var \Symfony\Component\Console\Terminal + */ + private $terminal; + /** + * @var string + */ + private $defaultCommand; + /** + * @var bool + */ + private $singleCommand = \false; + /** + * @var bool + */ + private $initialized = \false; + /** + * @var \Symfony\Component\Console\SignalRegistry\SignalRegistry|null + */ + private $signalRegistry; + /** + * @var mixed[] + */ + private $signalsToDispatchEvent = []; + public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN') + { + $this->name = $name; + $this->version = $version; + $this->terminal = new Terminal(); + $this->defaultCommand = 'list'; + if (\defined('SIGINT') && SignalRegistry::isSupported()) { + $this->signalRegistry = new SignalRegistry(); + $this->signalsToDispatchEvent = [\SIGINT, \SIGTERM, \SIGUSR1, \SIGUSR2]; + } + } + /** + * @final + */ + public function setDispatcher(EventDispatcherInterface $dispatcher) : void + { + $this->dispatcher = $dispatcher; + } + /** + * @return void + */ + public function setCommandLoader(CommandLoaderInterface $commandLoader) + { + $this->commandLoader = $commandLoader; + } + public function getSignalRegistry() : SignalRegistry + { + if (!$this->signalRegistry) { + throw new RuntimeException('Signals are not supported. Make sure that the "pcntl" extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.'); + } + return $this->signalRegistry; + } + /** + * @return void + */ + public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent) + { + $this->signalsToDispatchEvent = $signalsToDispatchEvent; + } + /** + * Runs the current application. + * + * @return int 0 if everything went fine, or an error code + * + * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}. + */ + public function run(InputInterface $input = null, OutputInterface $output = null) : int + { + if (\function_exists('putenv')) { + @\putenv('LINES=' . $this->terminal->getHeight()); + @\putenv('COLUMNS=' . $this->terminal->getWidth()); + } + $input = $input ?? new ArgvInput(); + $output = $output ?? new ConsoleOutput(); + $renderException = function (\Throwable $e) use($output) { + if ($output instanceof ConsoleOutputInterface) { + $this->renderThrowable($e, $output->getErrorOutput()); + } else { + $this->renderThrowable($e, $output); + } + }; + if ($phpHandler = \set_exception_handler($renderException)) { + \restore_exception_handler(); + if (!\is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) { + $errorHandler = \true; + } elseif ($errorHandler = $phpHandler[0]->setExceptionHandler($renderException)) { + $phpHandler[0]->setExceptionHandler($errorHandler); + } + } + $this->configureIO($input, $output); + try { + $exitCode = $this->doRun($input, $output); + } catch (\Exception $e) { + if (!$this->catchExceptions) { + throw $e; + } + $renderException($e); + $exitCode = $e->getCode(); + if (\is_numeric($exitCode)) { + $exitCode = (int) $exitCode; + if ($exitCode <= 0) { + $exitCode = 1; + } + } else { + $exitCode = 1; + } + } finally { + // if the exception handler changed, keep it + // otherwise, unregister $renderException + if (!$phpHandler) { + if (\set_exception_handler($renderException) === $renderException) { + \restore_exception_handler(); + } + \restore_exception_handler(); + } elseif (!$errorHandler) { + $finalHandler = $phpHandler[0]->setExceptionHandler(null); + if ($finalHandler !== $renderException) { + $phpHandler[0]->setExceptionHandler($finalHandler); + } + } + } + if ($this->autoExit) { + if ($exitCode > 255) { + $exitCode = 255; + } + exit($exitCode); + } + return $exitCode; + } + /** + * Runs the current application. + * + * @return int 0 if everything went fine, or an error code + */ + public function doRun(InputInterface $input, OutputInterface $output) + { + if (\true === $input->hasParameterOption(['--version', '-V'], \true)) { + $output->writeln($this->getLongVersion()); + return 0; + } + try { + // Makes ArgvInput::getFirstArgument() able to distinguish an option from an argument. + $input->bind($this->getDefinition()); + } catch (ExceptionInterface $exception) { + // Errors must be ignored, full binding/validation happens later when the command is known. + } + $name = $this->getCommandName($input); + if (\true === $input->hasParameterOption(['--help', '-h'], \true)) { + if (!$name) { + $name = 'help'; + $input = new ArrayInput(['command_name' => $this->defaultCommand]); + } else { + $this->wantHelps = \true; + } + } + if (!$name) { + $name = $this->defaultCommand; + $definition = $this->getDefinition(); + $definition->setArguments(\array_merge($definition->getArguments(), ['command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name)])); + } + try { + $this->runningCommand = null; + // the command name MUST be the first element of the input + $command = $this->find($name); + } catch (\Throwable $e) { + if ($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException && 1 === \count($alternatives = $e->getAlternatives()) && $input->isInteractive()) { + $alternative = $alternatives[0]; + $style = new SymfonyStyle($input, $output); + $output->writeln(''); + $formattedBlock = (new FormatterHelper())->formatBlock(\sprintf('Command "%s" is not defined.', $name), 'error', \true); + $output->writeln($formattedBlock); + if (!$style->confirm(\sprintf('Do you want to run "%s" instead? ', $alternative), \false)) { + if (null !== $this->dispatcher) { + $event = new ConsoleErrorEvent($input, $output, $e); + $this->dispatcher->dispatch($event, ConsoleEvents::ERROR); + return $event->getExitCode(); + } + return 1; + } + $command = $this->find($alternative); + } else { + if (null !== $this->dispatcher) { + $event = new ConsoleErrorEvent($input, $output, $e); + $this->dispatcher->dispatch($event, ConsoleEvents::ERROR); + if (0 === $event->getExitCode()) { + return 0; + } + $e = $event->getError(); + } + try { + if ($e instanceof CommandNotFoundException && ($namespace = $this->findNamespace($name))) { + $helper = new DescriptorHelper(); + $helper->describe($output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output, $this, ['format' => 'txt', 'raw_text' => \false, 'namespace' => $namespace, 'short' => \false]); + return isset($event) ? $event->getExitCode() : 1; + } + throw $e; + } catch (NamespaceNotFoundException $exception) { + throw $e; + } + } + } + if ($command instanceof LazyCommand) { + $command = $command->getCommand(); + } + $this->runningCommand = $command; + $exitCode = $this->doRunCommand($command, $input, $output); + $this->runningCommand = null; + return $exitCode; + } + /** + * @return void + */ + public function reset() + { + } + /** + * @return void + */ + public function setHelperSet(HelperSet $helperSet) + { + $this->helperSet = $helperSet; + } + /** + * Get the helper set associated with the command. + */ + public function getHelperSet() : HelperSet + { + return $this->helperSet = $this->helperSet ?? $this->getDefaultHelperSet(); + } + /** + * @return void + */ + public function setDefinition(InputDefinition $definition) + { + $this->definition = $definition; + } + /** + * Gets the InputDefinition related to this Application. + */ + public function getDefinition() : InputDefinition + { + $this->definition = $this->definition ?? $this->getDefaultInputDefinition(); + if ($this->singleCommand) { + $inputDefinition = $this->definition; + $inputDefinition->setArguments(); + return $inputDefinition; + } + return $this->definition; + } + /** + * Adds suggestions to $suggestions for the current completion input (e.g. option or argument). + */ + public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void + { + if (CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType() && 'command' === $input->getCompletionName()) { + foreach ($this->all() as $name => $command) { + // skip hidden commands and aliased commands as they already get added below + if ($command->isHidden() || $command->getName() !== $name) { + continue; + } + $suggestions->suggestValue(new Suggestion($command->getName(), $command->getDescription())); + foreach ($command->getAliases() as $name) { + $suggestions->suggestValue(new Suggestion($name, $command->getDescription())); + } + } + return; + } + if (CompletionInput::TYPE_OPTION_NAME === $input->getCompletionType()) { + $suggestions->suggestOptions($this->getDefinition()->getOptions()); + return; + } + } + /** + * Gets the help message. + */ + public function getHelp() : string + { + return $this->getLongVersion(); + } + /** + * Gets whether to catch exceptions or not during commands execution. + */ + public function areExceptionsCaught() : bool + { + return $this->catchExceptions; + } + /** + * Sets whether to catch exceptions or not during commands execution. + * + * @return void + */ + public function setCatchExceptions(bool $boolean) + { + $this->catchExceptions = $boolean; + } + /** + * Gets whether to automatically exit after a command execution or not. + */ + public function isAutoExitEnabled() : bool + { + return $this->autoExit; + } + /** + * Sets whether to automatically exit after a command execution or not. + * + * @return void + */ + public function setAutoExit(bool $boolean) + { + $this->autoExit = $boolean; + } + /** + * Gets the name of the application. + */ + public function getName() : string + { + return $this->name; + } + /** + * Sets the application name. + * + * @return void + */ + public function setName(string $name) + { + $this->name = $name; + } + /** + * Gets the application version. + */ + public function getVersion() : string + { + return $this->version; + } + /** + * Sets the application version. + * + * @return void + */ + public function setVersion(string $version) + { + $this->version = $version; + } + /** + * Returns the long version of the application. + * + * @return string + */ + public function getLongVersion() + { + if ('UNKNOWN' !== $this->getName()) { + if ('UNKNOWN' !== $this->getVersion()) { + return \sprintf('%s %s', $this->getName(), $this->getVersion()); + } + return $this->getName(); + } + return 'Console Tool'; + } + /** + * Registers a new command. + */ + public function register(string $name) : Command + { + return $this->add(new Command($name)); + } + /** + * Adds an array of command objects. + * + * If a Command is not enabled it will not be added. + * + * @param Command[] $commands An array of commands + * + * @return void + */ + public function addCommands(array $commands) + { + foreach ($commands as $command) { + $this->add($command); + } + } + /** + * Adds a command object. + * + * If a command with the same name already exists, it will be overridden. + * If the command is not enabled it will not be added. + * + * @return Command|null + */ + public function add(Command $command) + { + $this->init(); + $command->setApplication($this); + if (!$command->isEnabled()) { + $command->setApplication(null); + return null; + } + if (!$command instanceof LazyCommand) { + // Will throw if the command is not correctly initialized. + $command->getDefinition(); + } + if (!$command->getName()) { + throw new LogicException(\sprintf('The command defined in "%s" cannot have an empty name.', \get_debug_type($command))); + } + $this->commands[$command->getName()] = $command; + foreach ($command->getAliases() as $alias) { + $this->commands[$alias] = $command; + } + return $command; + } + /** + * Returns a registered command by name or alias. + * + * @return Command + * + * @throws CommandNotFoundException When given command name does not exist + */ + public function get(string $name) + { + $this->init(); + if (!$this->has($name)) { + throw new CommandNotFoundException(\sprintf('The command "%s" does not exist.', $name)); + } + // When the command has a different name than the one used at the command loader level + if (!isset($this->commands[$name])) { + throw new CommandNotFoundException(\sprintf('The "%s" command cannot be found because it is registered under multiple names. Make sure you don\'t set a different name via constructor or "setName()".', $name)); + } + $command = $this->commands[$name]; + if ($this->wantHelps) { + $this->wantHelps = \false; + $helpCommand = $this->get('help'); + $helpCommand->setCommand($command); + return $helpCommand; + } + return $command; + } + /** + * Returns true if the command exists, false otherwise. + */ + public function has(string $name) : bool + { + $this->init(); + return isset($this->commands[$name]) || (($nullsafeVariable1 = $this->commandLoader) ? $nullsafeVariable1->has($name) : null) && $this->add($this->commandLoader->get($name)); + } + /** + * Returns an array of all unique namespaces used by currently registered commands. + * + * It does not return the global namespace which always exists. + * + * @return string[] + */ + public function getNamespaces() : array + { + $namespaces = []; + foreach ($this->all() as $command) { + if ($command->isHidden()) { + continue; + } + $namespaces[] = $this->extractAllNamespaces($command->getName()); + foreach ($command->getAliases() as $alias) { + $namespaces[] = $this->extractAllNamespaces($alias); + } + } + return \array_values(\array_unique(\array_filter(\array_merge([], ...$namespaces)))); + } + /** + * Finds a registered namespace by a name or an abbreviation. + * + * @throws NamespaceNotFoundException When namespace is incorrect or ambiguous + */ + public function findNamespace(string $namespace) : string + { + $allNamespaces = $this->getNamespaces(); + $expr = \implode('[^:]*:', \array_map('preg_quote', \explode(':', $namespace))) . '[^:]*'; + $namespaces = \preg_grep('{^' . $expr . '}', $allNamespaces); + if (empty($namespaces)) { + $message = \sprintf('There are no commands defined in the "%s" namespace.', $namespace); + if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { + if (1 == \count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + $message .= \implode("\n ", $alternatives); + } + throw new NamespaceNotFoundException($message, $alternatives); + } + $exact = \in_array($namespace, $namespaces, \true); + if (\count($namespaces) > 1 && !$exact) { + throw new NamespaceNotFoundException(\sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $namespace, $this->getAbbreviationSuggestions(\array_values($namespaces))), \array_values($namespaces)); + } + return $exact ? $namespace : \reset($namespaces); + } + /** + * Finds a command by name or alias. + * + * Contrary to get, this command tries to find the best + * match if you give it an abbreviation of a name or alias. + * + * @return Command + * + * @throws CommandNotFoundException When command name is incorrect or ambiguous + */ + public function find(string $name) + { + $this->init(); + $aliases = []; + foreach ($this->commands as $command) { + foreach ($command->getAliases() as $alias) { + if (!$this->has($alias)) { + $this->commands[$alias] = $command; + } + } + } + if ($this->has($name)) { + return $this->get($name); + } + $allCommands = $this->commandLoader ? \array_merge($this->commandLoader->getNames(), \array_keys($this->commands)) : \array_keys($this->commands); + $expr = \implode('[^:]*:', \array_map('preg_quote', \explode(':', $name))) . '[^:]*'; + $commands = \preg_grep('{^' . $expr . '}', $allCommands); + if (empty($commands)) { + $commands = \preg_grep('{^' . $expr . '}i', $allCommands); + } + // if no commands matched or we just matched namespaces + if (empty($commands) || \count(\preg_grep('{^' . $expr . '$}i', $commands)) < 1) { + if (\false !== ($pos = \strrpos($name, ':'))) { + // check if a namespace exists and contains commands + $this->findNamespace(\substr($name, 0, $pos)); + } + $message = \sprintf('Command "%s" is not defined.', $name); + if ($alternatives = $this->findAlternatives($name, $allCommands)) { + // remove hidden commands + $alternatives = \array_filter($alternatives, function ($name) { + return !$this->get($name)->isHidden(); + }); + if (1 == \count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + $message .= \implode("\n ", $alternatives); + } + throw new CommandNotFoundException($message, \array_values($alternatives)); + } + // filter out aliases for commands which are already on the list + if (\count($commands) > 1) { + $commandList = $this->commandLoader ? \array_merge(\array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands; + $commands = \array_unique(\array_filter($commands, function ($nameOrAlias) use(&$commandList, $commands, &$aliases) { + if (!$commandList[$nameOrAlias] instanceof Command) { + $commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias); + } + $commandName = $commandList[$nameOrAlias]->getName(); + $aliases[$nameOrAlias] = $commandName; + return $commandName === $nameOrAlias || !\in_array($commandName, $commands); + })); + } + if (\count($commands) > 1) { + $usableWidth = $this->terminal->getWidth() - 10; + $abbrevs = \array_values($commands); + $maxLen = 0; + foreach ($abbrevs as $abbrev) { + $maxLen = \max(Helper::width($abbrev), $maxLen); + } + $abbrevs = \array_map(function ($cmd) use($commandList, $usableWidth, $maxLen, &$commands) { + if ($commandList[$cmd]->isHidden()) { + unset($commands[\array_search($cmd, $commands)]); + return \false; + } + $abbrev = \str_pad($cmd, $maxLen, ' ') . ' ' . $commandList[$cmd]->getDescription(); + return Helper::width($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3) . '...' : $abbrev; + }, \array_values($commands)); + if (\count($commands) > 1) { + $suggestions = $this->getAbbreviationSuggestions(\array_filter($abbrevs)); + throw new CommandNotFoundException(\sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $name, $suggestions), \array_values($commands)); + } + } + $command = $this->get(\reset($commands)); + if ($command->isHidden()) { + throw new CommandNotFoundException(\sprintf('The command "%s" does not exist.', $name)); + } + return $command; + } + /** + * Gets the commands (registered in the given namespace if provided). + * + * The array keys are the full names and the values the command instances. + * + * @return Command[] + */ + public function all(string $namespace = null) + { + $this->init(); + if (null === $namespace) { + if (!$this->commandLoader) { + return $this->commands; + } + $commands = $this->commands; + foreach ($this->commandLoader->getNames() as $name) { + if (!isset($commands[$name]) && $this->has($name)) { + $commands[$name] = $this->get($name); + } + } + return $commands; + } + $commands = []; + foreach ($this->commands as $name => $command) { + if ($namespace === $this->extractNamespace($name, \substr_count($namespace, ':') + 1)) { + $commands[$name] = $command; + } + } + if ($this->commandLoader) { + foreach ($this->commandLoader->getNames() as $name) { + if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, \substr_count($namespace, ':') + 1) && $this->has($name)) { + $commands[$name] = $this->get($name); + } + } + } + return $commands; + } + /** + * Returns an array of possible abbreviations given a set of names. + * + * @return string[][] + */ + public static function getAbbreviations(array $names) : array + { + $abbrevs = []; + foreach ($names as $name) { + for ($len = \strlen($name); $len > 0; --$len) { + $abbrev = \substr($name, 0, $len); + $abbrevs[$abbrev][] = $name; + } + } + return $abbrevs; + } + public function renderThrowable(\Throwable $e, OutputInterface $output) : void + { + $output->writeln('', OutputInterface::VERBOSITY_QUIET); + $this->doRenderThrowable($e, $output); + if (null !== $this->runningCommand) { + $output->writeln(\sprintf('%s', OutputFormatter::escape(\sprintf($this->runningCommand->getSynopsis(), $this->getName()))), OutputInterface::VERBOSITY_QUIET); + $output->writeln('', OutputInterface::VERBOSITY_QUIET); + } + } + protected function doRenderThrowable(\Throwable $e, OutputInterface $output) : void + { + do { + $message = \trim($e->getMessage()); + if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $class = \get_debug_type($e); + $title = \sprintf(' [%s%s] ', $class, 0 !== ($code = $e->getCode()) ? ' (' . $code . ')' : ''); + $len = Helper::width($title); + } else { + $len = 0; + } + if (\strpos($message, "@anonymous\x00") !== \false) { + $message = \preg_replace_callback('/[a-zA-Z_\\x7f-\\xff][\\\\a-zA-Z0-9_\\x7f-\\xff]*+@anonymous\\x00.*?\\.php(?:0x?|:[0-9]++\\$)[0-9a-fA-F]++/', function ($m) { + return \class_exists($m[0], \false) ? ((\get_parent_class($m[0]) ?: \key(\class_implements($m[0]))) ?: 'class') . '@anonymous' : $m[0]; + }, $message); + } + $width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : \PHP_INT_MAX; + $lines = []; + foreach ('' !== $message ? \preg_split('/\\r?\\n/', $message) : [] as $line) { + foreach ($this->splitStringByWidth($line, $width - 4) as $line) { + // pre-format lines to get the right string length + $lineLength = Helper::width($line) + 4; + $lines[] = [$line, $lineLength]; + $len = \max($lineLength, $len); + } + } + $messages = []; + if (!$e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $messages[] = \sprintf('%s', OutputFormatter::escape(\sprintf('In %s line %s:', \basename($e->getFile()) ?: 'n/a', $e->getLine() ?: 'n/a'))); + } + $messages[] = $emptyLine = \sprintf('%s', \str_repeat(' ', $len)); + if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $messages[] = \sprintf('%s%s', $title, \str_repeat(' ', \max(0, $len - Helper::width($title)))); + } + foreach ($lines as $line) { + $messages[] = \sprintf(' %s %s', OutputFormatter::escape($line[0]), \str_repeat(' ', $len - $line[1])); + } + $messages[] = $emptyLine; + $messages[] = ''; + $output->writeln($messages, OutputInterface::VERBOSITY_QUIET); + if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $output->writeln('Exception trace:', OutputInterface::VERBOSITY_QUIET); + // exception related properties + $trace = $e->getTrace(); + \array_unshift($trace, ['function' => '', 'file' => $e->getFile() ?: 'n/a', 'line' => $e->getLine() ?: 'n/a', 'args' => []]); + for ($i = 0, $count = \count($trace); $i < $count; ++$i) { + $class = $trace[$i]['class'] ?? ''; + $type = $trace[$i]['type'] ?? ''; + $function = $trace[$i]['function'] ?? ''; + $file = $trace[$i]['file'] ?? 'n/a'; + $line = $trace[$i]['line'] ?? 'n/a'; + $output->writeln(\sprintf(' %s%s at %s:%s', $class, $function ? $type . $function . '()' : '', $file, $line), OutputInterface::VERBOSITY_QUIET); + } + $output->writeln('', OutputInterface::VERBOSITY_QUIET); + } + } while ($e = $e->getPrevious()); + } + /** + * Configures the input and output instances based on the user arguments and options. + * + * @return void + */ + protected function configureIO(InputInterface $input, OutputInterface $output) + { + if (\true === $input->hasParameterOption(['--ansi'], \true)) { + $output->setDecorated(\true); + } elseif (\true === $input->hasParameterOption(['--no-ansi'], \true)) { + $output->setDecorated(\false); + } + if (\true === $input->hasParameterOption(['--no-interaction', '-n'], \true)) { + $input->setInteractive(\false); + } + switch ($shellVerbosity = (int) \getenv('SHELL_VERBOSITY')) { + case -1: + $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); + break; + case 1: + $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); + break; + case 2: + $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); + break; + case 3: + $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); + break; + default: + $shellVerbosity = 0; + break; + } + if (\true === $input->hasParameterOption(['--quiet', '-q'], \true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); + $shellVerbosity = -1; + } else { + if ($input->hasParameterOption('-vvv', \true) || $input->hasParameterOption('--verbose=3', \true) || 3 === $input->getParameterOption('--verbose', \false, \true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); + $shellVerbosity = 3; + } elseif ($input->hasParameterOption('-vv', \true) || $input->hasParameterOption('--verbose=2', \true) || 2 === $input->getParameterOption('--verbose', \false, \true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); + $shellVerbosity = 2; + } elseif ($input->hasParameterOption('-v', \true) || $input->hasParameterOption('--verbose=1', \true) || $input->hasParameterOption('--verbose', \true) || $input->getParameterOption('--verbose', \false, \true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); + $shellVerbosity = 1; + } + } + if (-1 === $shellVerbosity) { + $input->setInteractive(\false); + } + if (\function_exists('putenv')) { + @\putenv('SHELL_VERBOSITY=' . $shellVerbosity); + } + $_ENV['SHELL_VERBOSITY'] = $shellVerbosity; + $_SERVER['SHELL_VERBOSITY'] = $shellVerbosity; + } + /** + * Runs the current command. + * + * If an event dispatcher has been attached to the application, + * events are also dispatched during the life-cycle of the command. + * + * @return int 0 if everything went fine, or an error code + */ + protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output) + { + foreach ($command->getHelperSet() as $helper) { + if ($helper instanceof InputAwareInterface) { + $helper->setInput($input); + } + } + $commandSignals = $command instanceof SignalableCommandInterface ? $command->getSubscribedSignals() : []; + if ($commandSignals || $this->dispatcher && $this->signalsToDispatchEvent) { + if (!$this->signalRegistry) { + throw new RuntimeException('Unable to subscribe to signal events. Make sure that the "pcntl" extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.'); + } + if (Terminal::hasSttyAvailable()) { + $sttyMode = \shell_exec('stty -g'); + foreach ([\SIGINT, \SIGTERM] as $signal) { + $this->signalRegistry->register($signal, static function () use($sttyMode) { + return \shell_exec('stty ' . $sttyMode); + }); + } + } + if ($this->dispatcher) { + // We register application signals, so that we can dispatch the event + foreach ($this->signalsToDispatchEvent as $signal) { + $event = new ConsoleSignalEvent($command, $input, $output, $signal); + $this->signalRegistry->register($signal, function ($signal) use($event, $command, $commandSignals) { + $this->dispatcher->dispatch($event, ConsoleEvents::SIGNAL); + $exitCode = $event->getExitCode(); + // If the command is signalable, we call the handleSignal() method + if (\in_array($signal, $commandSignals, \true)) { + $exitCode = $command->handleSignal($signal, $exitCode); + // BC layer for Symfony <= 5 + if (null === $exitCode) { + trigger_deprecation('symfony/console', '6.3', 'Not returning an exit code from "%s::handleSignal()" is deprecated, return "false" to keep the command running or "0" to exit successfully.', \get_debug_type($command)); + $exitCode = 0; + } + } + if (\false !== $exitCode) { + exit($exitCode); + } + }); + } + // then we register command signals, but not if already handled after the dispatcher + $commandSignals = \array_diff($commandSignals, $this->signalsToDispatchEvent); + } + foreach ($commandSignals as $signal) { + $this->signalRegistry->register($signal, function (int $signal) use($command) : void { + $exitCode = $command->handleSignal($signal); + // BC layer for Symfony <= 5 + if (null === $exitCode) { + trigger_deprecation('symfony/console', '6.3', 'Not returning an exit code from "%s::handleSignal()" is deprecated, return "false" to keep the command running or "0" to exit successfully.', \get_debug_type($command)); + $exitCode = 0; + } + if (\false !== $exitCode) { + exit($exitCode); + } + }); + } + } + if (null === $this->dispatcher) { + return $command->run($input, $output); + } + // bind before the console.command event, so the listeners have access to input options/arguments + try { + $command->mergeApplicationDefinition(); + $input->bind($command->getDefinition()); + } catch (ExceptionInterface $exception) { + // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition + } + $event = new ConsoleCommandEvent($command, $input, $output); + $e = null; + try { + $this->dispatcher->dispatch($event, ConsoleEvents::COMMAND); + if ($event->commandShouldRun()) { + $exitCode = $command->run($input, $output); + } else { + $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; + } + } catch (\Throwable $e) { + $event = new ConsoleErrorEvent($input, $output, $e, $command); + $this->dispatcher->dispatch($event, ConsoleEvents::ERROR); + $e = $event->getError(); + if (0 === ($exitCode = $event->getExitCode())) { + $e = null; + } + } + $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); + $this->dispatcher->dispatch($event, ConsoleEvents::TERMINATE); + if (null !== $e) { + throw $e; + } + return $event->getExitCode(); + } + /** + * Gets the name of the command based on input. + */ + protected function getCommandName(InputInterface $input) : ?string + { + return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument(); + } + /** + * Gets the default input definition. + */ + protected function getDefaultInputDefinition() : InputDefinition + { + return new InputDefinition([new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display help for the given command. When no command is given display help for the ' . $this->defaultCommand . ' command'), new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'), new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'), new InputOption('--ansi', '', InputOption::VALUE_NEGATABLE, 'Force (or disable --no-ansi) ANSI output', null), new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question')]); + } + /** + * Gets the default commands that should always be available. + * + * @return Command[] + */ + protected function getDefaultCommands() : array + { + return [new HelpCommand(), new ListCommand(), new CompleteCommand(), new DumpCompletionCommand()]; + } + /** + * Gets the default helper set with the helpers that should always be available. + */ + protected function getDefaultHelperSet() : HelperSet + { + return new HelperSet([new FormatterHelper(), new DebugFormatterHelper(), new ProcessHelper(), new QuestionHelper()]); + } + /** + * Returns abbreviated suggestions in string format. + */ + private function getAbbreviationSuggestions(array $abbrevs) : string + { + return ' ' . \implode("\n ", $abbrevs); + } + /** + * Returns the namespace part of the command name. + * + * This method is not part of public API and should not be used directly. + */ + public function extractNamespace(string $name, int $limit = null) : string + { + $parts = \explode(':', $name, -1); + return \implode(':', null === $limit ? $parts : \array_slice($parts, 0, $limit)); + } + /** + * Finds alternative of $name among $collection, + * if nothing is found in $collection, try in $abbrevs. + * + * @return string[] + */ + private function findAlternatives(string $name, iterable $collection) : array + { + $threshold = 1000.0; + $alternatives = []; + $collectionParts = []; + foreach ($collection as $item) { + $collectionParts[$item] = \explode(':', $item); + } + foreach (\explode(':', $name) as $i => $subname) { + foreach ($collectionParts as $collectionName => $parts) { + $exists = isset($alternatives[$collectionName]); + if (!isset($parts[$i]) && $exists) { + $alternatives[$collectionName] += $threshold; + continue; + } elseif (!isset($parts[$i])) { + continue; + } + $lev = \levenshtein($subname, $parts[$i]); + if ($lev <= \strlen($subname) / 3 || '' !== $subname && \strpos($parts[$i], $subname) !== \false) { + $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; + } elseif ($exists) { + $alternatives[$collectionName] += $threshold; + } + } + } + foreach ($collection as $item) { + $lev = \levenshtein($name, $item); + if ($lev <= \strlen($name) / 3 || \strpos($item, $name) !== \false) { + $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; + } + } + $alternatives = \array_filter($alternatives, function ($lev) use($threshold) { + return $lev < 2 * $threshold; + }); + \ksort($alternatives, \SORT_NATURAL | \SORT_FLAG_CASE); + return \array_keys($alternatives); + } + /** + * Sets the default Command name. + * + * @return $this + */ + public function setDefaultCommand(string $commandName, bool $isSingleCommand = \false) + { + $this->defaultCommand = \explode('|', \ltrim($commandName, '|'))[0]; + if ($isSingleCommand) { + // Ensure the command exist + $this->find($commandName); + $this->singleCommand = \true; + } + return $this; + } + /** + * @internal + */ + public function isSingleCommand() : bool + { + return $this->singleCommand; + } + private function splitStringByWidth(string $string, int $width) : array + { + // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly. + // additionally, array_slice() is not enough as some character has doubled width. + // we need a function to split string not by character count but by string width + if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) { + return \str_split($string, $width); + } + $utf8String = \mb_convert_encoding($string, 'utf8', $encoding); + $lines = []; + $line = ''; + $offset = 0; + while (\preg_match('/.{1,10000}/u', $utf8String, $m, 0, $offset)) { + $offset += \strlen($m[0]); + foreach (\preg_split('//u', $m[0]) as $char) { + // test if $char could be appended to current line + if (\mb_strwidth($line . $char, 'utf8') <= $width) { + $line .= $char; + continue; + } + // if not, push current line to array and make new line + $lines[] = \str_pad($line, $width); + $line = $char; + } + } + $lines[] = \count($lines) ? \str_pad($line, $width) : $line; + \mb_convert_variables($encoding, 'utf8', $lines); + return $lines; + } + /** + * Returns all namespaces of the command name. + * + * @return string[] + */ + private function extractAllNamespaces(string $name) : array + { + // -1 as third argument is needed to skip the command short name when exploding + $parts = \explode(':', $name, -1); + $namespaces = []; + foreach ($parts as $part) { + if (\count($namespaces)) { + $namespaces[] = \end($namespaces) . ':' . $part; + } else { + $namespaces[] = $part; + } + } + return $namespaces; + } + private function init() : void + { + if ($this->initialized) { + return; + } + $this->initialized = \true; + foreach ($this->getDefaultCommands() as $command) { + $this->add($command); + } + } +} diff --git a/vendor/symfony/console/Attribute/AsCommand.php b/vendor/symfony/console/Attribute/AsCommand.php new file mode 100644 index 0000000000..45ab0c7c29 --- /dev/null +++ b/vendor/symfony/console/Attribute/AsCommand.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Attribute; + +/** + * Service tag to autoconfigure commands. + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class AsCommand +{ + /** + * @var string + */ + public $name; + /** + * @var string|null + */ + public $description; + public function __construct(string $name, ?string $description = null, array $aliases = [], bool $hidden = \false) + { + $this->name = $name; + $this->description = $description; + if (!$hidden && !$aliases) { + return; + } + $name = \explode('|', $name); + $name = \array_merge($name, $aliases); + if ($hidden && '' !== $name[0]) { + \array_unshift($name, ''); + } + $this->name = \implode('|', $name); + } +} diff --git a/vendor/symfony/console/CHANGELOG.md b/vendor/symfony/console/CHANGELOG.md new file mode 100644 index 0000000000..3428a57de3 --- /dev/null +++ b/vendor/symfony/console/CHANGELOG.md @@ -0,0 +1,252 @@ +CHANGELOG +========= + +6.3 +--- + + * Add support for choosing exit code while handling signal, or to not exit at all + * Add `ProgressBar::setPlaceholderFormatter` to set a placeholder attached to a instance, instead of being global. + * Add `ReStructuredTextDescriptor` + +6.2 +--- + + * Improve truecolor terminal detection in some cases + * Add support for 256 color terminals (conversion from Ansi24 to Ansi8 if terminal is capable of it) + * Deprecate calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()`, `Question::setAutocompleterCallback/setValidator()`without any arguments + * Change the signature of `OutputFormatterStyleInterface::setForeground/setBackground()` to `setForeground/setBackground(?string)` + * Change the signature of `HelperInterface::setHelperSet()` to `setHelperSet(?HelperSet)` + +6.1 +--- + + * Add support to display table vertically when calling setVertical() + * Add method `__toString()` to `InputInterface` + * Added `OutputWrapper` to prevent truncated URL in `SymfonyStyle::createBlock`. + * Deprecate `Command::$defaultName` and `Command::$defaultDescription`, use the `AsCommand` attribute instead + * Add suggested values for arguments and options in input definition, for input completion + * Add `$resumeAt` parameter to `ProgressBar#start()`, so that one can easily 'resume' progress on longer tasks, and still get accurate `getEstimate()` and `getRemaining()` results. + +6.0 +--- + + * `Command::setHidden()` has a default value (`true`) for `$hidden` parameter and is final + * Remove `Helper::strlen()`, use `Helper::width()` instead + * Remove `Helper::strlenWithoutDecoration()`, use `Helper::removeDecoration()` instead + * `AddConsoleCommandPass` can not be configured anymore + * Remove `HelperSet::setCommand()` and `getCommand()` without replacement + +5.4 +--- + + * Add `TesterTrait::assertCommandIsSuccessful()` to test command + * Deprecate `HelperSet::setCommand()` and `getCommand()` without replacement + +5.3 +--- + + * Add `GithubActionReporter` to render annotations in a Github Action + * Add `InputOption::VALUE_NEGATABLE` flag to handle `--foo`/`--no-foo` options + * Add the `Command::$defaultDescription` static property and the `description` attribute + on the `console.command` tag to allow the `list` command to instantiate commands lazily + * Add option `--short` to the `list` command + * Add support for bright colors + * Add `#[AsCommand]` attribute for declaring commands on PHP 8 + * Add `Helper::width()` and `Helper::length()` + * The `--ansi` and `--no-ansi` options now default to `null`. + +5.2.0 +----- + + * Added `SingleCommandApplication::setAutoExit()` to allow testing via `CommandTester` + * added support for multiline responses to questions through `Question::setMultiline()` + and `Question::isMultiline()` + * Added `SignalRegistry` class to stack signals handlers + * Added support for signals: + * Added `Application::getSignalRegistry()` and `Application::setSignalsToDispatchEvent()` methods + * Added `SignalableCommandInterface` interface + * Added `TableCellStyle` class to customize table cell + * Removed `php ` prefix invocation from help messages. + +5.1.0 +----- + + * `Command::setHidden()` is final since Symfony 5.1 + * Add `SingleCommandApplication` + * Add `Cursor` class + +5.0.0 +----- + + * removed support for finding hidden commands using an abbreviation, use the full name instead + * removed `TableStyle::setCrossingChar()` method in favor of `TableStyle::setDefaultCrossingChar()` + * removed `TableStyle::setHorizontalBorderChar()` method in favor of `TableStyle::setDefaultCrossingChars()` + * removed `TableStyle::getHorizontalBorderChar()` method in favor of `TableStyle::getBorderChars()` + * removed `TableStyle::setVerticalBorderChar()` method in favor of `TableStyle::setVerticalBorderChars()` + * removed `TableStyle::getVerticalBorderChar()` method in favor of `TableStyle::getBorderChars()` + * removed support for returning `null` from `Command::execute()`, return `0` instead + * `ProcessHelper::run()` accepts only `array|Symfony\Component\Process\Process` for its `command` argument + * `Application::setDispatcher` accepts only `Symfony\Contracts\EventDispatcher\EventDispatcherInterface` + for its `dispatcher` argument + * renamed `Application::renderException()` and `Application::doRenderException()` + to `renderThrowable()` and `doRenderThrowable()` respectively. + +4.4.0 +----- + + * deprecated finding hidden commands using an abbreviation, use the full name instead + * added `Question::setTrimmable` default to true to allow the answer to be trimmed + * added method `minSecondsBetweenRedraws()` and `maxSecondsBetweenRedraws()` on `ProgressBar` + * `Application` implements `ResetInterface` + * marked all dispatched event classes as `@final` + * added support for displaying table horizontally + * deprecated returning `null` from `Command::execute()`, return `0` instead + * Deprecated the `Application::renderException()` and `Application::doRenderException()` methods, + use `renderThrowable()` and `doRenderThrowable()` instead. + * added support for the `NO_COLOR` env var (https://no-color.org/) + +4.3.0 +----- + + * added support for hyperlinks + * added `ProgressBar::iterate()` method that simplify updating the progress bar when iterating + * added `Question::setAutocompleterCallback()` to provide a callback function + that dynamically generates suggestions as the user types + +4.2.0 +----- + + * allowed passing commands as `[$process, 'ENV_VAR' => 'value']` to + `ProcessHelper::run()` to pass environment variables + * deprecated passing a command as a string to `ProcessHelper::run()`, + pass it the command as an array of its arguments instead + * made the `ProcessHelper` class final + * added `WrappableOutputFormatterInterface::formatAndWrap()` (implemented in `OutputFormatter`) + * added `capture_stderr_separately` option to `CommandTester::execute()` + +4.1.0 +----- + + * added option to run suggested command if command is not found and only 1 alternative is available + * added option to modify console output and print multiple modifiable sections + * added support for iterable messages in output `write` and `writeln` methods + +4.0.0 +----- + + * `OutputFormatter` throws an exception when unknown options are used + * removed `QuestionHelper::setInputStream()/getInputStream()` + * removed `Application::getTerminalWidth()/getTerminalHeight()` and + `Application::setTerminalDimensions()/getTerminalDimensions()` + * removed `ConsoleExceptionEvent` + * removed `ConsoleEvents::EXCEPTION` + +3.4.0 +----- + + * added `SHELL_VERBOSITY` env var to control verbosity + * added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11 + `ContainerCommandLoader` for commands lazy-loading + * added a case-insensitive command name matching fallback + * added static `Command::$defaultName/getDefaultName()`, allowing for + commands to be registered at compile time in the application command loader. + Setting the `$defaultName` property avoids the need for filling the `command` + attribute on the `console.command` tag when using `AddConsoleCommandPass`. + +3.3.0 +----- + + * added `ExceptionListener` + * added `AddConsoleCommandPass` (originally in FrameworkBundle) + * [BC BREAK] `Input::getOption()` no longer returns the default value for options + with value optional explicitly passed empty + * added console.error event to catch exceptions thrown by other listeners + * deprecated console.exception event in favor of console.error + * added ability to handle `CommandNotFoundException` through the + `console.error` event + * deprecated default validation in `SymfonyQuestionHelper::ask` + +3.2.0 +------ + + * added `setInputs()` method to CommandTester for ease testing of commands expecting inputs + * added `setStream()` and `getStream()` methods to Input (implement StreamableInputInterface) + * added StreamableInputInterface + * added LockableTrait + +3.1.0 +----- + + * added truncate method to FormatterHelper + * added setColumnWidth(s) method to Table + +2.8.3 +----- + + * remove readline support from the question helper as it caused issues + +2.8.0 +----- + + * use readline for user input in the question helper when available to allow + the use of arrow keys + +2.6.0 +----- + + * added a Process helper + * added a DebugFormatter helper + +2.5.0 +----- + + * deprecated the dialog helper (use the question helper instead) + * deprecated TableHelper in favor of Table + * deprecated ProgressHelper in favor of ProgressBar + * added ConsoleLogger + * added a question helper + * added a way to set the process name of a command + * added a way to set a default command instead of `ListCommand` + +2.4.0 +----- + + * added a way to force terminal dimensions + * added a convenient method to detect verbosity level + * [BC BREAK] made descriptors use output instead of returning a string + +2.3.0 +----- + + * added multiselect support to the select dialog helper + * added Table Helper for tabular data rendering + * added support for events in `Application` + * added a way to normalize EOLs in `ApplicationTester::getDisplay()` and `CommandTester::getDisplay()` + * added a way to set the progress bar progress via the `setCurrent` method + * added support for multiple InputOption shortcuts, written as `'-a|-b|-c'` + * added two additional verbosity levels, VERBOSITY_VERY_VERBOSE and VERBOSITY_DEBUG + +2.2.0 +----- + + * added support for colorization on Windows via ConEmu + * add a method to Dialog Helper to ask for a question and hide the response + * added support for interactive selections in console (DialogHelper::select()) + * added support for autocompletion as you type in Dialog Helper + +2.1.0 +----- + + * added ConsoleOutputInterface + * added the possibility to disable a command (Command::isEnabled()) + * added suggestions when a command does not exist + * added a --raw option to the list command + * added support for STDERR in the console output class (errors are now sent + to STDERR) + * made the defaults (helper set, commands, input definition) in Application + more easily customizable + * added support for the shell even if readline is not available + * added support for process isolation in Symfony shell via + `--process-isolation` switch + * added support for `--`, which disables options parsing after that point + (tokens will be parsed as arguments) diff --git a/vendor/symfony/console/CI/GithubActionReporter.php b/vendor/symfony/console/CI/GithubActionReporter.php new file mode 100644 index 0000000000..f60d40d229 --- /dev/null +++ b/vendor/symfony/console/CI/GithubActionReporter.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\CI; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Utility class for Github actions. + * + * @author Maxime Steinhausser + */ +class GithubActionReporter +{ + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + /** + * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L80-L85 + */ + private const ESCAPED_DATA = ['%' => '%25', "\r" => '%0D', "\n" => '%0A']; + /** + * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L87-L94 + */ + private const ESCAPED_PROPERTIES = ['%' => '%25', "\r" => '%0D', "\n" => '%0A', ':' => '%3A', ',' => '%2C']; + public function __construct(OutputInterface $output) + { + $this->output = $output; + } + public static function isGithubActionEnvironment() : bool + { + return \false !== \getenv('GITHUB_ACTIONS'); + } + /** + * Output an error using the Github annotations format. + * + * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message + */ + public function error(string $message, string $file = null, int $line = null, int $col = null) : void + { + $this->log('error', $message, $file, $line, $col); + } + /** + * Output a warning using the Github annotations format. + * + * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message + */ + public function warning(string $message, string $file = null, int $line = null, int $col = null) : void + { + $this->log('warning', $message, $file, $line, $col); + } + /** + * Output a debug log using the Github annotations format. + * + * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message + */ + public function debug(string $message, string $file = null, int $line = null, int $col = null) : void + { + $this->log('debug', $message, $file, $line, $col); + } + private function log(string $type, string $message, string $file = null, int $line = null, int $col = null) : void + { + // Some values must be encoded. + $message = \strtr($message, self::ESCAPED_DATA); + if (!$file) { + // No file provided, output the message solely: + $this->output->writeln(\sprintf('::%s::%s', $type, $message)); + return; + } + $this->output->writeln(\sprintf('::%s file=%s,line=%s,col=%s::%s', $type, \strtr($file, self::ESCAPED_PROPERTIES), \strtr($line ?? 1, self::ESCAPED_PROPERTIES), \strtr($col ?? 0, self::ESCAPED_PROPERTIES), $message)); + } +} diff --git a/vendor/symfony/console/Color.php b/vendor/symfony/console/Color.php new file mode 100644 index 0000000000..9acbcfe518 --- /dev/null +++ b/vendor/symfony/console/Color.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +/** + * @author Fabien Potencier + */ +final class Color +{ + private const COLORS = ['black' => 0, 'red' => 1, 'green' => 2, 'yellow' => 3, 'blue' => 4, 'magenta' => 5, 'cyan' => 6, 'white' => 7, 'default' => 9]; + private const BRIGHT_COLORS = ['gray' => 0, 'bright-red' => 1, 'bright-green' => 2, 'bright-yellow' => 3, 'bright-blue' => 4, 'bright-magenta' => 5, 'bright-cyan' => 6, 'bright-white' => 7]; + private const AVAILABLE_OPTIONS = ['bold' => ['set' => 1, 'unset' => 22], 'underscore' => ['set' => 4, 'unset' => 24], 'blink' => ['set' => 5, 'unset' => 25], 'reverse' => ['set' => 7, 'unset' => 27], 'conceal' => ['set' => 8, 'unset' => 28]]; + /** + * @var string + */ + private $foreground; + /** + * @var string + */ + private $background; + /** + * @var mixed[] + */ + private $options = []; + public function __construct(string $foreground = '', string $background = '', array $options = []) + { + $this->foreground = $this->parseColor($foreground); + $this->background = $this->parseColor($background, \true); + foreach ($options as $option) { + if (!isset(self::AVAILABLE_OPTIONS[$option])) { + throw new InvalidArgumentException(\sprintf('Invalid option specified: "%s". Expected one of (%s).', $option, \implode(', ', \array_keys(self::AVAILABLE_OPTIONS)))); + } + $this->options[$option] = self::AVAILABLE_OPTIONS[$option]; + } + } + public function apply(string $text) : string + { + return $this->set() . $text . $this->unset(); + } + public function set() : string + { + $setCodes = []; + if ('' !== $this->foreground) { + $setCodes[] = $this->foreground; + } + if ('' !== $this->background) { + $setCodes[] = $this->background; + } + foreach ($this->options as $option) { + $setCodes[] = $option['set']; + } + if (0 === \count($setCodes)) { + return ''; + } + return \sprintf("\x1b[%sm", \implode(';', $setCodes)); + } + public function unset() : string + { + $unsetCodes = []; + if ('' !== $this->foreground) { + $unsetCodes[] = 39; + } + if ('' !== $this->background) { + $unsetCodes[] = 49; + } + foreach ($this->options as $option) { + $unsetCodes[] = $option['unset']; + } + if (0 === \count($unsetCodes)) { + return ''; + } + return \sprintf("\x1b[%sm", \implode(';', $unsetCodes)); + } + private function parseColor(string $color, bool $background = \false) : string + { + if ('' === $color) { + return ''; + } + if ('#' === $color[0]) { + return ($background ? '4' : '3') . Terminal::getColorMode()->convertFromHexToAnsiColorCode($color); + } + if (isset(self::COLORS[$color])) { + return ($background ? '4' : '3') . self::COLORS[$color]; + } + if (isset(self::BRIGHT_COLORS[$color])) { + return ($background ? '10' : '9') . self::BRIGHT_COLORS[$color]; + } + throw new InvalidArgumentException(\sprintf('Invalid "%s" color; expected one of (%s).', $color, \implode(', ', \array_merge(\array_keys(self::COLORS), \array_keys(self::BRIGHT_COLORS))))); + } +} diff --git a/vendor/symfony/console/Command/Command.php b/vendor/symfony/console/Command/Command.php new file mode 100644 index 0000000000..8e380bd0ad --- /dev/null +++ b/vendor/symfony/console/Command/Command.php @@ -0,0 +1,677 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Attribute\AsCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Suggestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\HelperInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\HelperSet; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Base class for all commands. + * + * @author Fabien Potencier + */ +class Command +{ + // see https://tldp.org/LDP/abs/html/exitcodes.html + public const SUCCESS = 0; + public const FAILURE = 1; + public const INVALID = 2; + /** + * @var string|null The default command name + * + * @deprecated since Symfony 6.1, use the AsCommand attribute instead + */ + protected static $defaultName; + /** + * @var string|null The default command description + * + * @deprecated since Symfony 6.1, use the AsCommand attribute instead + */ + protected static $defaultDescription; + /** + * @var \Symfony\Component\Console\Application|null + */ + private $application; + /** + * @var string|null + */ + private $name; + /** + * @var string|null + */ + private $processTitle; + /** + * @var mixed[] + */ + private $aliases = []; + /** + * @var \Symfony\Component\Console\Input\InputDefinition + */ + private $definition; + /** + * @var bool + */ + private $hidden = \false; + /** + * @var string + */ + private $help = ''; + /** + * @var string + */ + private $description = ''; + /** + * @var \Symfony\Component\Console\Input\InputDefinition|null + */ + private $fullDefinition; + /** + * @var bool + */ + private $ignoreValidationErrors = \false; + /** + * @var \Closure|null + */ + private $code; + /** + * @var mixed[] + */ + private $synopsis = []; + /** + * @var mixed[] + */ + private $usages = []; + /** + * @var \Symfony\Component\Console\Helper\HelperSet|null + */ + private $helperSet; + public static function getDefaultName() : ?string + { + $class = static::class; + if ($attribute = \method_exists(new \ReflectionClass($class), 'getAttributes') ? (new \ReflectionClass($class))->getAttributes(AsCommand::class) : []) { + return $attribute[0]->newInstance()->name; + } + $r = new \ReflectionProperty($class, 'defaultName'); + $r->setAccessible(\true); + if ($class !== $r->class || null === static::$defaultName) { + return null; + } + trigger_deprecation('symfony/console', '6.1', 'Relying on the static property "$defaultName" for setting a command name is deprecated. Add the "%s" attribute to the "%s" class instead.', AsCommand::class, static::class); + return static::$defaultName; + } + public static function getDefaultDescription() : ?string + { + $class = static::class; + if ($attribute = \method_exists(new \ReflectionClass($class), 'getAttributes') ? (new \ReflectionClass($class))->getAttributes(AsCommand::class) : []) { + return $attribute[0]->newInstance()->description; + } + $r = new \ReflectionProperty($class, 'defaultDescription'); + $r->setAccessible(\true); + if ($class !== $r->class || null === static::$defaultDescription) { + return null; + } + trigger_deprecation('symfony/console', '6.1', 'Relying on the static property "$defaultDescription" for setting a command description is deprecated. Add the "%s" attribute to the "%s" class instead.', AsCommand::class, static::class); + return static::$defaultDescription; + } + /** + * @param string|null $name The name of the command; passing null means it must be set in configure() + * + * @throws LogicException When the command name is empty + */ + public function __construct(string $name = null) + { + $this->definition = new InputDefinition(); + if (null === $name && null !== ($name = static::getDefaultName())) { + $aliases = \explode('|', $name); + if ('' === ($name = \array_shift($aliases))) { + $this->setHidden(\true); + $name = \array_shift($aliases); + } + $this->setAliases($aliases); + } + if (null !== $name) { + $this->setName($name); + } + if ('' === $this->description) { + $this->setDescription(static::getDefaultDescription() ?? ''); + } + $this->configure(); + } + /** + * Ignores validation errors. + * + * This is mainly useful for the help command. + * + * @return void + */ + public function ignoreValidationErrors() + { + $this->ignoreValidationErrors = \true; + } + /** + * @return void + */ + public function setApplication(Application $application = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + $this->application = $application; + if ($application) { + $this->setHelperSet($application->getHelperSet()); + } else { + $this->helperSet = null; + } + $this->fullDefinition = null; + } + /** + * @return void + */ + public function setHelperSet(HelperSet $helperSet) + { + $this->helperSet = $helperSet; + } + /** + * Gets the helper set. + */ + public function getHelperSet() : ?HelperSet + { + return $this->helperSet; + } + /** + * Gets the application instance for this command. + */ + public function getApplication() : ?Application + { + return $this->application; + } + /** + * Checks whether the command is enabled or not in the current environment. + * + * Override this to check for x or y and return false if the command cannot + * run properly under the current conditions. + * + * @return bool + */ + public function isEnabled() + { + return \true; + } + /** + * Configures the current command. + * + * @return void + */ + protected function configure() + { + } + /** + * Executes the current command. + * + * This method is not abstract because you can use this class + * as a concrete class. In this case, instead of defining the + * execute() method, you set the code to execute by passing + * a Closure to the setCode() method. + * + * @return int 0 if everything went fine, or an exit code + * + * @throws LogicException When this abstract method is not implemented + * + * @see setCode() + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + throw new LogicException('You must override the execute() method in the concrete command class.'); + } + /** + * Interacts with the user. + * + * This method is executed before the InputDefinition is validated. + * This means that this is the only place where the command can + * interactively ask for values of missing required arguments. + * + * @return void + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + } + /** + * Initializes the command after the input has been bound and before the input + * is validated. + * + * This is mainly useful when a lot of commands extends one main command + * where some things need to be initialized based on the input arguments and options. + * + * @see InputInterface::bind() + * @see InputInterface::validate() + * + * @return void + */ + protected function initialize(InputInterface $input, OutputInterface $output) + { + } + /** + * Runs the command. + * + * The code to execute is either defined directly with the + * setCode() method or by overriding the execute() method + * in a sub-class. + * + * @return int The command exit code + * + * @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}. + * + * @see setCode() + * @see execute() + */ + public function run(InputInterface $input, OutputInterface $output) : int + { + // add the application arguments and options + $this->mergeApplicationDefinition(); + // bind the input against the command specific arguments/options + try { + $input->bind($this->getDefinition()); + } catch (ExceptionInterface $e) { + if (!$this->ignoreValidationErrors) { + throw $e; + } + } + $this->initialize($input, $output); + if (null !== $this->processTitle) { + if (\function_exists('cli_set_process_title')) { + if (!@\cli_set_process_title($this->processTitle)) { + if ('Darwin' === \PHP_OS) { + $output->writeln('Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.', OutputInterface::VERBOSITY_VERY_VERBOSE); + } else { + \cli_set_process_title($this->processTitle); + } + } + } elseif (\function_exists('MonorepoBuilderPrefix202310\\setproctitle')) { + setproctitle($this->processTitle); + } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) { + $output->writeln('Install the proctitle PECL to be able to change the process title.'); + } + } + if ($input->isInteractive()) { + $this->interact($input, $output); + } + // The command name argument is often omitted when a command is executed directly with its run() method. + // It would fail the validation if we didn't make sure the command argument is present, + // since it's required by the application. + if ($input->hasArgument('command') && null === $input->getArgument('command')) { + $input->setArgument('command', $this->getName()); + } + $input->validate(); + if ($this->code) { + $statusCode = ($this->code)($input, $output); + } else { + $statusCode = $this->execute($input, $output); + if (!\is_int($statusCode)) { + throw new \TypeError(\sprintf('Return value of "%s::execute()" must be of the type int, "%s" returned.', static::class, \get_debug_type($statusCode))); + } + } + return \is_numeric($statusCode) ? (int) $statusCode : 0; + } + /** + * Adds suggestions to $suggestions for the current completion input (e.g. option or argument). + */ + public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void + { + $definition = $this->getDefinition(); + if (CompletionInput::TYPE_OPTION_VALUE === $input->getCompletionType() && $definition->hasOption($input->getCompletionName())) { + $definition->getOption($input->getCompletionName())->complete($input, $suggestions); + } elseif (CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType() && $definition->hasArgument($input->getCompletionName())) { + $definition->getArgument($input->getCompletionName())->complete($input, $suggestions); + } + } + /** + * Sets the code to execute when running this command. + * + * If this method is used, it overrides the code defined + * in the execute() method. + * + * @param callable $code A callable(InputInterface $input, OutputInterface $output) + * + * @return $this + * + * @throws InvalidArgumentException + * + * @see execute() + */ + public function setCode(callable $code) + { + if ($code instanceof \Closure) { + $r = new \ReflectionFunction($code); + if (null === $r->getClosureThis()) { + \set_error_handler(static function () { + }); + try { + if ($c = \Closure::bind($code, $this)) { + $code = $c; + } + } finally { + \restore_error_handler(); + } + } + } else { + $code = \Closure::fromCallable($code); + } + $this->code = $code; + return $this; + } + /** + * Merges the application definition with the command definition. + * + * This method is not part of public API and should not be used directly. + * + * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments + * + * @internal + */ + public function mergeApplicationDefinition(bool $mergeArgs = \true) : void + { + if (null === $this->application) { + return; + } + $this->fullDefinition = new InputDefinition(); + $this->fullDefinition->setOptions($this->definition->getOptions()); + $this->fullDefinition->addOptions($this->application->getDefinition()->getOptions()); + if ($mergeArgs) { + $this->fullDefinition->setArguments($this->application->getDefinition()->getArguments()); + $this->fullDefinition->addArguments($this->definition->getArguments()); + } else { + $this->fullDefinition->setArguments($this->definition->getArguments()); + } + } + /** + * Sets an array of argument and option instances. + * + * @return $this + * @param mixed[]|\Symfony\Component\Console\Input\InputDefinition $definition + */ + public function setDefinition($definition) + { + if ($definition instanceof InputDefinition) { + $this->definition = $definition; + } else { + $this->definition->setDefinition($definition); + } + $this->fullDefinition = null; + return $this; + } + /** + * Gets the InputDefinition attached to this Command. + */ + public function getDefinition() : InputDefinition + { + return $this->fullDefinition ?? $this->getNativeDefinition(); + } + /** + * Gets the InputDefinition to be used to create representations of this Command. + * + * Can be overridden to provide the original command representation when it would otherwise + * be changed by merging with the application InputDefinition. + * + * This method is not part of public API and should not be used directly. + */ + public function getNativeDefinition() : InputDefinition + { + if (!isset($this->definition)) { + throw new LogicException(\sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', static::class)); + } + return $this->definition; + } + /** + * Adds an argument. + * + * @param $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL + * @param $default The default value (for InputArgument::OPTIONAL mode only) + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * + * @return $this + * + * @throws InvalidArgumentException When argument mode is not valid + * @param mixed $default + */ + public function addArgument(string $name, int $mode = null, string $description = '', $default = null) + { + $suggestedValues = 5 <= \func_num_args() ? \func_get_arg(4) : []; + if (!\is_array($suggestedValues) && !$suggestedValues instanceof \Closure) { + throw new \TypeError(\sprintf('Argument 5 passed to "%s()" must be array or \\Closure, "%s" given.', __METHOD__, \get_debug_type($suggestedValues))); + } + $this->definition->addArgument(new InputArgument($name, $mode, $description, $default, $suggestedValues)); + ($nullsafeVariable1 = $this->fullDefinition) ? $nullsafeVariable1->addArgument(new InputArgument($name, $mode, $description, $default, $suggestedValues)) : null; + return $this; + } + /** + * Adds an option. + * + * @param $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param $mode The option mode: One of the InputOption::VALUE_* constants + * @param $default The default value (must be null for InputOption::VALUE_NONE) + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * + * @return $this + * + * @throws InvalidArgumentException If option mode is invalid or incompatible + * @param string|mixed[] $shortcut + * @param mixed $default + */ + public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) + { + $suggestedValues = 6 <= \func_num_args() ? \func_get_arg(5) : []; + if (!\is_array($suggestedValues) && !$suggestedValues instanceof \Closure) { + throw new \TypeError(\sprintf('Argument 5 passed to "%s()" must be array or \\Closure, "%s" given.', __METHOD__, \get_debug_type($suggestedValues))); + } + $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default, $suggestedValues)); + ($nullsafeVariable2 = $this->fullDefinition) ? $nullsafeVariable2->addOption(new InputOption($name, $shortcut, $mode, $description, $default, $suggestedValues)) : null; + return $this; + } + /** + * Sets the name of the command. + * + * This method can set both the namespace and the name if + * you separate them by a colon (:) + * + * $command->setName('foo:bar'); + * + * @return $this + * + * @throws InvalidArgumentException When the name is invalid + */ + public function setName(string $name) + { + $this->validateName($name); + $this->name = $name; + return $this; + } + /** + * Sets the process title of the command. + * + * This feature should be used only when creating a long process command, + * like a daemon. + * + * @return $this + */ + public function setProcessTitle(string $title) + { + $this->processTitle = $title; + return $this; + } + /** + * Returns the command name. + */ + public function getName() : ?string + { + return $this->name; + } + /** + * @param bool $hidden Whether or not the command should be hidden from the list of commands + * + * @return $this + */ + public function setHidden(bool $hidden = \true) + { + $this->hidden = $hidden; + return $this; + } + /** + * @return bool whether the command should be publicly shown or not + */ + public function isHidden() : bool + { + return $this->hidden; + } + /** + * Sets the description for the command. + * + * @return $this + */ + public function setDescription(string $description) + { + $this->description = $description; + return $this; + } + /** + * Returns the description for the command. + */ + public function getDescription() : string + { + return $this->description; + } + /** + * Sets the help for the command. + * + * @return $this + */ + public function setHelp(string $help) + { + $this->help = $help; + return $this; + } + /** + * Returns the help for the command. + */ + public function getHelp() : string + { + return $this->help; + } + /** + * Returns the processed help for the command replacing the %command.name% and + * %command.full_name% patterns with the real values dynamically. + */ + public function getProcessedHelp() : string + { + $name = $this->name; + $isSingleCommand = ($nullsafeVariable3 = $this->application) ? $nullsafeVariable3->isSingleCommand() : null; + $placeholders = ['%command.name%', '%command.full_name%']; + $replacements = [$name, $isSingleCommand ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'] . ' ' . $name]; + return \str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription()); + } + /** + * Sets the aliases for the command. + * + * @param string[] $aliases An array of aliases for the command + * + * @return $this + * + * @throws InvalidArgumentException When an alias is invalid + */ + public function setAliases(iterable $aliases) + { + $list = []; + foreach ($aliases as $alias) { + $this->validateName($alias); + $list[] = $alias; + } + $this->aliases = \is_array($aliases) ? $aliases : $list; + return $this; + } + /** + * Returns the aliases for the command. + */ + public function getAliases() : array + { + return $this->aliases; + } + /** + * Returns the synopsis for the command. + * + * @param bool $short Whether to show the short version of the synopsis (with options folded) or not + */ + public function getSynopsis(bool $short = \false) : string + { + $key = $short ? 'short' : 'long'; + if (!isset($this->synopsis[$key])) { + $this->synopsis[$key] = \trim(\sprintf('%s %s', $this->name, $this->definition->getSynopsis($short))); + } + return $this->synopsis[$key]; + } + /** + * Add a command usage example, it'll be prefixed with the command name. + * + * @return $this + */ + public function addUsage(string $usage) + { + if (\strncmp($usage, $this->name, \strlen($this->name)) !== 0) { + $usage = \sprintf('%s %s', $this->name, $usage); + } + $this->usages[] = $usage; + return $this; + } + /** + * Returns alternative usages of the command. + */ + public function getUsages() : array + { + return $this->usages; + } + /** + * Gets a helper instance by name. + * + * @return HelperInterface + * + * @throws LogicException if no HelperSet is defined + * @throws InvalidArgumentException if the helper is not defined + */ + public function getHelper(string $name) + { + if (null === $this->helperSet) { + 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)); + } + return $this->helperSet->get($name); + } + /** + * Validates a command name. + * + * It must be non-empty and parts can optionally be separated by ":". + * + * @throws InvalidArgumentException When the name is invalid + */ + private function validateName(string $name) : void + { + if (!\preg_match('/^[^\\:]++(\\:[^\\:]++)*$/', $name)) { + throw new InvalidArgumentException(\sprintf('Command name "%s" is invalid.', $name)); + } + } +} diff --git a/vendor/symfony/console/Command/CompleteCommand.php b/vendor/symfony/console/Command/CompleteCommand.php new file mode 100644 index 0000000000..44efe83ceb --- /dev/null +++ b/vendor/symfony/console/Command/CompleteCommand.php @@ -0,0 +1,158 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Attribute\AsCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output\BashCompletionOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output\CompletionOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output\FishCompletionOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output\ZshCompletionOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\CommandNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Responsible for providing the values to the shell completion. + * + * @author Wouter de Jong + */ +final class CompleteCommand extends Command +{ + public const COMPLETION_API_VERSION = '1'; + /** + * @deprecated since Symfony 6.1 + */ + protected static $defaultName = '|_complete'; + /** + * @deprecated since Symfony 6.1 + */ + protected static $defaultDescription = 'Internal command to provide shell completion suggestions'; + private $completionOutputs; + private $isDebug = \false; + /** + * @param array> $completionOutputs A list of additional completion outputs, with shell name as key and FQCN as value + */ + public function __construct(array $completionOutputs = []) + { + // must be set before the parent constructor, as the property value is used in configure() + $this->completionOutputs = $completionOutputs + ['bash' => BashCompletionOutput::class, 'fish' => FishCompletionOutput::class, 'zsh' => ZshCompletionOutput::class]; + parent::__construct(); + } + protected function configure() : void + { + $this->addOption('shell', 's', InputOption::VALUE_REQUIRED, 'The shell type ("' . \implode('", "', \array_keys($this->completionOutputs)) . '")')->addOption('input', 'i', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'An array of input tokens (e.g. COMP_WORDS or argv)')->addOption('current', 'c', InputOption::VALUE_REQUIRED, 'The index of the "input" array that the cursor is in (e.g. COMP_CWORD)')->addOption('api-version', 'a', InputOption::VALUE_REQUIRED, 'The API version of the completion script')->addOption('symfony', 'S', InputOption::VALUE_REQUIRED, 'deprecated'); + } + protected function initialize(InputInterface $input, OutputInterface $output) : void + { + $this->isDebug = \filter_var(\getenv('SYMFONY_COMPLETION_DEBUG'), \FILTER_VALIDATE_BOOL); + } + protected function execute(InputInterface $input, OutputInterface $output) : int + { + try { + // "symfony" must be kept for compat with the shell scripts generated by Symfony Console 5.4 - 6.1 + $version = $input->getOption('symfony') ? '1' : $input->getOption('api-version'); + if ($version && \version_compare($version, self::COMPLETION_API_VERSION, '<')) { + $message = \sprintf('Completion script version is not supported ("%s" given, ">=%s" required).', $version, self::COMPLETION_API_VERSION); + $this->log($message); + $output->writeln($message . ' Install the Symfony completion script again by using the "completion" command.'); + return 126; + } + $shell = $input->getOption('shell'); + if (!$shell) { + throw new \RuntimeException('The "--shell" option must be set.'); + } + if (!($completionOutput = $this->completionOutputs[$shell] ?? \false)) { + throw new \RuntimeException(\sprintf('Shell completion is not supported for your shell: "%s" (supported: "%s").', $shell, \implode('", "', \array_keys($this->completionOutputs)))); + } + $completionInput = $this->createCompletionInput($input); + $suggestions = new CompletionSuggestions(); + $this->log(['', '' . \date('Y-m-d H:i:s') . '', 'Input: ("|" indicates the cursor position)', ' ' . (string) $completionInput, 'Command:', ' ' . (string) \implode(' ', $_SERVER['argv']), 'Messages:']); + $command = $this->findCommand($completionInput, $output); + if (null === $command) { + $this->log(' No command found, completing using the Application class.'); + $this->getApplication()->complete($completionInput, $suggestions); + } elseif ($completionInput->mustSuggestArgumentValuesFor('command') && $command->getName() !== $completionInput->getCompletionValue() && !\in_array($completionInput->getCompletionValue(), $command->getAliases(), \true)) { + $this->log(' No command found, completing using the Application class.'); + // expand shortcut names ("cache:cl") into their full name ("cache:clear") + $suggestions->suggestValues(\array_filter(\array_merge([$command->getName()], $command->getAliases()))); + } else { + $command->mergeApplicationDefinition(); + $completionInput->bind($command->getDefinition()); + if (CompletionInput::TYPE_OPTION_NAME === $completionInput->getCompletionType()) { + $this->log(' Completing option names for the ' . \get_class($command instanceof LazyCommand ? $command->getCommand() : $command) . ' command.'); + $suggestions->suggestOptions($command->getDefinition()->getOptions()); + } else { + $this->log([' Completing using the ' . \get_class($command instanceof LazyCommand ? $command->getCommand() : $command) . ' class.', ' Completing ' . $completionInput->getCompletionType() . ' for ' . $completionInput->getCompletionName() . '']); + if (null !== ($compval = $completionInput->getCompletionValue())) { + $this->log(' Current value: ' . $compval . ''); + } + $command->complete($completionInput, $suggestions); + } + } + /** @var CompletionOutputInterface $completionOutput */ + $completionOutput = new $completionOutput(); + $this->log('Suggestions:'); + if ($options = $suggestions->getOptionSuggestions()) { + $this->log(' --' . \implode(' --', \array_map(function ($o) { + return $o->getName(); + }, $options))); + } elseif ($values = $suggestions->getValueSuggestions()) { + $this->log(' ' . \implode(' ', $values)); + } else { + $this->log(' No suggestions were provided'); + } + $completionOutput->write($suggestions, $output); + } catch (\Throwable $e) { + $this->log(['Error!', (string) $e]); + if ($output->isDebug()) { + throw $e; + } + return 2; + } + return 0; + } + private function createCompletionInput(InputInterface $input) : CompletionInput + { + $currentIndex = $input->getOption('current'); + if (!$currentIndex || !\ctype_digit($currentIndex)) { + throw new \RuntimeException('The "--current" option must be set and it must be an integer.'); + } + $completionInput = CompletionInput::fromTokens($input->getOption('input'), (int) $currentIndex); + try { + $completionInput->bind($this->getApplication()->getDefinition()); + } catch (ExceptionInterface $exception) { + } + return $completionInput; + } + private function findCommand(CompletionInput $completionInput, OutputInterface $output) : ?Command + { + try { + $inputName = $completionInput->getFirstArgument(); + if (null === $inputName) { + return null; + } + return $this->getApplication()->find($inputName); + } catch (CommandNotFoundException $exception) { + } + return null; + } + private function log($messages) : void + { + if (!$this->isDebug) { + return; + } + $commandName = \basename($_SERVER['argv'][0]); + \file_put_contents(\sys_get_temp_dir() . '/sf_' . $commandName . '.log', \implode(\PHP_EOL, (array) $messages) . \PHP_EOL, \FILE_APPEND); + } +} diff --git a/vendor/symfony/console/Command/DumpCompletionCommand.php b/vendor/symfony/console/Command/DumpCompletionCommand.php new file mode 100644 index 0000000000..08fb6b74c4 --- /dev/null +++ b/vendor/symfony/console/Command/DumpCompletionCommand.php @@ -0,0 +1,143 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Attribute\AsCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Process; +/** + * Dumps the completion script for the current shell. + * + * @author Wouter de Jong + */ +final class DumpCompletionCommand extends Command +{ + /** + * @deprecated since Symfony 6.1 + */ + protected static $defaultName = 'completion'; + /** + * @deprecated since Symfony 6.1 + */ + protected static $defaultDescription = 'Dump the shell completion script'; + /** + * @var mixed[] + */ + private $supportedShells; + protected function configure() : void + { + $fullCommand = $_SERVER['PHP_SELF']; + $commandName = \basename($fullCommand); + $fullCommand = @\realpath($fullCommand) ?: $fullCommand; + $shell = $this->guessShell(); + switch ($shell) { + case 'fish': + [$rcFile, $completionFile] = ['~/.config/fish/config.fish', "/etc/fish/completions/{$commandName}.fish"]; + break; + case 'zsh': + [$rcFile, $completionFile] = ['~/.zshrc', '$fpath[1]/_' . $commandName]; + break; + default: + [$rcFile, $completionFile] = ['~/.bashrc', "/etc/bash_completion.d/{$commandName}"]; + break; + } + $supportedShells = \implode(', ', $this->getSupportedShells()); + $this->setHelp(<<%command.name% command dumps the shell completion script required +to use shell autocompletion (currently, {$supportedShells} completion are supported). + +Static installation +------------------- + +Dump the script to a global completion file and restart your shell: + + %command.full_name% {$shell} | sudo tee {$completionFile} + +Or dump the script to a local file and source it: + + %command.full_name% {$shell} > completion.sh + + # source the file whenever you use the project + source completion.sh + + # or add this line at the end of your "{$rcFile}" file: + source /path/to/completion.sh + +Dynamic installation +-------------------- + +Add this to the end of your shell configuration file (e.g. "{$rcFile}"): + + eval "\$({$fullCommand} completion {$shell})" +EOH +)->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given', null, \Closure::fromCallable([$this, 'getSupportedShells']))->addOption('debug', null, InputOption::VALUE_NONE, 'Tail the completion debug log'); + } + protected function execute(InputInterface $input, OutputInterface $output) : int + { + $commandName = \basename($_SERVER['argv'][0]); + if ($input->getOption('debug')) { + $this->tailDebugLog($commandName, $output); + return 0; + } + $shell = $input->getArgument('shell') ?? self::guessShell(); + $completionFile = __DIR__ . '/../Resources/completion.' . $shell; + if (!\file_exists($completionFile)) { + $supportedShells = $this->getSupportedShells(); + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + if ($shell) { + $output->writeln(\sprintf('Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").', $shell, \implode('", "', $supportedShells))); + } else { + $output->writeln(\sprintf('Shell not detected, Symfony shell completion only supports "%s").', \implode('", "', $supportedShells))); + } + return 2; + } + $output->write(\str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, CompleteCommand::COMPLETION_API_VERSION], \file_get_contents($completionFile))); + return 0; + } + private static function guessShell() : string + { + return \basename($_SERVER['SHELL'] ?? ''); + } + private function tailDebugLog(string $commandName, OutputInterface $output) : void + { + $debugFile = \sys_get_temp_dir() . '/sf_' . $commandName . '.log'; + if (!\file_exists($debugFile)) { + \touch($debugFile); + } + $process = new Process(['tail', '-f', $debugFile], null, null, null, 0); + $process->run(function (string $type, string $line) use($output) : void { + $output->write($line); + }); + } + /** + * @return string[] + */ + private function getSupportedShells() : array + { + if (isset($this->supportedShells)) { + return $this->supportedShells; + } + $shells = []; + foreach (new \DirectoryIterator(__DIR__ . '/../Resources/') as $file) { + if (\strncmp($file->getBasename(), 'completion.', \strlen('completion.')) === 0 && $file->isFile()) { + $shells[] = $file->getExtension(); + } + } + \sort($shells); + return $this->supportedShells = $shells; + } +} diff --git a/vendor/symfony/console/Command/HelpCommand.php b/vendor/symfony/console/Command/HelpCommand.php new file mode 100644 index 0000000000..d9d82acd6d --- /dev/null +++ b/vendor/symfony/console/Command/HelpCommand.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\ApplicationDescription; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\DescriptorHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * HelpCommand displays the help for a given command. + * + * @author Fabien Potencier + */ +class HelpCommand extends Command +{ + /** + * @var \Symfony\Component\Console\Command\Command + */ + private $command; + /** + * @return void + */ + protected function configure() + { + $this->ignoreValidationErrors(); + $this->setName('help')->setDefinition([new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help', function () { + return \array_keys((new ApplicationDescription($this->getApplication()))->getCommands()); + }), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt', function () { + return (new DescriptorHelper())->getFormats(); + }), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help')])->setDescription('Display help for a command')->setHelp(<<<'EOF' +The %command.name% command displays help for a given command: + + %command.full_name% list + +You can also output the help in other formats by using the --format option: + + %command.full_name% --format=xml list + +To display the list of available commands, please use the list command. +EOF +); + } + /** + * @return void + */ + public function setCommand(Command $command) + { + $this->command = $command; + } + protected function execute(InputInterface $input, OutputInterface $output) : int + { + $this->command = $this->command ?? $this->getApplication()->find($input->getArgument('command_name')); + $helper = new DescriptorHelper(); + $helper->describe($output, $this->command, ['format' => $input->getOption('format'), 'raw_text' => $input->getOption('raw')]); + unset($this->command); + return 0; + } +} diff --git a/vendor/symfony/console/Command/LazyCommand.php b/vendor/symfony/console/Command/LazyCommand.php new file mode 100644 index 0000000000..974097561d --- /dev/null +++ b/vendor/symfony/console/Command/LazyCommand.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Suggestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\HelperInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\HelperSet; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Nicolas Grekas + */ +final class LazyCommand extends Command +{ + /** + * @var \Closure|\Symfony\Component\Console\Command\Command + */ + private $command; + /** + * @var bool|null + */ + private $isEnabled; + public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = \true) + { + $this->setName($name)->setAliases($aliases)->setHidden($isHidden)->setDescription($description); + $this->command = $commandFactory; + $this->isEnabled = $isEnabled; + } + public function ignoreValidationErrors() : void + { + $this->getCommand()->ignoreValidationErrors(); + } + public function setApplication(Application $application = null) : void + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + if ($this->command instanceof parent) { + $this->command->setApplication($application); + } + parent::setApplication($application); + } + public function setHelperSet(HelperSet $helperSet) : void + { + if ($this->command instanceof parent) { + $this->command->setHelperSet($helperSet); + } + parent::setHelperSet($helperSet); + } + public function isEnabled() : bool + { + return $this->isEnabled ?? $this->getCommand()->isEnabled(); + } + public function run(InputInterface $input, OutputInterface $output) : int + { + return $this->getCommand()->run($input, $output); + } + public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void + { + $this->getCommand()->complete($input, $suggestions); + } + /** + * @return static + */ + public function setCode(callable $code) + { + $this->getCommand()->setCode($code); + return $this; + } + /** + * @internal + */ + public function mergeApplicationDefinition(bool $mergeArgs = \true) : void + { + $this->getCommand()->mergeApplicationDefinition($mergeArgs); + } + /** + * @param mixed[]|\Symfony\Component\Console\Input\InputDefinition $definition + * @return static + */ + public function setDefinition($definition) + { + $this->getCommand()->setDefinition($definition); + return $this; + } + public function getDefinition() : InputDefinition + { + return $this->getCommand()->getDefinition(); + } + public function getNativeDefinition() : InputDefinition + { + return $this->getCommand()->getNativeDefinition(); + } + /** + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * @param mixed $default + * @return static + */ + public function addArgument(string $name, int $mode = null, string $description = '', $default = null) + { + $suggestedValues = 5 <= \func_num_args() ? \func_get_arg(4) : []; + $this->getCommand()->addArgument($name, $mode, $description, $default, $suggestedValues); + return $this; + } + /** + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * @param string|mixed[] $shortcut + * @param mixed $default + * @return static + */ + public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) + { + $suggestedValues = 6 <= \func_num_args() ? \func_get_arg(5) : []; + $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default, $suggestedValues); + return $this; + } + /** + * @return static + */ + public function setProcessTitle(string $title) + { + $this->getCommand()->setProcessTitle($title); + return $this; + } + /** + * @return static + */ + public function setHelp(string $help) + { + $this->getCommand()->setHelp($help); + return $this; + } + public function getHelp() : string + { + return $this->getCommand()->getHelp(); + } + public function getProcessedHelp() : string + { + return $this->getCommand()->getProcessedHelp(); + } + public function getSynopsis(bool $short = \false) : string + { + return $this->getCommand()->getSynopsis($short); + } + /** + * @return static + */ + public function addUsage(string $usage) + { + $this->getCommand()->addUsage($usage); + return $this; + } + public function getUsages() : array + { + return $this->getCommand()->getUsages(); + } + public function getHelper(string $name) : HelperInterface + { + return $this->getCommand()->getHelper($name); + } + public function getCommand() : parent + { + if (!$this->command instanceof \Closure) { + return $this->command; + } + $command = $this->command = ($this->command)(); + $command->setApplication($this->getApplication()); + if (null !== $this->getHelperSet()) { + $command->setHelperSet($this->getHelperSet()); + } + $command->setName($this->getName())->setAliases($this->getAliases())->setHidden($this->isHidden())->setDescription($this->getDescription()); + // Will throw if the command is not correctly initialized. + $command->getDefinition(); + return $command; + } +} diff --git a/vendor/symfony/console/Command/ListCommand.php b/vendor/symfony/console/Command/ListCommand.php new file mode 100644 index 0000000000..c4bddf2292 --- /dev/null +++ b/vendor/symfony/console/Command/ListCommand.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\ApplicationDescription; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\DescriptorHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * ListCommand displays the list of all available commands for the application. + * + * @author Fabien Potencier + */ +class ListCommand extends Command +{ + /** + * @return void + */ + protected function configure() + { + $this->setName('list')->setDefinition([new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name', null, function () { + return \array_keys((new ApplicationDescription($this->getApplication()))->getNamespaces()); + }), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt', function () { + return (new DescriptorHelper())->getFormats(); + }), new InputOption('short', null, InputOption::VALUE_NONE, 'To skip describing commands\' arguments')])->setDescription('List commands')->setHelp(<<<'EOF' +The %command.name% command lists all commands: + + %command.full_name% + +You can also display the commands for a specific namespace: + + %command.full_name% test + +You can also output the information in other formats by using the --format option: + + %command.full_name% --format=xml + +It's also possible to get raw list of commands (useful for embedding command runner): + + %command.full_name% --raw +EOF +); + } + protected function execute(InputInterface $input, OutputInterface $output) : int + { + $helper = new DescriptorHelper(); + $helper->describe($output, $this->getApplication(), ['format' => $input->getOption('format'), 'raw_text' => $input->getOption('raw'), 'namespace' => $input->getArgument('namespace'), 'short' => $input->getOption('short')]); + return 0; + } +} diff --git a/vendor/symfony/console/Command/LockableTrait.php b/vendor/symfony/console/Command/LockableTrait.php new file mode 100644 index 0000000000..0b26403963 --- /dev/null +++ b/vendor/symfony/console/Command/LockableTrait.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\Lock\LockFactory; +use MonorepoBuilderPrefix202310\Symfony\Component\Lock\LockInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Lock\Store\FlockStore; +use MonorepoBuilderPrefix202310\Symfony\Component\Lock\Store\SemaphoreStore; +/** + * Basic lock feature for commands. + * + * @author Geoffrey Brier + */ +trait LockableTrait +{ + /** + * @var \Symfony\Component\Lock\LockInterface|null + */ + private $lock; + /** + * Locks a command. + */ + private function lock(string $name = null, bool $blocking = \false) : bool + { + if (!\class_exists(SemaphoreStore::class)) { + throw new LogicException('To enable the locking feature you must install the symfony/lock component. Try running "composer require symfony/lock".'); + } + if (null !== $this->lock) { + throw new LogicException('A lock is already in place.'); + } + if (SemaphoreStore::isSupported()) { + $store = new SemaphoreStore(); + } else { + $store = new FlockStore(); + } + $this->lock = (new LockFactory($store))->createLock($name ?: $this->getName()); + if (!$this->lock->acquire($blocking)) { + $this->lock = null; + return \false; + } + return \true; + } + /** + * Releases the command lock if there is one. + */ + private function release() : void + { + if ($this->lock) { + $this->lock->release(); + $this->lock = null; + } + } +} diff --git a/vendor/symfony/console/Command/SignalableCommandInterface.php b/vendor/symfony/console/Command/SignalableCommandInterface.php new file mode 100644 index 0000000000..a90a691633 --- /dev/null +++ b/vendor/symfony/console/Command/SignalableCommandInterface.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Command; + +/** + * Interface for command reacting to signal. + * + * @author Grégoire Pineau + */ +interface SignalableCommandInterface +{ + /** + * Returns the list of signals to subscribe. + */ + public function getSubscribedSignals() : array; + /** + * The method will be called when the application is signaled. + * + * @param int|false $previousExitCode + * @return int|false The exit code to return or false to continue the normal execution + */ + public function handleSignal(int $signal); +} diff --git a/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php b/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php new file mode 100644 index 0000000000..a5f944d0f2 --- /dev/null +++ b/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\CommandLoader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\CommandNotFoundException; +/** + * @author Robin Chalas + */ +interface CommandLoaderInterface +{ + /** + * Loads a command. + * + * @throws CommandNotFoundException + */ + public function get(string $name) : Command; + /** + * Checks if a command exists. + */ + public function has(string $name) : bool; + /** + * @return string[] + */ + public function getNames() : array; +} diff --git a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php new file mode 100644 index 0000000000..c4c667bc41 --- /dev/null +++ b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\CommandLoader; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\CommandNotFoundException; +/** + * Loads commands from a PSR-11 container. + * + * @author Robin Chalas + */ +class ContainerCommandLoader implements CommandLoaderInterface +{ + /** + * @var \Psr\Container\ContainerInterface + */ + private $container; + /** + * @var mixed[] + */ + private $commandMap; + /** + * @param array $commandMap An array with command names as keys and service ids as values + */ + public function __construct(ContainerInterface $container, array $commandMap) + { + $this->container = $container; + $this->commandMap = $commandMap; + } + public function get(string $name) : Command + { + if (!$this->has($name)) { + throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name)); + } + return $this->container->get($this->commandMap[$name]); + } + public function has(string $name) : bool + { + return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]); + } + public function getNames() : array + { + return \array_keys($this->commandMap); + } +} diff --git a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php new file mode 100644 index 0000000000..39f0c33cd8 --- /dev/null +++ b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\CommandLoader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\CommandNotFoundException; +/** + * A simple command loader using factories to instantiate commands lazily. + * + * @author Maxime Steinhausser + */ +class FactoryCommandLoader implements CommandLoaderInterface +{ + /** + * @var mixed[] + */ + private $factories; + /** + * @param callable[] $factories Indexed by command names + */ + public function __construct(array $factories) + { + $this->factories = $factories; + } + public function has(string $name) : bool + { + return isset($this->factories[$name]); + } + public function get(string $name) : Command + { + if (!isset($this->factories[$name])) { + throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name)); + } + $factory = $this->factories[$name]; + return $factory(); + } + public function getNames() : array + { + return \array_keys($this->factories); + } +} diff --git a/vendor/symfony/console/Completion/CompletionInput.php b/vendor/symfony/console/Completion/CompletionInput.php new file mode 100644 index 0000000000..cd21c06f4b --- /dev/null +++ b/vendor/symfony/console/Completion/CompletionInput.php @@ -0,0 +1,210 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\ArgvInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +/** + * An input specialized for shell completion. + * + * This input allows unfinished option names or values and exposes what kind of + * completion is expected. + * + * @author Wouter de Jong + */ +final class CompletionInput extends ArgvInput +{ + public const TYPE_ARGUMENT_VALUE = 'argument_value'; + public const TYPE_OPTION_VALUE = 'option_value'; + public const TYPE_OPTION_NAME = 'option_name'; + public const TYPE_NONE = 'none'; + private $tokens; + private $currentIndex; + private $completionType; + private $completionName; + private $completionValue = ''; + /** + * Converts a terminal string into tokens. + * + * This is required for shell completions without COMP_WORDS support. + */ + public static function fromString(string $inputStr, int $currentIndex) : self + { + \preg_match_all('/(?<=^|\\s)([\'"]?)(.+?)(?tokens = $tokens; + $input->currentIndex = $currentIndex; + return $input; + } + public function bind(InputDefinition $definition) : void + { + parent::bind($definition); + $relevantToken = $this->getRelevantToken(); + if ('-' === $relevantToken[0]) { + // the current token is an input option: complete either option name or option value + [$optionToken, $optionValue] = \explode('=', $relevantToken, 2) + ['', '']; + $option = $this->getOptionFromToken($optionToken); + if (null === $option && !$this->isCursorFree()) { + $this->completionType = self::TYPE_OPTION_NAME; + $this->completionValue = $relevantToken; + return; + } + if (($nullsafeVariable1 = $option) ? $nullsafeVariable1->acceptValue() : null) { + $this->completionType = self::TYPE_OPTION_VALUE; + $this->completionName = $option->getName(); + $this->completionValue = $optionValue ?: (\strncmp($optionToken, '--', \strlen('--')) !== 0 ? \substr($optionToken, 2) : ''); + return; + } + } + $previousToken = $this->tokens[$this->currentIndex - 1]; + if ('-' === $previousToken[0] && '' !== \trim($previousToken, '-')) { + // check if previous option accepted a value + $previousOption = $this->getOptionFromToken($previousToken); + if (($nullsafeVariable2 = $previousOption) ? $nullsafeVariable2->acceptValue() : null) { + $this->completionType = self::TYPE_OPTION_VALUE; + $this->completionName = $previousOption->getName(); + $this->completionValue = $relevantToken; + return; + } + } + // complete argument value + $this->completionType = self::TYPE_ARGUMENT_VALUE; + foreach ($this->definition->getArguments() as $argumentName => $argument) { + if (!isset($this->arguments[$argumentName])) { + break; + } + $argumentValue = $this->arguments[$argumentName]; + $this->completionName = $argumentName; + if (\is_array($argumentValue)) { + \end($argumentValue); + $this->completionValue = $argumentValue ? $argumentValue[\key($argumentValue)] : null; + } else { + $this->completionValue = $argumentValue; + } + } + if ($this->currentIndex >= \count($this->tokens)) { + if (!isset($this->arguments[$argumentName]) || $this->definition->getArgument($argumentName)->isArray()) { + $this->completionName = $argumentName; + $this->completionValue = ''; + } else { + // we've reached the end + $this->completionType = self::TYPE_NONE; + $this->completionName = null; + $this->completionValue = ''; + } + } + } + /** + * Returns the type of completion required. + * + * TYPE_ARGUMENT_VALUE when completing the value of an input argument + * TYPE_OPTION_VALUE when completing the value of an input option + * TYPE_OPTION_NAME when completing the name of an input option + * TYPE_NONE when nothing should be completed + * + * @return string One of self::TYPE_* constants. TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component + */ + public function getCompletionType() : string + { + return $this->completionType; + } + /** + * The name of the input option or argument when completing a value. + * + * @return string|null returns null when completing an option name + */ + public function getCompletionName() : ?string + { + return $this->completionName; + } + /** + * The value already typed by the user (or empty string). + */ + public function getCompletionValue() : string + { + return $this->completionValue; + } + public function mustSuggestOptionValuesFor(string $optionName) : bool + { + return self::TYPE_OPTION_VALUE === $this->getCompletionType() && $optionName === $this->getCompletionName(); + } + public function mustSuggestArgumentValuesFor(string $argumentName) : bool + { + return self::TYPE_ARGUMENT_VALUE === $this->getCompletionType() && $argumentName === $this->getCompletionName(); + } + protected function parseToken(string $token, bool $parseOptions) : bool + { + try { + return parent::parseToken($token, $parseOptions); + } catch (RuntimeException $exception) { + // suppress errors, completed input is almost never valid + } + return $parseOptions; + } + private function getOptionFromToken(string $optionToken) : ?InputOption + { + $optionName = \ltrim($optionToken, '-'); + if (!$optionName) { + return null; + } + if ('-' === ($optionToken[1] ?? ' ')) { + // long option name + return $this->definition->hasOption($optionName) ? $this->definition->getOption($optionName) : null; + } + // short option name + return $this->definition->hasShortcut($optionName[0]) ? $this->definition->getOptionForShortcut($optionName[0]) : null; + } + /** + * The token of the cursor, or the last token if the cursor is at the end of the input. + */ + private function getRelevantToken() : string + { + return $this->tokens[$this->isCursorFree() ? $this->currentIndex - 1 : $this->currentIndex]; + } + /** + * Whether the cursor is "free" (i.e. at the end of the input preceded by a space). + */ + private function isCursorFree() : bool + { + $nrOfTokens = \count($this->tokens); + if ($this->currentIndex > $nrOfTokens) { + throw new \LogicException('Current index is invalid, it must be the number of input tokens or one more.'); + } + return $this->currentIndex >= $nrOfTokens; + } + public function __toString() : string + { + $str = ''; + foreach ($this->tokens as $i => $token) { + $str .= $token; + if ($this->currentIndex === $i) { + $str .= '|'; + } + $str .= ' '; + } + if ($this->currentIndex > $i) { + $str .= '|'; + } + return \rtrim($str); + } +} diff --git a/vendor/symfony/console/Completion/CompletionSuggestions.php b/vendor/symfony/console/Completion/CompletionSuggestions.php new file mode 100644 index 0000000000..8a1a6ed242 --- /dev/null +++ b/vendor/symfony/console/Completion/CompletionSuggestions.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +/** + * Stores all completion suggestions for the current input. + * + * @author Wouter de Jong + */ +final class CompletionSuggestions +{ + private $valueSuggestions = []; + private $optionSuggestions = []; + /** + * Add a suggested value for an input option or argument. + * + * @return $this + * @param string|\Symfony\Component\Console\Completion\Suggestion $value + */ + public function suggestValue($value) + { + $this->valueSuggestions[] = !$value instanceof Suggestion ? new Suggestion($value) : $value; + return $this; + } + /** + * Add multiple suggested values at once for an input option or argument. + * + * @param list $values + * + * @return $this + */ + public function suggestValues(array $values) + { + foreach ($values as $value) { + $this->suggestValue($value); + } + return $this; + } + /** + * Add a suggestion for an input option name. + * + * @return $this + */ + public function suggestOption(InputOption $option) + { + $this->optionSuggestions[] = $option; + return $this; + } + /** + * Add multiple suggestions for input option names at once. + * + * @param InputOption[] $options + * + * @return $this + */ + public function suggestOptions(array $options) + { + foreach ($options as $option) { + $this->suggestOption($option); + } + return $this; + } + /** + * @return InputOption[] + */ + public function getOptionSuggestions() : array + { + return $this->optionSuggestions; + } + /** + * @return Suggestion[] + */ + public function getValueSuggestions() : array + { + return $this->valueSuggestions; + } +} diff --git a/vendor/symfony/console/Completion/Output/BashCompletionOutput.php b/vendor/symfony/console/Completion/Output/BashCompletionOutput.php new file mode 100644 index 0000000000..c39ea39846 --- /dev/null +++ b/vendor/symfony/console/Completion/Output/BashCompletionOutput.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Wouter de Jong + */ +class BashCompletionOutput implements CompletionOutputInterface +{ + public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void + { + $values = $suggestions->getValueSuggestions(); + foreach ($suggestions->getOptionSuggestions() as $option) { + $values[] = '--' . $option->getName(); + if ($option->isNegatable()) { + $values[] = '--no-' . $option->getName(); + } + } + $output->writeln(\implode("\n", $values)); + } +} diff --git a/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php b/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php new file mode 100644 index 0000000000..d4bdd8e4b2 --- /dev/null +++ b/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Transforms the {@see CompletionSuggestions} object into output readable by the shell completion. + * + * @author Wouter de Jong + */ +interface CompletionOutputInterface +{ + public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void; +} diff --git a/vendor/symfony/console/Completion/Output/FishCompletionOutput.php b/vendor/symfony/console/Completion/Output/FishCompletionOutput.php new file mode 100644 index 0000000000..8d318815e5 --- /dev/null +++ b/vendor/symfony/console/Completion/Output/FishCompletionOutput.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Guillaume Aveline + */ +class FishCompletionOutput implements CompletionOutputInterface +{ + public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void + { + $values = $suggestions->getValueSuggestions(); + foreach ($suggestions->getOptionSuggestions() as $option) { + $values[] = '--' . $option->getName(); + if ($option->isNegatable()) { + $values[] = '--no-' . $option->getName(); + } + } + $output->write(\implode("\n", $values)); + } +} diff --git a/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php b/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php new file mode 100644 index 0000000000..6ea733e2c7 --- /dev/null +++ b/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Jitendra A + */ +class ZshCompletionOutput implements CompletionOutputInterface +{ + public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void + { + $values = []; + foreach ($suggestions->getValueSuggestions() as $value) { + $values[] = $value->getValue() . ($value->getDescription() ? "\t" . $value->getDescription() : ''); + } + foreach ($suggestions->getOptionSuggestions() as $option) { + $values[] = '--' . $option->getName() . ($option->getDescription() ? "\t" . $option->getDescription() : ''); + if ($option->isNegatable()) { + $values[] = '--no-' . $option->getName() . ($option->getDescription() ? "\t" . $option->getDescription() : ''); + } + } + $output->write(\implode("\n", $values) . "\n"); + } +} diff --git a/vendor/symfony/console/Completion/Suggestion.php b/vendor/symfony/console/Completion/Suggestion.php new file mode 100644 index 0000000000..e1000125a0 --- /dev/null +++ b/vendor/symfony/console/Completion/Suggestion.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion; + +/** + * Represents a single suggested value. + * + * @author Wouter de Jong + */ +class Suggestion +{ + /** + * @readonly + * @var string + */ + private $value; + /** + * @readonly + * @var string + */ + private $description = ''; + public function __construct(string $value, string $description = '') + { + $this->value = $value; + $this->description = $description; + } + public function getValue() : string + { + return $this->value; + } + public function getDescription() : string + { + return $this->description; + } + public function __toString() : string + { + return $this->getValue(); + } +} diff --git a/vendor/symfony/console/ConsoleEvents.php b/vendor/symfony/console/ConsoleEvents.php new file mode 100644 index 0000000000..e31030620b --- /dev/null +++ b/vendor/symfony/console/ConsoleEvents.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleCommandEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleErrorEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleSignalEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleTerminateEvent; +/** + * Contains all events dispatched by an Application. + * + * @author Francesco Levorato + */ +final class ConsoleEvents +{ + /** + * The COMMAND event allows you to attach listeners before any command is + * executed by the console. It also allows you to modify the command, input and output + * before they are handed to the command. + * + * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent") + */ + public const COMMAND = 'console.command'; + /** + * The SIGNAL event allows you to perform some actions + * after the command execution was interrupted. + * + * @Event("Symfony\Component\Console\Event\ConsoleSignalEvent") + */ + public const SIGNAL = 'console.signal'; + /** + * The TERMINATE event allows you to attach listeners after a command is + * executed by the console. + * + * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent") + */ + public const TERMINATE = 'console.terminate'; + /** + * The ERROR event occurs when an uncaught exception or error appears. + * + * This event allows you to deal with the exception/error or + * to modify the thrown exception. + * + * @Event("Symfony\Component\Console\Event\ConsoleErrorEvent") + */ + public const ERROR = 'console.error'; + /** + * Event aliases. + * + * These aliases can be consumed by RegisterListenersPass. + */ + public const ALIASES = [ConsoleCommandEvent::class => self::COMMAND, ConsoleErrorEvent::class => self::ERROR, ConsoleSignalEvent::class => self::SIGNAL, ConsoleTerminateEvent::class => self::TERMINATE]; +} diff --git a/vendor/symfony/console/Cursor.php b/vendor/symfony/console/Cursor.php new file mode 100644 index 0000000000..eb2459b55d --- /dev/null +++ b/vendor/symfony/console/Cursor.php @@ -0,0 +1,167 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Pierre du Plessis + */ +final class Cursor +{ + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + private $input; + /** + * @param resource|null $input + */ + public function __construct(OutputInterface $output, $input = null) + { + $this->output = $output; + $this->input = $input ?? (\defined('STDIN') ? \STDIN : \fopen('php://input', 'r+')); + } + /** + * @return $this + */ + public function moveUp(int $lines = 1) + { + $this->output->write(\sprintf("\x1b[%dA", $lines)); + return $this; + } + /** + * @return $this + */ + public function moveDown(int $lines = 1) + { + $this->output->write(\sprintf("\x1b[%dB", $lines)); + return $this; + } + /** + * @return $this + */ + public function moveRight(int $columns = 1) + { + $this->output->write(\sprintf("\x1b[%dC", $columns)); + return $this; + } + /** + * @return $this + */ + public function moveLeft(int $columns = 1) + { + $this->output->write(\sprintf("\x1b[%dD", $columns)); + return $this; + } + /** + * @return $this + */ + public function moveToColumn(int $column) + { + $this->output->write(\sprintf("\x1b[%dG", $column)); + return $this; + } + /** + * @return $this + */ + public function moveToPosition(int $column, int $row) + { + $this->output->write(\sprintf("\x1b[%d;%dH", $row + 1, $column)); + return $this; + } + /** + * @return $this + */ + public function savePosition() + { + $this->output->write("\x1b7"); + return $this; + } + /** + * @return $this + */ + public function restorePosition() + { + $this->output->write("\x1b8"); + return $this; + } + /** + * @return $this + */ + public function hide() + { + $this->output->write("\x1b[?25l"); + return $this; + } + /** + * @return $this + */ + public function show() + { + $this->output->write("\x1b[?25h\x1b[?0c"); + return $this; + } + /** + * Clears all the output from the current line. + * + * @return $this + */ + public function clearLine() + { + $this->output->write("\x1b[2K"); + return $this; + } + /** + * Clears all the output from the current line after the current position. + */ + public function clearLineAfter() : self + { + $this->output->write("\x1b[K"); + return $this; + } + /** + * Clears all the output from the cursors' current position to the end of the screen. + * + * @return $this + */ + public function clearOutput() + { + $this->output->write("\x1b[0J"); + return $this; + } + /** + * Clears the entire screen. + * + * @return $this + */ + public function clearScreen() + { + $this->output->write("\x1b[2J"); + return $this; + } + /** + * Returns the current cursor position as x,y coordinates. + */ + public function getCurrentPosition() : array + { + static $isTtySupported; + if (!($isTtySupported = $isTtySupported ?? '/' === \DIRECTORY_SEPARATOR && \stream_isatty(\STDOUT))) { + return [1, 1]; + } + $sttyMode = \shell_exec('stty -g'); + \shell_exec('stty -icanon -echo'); + @\fwrite($this->input, "\x1b[6n"); + $code = \trim(\fread($this->input, 1024)); + \shell_exec(\sprintf('stty %s', $sttyMode)); + \sscanf($code, "\x1b[%d;%dR", $row, $col); + return [$col, $row]; + } +} diff --git a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php new file mode 100644 index 0000000000..431c0ce165 --- /dev/null +++ b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\LazyCommand; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\CommandLoader\ContainerCommandLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +/** + * Registers console commands. + * + * @author Grégoire Pineau + */ +class AddConsoleCommandPass implements CompilerPassInterface +{ + /** + * @return void + */ + public function process(ContainerBuilder $container) + { + $commandServices = $container->findTaggedServiceIds('console.command', \true); + $lazyCommandMap = []; + $lazyCommandRefs = []; + $serviceIds = []; + foreach ($commandServices as $id => $tags) { + $definition = $container->getDefinition($id); + $definition->addTag('container.no_preload'); + $class = $container->getParameterBag()->resolveValue($definition->getClass()); + if (isset($tags[0]['command'])) { + $aliases = $tags[0]['command']; + } else { + if (!($r = $container->getReflectionClass($class))) { + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + if (!$r->isSubclassOf(Command::class)) { + throw new InvalidArgumentException(\sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, 'console.command', Command::class)); + } + $aliases = \str_replace('%', '%%', $class::getDefaultName() ?? ''); + } + $aliases = \explode('|', $aliases ?? ''); + $commandName = \array_shift($aliases); + if ($isHidden = '' === $commandName) { + $commandName = \array_shift($aliases); + } + if (null === $commandName) { + if (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag('container.private')) { + $commandId = 'console.command.public_alias.' . $id; + $container->setAlias($commandId, $id)->setPublic(\true); + $id = $commandId; + } + $serviceIds[] = $id; + continue; + } + $description = $tags[0]['description'] ?? null; + unset($tags[0]); + $lazyCommandMap[$commandName] = $id; + $lazyCommandRefs[$id] = new TypedReference($id, $class); + foreach ($aliases as $alias) { + $lazyCommandMap[$alias] = $id; + } + foreach ($tags as $tag) { + if (isset($tag['command'])) { + $aliases[] = $tag['command']; + $lazyCommandMap[$tag['command']] = $id; + } + $description = $description ?? $tag['description'] ?? null; + } + $definition->addMethodCall('setName', [$commandName]); + if ($aliases) { + $definition->addMethodCall('setAliases', [$aliases]); + } + if ($isHidden) { + $definition->addMethodCall('setHidden', [\true]); + } + if (!$description) { + if (!($r = $container->getReflectionClass($class))) { + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + if (!$r->isSubclassOf(Command::class)) { + throw new InvalidArgumentException(\sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, 'console.command', Command::class)); + } + $description = \str_replace('%', '%%', $class::getDefaultDescription() ?? ''); + } + if ($description) { + $definition->addMethodCall('setDescription', [$description]); + $container->register('.' . $id . '.lazy', LazyCommand::class)->setArguments([$commandName, $aliases, $description, $isHidden, new ServiceClosureArgument($lazyCommandRefs[$id])]); + $lazyCommandRefs[$id] = new Reference('.' . $id . '.lazy'); + } + } + $container->register('console.command_loader', ContainerCommandLoader::class)->setPublic(\true)->addTag('container.no_preload')->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]); + $container->setParameter('console.command.ids', $serviceIds); + } +} diff --git a/vendor/symfony/console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Descriptor/ApplicationDescription.php new file mode 100644 index 0000000000..de43d71f31 --- /dev/null +++ b/vendor/symfony/console/Descriptor/ApplicationDescription.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\CommandNotFoundException; +/** + * @author Jean-François Simon + * + * @internal + */ +class ApplicationDescription +{ + public const GLOBAL_NAMESPACE = '_global'; + /** + * @var \Symfony\Component\Console\Application + */ + private $application; + /** + * @var string|null + */ + private $namespace; + /** + * @var bool + */ + private $showHidden; + /** + * @var mixed[] + */ + private $namespaces; + /** + * @var array + */ + private $commands; + /** + * @var array + */ + private $aliases = []; + public function __construct(Application $application, string $namespace = null, bool $showHidden = \false) + { + $this->application = $application; + $this->namespace = $namespace; + $this->showHidden = $showHidden; + } + public function getNamespaces() : array + { + if (!isset($this->namespaces)) { + $this->inspectApplication(); + } + return $this->namespaces; + } + /** + * @return Command[] + */ + public function getCommands() : array + { + if (!isset($this->commands)) { + $this->inspectApplication(); + } + return $this->commands; + } + /** + * @throws CommandNotFoundException + */ + public function getCommand(string $name) : Command + { + if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) { + throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name)); + } + return $this->commands[$name] ?? $this->aliases[$name]; + } + private function inspectApplication() : void + { + $this->commands = []; + $this->namespaces = []; + $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null); + foreach ($this->sortCommands($all) as $namespace => $commands) { + $names = []; + /** @var Command $command */ + foreach ($commands as $name => $command) { + if (!$command->getName() || !$this->showHidden && $command->isHidden()) { + continue; + } + if ($command->getName() === $name) { + $this->commands[$name] = $command; + } else { + $this->aliases[$name] = $command; + } + $names[] = $name; + } + $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names]; + } + } + private function sortCommands(array $commands) : array + { + $namespacedCommands = []; + $globalCommands = []; + $sortedCommands = []; + foreach ($commands as $name => $command) { + $key = $this->application->extractNamespace($name, 1); + if (\in_array($key, ['', self::GLOBAL_NAMESPACE], \true)) { + $globalCommands[$name] = $command; + } else { + $namespacedCommands[$key][$name] = $command; + } + } + if ($globalCommands) { + \ksort($globalCommands); + $sortedCommands[self::GLOBAL_NAMESPACE] = $globalCommands; + } + if ($namespacedCommands) { + \ksort($namespacedCommands, \SORT_STRING); + foreach ($namespacedCommands as $key => $commandsSet) { + \ksort($commandsSet); + $sortedCommands[$key] = $commandsSet; + } + } + return $sortedCommands; + } +} diff --git a/vendor/symfony/console/Descriptor/Descriptor.php b/vendor/symfony/console/Descriptor/Descriptor.php new file mode 100644 index 0000000000..7a9ab5526a --- /dev/null +++ b/vendor/symfony/console/Descriptor/Descriptor.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Jean-François Simon + * + * @internal + */ +abstract class Descriptor implements DescriptorInterface +{ + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + protected $output; + public function describe(OutputInterface $output, object $object, array $options = []) : void + { + $this->output = $output; + switch (\true) { + case $object instanceof InputArgument: + $this->describeInputArgument($object, $options); + break; + case $object instanceof InputOption: + $this->describeInputOption($object, $options); + break; + case $object instanceof InputDefinition: + $this->describeInputDefinition($object, $options); + break; + case $object instanceof Command: + $this->describeCommand($object, $options); + break; + case $object instanceof Application: + $this->describeApplication($object, $options); + break; + default: + throw new InvalidArgumentException(\sprintf('Object of type "%s" is not describable.', \get_debug_type($object))); + } + } + protected function write(string $content, bool $decorated = \false) : void + { + $this->output->write($content, \false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW); + } + /** + * Describes an InputArgument instance. + */ + protected abstract function describeInputArgument(InputArgument $argument, array $options = []) : void; + /** + * Describes an InputOption instance. + */ + protected abstract function describeInputOption(InputOption $option, array $options = []) : void; + /** + * Describes an InputDefinition instance. + */ + protected abstract function describeInputDefinition(InputDefinition $definition, array $options = []) : void; + /** + * Describes a Command instance. + */ + protected abstract function describeCommand(Command $command, array $options = []) : void; + /** + * Describes an Application instance. + */ + protected abstract function describeApplication(Application $application, array $options = []) : void; +} diff --git a/vendor/symfony/console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Descriptor/DescriptorInterface.php new file mode 100644 index 0000000000..f0a200639f --- /dev/null +++ b/vendor/symfony/console/Descriptor/DescriptorInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Descriptor interface. + * + * @author Jean-François Simon + */ +interface DescriptorInterface +{ + /** + * @return void + */ + public function describe(OutputInterface $output, object $object, array $options = []); +} diff --git a/vendor/symfony/console/Descriptor/JsonDescriptor.php b/vendor/symfony/console/Descriptor/JsonDescriptor.php new file mode 100644 index 0000000000..be7d2caf4f --- /dev/null +++ b/vendor/symfony/console/Descriptor/JsonDescriptor.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +/** + * JSON descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class JsonDescriptor extends Descriptor +{ + protected function describeInputArgument(InputArgument $argument, array $options = []) : void + { + $this->writeData($this->getInputArgumentData($argument), $options); + } + protected function describeInputOption(InputOption $option, array $options = []) : void + { + $this->writeData($this->getInputOptionData($option), $options); + if ($option->isNegatable()) { + $this->writeData($this->getInputOptionData($option, \true), $options); + } + } + protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void + { + $this->writeData($this->getInputDefinitionData($definition), $options); + } + protected function describeCommand(Command $command, array $options = []) : void + { + $this->writeData($this->getCommandData($command, $options['short'] ?? \false), $options); + } + protected function describeApplication(Application $application, array $options = []) : void + { + $describedNamespace = $options['namespace'] ?? null; + $description = new ApplicationDescription($application, $describedNamespace, \true); + $commands = []; + foreach ($description->getCommands() as $command) { + $commands[] = $this->getCommandData($command, $options['short'] ?? \false); + } + $data = []; + if ('UNKNOWN' !== $application->getName()) { + $data['application']['name'] = $application->getName(); + if ('UNKNOWN' !== $application->getVersion()) { + $data['application']['version'] = $application->getVersion(); + } + } + $data['commands'] = $commands; + if ($describedNamespace) { + $data['namespace'] = $describedNamespace; + } else { + $data['namespaces'] = \array_values($description->getNamespaces()); + } + $this->writeData($data, $options); + } + /** + * Writes data as json. + */ + private function writeData(array $data, array $options) : void + { + $flags = $options['json_encoding'] ?? 0; + $this->write(\json_encode($data, $flags)); + } + private function getInputArgumentData(InputArgument $argument) : array + { + return ['name' => $argument->getName(), 'is_required' => $argument->isRequired(), 'is_array' => $argument->isArray(), 'description' => \preg_replace('/\\s*[\\r\\n]\\s*/', ' ', $argument->getDescription()), 'default' => \INF === $argument->getDefault() ? 'INF' : $argument->getDefault()]; + } + private function getInputOptionData(InputOption $option, bool $negated = \false) : array + { + return $negated ? ['name' => '--no-' . $option->getName(), 'shortcut' => '', 'accept_value' => \false, 'is_value_required' => \false, 'is_multiple' => \false, 'description' => 'Negate the "--' . $option->getName() . '" option', 'default' => \false] : ['name' => '--' . $option->getName(), 'shortcut' => $option->getShortcut() ? '-' . \str_replace('|', '|-', $option->getShortcut()) : '', 'accept_value' => $option->acceptValue(), 'is_value_required' => $option->isValueRequired(), 'is_multiple' => $option->isArray(), 'description' => \preg_replace('/\\s*[\\r\\n]\\s*/', ' ', $option->getDescription()), 'default' => \INF === $option->getDefault() ? 'INF' : $option->getDefault()]; + } + private function getInputDefinitionData(InputDefinition $definition) : array + { + $inputArguments = []; + foreach ($definition->getArguments() as $name => $argument) { + $inputArguments[$name] = $this->getInputArgumentData($argument); + } + $inputOptions = []; + foreach ($definition->getOptions() as $name => $option) { + $inputOptions[$name] = $this->getInputOptionData($option); + if ($option->isNegatable()) { + $inputOptions['no-' . $name] = $this->getInputOptionData($option, \true); + } + } + return ['arguments' => $inputArguments, 'options' => $inputOptions]; + } + private function getCommandData(Command $command, bool $short = \false) : array + { + $data = ['name' => $command->getName(), 'description' => $command->getDescription()]; + if ($short) { + $data += ['usage' => $command->getAliases()]; + } else { + $command->mergeApplicationDefinition(\false); + $data += ['usage' => \array_merge([$command->getSynopsis()], $command->getUsages(), $command->getAliases()), 'help' => $command->getProcessedHelp(), 'definition' => $this->getInputDefinitionData($command->getDefinition())]; + } + $data['hidden'] = $command->isHidden(); + return $data; + } +} diff --git a/vendor/symfony/console/Descriptor/MarkdownDescriptor.php b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php new file mode 100644 index 0000000000..07978da76a --- /dev/null +++ b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\Helper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Markdown descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class MarkdownDescriptor extends Descriptor +{ + public function describe(OutputInterface $output, object $object, array $options = []) : void + { + $decorated = $output->isDecorated(); + $output->setDecorated(\false); + parent::describe($output, $object, $options); + $output->setDecorated($decorated); + } + protected function write(string $content, bool $decorated = \true) : void + { + parent::write($content, $decorated); + } + protected function describeInputArgument(InputArgument $argument, array $options = []) : void + { + $this->write('#### `' . ($argument->getName() ?: '') . "`\n\n" . ($argument->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $argument->getDescription()) . "\n\n" : '') . '* Is required: ' . ($argument->isRequired() ? 'yes' : 'no') . "\n" . '* Is array: ' . ($argument->isArray() ? 'yes' : 'no') . "\n" . '* Default: `' . \str_replace("\n", '', \var_export($argument->getDefault(), \true)) . '`'); + } + protected function describeInputOption(InputOption $option, array $options = []) : void + { + $name = '--' . $option->getName(); + if ($option->isNegatable()) { + $name .= '|--no-' . $option->getName(); + } + if ($option->getShortcut()) { + $name .= '|-' . \str_replace('|', '|-', $option->getShortcut()) . ''; + } + $this->write('#### `' . $name . '`' . "\n\n" . ($option->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $option->getDescription()) . "\n\n" : '') . '* Accept value: ' . ($option->acceptValue() ? 'yes' : 'no') . "\n" . '* Is value required: ' . ($option->isValueRequired() ? 'yes' : 'no') . "\n" . '* Is multiple: ' . ($option->isArray() ? 'yes' : 'no') . "\n" . '* Is negatable: ' . ($option->isNegatable() ? 'yes' : 'no') . "\n" . '* Default: `' . \str_replace("\n", '', \var_export($option->getDefault(), \true)) . '`'); + } + protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void + { + if ($showArguments = \count($definition->getArguments()) > 0) { + $this->write('### Arguments'); + foreach ($definition->getArguments() as $argument) { + $this->write("\n\n"); + $this->describeInputArgument($argument); + } + } + if (\count($definition->getOptions()) > 0) { + if ($showArguments) { + $this->write("\n\n"); + } + $this->write('### Options'); + foreach ($definition->getOptions() as $option) { + $this->write("\n\n"); + $this->describeInputOption($option); + } + } + } + protected function describeCommand(Command $command, array $options = []) : void + { + if ($options['short'] ?? \false) { + $this->write('`' . $command->getName() . "`\n" . \str_repeat('-', Helper::width($command->getName()) + 2) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . '### Usage' . "\n\n" . \array_reduce($command->getAliases(), function ($carry, $usage) { + return $carry . '* `' . $usage . '`' . "\n"; + })); + return; + } + $command->mergeApplicationDefinition(\false); + $this->write('`' . $command->getName() . "`\n" . \str_repeat('-', Helper::width($command->getName()) + 2) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . '### Usage' . "\n\n" . \array_reduce(\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) { + return $carry . '* `' . $usage . '`' . "\n"; + })); + if ($help = $command->getProcessedHelp()) { + $this->write("\n"); + $this->write($help); + } + $definition = $command->getDefinition(); + if ($definition->getOptions() || $definition->getArguments()) { + $this->write("\n\n"); + $this->describeInputDefinition($definition); + } + } + protected function describeApplication(Application $application, array $options = []) : void + { + $describedNamespace = $options['namespace'] ?? null; + $description = new ApplicationDescription($application, $describedNamespace); + $title = $this->getApplicationTitle($application); + $this->write($title . "\n" . \str_repeat('=', Helper::width($title))); + foreach ($description->getNamespaces() as $namespace) { + if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { + $this->write("\n\n"); + $this->write('**' . $namespace['id'] . ':**'); + } + $this->write("\n\n"); + $this->write(\implode("\n", \array_map(function ($commandName) use($description) { + return \sprintf('* [`%s`](#%s)', $commandName, \str_replace(':', '', $description->getCommand($commandName)->getName())); + }, $namespace['commands']))); + } + foreach ($description->getCommands() as $command) { + $this->write("\n\n"); + $this->describeCommand($command, $options); + } + } + private function getApplicationTitle(Application $application) : string + { + if ('UNKNOWN' !== $application->getName()) { + if ('UNKNOWN' !== $application->getVersion()) { + return \sprintf('%s %s', $application->getName(), $application->getVersion()); + } + return $application->getName(); + } + return 'Console Tool'; + } +} diff --git a/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php b/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php new file mode 100644 index 0000000000..c43f583db1 --- /dev/null +++ b/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php @@ -0,0 +1,234 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\Helper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\String\UnicodeString; +class ReStructuredTextDescriptor extends Descriptor +{ + //

+ /** + * @var string + */ + private $partChar = '='; + //

+ /** + * @var string + */ + private $chapterChar = '-'; + //

+ /** + * @var string + */ + private $sectionChar = '~'; + //

+ /** + * @var string + */ + private $subsectionChar = '.'; + //

+ /** + * @var string + */ + private $subsubsectionChar = '^'; + //
+ /** + * @var string + */ + private $paragraphsChar = '"'; + /** + * @var mixed[] + */ + private $visibleNamespaces = []; + public function describe(OutputInterface $output, object $object, array $options = []) : void + { + $decorated = $output->isDecorated(); + $output->setDecorated(\false); + parent::describe($output, $object, $options); + $output->setDecorated($decorated); + } + /** + * Override parent method to set $decorated = true. + */ + protected function write(string $content, bool $decorated = \true) : void + { + parent::write($content, $decorated); + } + protected function describeInputArgument(InputArgument $argument, array $options = []) : void + { + $this->write($argument->getName() ?: '' . "\n" . \str_repeat($this->paragraphsChar, Helper::width($argument->getName())) . "\n\n" . ($argument->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $argument->getDescription()) . "\n\n" : '') . '- **Is required**: ' . ($argument->isRequired() ? 'yes' : 'no') . "\n" . '- **Is array**: ' . ($argument->isArray() ? 'yes' : 'no') . "\n" . '- **Default**: ``' . \str_replace("\n", '', \var_export($argument->getDefault(), \true)) . '``'); + } + protected function describeInputOption(InputOption $option, array $options = []) : void + { + $name = '\\-\\-' . $option->getName(); + if ($option->isNegatable()) { + $name .= '|\\-\\-no-' . $option->getName(); + } + if ($option->getShortcut()) { + $name .= '|-' . \str_replace('|', '|-', $option->getShortcut()); + } + $optionDescription = $option->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n\n", $option->getDescription()) . "\n\n" : ''; + $optionDescription = (new UnicodeString($optionDescription))->ascii(); + $this->write($name . "\n" . \str_repeat($this->paragraphsChar, Helper::width($name)) . "\n\n" . $optionDescription . '- **Accept value**: ' . ($option->acceptValue() ? 'yes' : 'no') . "\n" . '- **Is value required**: ' . ($option->isValueRequired() ? 'yes' : 'no') . "\n" . '- **Is multiple**: ' . ($option->isArray() ? 'yes' : 'no') . "\n" . '- **Is negatable**: ' . ($option->isNegatable() ? 'yes' : 'no') . "\n" . '- **Default**: ``' . \str_replace("\n", '', \var_export($option->getDefault(), \true)) . '``' . "\n"); + } + protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void + { + if ($showArguments = (bool) $definition->getArguments()) { + $this->write("Arguments\n" . \str_repeat($this->subsubsectionChar, 9)) . "\n\n"; + foreach ($definition->getArguments() as $argument) { + $this->write("\n\n"); + $this->describeInputArgument($argument); + } + } + if ($nonDefaultOptions = $this->getNonDefaultOptions($definition)) { + if ($showArguments) { + $this->write("\n\n"); + } + $this->write("Options\n" . \str_repeat($this->subsubsectionChar, 7) . "\n\n"); + foreach ($nonDefaultOptions as $option) { + $this->describeInputOption($option); + $this->write("\n"); + } + } + } + protected function describeCommand(Command $command, array $options = []) : void + { + if ($options['short'] ?? \false) { + $this->write('``' . $command->getName() . "``\n" . \str_repeat($this->subsectionChar, Helper::width($command->getName())) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . "Usage\n" . \str_repeat($this->paragraphsChar, 5) . "\n\n" . \array_reduce($command->getAliases(), static function ($carry, $usage) { + return $carry . '- ``' . $usage . '``' . "\n"; + })); + return; + } + $command->mergeApplicationDefinition(\false); + foreach ($command->getAliases() as $alias) { + $this->write('.. _' . $alias . ":\n\n"); + } + $this->write($command->getName() . "\n" . \str_repeat($this->subsectionChar, Helper::width($command->getName())) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . "Usage\n" . \str_repeat($this->subsubsectionChar, 5) . "\n\n" . \array_reduce(\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), static function ($carry, $usage) { + return $carry . '- ``' . $usage . '``' . "\n"; + })); + if ($help = $command->getProcessedHelp()) { + $this->write("\n"); + $this->write($help); + } + $definition = $command->getDefinition(); + if ($definition->getOptions() || $definition->getArguments()) { + $this->write("\n\n"); + $this->describeInputDefinition($definition); + } + } + protected function describeApplication(Application $application, array $options = []) : void + { + $description = new ApplicationDescription($application, $options['namespace'] ?? null); + $title = $this->getApplicationTitle($application); + $this->write($title . "\n" . \str_repeat($this->partChar, Helper::width($title))); + $this->createTableOfContents($description, $application); + $this->describeCommands($application, $options); + } + private function getApplicationTitle(Application $application) : string + { + if ('UNKNOWN' === $application->getName()) { + return 'Console Tool'; + } + if ('UNKNOWN' !== $application->getVersion()) { + return \sprintf('%s %s', $application->getName(), $application->getVersion()); + } + return $application->getName(); + } + private function describeCommands($application, array $options) : void + { + $title = 'Commands'; + $this->write("\n\n{$title}\n" . \str_repeat($this->chapterChar, Helper::width($title)) . "\n\n"); + foreach ($this->visibleNamespaces as $namespace) { + if ('_global' === $namespace) { + $commands = $application->all(''); + $this->write('Global' . "\n" . \str_repeat($this->sectionChar, Helper::width('Global')) . "\n\n"); + } else { + $commands = $application->all($namespace); + $this->write($namespace . "\n" . \str_repeat($this->sectionChar, Helper::width($namespace)) . "\n\n"); + } + foreach ($this->removeAliasesAndHiddenCommands($commands) as $command) { + $this->describeCommand($command, $options); + $this->write("\n\n"); + } + } + } + private function createTableOfContents(ApplicationDescription $description, Application $application) : void + { + $this->setVisibleNamespaces($description); + $chapterTitle = 'Table of Contents'; + $this->write("\n\n{$chapterTitle}\n" . \str_repeat($this->chapterChar, Helper::width($chapterTitle)) . "\n\n"); + foreach ($this->visibleNamespaces as $namespace) { + if ('_global' === $namespace) { + $commands = $application->all(''); + } else { + $commands = $application->all($namespace); + $this->write("\n\n"); + $this->write($namespace . "\n" . \str_repeat($this->sectionChar, Helper::width($namespace)) . "\n\n"); + } + $commands = $this->removeAliasesAndHiddenCommands($commands); + $this->write("\n\n"); + $this->write(\implode("\n", \array_map(static function ($commandName) { + return \sprintf('- `%s`_', $commandName); + }, \array_keys($commands)))); + } + } + private function getNonDefaultOptions(InputDefinition $definition) : array + { + $globalOptions = ['help', 'quiet', 'verbose', 'version', 'ansi', 'no-interaction']; + $nonDefaultOptions = []; + foreach ($definition->getOptions() as $option) { + // Skip global options. + if (!\in_array($option->getName(), $globalOptions)) { + $nonDefaultOptions[] = $option; + } + } + return $nonDefaultOptions; + } + private function setVisibleNamespaces(ApplicationDescription $description) : void + { + $commands = $description->getCommands(); + foreach ($description->getNamespaces() as $namespace) { + try { + $namespaceCommands = $namespace['commands']; + foreach ($namespaceCommands as $key => $commandName) { + if (!\array_key_exists($commandName, $commands)) { + // If the array key does not exist, then this is an alias. + unset($namespaceCommands[$key]); + } elseif ($commands[$commandName]->isHidden()) { + unset($namespaceCommands[$key]); + } + } + if (!$namespaceCommands) { + // If the namespace contained only aliases or hidden commands, skip the namespace. + continue; + } + } catch (\Exception $exception) { + } + $this->visibleNamespaces[] = $namespace['id']; + } + } + private function removeAliasesAndHiddenCommands(array $commands) : array + { + foreach ($commands as $key => $command) { + if ($command->isHidden() || \in_array($key, $command->getAliases(), \true)) { + unset($commands[$key]); + } + } + unset($commands['completion']); + return $commands; + } +} diff --git a/vendor/symfony/console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Descriptor/TextDescriptor.php new file mode 100644 index 0000000000..5ceba9be4c --- /dev/null +++ b/vendor/symfony/console/Descriptor/TextDescriptor.php @@ -0,0 +1,274 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\Helper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +/** + * Text descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class TextDescriptor extends Descriptor +{ + protected function describeInputArgument(InputArgument $argument, array $options = []) : void + { + if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) { + $default = \sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault())); + } else { + $default = ''; + } + $totalWidth = $options['total_width'] ?? Helper::width($argument->getName()); + $spacingWidth = $totalWidth - \strlen($argument->getName()); + $this->writeText(\sprintf( + ' %s %s%s%s', + $argument->getName(), + \str_repeat(' ', $spacingWidth), + // + 4 = 2 spaces before , 2 spaces after + \preg_replace('/\\s*[\\r\\n]\\s*/', "\n" . \str_repeat(' ', $totalWidth + 4), $argument->getDescription()), + $default + ), $options); + } + protected function describeInputOption(InputOption $option, array $options = []) : void + { + if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) { + $default = \sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault())); + } else { + $default = ''; + } + $value = ''; + if ($option->acceptValue()) { + $value = '=' . \strtoupper($option->getName()); + if ($option->isValueOptional()) { + $value = '[' . $value . ']'; + } + } + $totalWidth = $options['total_width'] ?? $this->calculateTotalWidthForOptions([$option]); + $synopsis = \sprintf('%s%s', $option->getShortcut() ? \sprintf('-%s, ', $option->getShortcut()) : ' ', \sprintf($option->isNegatable() ? '--%1$s|--no-%1$s' : '--%1$s%2$s', $option->getName(), $value)); + $spacingWidth = $totalWidth - Helper::width($synopsis); + $this->writeText(\sprintf( + ' %s %s%s%s%s', + $synopsis, + \str_repeat(' ', $spacingWidth), + // + 4 = 2 spaces before , 2 spaces after + \preg_replace('/\\s*[\\r\\n]\\s*/', "\n" . \str_repeat(' ', $totalWidth + 4), $option->getDescription()), + $default, + $option->isArray() ? ' (multiple values allowed)' : '' + ), $options); + } + protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void + { + $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions()); + foreach ($definition->getArguments() as $argument) { + $totalWidth = \max($totalWidth, Helper::width($argument->getName())); + } + if ($definition->getArguments()) { + $this->writeText('Arguments:', $options); + $this->writeText("\n"); + foreach ($definition->getArguments() as $argument) { + $this->describeInputArgument($argument, \array_merge($options, ['total_width' => $totalWidth])); + $this->writeText("\n"); + } + } + if ($definition->getArguments() && $definition->getOptions()) { + $this->writeText("\n"); + } + if ($definition->getOptions()) { + $laterOptions = []; + $this->writeText('Options:', $options); + foreach ($definition->getOptions() as $option) { + if (\strlen($option->getShortcut() ?? '') > 1) { + $laterOptions[] = $option; + continue; + } + $this->writeText("\n"); + $this->describeInputOption($option, \array_merge($options, ['total_width' => $totalWidth])); + } + foreach ($laterOptions as $option) { + $this->writeText("\n"); + $this->describeInputOption($option, \array_merge($options, ['total_width' => $totalWidth])); + } + } + } + protected function describeCommand(Command $command, array $options = []) : void + { + $command->mergeApplicationDefinition(\false); + if ($description = $command->getDescription()) { + $this->writeText('Description:', $options); + $this->writeText("\n"); + $this->writeText(' ' . $description); + $this->writeText("\n\n"); + } + $this->writeText('Usage:', $options); + foreach (\array_merge([$command->getSynopsis(\true)], $command->getAliases(), $command->getUsages()) as $usage) { + $this->writeText("\n"); + $this->writeText(' ' . OutputFormatter::escape($usage), $options); + } + $this->writeText("\n"); + $definition = $command->getDefinition(); + if ($definition->getOptions() || $definition->getArguments()) { + $this->writeText("\n"); + $this->describeInputDefinition($definition, $options); + $this->writeText("\n"); + } + $help = $command->getProcessedHelp(); + if ($help && $help !== $description) { + $this->writeText("\n"); + $this->writeText('Help:', $options); + $this->writeText("\n"); + $this->writeText(' ' . \str_replace("\n", "\n ", $help), $options); + $this->writeText("\n"); + } + } + protected function describeApplication(Application $application, array $options = []) : void + { + $describedNamespace = $options['namespace'] ?? null; + $description = new ApplicationDescription($application, $describedNamespace); + if (isset($options['raw_text']) && $options['raw_text']) { + $width = $this->getColumnWidth($description->getCommands()); + foreach ($description->getCommands() as $command) { + $this->writeText(\sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options); + $this->writeText("\n"); + } + } else { + if ('' != ($help = $application->getHelp())) { + $this->writeText("{$help}\n\n", $options); + } + $this->writeText("Usage:\n", $options); + $this->writeText(" command [options] [arguments]\n\n", $options); + $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options); + $this->writeText("\n"); + $this->writeText("\n"); + $commands = $description->getCommands(); + $namespaces = $description->getNamespaces(); + if ($describedNamespace && $namespaces) { + // make sure all alias commands are included when describing a specific namespace + $describedNamespaceInfo = \reset($namespaces); + foreach ($describedNamespaceInfo['commands'] as $name) { + $commands[$name] = $description->getCommand($name); + } + } + // calculate max. width based on available commands per namespace + $width = $this->getColumnWidth(\array_merge(...\array_values(\array_map(function ($namespace) use($commands) { + return \array_intersect($namespace['commands'], \array_keys($commands)); + }, \array_values($namespaces))))); + if ($describedNamespace) { + $this->writeText(\sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options); + } else { + $this->writeText('Available commands:', $options); + } + foreach ($namespaces as $namespace) { + $namespace['commands'] = \array_filter($namespace['commands'], function ($name) use($commands) { + return isset($commands[$name]); + }); + if (!$namespace['commands']) { + continue; + } + if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { + $this->writeText("\n"); + $this->writeText(' ' . $namespace['id'] . '', $options); + } + foreach ($namespace['commands'] as $name) { + $this->writeText("\n"); + $spacingWidth = $width - Helper::width($name); + $command = $commands[$name]; + $commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : ''; + $this->writeText(\sprintf(' %s%s%s', $name, \str_repeat(' ', $spacingWidth), $commandAliases . $command->getDescription()), $options); + } + } + $this->writeText("\n"); + } + } + private function writeText(string $content, array $options = []) : void + { + $this->write(isset($options['raw_text']) && $options['raw_text'] ? \strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : \true); + } + /** + * Formats command aliases to show them in the command description. + */ + private function getCommandAliasesText(Command $command) : string + { + $text = ''; + $aliases = $command->getAliases(); + if ($aliases) { + $text = '[' . \implode('|', $aliases) . '] '; + } + return $text; + } + /** + * Formats input option/argument default value. + * @param mixed $default + */ + private function formatDefaultValue($default) : string + { + if (\INF === $default) { + return 'INF'; + } + if (\is_string($default)) { + $default = OutputFormatter::escape($default); + } elseif (\is_array($default)) { + foreach ($default as $key => $value) { + if (\is_string($value)) { + $default[$key] = OutputFormatter::escape($value); + } + } + } + return \str_replace('\\\\', '\\', \json_encode($default, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)); + } + /** + * @param array $commands + */ + private function getColumnWidth(array $commands) : int + { + $widths = []; + foreach ($commands as $command) { + if ($command instanceof Command) { + $widths[] = Helper::width($command->getName()); + foreach ($command->getAliases() as $alias) { + $widths[] = Helper::width($alias); + } + } else { + $widths[] = Helper::width($command); + } + } + return $widths ? \max($widths) + 2 : 0; + } + /** + * @param InputOption[] $options + */ + private function calculateTotalWidthForOptions(array $options) : int + { + $totalWidth = 0; + foreach ($options as $option) { + // "-" + shortcut + ", --" + name + $nameLength = 1 + \max(Helper::width($option->getShortcut()), 1) + 4 + Helper::width($option->getName()); + if ($option->isNegatable()) { + $nameLength += 6 + Helper::width($option->getName()); + // |--no- + name + } elseif ($option->acceptValue()) { + $valueLength = 1 + Helper::width($option->getName()); + // = + value + $valueLength += $option->isValueOptional() ? 2 : 0; + // [ + ] + $nameLength += $valueLength; + } + $totalWidth = \max($totalWidth, $nameLength); + } + return $totalWidth; + } +} diff --git a/vendor/symfony/console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Descriptor/XmlDescriptor.php new file mode 100644 index 0000000000..26f1e58739 --- /dev/null +++ b/vendor/symfony/console/Descriptor/XmlDescriptor.php @@ -0,0 +1,191 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputOption; +/** + * XML descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class XmlDescriptor extends Descriptor +{ + public function getInputDefinitionDocument(InputDefinition $definition) : \DOMDocument + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($definitionXML = $dom->createElement('definition')); + $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments')); + foreach ($definition->getArguments() as $argument) { + $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument)); + } + $definitionXML->appendChild($optionsXML = $dom->createElement('options')); + foreach ($definition->getOptions() as $option) { + $this->appendDocument($optionsXML, $this->getInputOptionDocument($option)); + } + return $dom; + } + public function getCommandDocument(Command $command, bool $short = \false) : \DOMDocument + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($commandXML = $dom->createElement('command')); + $commandXML->setAttribute('id', $command->getName()); + $commandXML->setAttribute('name', $command->getName()); + $commandXML->setAttribute('hidden', $command->isHidden() ? 1 : 0); + $commandXML->appendChild($usagesXML = $dom->createElement('usages')); + $commandXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode(\str_replace("\n", "\n ", $command->getDescription()))); + if ($short) { + foreach ($command->getAliases() as $usage) { + $usagesXML->appendChild($dom->createElement('usage', $usage)); + } + } else { + $command->mergeApplicationDefinition(\false); + foreach (\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()) as $usage) { + $usagesXML->appendChild($dom->createElement('usage', $usage)); + } + $commandXML->appendChild($helpXML = $dom->createElement('help')); + $helpXML->appendChild($dom->createTextNode(\str_replace("\n", "\n ", $command->getProcessedHelp()))); + $definitionXML = $this->getInputDefinitionDocument($command->getDefinition()); + $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0)); + } + return $dom; + } + public function getApplicationDocument(Application $application, string $namespace = null, bool $short = \false) : \DOMDocument + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($rootXml = $dom->createElement('symfony')); + if ('UNKNOWN' !== $application->getName()) { + $rootXml->setAttribute('name', $application->getName()); + if ('UNKNOWN' !== $application->getVersion()) { + $rootXml->setAttribute('version', $application->getVersion()); + } + } + $rootXml->appendChild($commandsXML = $dom->createElement('commands')); + $description = new ApplicationDescription($application, $namespace, \true); + if ($namespace) { + $commandsXML->setAttribute('namespace', $namespace); + } + foreach ($description->getCommands() as $command) { + $this->appendDocument($commandsXML, $this->getCommandDocument($command, $short)); + } + if (!$namespace) { + $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces')); + foreach ($description->getNamespaces() as $namespaceDescription) { + $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace')); + $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']); + foreach ($namespaceDescription['commands'] as $name) { + $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command')); + $commandXML->appendChild($dom->createTextNode($name)); + } + } + } + return $dom; + } + protected function describeInputArgument(InputArgument $argument, array $options = []) : void + { + $this->writeDocument($this->getInputArgumentDocument($argument)); + } + protected function describeInputOption(InputOption $option, array $options = []) : void + { + $this->writeDocument($this->getInputOptionDocument($option)); + } + protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void + { + $this->writeDocument($this->getInputDefinitionDocument($definition)); + } + protected function describeCommand(Command $command, array $options = []) : void + { + $this->writeDocument($this->getCommandDocument($command, $options['short'] ?? \false)); + } + protected function describeApplication(Application $application, array $options = []) : void + { + $this->writeDocument($this->getApplicationDocument($application, $options['namespace'] ?? null, $options['short'] ?? \false)); + } + /** + * Appends document children to parent node. + */ + private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent) : void + { + foreach ($importedParent->childNodes as $childNode) { + $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, \true)); + } + } + /** + * Writes DOM document. + */ + private function writeDocument(\DOMDocument $dom) : void + { + $dom->formatOutput = \true; + $this->write($dom->saveXML()); + } + private function getInputArgumentDocument(InputArgument $argument) : \DOMDocument + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($objectXML = $dom->createElement('argument')); + $objectXML->setAttribute('name', $argument->getName()); + $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0); + $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0); + $objectXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode($argument->getDescription())); + $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); + $defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? [\var_export($argument->getDefault(), \true)] : ($argument->getDefault() ? [$argument->getDefault()] : [])); + foreach ($defaults as $default) { + $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); + $defaultXML->appendChild($dom->createTextNode($default)); + } + return $dom; + } + private function getInputOptionDocument(InputOption $option) : \DOMDocument + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($objectXML = $dom->createElement('option')); + $objectXML->setAttribute('name', '--' . $option->getName()); + $pos = \strpos($option->getShortcut() ?? '', '|'); + if (\false !== $pos) { + $objectXML->setAttribute('shortcut', '-' . \substr($option->getShortcut(), 0, $pos)); + $objectXML->setAttribute('shortcuts', '-' . \str_replace('|', '|-', $option->getShortcut())); + } else { + $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-' . $option->getShortcut() : ''); + } + $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0); + $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0); + $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0); + $objectXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode($option->getDescription())); + if ($option->acceptValue()) { + $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [\var_export($option->getDefault(), \true)] : ($option->getDefault() ? [$option->getDefault()] : [])); + $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); + if (!empty($defaults)) { + foreach ($defaults as $default) { + $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); + $defaultXML->appendChild($dom->createTextNode($default)); + } + } + } + if ($option->isNegatable()) { + $dom->appendChild($objectXML = $dom->createElement('option')); + $objectXML->setAttribute('name', '--no-' . $option->getName()); + $objectXML->setAttribute('shortcut', ''); + $objectXML->setAttribute('accept_value', 0); + $objectXML->setAttribute('is_value_required', 0); + $objectXML->setAttribute('is_multiple', 0); + $objectXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode('Negate the "--' . $option->getName() . '" option')); + } + return $dom; + } +} diff --git a/vendor/symfony/console/Event/ConsoleCommandEvent.php b/vendor/symfony/console/Event/ConsoleCommandEvent.php new file mode 100644 index 0000000000..3f5d56810e --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleCommandEvent.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Event; + +/** + * Allows to do things before the command is executed, like skipping the command or changing the input. + * + * @author Fabien Potencier + */ +final class ConsoleCommandEvent extends ConsoleEvent +{ + /** + * The return code for skipped commands, this will also be passed into the terminate event. + */ + public const RETURN_CODE_DISABLED = 113; + /** + * Indicates if the command should be run or skipped. + * @var bool + */ + private $commandShouldRun = \true; + /** + * Disables the command, so it won't be run. + */ + public function disableCommand() : bool + { + return $this->commandShouldRun = \false; + } + public function enableCommand() : bool + { + return $this->commandShouldRun = \true; + } + /** + * Returns true if the command is runnable, false otherwise. + */ + public function commandShouldRun() : bool + { + return $this->commandShouldRun; + } +} diff --git a/vendor/symfony/console/Event/ConsoleErrorEvent.php b/vendor/symfony/console/Event/ConsoleErrorEvent.php new file mode 100644 index 0000000000..270be95da0 --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleErrorEvent.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Event; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Allows to handle throwables thrown while running a command. + * + * @author Wouter de Jong + */ +final class ConsoleErrorEvent extends ConsoleEvent +{ + /** + * @var \Throwable + */ + private $error; + /** + * @var int + */ + private $exitCode; + public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null) + { + parent::__construct($command, $input, $output); + $this->error = $error; + } + public function getError() : \Throwable + { + return $this->error; + } + public function setError(\Throwable $error) : void + { + $this->error = $error; + } + public function setExitCode(int $exitCode) : void + { + $this->exitCode = $exitCode; + $r = new \ReflectionProperty($this->error, 'code'); + $r->setAccessible(\true); + $r->setValue($this->error, $this->exitCode); + } + public function getExitCode() : int + { + return $this->exitCode ?? (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1); + } +} diff --git a/vendor/symfony/console/Event/ConsoleEvent.php b/vendor/symfony/console/Event/ConsoleEvent.php new file mode 100644 index 0000000000..5d2b889646 --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleEvent.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Event; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\EventDispatcher\Event; +/** + * Allows to inspect input and output of a command. + * + * @author Francesco Levorato + */ +class ConsoleEvent extends Event +{ + protected $command; + /** + * @var \Symfony\Component\Console\Input\InputInterface + */ + private $input; + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + public function __construct(?Command $command, InputInterface $input, OutputInterface $output) + { + $this->command = $command; + $this->input = $input; + $this->output = $output; + } + /** + * Gets the command that is executed. + */ + public function getCommand() : ?Command + { + return $this->command; + } + /** + * Gets the input instance. + */ + public function getInput() : InputInterface + { + return $this->input; + } + /** + * Gets the output instance. + */ + public function getOutput() : OutputInterface + { + return $this->output; + } +} diff --git a/vendor/symfony/console/Event/ConsoleSignalEvent.php b/vendor/symfony/console/Event/ConsoleSignalEvent.php new file mode 100644 index 0000000000..a09c00f1e2 --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleSignalEvent.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Event; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author marie + */ +final class ConsoleSignalEvent extends ConsoleEvent +{ + /** + * @var int + */ + private $handlingSignal; + /** + * @var int|false + */ + private $exitCode; + /** + * @param int|false $exitCode + */ + public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal, $exitCode = 0) + { + parent::__construct($command, $input, $output); + $this->handlingSignal = $handlingSignal; + $this->exitCode = $exitCode; + } + public function getHandlingSignal() : int + { + return $this->handlingSignal; + } + public function setExitCode(int $exitCode) : void + { + if ($exitCode < 0 || $exitCode > 255) { + throw new \InvalidArgumentException('Exit code must be between 0 and 255.'); + } + $this->exitCode = $exitCode; + } + public function abortExit() : void + { + $this->exitCode = \false; + } + /** + * @return int|false + */ + public function getExitCode() + { + return $this->exitCode; + } +} diff --git a/vendor/symfony/console/Event/ConsoleTerminateEvent.php b/vendor/symfony/console/Event/ConsoleTerminateEvent.php new file mode 100644 index 0000000000..94df4b8d41 --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleTerminateEvent.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Event; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Allows to manipulate the exit code of a command after its execution. + * + * @author Francesco Levorato + */ +final class ConsoleTerminateEvent extends ConsoleEvent +{ + /** + * @var int + */ + private $exitCode; + public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode) + { + parent::__construct($command, $input, $output); + $this->setExitCode($exitCode); + } + public function setExitCode(int $exitCode) : void + { + $this->exitCode = $exitCode; + } + public function getExitCode() : int + { + return $this->exitCode; + } +} diff --git a/vendor/symfony/console/EventListener/ErrorListener.php b/vendor/symfony/console/EventListener/ErrorListener.php new file mode 100644 index 0000000000..51ab61b99e --- /dev/null +++ b/vendor/symfony/console/EventListener/ErrorListener.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\EventListener; + +use MonorepoBuilderPrefix202310\Psr\Log\LoggerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\ConsoleEvents; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleErrorEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Event\ConsoleTerminateEvent; +use MonorepoBuilderPrefix202310\Symfony\Component\EventDispatcher\EventSubscriberInterface; +/** + * @author James Halsall + * @author Robin Chalas + */ +class ErrorListener implements EventSubscriberInterface +{ + /** + * @var \Psr\Log\LoggerInterface|null + */ + private $logger; + public function __construct(LoggerInterface $logger = null) + { + $this->logger = $logger; + } + /** + * @return void + */ + public function onConsoleError(ConsoleErrorEvent $event) + { + if (null === $this->logger) { + return; + } + $error = $event->getError(); + if (!($inputString = $this->getInputString($event))) { + $this->logger->critical('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]); + return; + } + $this->logger->critical('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]); + } + /** + * @return void + */ + public function onConsoleTerminate(ConsoleTerminateEvent $event) + { + if (null === $this->logger) { + return; + } + $exitCode = $event->getExitCode(); + if (0 === $exitCode) { + return; + } + if (!($inputString = $this->getInputString($event))) { + $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]); + return; + } + $this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]); + } + public static function getSubscribedEvents() : array + { + return [ConsoleEvents::ERROR => ['onConsoleError', -128], ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128]]; + } + private static function getInputString(ConsoleEvent $event) : ?string + { + $commandName = ($nullsafeVariable1 = $event->getCommand()) ? $nullsafeVariable1->getName() : null; + $input = $event->getInput(); + if ($input instanceof \Stringable) { + if ($commandName) { + return \str_replace(["'{$commandName}'", "\"{$commandName}\""], $commandName, (string) $input); + } + return (string) $input; + } + return $commandName; + } +} diff --git a/vendor/symfony/console/Exception/CommandNotFoundException.php b/vendor/symfony/console/Exception/CommandNotFoundException.php new file mode 100644 index 0000000000..c2f8e1346e --- /dev/null +++ b/vendor/symfony/console/Exception/CommandNotFoundException.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * Represents an incorrect command name typed in the console. + * + * @author Jérôme Tamarelle + */ +class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface +{ + /** + * @var mixed[] + */ + private $alternatives; + /** + * @param string $message Exception message to throw + * @param string[] $alternatives List of similar defined names + * @param int $code Exception code + * @param \Throwable|null $previous Previous exception used for the exception chaining + */ + public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + $this->alternatives = $alternatives; + } + /** + * @return string[] + */ + public function getAlternatives() : array + { + return $this->alternatives; + } +} diff --git a/vendor/symfony/console/Exception/ExceptionInterface.php b/vendor/symfony/console/Exception/ExceptionInterface.php new file mode 100644 index 0000000000..0eda905afa --- /dev/null +++ b/vendor/symfony/console/Exception/ExceptionInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * ExceptionInterface. + * + * @author Jérôme Tamarelle + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/console/Exception/InvalidArgumentException.php b/vendor/symfony/console/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000..9688baf430 --- /dev/null +++ b/vendor/symfony/console/Exception/InvalidArgumentException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * @author Jérôme Tamarelle + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Exception/InvalidOptionException.php b/vendor/symfony/console/Exception/InvalidOptionException.php new file mode 100644 index 0000000000..5be0e72d50 --- /dev/null +++ b/vendor/symfony/console/Exception/InvalidOptionException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * Represents an incorrect option name or value typed in the console. + * + * @author Jérôme Tamarelle + */ +class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Exception/LogicException.php b/vendor/symfony/console/Exception/LogicException.php new file mode 100644 index 0000000000..5ee19ae762 --- /dev/null +++ b/vendor/symfony/console/Exception/LogicException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * @author Jérôme Tamarelle + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Exception/MissingInputException.php b/vendor/symfony/console/Exception/MissingInputException.php new file mode 100644 index 0000000000..53bc5e7c89 --- /dev/null +++ b/vendor/symfony/console/Exception/MissingInputException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * Represents failure to read input from stdin. + * + * @author Gabriel Ostrolucký + */ +class MissingInputException extends RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Exception/NamespaceNotFoundException.php b/vendor/symfony/console/Exception/NamespaceNotFoundException.php new file mode 100644 index 0000000000..3d80833a55 --- /dev/null +++ b/vendor/symfony/console/Exception/NamespaceNotFoundException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * Represents an incorrect namespace typed in the console. + * + * @author Pierre du Plessis + */ +class NamespaceNotFoundException extends CommandNotFoundException +{ +} diff --git a/vendor/symfony/console/Exception/RuntimeException.php b/vendor/symfony/console/Exception/RuntimeException.php new file mode 100644 index 0000000000..75eaaac552 --- /dev/null +++ b/vendor/symfony/console/Exception/RuntimeException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception; + +/** + * @author Jérôme Tamarelle + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Formatter/NullOutputFormatter.php b/vendor/symfony/console/Formatter/NullOutputFormatter.php new file mode 100644 index 0000000000..03169d5071 --- /dev/null +++ b/vendor/symfony/console/Formatter/NullOutputFormatter.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +/** + * @author Tien Xuan Vo + */ +final class NullOutputFormatter implements OutputFormatterInterface +{ + /** + * @var \Symfony\Component\Console\Formatter\NullOutputFormatterStyle + */ + private $style; + public function format(?string $message) : ?string + { + return null; + } + public function getStyle(string $name) : OutputFormatterStyleInterface + { + // to comply with the interface we must return a OutputFormatterStyleInterface + return $this->style = $this->style ?? new NullOutputFormatterStyle(); + } + public function hasStyle(string $name) : bool + { + return \false; + } + public function isDecorated() : bool + { + return \false; + } + public function setDecorated(bool $decorated) : void + { + // do nothing + } + public function setStyle(string $name, OutputFormatterStyleInterface $style) : void + { + // do nothing + } +} diff --git a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php new file mode 100644 index 0000000000..9eb4b6e60f --- /dev/null +++ b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +/** + * @author Tien Xuan Vo + */ +final class NullOutputFormatterStyle implements OutputFormatterStyleInterface +{ + public function apply(string $text) : string + { + return $text; + } + public function setBackground(string $color = null) : void + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + // do nothing + } + public function setForeground(string $color = null) : void + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + // do nothing + } + public function setOption(string $option) : void + { + // do nothing + } + public function setOptions(array $options) : void + { + // do nothing + } + public function unsetOption(string $option) : void + { + // do nothing + } +} diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php new file mode 100644 index 0000000000..3164a8cb0e --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatter.php @@ -0,0 +1,241 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use function MonorepoBuilderPrefix202310\Symfony\Component\String\b; +/** + * Formatter class for console output. + * + * @author Konstantin Kudryashov + * @author Roland Franssen + */ +class OutputFormatter implements WrappableOutputFormatterInterface +{ + /** + * @var bool + */ + private $decorated; + /** + * @var mixed[] + */ + private $styles = []; + /** + * @var \Symfony\Component\Console\Formatter\OutputFormatterStyleStack + */ + private $styleStack; + public function __clone() + { + $this->styleStack = clone $this->styleStack; + foreach ($this->styles as $key => $value) { + $this->styles[$key] = clone $value; + } + } + /** + * Escapes "<" and ">" special chars in given text. + */ + public static function escape(string $text) : string + { + $text = \preg_replace('/([^\\\\]|^)([<>])/', '$1\\\\$2', $text); + return self::escapeTrailingBackslash($text); + } + /** + * Escapes trailing "\" in given text. + * + * @internal + */ + public static function escapeTrailingBackslash(string $text) : string + { + if (\substr_compare($text, '\\', -\strlen('\\')) === 0) { + $len = \strlen($text); + $text = \rtrim($text, '\\'); + $text = \str_replace("\x00", '', $text); + $text .= \str_repeat("\x00", $len - \strlen($text)); + } + return $text; + } + /** + * Initializes console output formatter. + * + * @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances + */ + public function __construct(bool $decorated = \false, array $styles = []) + { + $this->decorated = $decorated; + $this->setStyle('error', new OutputFormatterStyle('white', 'red')); + $this->setStyle('info', new OutputFormatterStyle('green')); + $this->setStyle('comment', new OutputFormatterStyle('yellow')); + $this->setStyle('question', new OutputFormatterStyle('black', 'cyan')); + foreach ($styles as $name => $style) { + $this->setStyle($name, $style); + } + $this->styleStack = new OutputFormatterStyleStack(); + } + /** + * @return void + */ + public function setDecorated(bool $decorated) + { + $this->decorated = $decorated; + } + public function isDecorated() : bool + { + return $this->decorated; + } + /** + * @return void + */ + public function setStyle(string $name, OutputFormatterStyleInterface $style) + { + $this->styles[\strtolower($name)] = $style; + } + public function hasStyle(string $name) : bool + { + return isset($this->styles[\strtolower($name)]); + } + public function getStyle(string $name) : OutputFormatterStyleInterface + { + if (!$this->hasStyle($name)) { + throw new InvalidArgumentException(\sprintf('Undefined style: "%s".', $name)); + } + return $this->styles[\strtolower($name)]; + } + public function format(?string $message) : ?string + { + return $this->formatAndWrap($message, 0); + } + /** + * @return string + */ + public function formatAndWrap(?string $message, int $width) + { + if (null === $message) { + return ''; + } + $offset = 0; + $output = ''; + $openTagRegex = '[a-z](?:[^\\\\<>]*+ | \\\\.)*'; + $closeTagRegex = '[a-z][^<>]*+'; + $currentLineLength = 0; + \preg_match_all("#<(({$openTagRegex}) | /({$closeTagRegex})?)>#ix", $message, $matches, \PREG_OFFSET_CAPTURE); + foreach ($matches[0] as $i => $match) { + $pos = $match[1]; + $text = $match[0]; + if (0 != $pos && '\\' == $message[$pos - 1]) { + continue; + } + // add the text up to the next tag + $output .= $this->applyCurrentStyle(\substr($message, $offset, $pos - $offset), $output, $width, $currentLineLength); + $offset = $pos + \strlen($text); + // opening tag? + if ($open = '/' !== $text[1]) { + $tag = $matches[1][$i][0]; + } else { + $tag = $matches[3][$i][0] ?? ''; + } + if (!$open && !$tag) { + // + $this->styleStack->pop(); + } elseif (null === ($style = $this->createStyleFromString($tag))) { + $output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength); + } elseif ($open) { + $this->styleStack->push($style); + } else { + $this->styleStack->pop($style); + } + } + $output .= $this->applyCurrentStyle(\substr($message, $offset), $output, $width, $currentLineLength); + return \strtr($output, ["\x00" => '\\', '\\<' => '<', '\\>' => '>']); + } + public function getStyleStack() : OutputFormatterStyleStack + { + return $this->styleStack; + } + /** + * Tries to create new style instance from string. + */ + private function createStyleFromString(string $string) : ?OutputFormatterStyleInterface + { + if (isset($this->styles[$string])) { + return $this->styles[$string]; + } + if (!\preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, \PREG_SET_ORDER)) { + return null; + } + $style = new OutputFormatterStyle(); + foreach ($matches as $match) { + \array_shift($match); + $match[0] = \strtolower($match[0]); + if ('fg' == $match[0]) { + $style->setForeground(\strtolower($match[1])); + } elseif ('bg' == $match[0]) { + $style->setBackground(\strtolower($match[1])); + } elseif ('href' === $match[0]) { + $url = \preg_replace('{\\\\([<>])}', '$1', $match[1]); + $style->setHref($url); + } elseif ('options' === $match[0]) { + \preg_match_all('([^,;]+)', \strtolower($match[1]), $options); + $options = \array_shift($options); + foreach ($options as $option) { + $style->setOption($option); + } + } else { + return null; + } + } + return $style; + } + /** + * Applies current style from stack to text, if must be applied. + */ + private function applyCurrentStyle(string $text, string $current, int $width, int &$currentLineLength) : string + { + if ('' === $text) { + return ''; + } + if (!$width) { + return $this->isDecorated() ? $this->styleStack->getCurrent()->apply($text) : $text; + } + if (!$currentLineLength && '' !== $current) { + $text = \ltrim($text); + } + if ($currentLineLength) { + $prefix = \substr($text, 0, $i = $width - $currentLineLength) . "\n"; + $text = \substr($text, $i); + } else { + $prefix = ''; + } + \preg_match('~(\\n)$~', $text, $matches); + $text = $prefix . $this->addLineBreaks($text, $width); + $text = \rtrim($text, "\n") . ($matches[1] ?? ''); + if (!$currentLineLength && '' !== $current && \substr_compare($current, "\n", -\strlen("\n")) !== 0) { + $text = "\n" . $text; + } + $lines = \explode("\n", $text); + foreach ($lines as $line) { + $currentLineLength += \strlen($line); + if ($width <= $currentLineLength) { + $currentLineLength = 0; + } + } + if ($this->isDecorated()) { + foreach ($lines as $i => $line) { + $lines[$i] = $this->styleStack->getCurrent()->apply($line); + } + } + return \implode("\n", $lines); + } + private function addLineBreaks(string $text, int $width) : string + { + $encoding = \mb_detect_encoding($text, null, \true) ?: 'UTF-8'; + return b($text)->toCodePointString($encoding)->wordwrap($width, "\n", \true)->toByteString($encoding); + } +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php new file mode 100644 index 0000000000..c199fac4b0 --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterInterface.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +/** + * Formatter interface for console output. + * + * @author Konstantin Kudryashov + */ +interface OutputFormatterInterface +{ + /** + * Sets the decorated flag. + * + * @return void + */ + public function setDecorated(bool $decorated); + /** + * Whether the output will decorate messages. + */ + public function isDecorated() : bool; + /** + * Sets a new style. + * + * @return void + */ + public function setStyle(string $name, OutputFormatterStyleInterface $style); + /** + * Checks if output formatter has style with specified name. + */ + public function hasStyle(string $name) : bool; + /** + * Gets style options from style with specified name. + * + * @throws \InvalidArgumentException When style isn't defined + */ + public function getStyle(string $name) : OutputFormatterStyleInterface; + /** + * Formats a message according to the given styles. + */ + public function format(?string $message) : ?string; +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyle.php b/vendor/symfony/console/Formatter/OutputFormatterStyle.php new file mode 100644 index 0000000000..675026bc66 --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterStyle.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Color; +/** + * Formatter style class for defining styles. + * + * @author Konstantin Kudryashov + */ +class OutputFormatterStyle implements OutputFormatterStyleInterface +{ + /** + * @var \Symfony\Component\Console\Color + */ + private $color; + /** + * @var string + */ + private $foreground; + /** + * @var string + */ + private $background; + /** + * @var mixed[] + */ + private $options; + /** + * @var string|null + */ + private $href; + /** + * @var bool + */ + private $handlesHrefGracefully; + /** + * Initializes output formatter style. + * + * @param string|null $foreground The style foreground color name + * @param string|null $background The style background color name + */ + public function __construct(string $foreground = null, string $background = null, array $options = []) + { + $this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options); + } + /** + * @return void + */ + public function setForeground(string $color = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + $this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options); + } + /** + * @return void + */ + public function setBackground(string $color = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + $this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options); + } + public function setHref(string $url) : void + { + $this->href = $url; + } + /** + * @return void + */ + public function setOption(string $option) + { + $this->options[] = $option; + $this->color = new Color($this->foreground, $this->background, $this->options); + } + /** + * @return void + */ + public function unsetOption(string $option) + { + $pos = \array_search($option, $this->options); + if (\false !== $pos) { + unset($this->options[$pos]); + } + $this->color = new Color($this->foreground, $this->background, $this->options); + } + /** + * @return void + */ + public function setOptions(array $options) + { + $this->color = new Color($this->foreground, $this->background, $this->options = $options); + } + public function apply(string $text) : string + { + $this->handlesHrefGracefully = $this->handlesHrefGracefully ?? 'JetBrains-JediTerm' !== \getenv('TERMINAL_EMULATOR') && (!\getenv('KONSOLE_VERSION') || (int) \getenv('KONSOLE_VERSION') > 201100) && !isset($_SERVER['IDEA_INITIAL_DIRECTORY']); + if (null !== $this->href && $this->handlesHrefGracefully) { + $text = "\x1b]8;;{$this->href}\x1b\\{$text}\x1b]8;;\x1b\\"; + } + return $this->color->apply($text); + } +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php new file mode 100644 index 0000000000..1accc79859 --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +/** + * Formatter style interface for defining styles. + * + * @author Konstantin Kudryashov + */ +interface OutputFormatterStyleInterface +{ + /** + * Sets style foreground color. + * + * @return void + */ + public function setForeground(?string $color); + /** + * Sets style background color. + * + * @return void + */ + public function setBackground(?string $color); + /** + * Sets some specific style option. + * + * @return void + */ + public function setOption(string $option); + /** + * Unsets some specific style option. + * + * @return void + */ + public function unsetOption(string $option); + /** + * Sets multiple style options at once. + * + * @return void + */ + public function setOptions(array $options); + /** + * Applies the style to a given text. + */ + public function apply(string $text) : string; +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php new file mode 100644 index 0000000000..d65ee735f3 --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ResetInterface; +/** + * @author Jean-François Simon + */ +class OutputFormatterStyleStack implements ResetInterface +{ + /** + * @var OutputFormatterStyleInterface[] + */ + private $styles = []; + /** + * @var \Symfony\Component\Console\Formatter\OutputFormatterStyleInterface + */ + private $emptyStyle; + public function __construct(OutputFormatterStyleInterface $emptyStyle = null) + { + $this->emptyStyle = $emptyStyle ?? new OutputFormatterStyle(); + $this->reset(); + } + /** + * Resets stack (ie. empty internal arrays). + * + * @return void + */ + public function reset() + { + $this->styles = []; + } + /** + * Pushes a style in the stack. + * + * @return void + */ + public function push(OutputFormatterStyleInterface $style) + { + $this->styles[] = $style; + } + /** + * Pops a style from the stack. + * + * @throws InvalidArgumentException When style tags incorrectly nested + */ + public function pop(OutputFormatterStyleInterface $style = null) : OutputFormatterStyleInterface + { + if (!$this->styles) { + return $this->emptyStyle; + } + if (null === $style) { + return \array_pop($this->styles); + } + foreach (\array_reverse($this->styles, \true) as $index => $stackedStyle) { + if ($style->apply('') === $stackedStyle->apply('')) { + $this->styles = \array_slice($this->styles, 0, $index); + return $stackedStyle; + } + } + throw new InvalidArgumentException('Incorrectly nested style tag found.'); + } + /** + * Computes current style with stacks top codes. + */ + public function getCurrent() : OutputFormatterStyleInterface + { + if (!$this->styles) { + return $this->emptyStyle; + } + return $this->styles[\count($this->styles) - 1]; + } + /** + * @return $this + */ + public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle) + { + $this->emptyStyle = $emptyStyle; + return $this; + } + public function getEmptyStyle() : OutputFormatterStyleInterface + { + return $this->emptyStyle; + } +} diff --git a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php new file mode 100644 index 0000000000..23bf9e4138 --- /dev/null +++ b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter; + +/** + * Formatter interface for console output that supports word wrapping. + * + * @author Roland Franssen + */ +interface WrappableOutputFormatterInterface extends OutputFormatterInterface +{ + /** + * Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping). + * + * @return string + */ + public function formatAndWrap(?string $message, int $width); +} diff --git a/vendor/symfony/console/Helper/DebugFormatterHelper.php b/vendor/symfony/console/Helper/DebugFormatterHelper.php new file mode 100644 index 0000000000..2efd912e6c --- /dev/null +++ b/vendor/symfony/console/Helper/DebugFormatterHelper.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +/** + * Helps outputting debug information when running an external program from a command. + * + * An external program can be a Process, an HTTP request, or anything else. + * + * @author Fabien Potencier + */ +class DebugFormatterHelper extends Helper +{ + private const COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default']; + /** + * @var mixed[] + */ + private $started = []; + /** + * @var int + */ + private $count = -1; + /** + * Starts a debug formatting session. + */ + public function start(string $id, string $message, string $prefix = 'RUN') : string + { + $this->started[$id] = ['border' => ++$this->count % \count(self::COLORS)]; + return \sprintf("%s %s %s\n", $this->getBorder($id), $prefix, $message); + } + /** + * Adds progress to a formatting session. + */ + public function progress(string $id, string $buffer, bool $error = \false, string $prefix = 'OUT', string $errorPrefix = 'ERR') : string + { + $message = ''; + if ($error) { + if (isset($this->started[$id]['out'])) { + $message .= "\n"; + unset($this->started[$id]['out']); + } + if (!isset($this->started[$id]['err'])) { + $message .= \sprintf('%s %s ', $this->getBorder($id), $errorPrefix); + $this->started[$id]['err'] = \true; + } + $message .= \str_replace("\n", \sprintf("\n%s %s ", $this->getBorder($id), $errorPrefix), $buffer); + } else { + if (isset($this->started[$id]['err'])) { + $message .= "\n"; + unset($this->started[$id]['err']); + } + if (!isset($this->started[$id]['out'])) { + $message .= \sprintf('%s %s ', $this->getBorder($id), $prefix); + $this->started[$id]['out'] = \true; + } + $message .= \str_replace("\n", \sprintf("\n%s %s ", $this->getBorder($id), $prefix), $buffer); + } + return $message; + } + /** + * Stops a formatting session. + */ + public function stop(string $id, string $message, bool $successful, string $prefix = 'RES') : string + { + $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : ''; + if ($successful) { + return \sprintf("%s%s %s %s\n", $trailingEOL, $this->getBorder($id), $prefix, $message); + } + $message = \sprintf("%s%s %s %s\n", $trailingEOL, $this->getBorder($id), $prefix, $message); + unset($this->started[$id]['out'], $this->started[$id]['err']); + return $message; + } + private function getBorder(string $id) : string + { + return \sprintf(' ', self::COLORS[$this->started[$id]['border']]); + } + public function getName() : string + { + return 'debug_formatter'; + } +} diff --git a/vendor/symfony/console/Helper/DescriptorHelper.php b/vendor/symfony/console/Helper/DescriptorHelper.php new file mode 100644 index 0000000000..e49733936a --- /dev/null +++ b/vendor/symfony/console/Helper/DescriptorHelper.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\DescriptorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\JsonDescriptor; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\MarkdownDescriptor; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\ReStructuredTextDescriptor; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\TextDescriptor; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Descriptor\XmlDescriptor; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * This class adds helper method to describe objects in various formats. + * + * @author Jean-François Simon + */ +class DescriptorHelper extends Helper +{ + /** + * @var DescriptorInterface[] + */ + private $descriptors = []; + public function __construct() + { + $this->register('txt', new TextDescriptor())->register('xml', new XmlDescriptor())->register('json', new JsonDescriptor())->register('md', new MarkdownDescriptor())->register('rst', new ReStructuredTextDescriptor()); + } + /** + * Describes an object if supported. + * + * Available options are: + * * format: string, the output format name + * * raw_text: boolean, sets output type as raw + * + * @return void + * + * @throws InvalidArgumentException when the given format is not supported + */ + public function describe(OutputInterface $output, ?object $object, array $options = []) + { + $options = \array_merge(['raw_text' => \false, 'format' => 'txt'], $options); + if (!isset($this->descriptors[$options['format']])) { + throw new InvalidArgumentException(\sprintf('Unsupported format "%s".', $options['format'])); + } + $descriptor = $this->descriptors[$options['format']]; + $descriptor->describe($output, $object, $options); + } + /** + * Registers a descriptor. + * + * @return $this + */ + public function register(string $format, DescriptorInterface $descriptor) + { + $this->descriptors[$format] = $descriptor; + return $this; + } + public function getName() : string + { + return 'descriptor'; + } + public function getFormats() : array + { + return \array_keys($this->descriptors); + } +} diff --git a/vendor/symfony/console/Helper/Dumper.php b/vendor/symfony/console/Helper/Dumper.php new file mode 100644 index 0000000000..ef604f8a86 --- /dev/null +++ b/vendor/symfony/console/Helper/Dumper.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\VarDumper\Cloner\ClonerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\VarDumper\Cloner\VarCloner; +use MonorepoBuilderPrefix202310\Symfony\Component\VarDumper\Dumper\CliDumper; +/** + * @author Roland Franssen + */ +final class Dumper +{ + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + /** + * @var \Symfony\Component\VarDumper\Dumper\CliDumper|null + */ + private $dumper; + /** + * @var \Symfony\Component\VarDumper\Cloner\ClonerInterface|null + */ + private $cloner; + /** + * @var \Closure + */ + private $handler; + public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null) + { + $this->output = $output; + $this->dumper = $dumper; + $this->cloner = $cloner; + if (\class_exists(CliDumper::class)) { + $this->handler = function ($var) : string { + $dumper = $this->dumper = $this->dumper ?? new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR); + $dumper->setColors($this->output->isDecorated()); + return \rtrim($dumper->dump(($this->cloner = $this->cloner ?? new VarCloner())->cloneVar($var)->withRefHandles(\false), \true)); + }; + } else { + $this->handler = function ($var) : string { + switch (\true) { + case null === $var: + return 'null'; + case \true === $var: + return 'true'; + case \false === $var: + return 'false'; + case \is_string($var): + return '"' . $var . '"'; + default: + return \rtrim(\print_r($var, \true)); + } + }; + } + } + /** + * @param mixed $var + */ + public function __invoke($var) : string + { + return ($this->handler)($var); + } +} diff --git a/vendor/symfony/console/Helper/FormatterHelper.php b/vendor/symfony/console/Helper/FormatterHelper.php new file mode 100644 index 0000000000..1f41826822 --- /dev/null +++ b/vendor/symfony/console/Helper/FormatterHelper.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +/** + * The Formatter class provides helpers to format messages. + * + * @author Fabien Potencier + */ +class FormatterHelper extends Helper +{ + /** + * Formats a message within a section. + */ + public function formatSection(string $section, string $message, string $style = 'info') : string + { + return \sprintf('<%s>[%s] %s', $style, $section, $style, $message); + } + /** + * Formats a message as a block of text. + * @param string|mixed[] $messages + */ + public function formatBlock($messages, string $style, bool $large = \false) : string + { + if (!\is_array($messages)) { + $messages = [$messages]; + } + $len = 0; + $lines = []; + foreach ($messages as $message) { + $message = OutputFormatter::escape($message); + $lines[] = \sprintf($large ? ' %s ' : ' %s ', $message); + $len = \max(self::width($message) + ($large ? 4 : 2), $len); + } + $messages = $large ? [\str_repeat(' ', $len)] : []; + for ($i = 0; isset($lines[$i]); ++$i) { + $messages[] = $lines[$i] . \str_repeat(' ', $len - self::width($lines[$i])); + } + if ($large) { + $messages[] = \str_repeat(' ', $len); + } + for ($i = 0; isset($messages[$i]); ++$i) { + $messages[$i] = \sprintf('<%s>%s', $style, $messages[$i], $style); + } + return \implode("\n", $messages); + } + /** + * Truncates a message to the given length. + */ + public function truncate(string $message, int $length, string $suffix = '...') : string + { + $computedLength = $length - self::width($suffix); + if ($computedLength > self::width($message)) { + return $message; + } + return self::substr($message, 0, $length) . $suffix; + } + public function getName() : string + { + return 'formatter'; + } +} diff --git a/vendor/symfony/console/Helper/Helper.php b/vendor/symfony/console/Helper/Helper.php new file mode 100644 index 0000000000..85891a49c4 --- /dev/null +++ b/vendor/symfony/console/Helper/Helper.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\String\UnicodeString; +/** + * Helper is the base class for all helper classes. + * + * @author Fabien Potencier + */ +abstract class Helper implements HelperInterface +{ + protected $helperSet; + /** + * @return void + */ + public function setHelperSet(HelperSet $helperSet = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + $this->helperSet = $helperSet; + } + public function getHelperSet() : ?HelperSet + { + return $this->helperSet; + } + /** + * Returns the width of a string, using mb_strwidth if it is available. + * The width is how many characters positions the string will use. + */ + public static function width(?string $string) : int + { + $string = $string ?? ''; + if (\preg_match('//u', $string)) { + return (new UnicodeString($string))->width(\false); + } + if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) { + return \strlen($string); + } + return \mb_strwidth($string, $encoding); + } + /** + * Returns the length of a string, using mb_strlen if it is available. + * The length is related to how many bytes the string will use. + */ + public static function length(?string $string) : int + { + $string = $string ?? ''; + if (\preg_match('//u', $string)) { + return (new UnicodeString($string))->length(); + } + if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) { + return \strlen($string); + } + return \mb_strlen($string, $encoding); + } + /** + * Returns the subset of a string, using mb_substr if it is available. + */ + public static function substr(?string $string, int $from, int $length = null) : string + { + $string = $string ?? ''; + if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) { + return \substr($string, $from, $length); + } + return \mb_substr($string, $from, $length, $encoding); + } + /** + * @return string + * @param int|float $secs + */ + public static function formatTime($secs) + { + static $timeFormats = [[0, '< 1 sec'], [1, '1 sec'], [2, 'secs', 1], [60, '1 min'], [120, 'mins', 60], [3600, '1 hr'], [7200, 'hrs', 3600], [86400, '1 day'], [172800, 'days', 86400]]; + foreach ($timeFormats as $index => $format) { + if ($secs >= $format[0]) { + if (isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0] || $index == \count($timeFormats) - 1) { + if (2 == \count($format)) { + return $format[1]; + } + return \floor($secs / $format[2]) . ' ' . $format[1]; + } + } + } + } + /** + * @return string + */ + public static function formatMemory(int $memory) + { + if ($memory >= 1024 * 1024 * 1024) { + return \sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024); + } + if ($memory >= 1024 * 1024) { + return \sprintf('%.1f MiB', $memory / 1024 / 1024); + } + if ($memory >= 1024) { + return \sprintf('%d KiB', $memory / 1024); + } + return \sprintf('%d B', $memory); + } + /** + * @return string + */ + public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string) + { + $isDecorated = $formatter->isDecorated(); + $formatter->setDecorated(\false); + // remove <...> formatting + $string = $formatter->format($string ?? ''); + // remove already formatted characters + $string = \preg_replace("/\x1b\\[[^m]*m/", '', $string ?? ''); + // remove terminal hyperlinks + $string = \preg_replace('/\\033]8;[^;]*;[^\\033]*\\033\\\\/', '', $string ?? ''); + $formatter->setDecorated($isDecorated); + return $string; + } +} diff --git a/vendor/symfony/console/Helper/HelperInterface.php b/vendor/symfony/console/Helper/HelperInterface.php new file mode 100644 index 0000000000..50186cadaa --- /dev/null +++ b/vendor/symfony/console/Helper/HelperInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +/** + * HelperInterface is the interface all helpers must implement. + * + * @author Fabien Potencier + */ +interface HelperInterface +{ + /** + * Sets the helper set associated with this helper. + * + * @return void + */ + public function setHelperSet(?HelperSet $helperSet); + /** + * Gets the helper set associated with this helper. + */ + public function getHelperSet() : ?HelperSet; + /** + * Returns the canonical name of this helper. + * + * @return string + */ + public function getName(); +} diff --git a/vendor/symfony/console/Helper/HelperSet.php b/vendor/symfony/console/Helper/HelperSet.php new file mode 100644 index 0000000000..be10d4d142 --- /dev/null +++ b/vendor/symfony/console/Helper/HelperSet.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +/** + * HelperSet represents a set of helpers to be used with a command. + * + * @author Fabien Potencier + * + * @implements \IteratorAggregate + */ +class HelperSet implements \IteratorAggregate +{ + /** @var array */ + private $helpers = []; + /** + * @param HelperInterface[] $helpers + */ + public function __construct(array $helpers = []) + { + foreach ($helpers as $alias => $helper) { + $this->set($helper, \is_int($alias) ? null : $alias); + } + } + /** + * @return void + */ + public function set(HelperInterface $helper, string $alias = null) + { + $this->helpers[$helper->getName()] = $helper; + if (null !== $alias) { + $this->helpers[$alias] = $helper; + } + $helper->setHelperSet($this); + } + /** + * Returns true if the helper if defined. + */ + public function has(string $name) : bool + { + return isset($this->helpers[$name]); + } + /** + * Gets a helper value. + * + * @throws InvalidArgumentException if the helper is not defined + */ + public function get(string $name) : HelperInterface + { + if (!$this->has($name)) { + throw new InvalidArgumentException(\sprintf('The helper "%s" is not defined.', $name)); + } + return $this->helpers[$name]; + } + public function getIterator() : \Traversable + { + return new \ArrayIterator($this->helpers); + } +} diff --git a/vendor/symfony/console/Helper/InputAwareHelper.php b/vendor/symfony/console/Helper/InputAwareHelper.php new file mode 100644 index 0000000000..3c67c95f13 --- /dev/null +++ b/vendor/symfony/console/Helper/InputAwareHelper.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputAwareInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +/** + * An implementation of InputAwareInterface for Helpers. + * + * @author Wouter J + */ +abstract class InputAwareHelper extends Helper implements InputAwareInterface +{ + protected $input; + /** + * @return void + */ + public function setInput(InputInterface $input) + { + $this->input = $input; + } +} diff --git a/vendor/symfony/console/Helper/OutputWrapper.php b/vendor/symfony/console/Helper/OutputWrapper.php new file mode 100644 index 0000000000..e469a054eb --- /dev/null +++ b/vendor/symfony/console/Helper/OutputWrapper.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +/** + * Simple output wrapper for "tagged outputs" instead of wordwrap(). This solution is based on a StackOverflow + * answer: https://stackoverflow.com/a/20434776/1476819 from user557597 (alias SLN). + * + * (?: + * # -- Words/Characters + * ( # (1 start) + * (?> # Atomic Group - Match words with valid breaks + * .{1,16} # 1-N characters + * # Followed by one of 4 prioritized, non-linebreak whitespace + * (?: # break types: + * (?<= [^\S\r\n] ) # 1. - Behind a non-linebreak whitespace + * [^\S\r\n]? # ( optionally accept an extra non-linebreak whitespace ) + * | (?= \r? \n ) # 2. - Ahead a linebreak + * | $ # 3. - EOS + * | [^\S\r\n] # 4. - Accept an extra non-linebreak whitespace + * ) + * ) # End atomic group + * | + * .{1,16} # No valid word breaks, just break on the N'th character + * ) # (1 end) + * (?: \r? \n )? # Optional linebreak after Words/Characters + * | + * # -- Or, Linebreak + * (?: \r? \n | $ ) # Stand alone linebreak or at EOS + * ) + * + * @author Krisztián Ferenczi + * + * @see https://stackoverflow.com/a/20434776/1476819 + */ +final class OutputWrapper +{ + /** + * @var bool + */ + private $allowCutUrls = \false; + private const TAG_OPEN_REGEX_SEGMENT = '[a-z](?:[^\\\\<>]*+ | \\\\.)*'; + private const TAG_CLOSE_REGEX_SEGMENT = '[a-z][^<>]*+'; + private const URL_PATTERN = 'https?://\\S+'; + public function __construct(bool $allowCutUrls = \false) + { + $this->allowCutUrls = $allowCutUrls; + } + public function wrap(string $text, int $width, string $break = "\n") : string + { + if (!$width) { + return $text; + } + $tagPattern = \sprintf('<(?:(?:%s)|/(?:%s)?)>', self::TAG_OPEN_REGEX_SEGMENT, self::TAG_CLOSE_REGEX_SEGMENT); + $limitPattern = "{1,{$width}}"; + $patternBlocks = [$tagPattern]; + if (!$this->allowCutUrls) { + $patternBlocks[] = self::URL_PATTERN; + } + $patternBlocks[] = '.'; + $blocks = \implode('|', $patternBlocks); + $rowPattern = "(?:{$blocks}){$limitPattern}"; + $pattern = \sprintf('#(?:((?>(%1$s)((?<=[^\\S\\r\\n])[^\\S\\r\\n]?|(?=\\r?\\n)|$|[^\\S\\r\\n]))|(%1$s))(?:\\r?\\n)?|(?:\\r?\\n|$))#imux', $rowPattern); + $output = \rtrim(\preg_replace($pattern, '\\1' . $break, $text), $break); + return \str_replace(' ' . $break, $break, $output); + } +} diff --git a/vendor/symfony/console/Helper/ProcessHelper.php b/vendor/symfony/console/Helper/ProcessHelper.php new file mode 100644 index 0000000000..542a288fd0 --- /dev/null +++ b/vendor/symfony/console/Helper/ProcessHelper.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\ProcessFailedException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Process; +/** + * The ProcessHelper class provides helpers to run external processes. + * + * @author Fabien Potencier + * + * @final + */ +class ProcessHelper extends Helper +{ + /** + * Runs an external process. + * + * @param array|Process $cmd An instance of Process or an array of the command and arguments + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + */ + public function run(OutputInterface $output, $cmd, string $error = null, callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) : Process + { + if (!\class_exists(Process::class)) { + throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".'); + } + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $formatter = $this->getHelperSet()->get('debug_formatter'); + if ($cmd instanceof Process) { + $cmd = [$cmd]; + } + if (\is_string($cmd[0] ?? null)) { + $process = new Process($cmd); + $cmd = []; + } elseif (($cmd[0] ?? null) instanceof Process) { + $process = $cmd[0]; + unset($cmd[0]); + } else { + throw new \InvalidArgumentException(\sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__)); + } + if ($verbosity <= $output->getVerbosity()) { + $output->write($formatter->start(\spl_object_hash($process), $this->escapeString($process->getCommandLine()))); + } + if ($output->isDebug()) { + $callback = $this->wrapCallback($output, $process, $callback); + } + $process->run($callback, $cmd); + if ($verbosity <= $output->getVerbosity()) { + $message = $process->isSuccessful() ? 'Command ran successfully' : \sprintf('%s Command did not run successfully', $process->getExitCode()); + $output->write($formatter->stop(\spl_object_hash($process), $message, $process->isSuccessful())); + } + if (!$process->isSuccessful() && null !== $error) { + $output->writeln(\sprintf('%s', $this->escapeString($error))); + } + return $process; + } + /** + * Runs the process. + * + * This is identical to run() except that an exception is thrown if the process + * exits with a non-zero exit code. + * + * @param array|Process $cmd An instance of Process or a command to run + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @throws ProcessFailedException + * + * @see run() + */ + public function mustRun(OutputInterface $output, $cmd, string $error = null, callable $callback = null) : Process + { + $process = $this->run($output, $cmd, $error, $callback); + if (!$process->isSuccessful()) { + throw new ProcessFailedException($process); + } + return $process; + } + /** + * Wraps a Process callback to add debugging output. + */ + public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null) : callable + { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $formatter = $this->getHelperSet()->get('debug_formatter'); + return function ($type, $buffer) use($output, $process, $callback, $formatter) { + $output->write($formatter->progress(\spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type)); + if (null !== $callback) { + $callback($type, $buffer); + } + }; + } + private function escapeString(string $str) : string + { + return \str_replace('<', '\\<', $str); + } + public function getName() : string + { + return 'process'; + } +} diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php new file mode 100644 index 0000000000..3a7af28c54 --- /dev/null +++ b/vendor/symfony/console/Helper/ProgressBar.php @@ -0,0 +1,591 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Cursor; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleSectionOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Terminal; +/** + * The ProgressBar provides helpers to display progress output. + * + * @author Fabien Potencier + * @author Chris Jones + */ +final class ProgressBar +{ + public const FORMAT_VERBOSE = 'verbose'; + public const FORMAT_VERY_VERBOSE = 'very_verbose'; + public const FORMAT_DEBUG = 'debug'; + public const FORMAT_NORMAL = 'normal'; + private const FORMAT_VERBOSE_NOMAX = 'verbose_nomax'; + private const FORMAT_VERY_VERBOSE_NOMAX = 'very_verbose_nomax'; + private const FORMAT_DEBUG_NOMAX = 'debug_nomax'; + private const FORMAT_NORMAL_NOMAX = 'normal_nomax'; + /** + * @var int + */ + private $barWidth = 28; + /** + * @var string + */ + private $barChar; + /** + * @var string + */ + private $emptyBarChar = '-'; + /** + * @var string + */ + private $progressChar = '>'; + /** + * @var string|null + */ + private $format; + /** + * @var string|null + */ + private $internalFormat; + /** + * @var int|null + */ + private $redrawFreq = 1; + /** + * @var int + */ + private $writeCount = 0; + /** + * @var float + */ + private $lastWriteTime = 0; + /** + * @var float + */ + private $minSecondsBetweenRedraws = 0; + /** + * @var float + */ + private $maxSecondsBetweenRedraws = 1; + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + /** + * @var int + */ + private $step = 0; + /** + * @var int + */ + private $startingStep = 0; + /** + * @var int|null + */ + private $max; + /** + * @var int + */ + private $startTime; + /** + * @var int + */ + private $stepWidth; + /** + * @var float + */ + private $percent = 0.0; + /** + * @var mixed[] + */ + private $messages = []; + /** + * @var bool + */ + private $overwrite = \true; + /** + * @var \Symfony\Component\Console\Terminal + */ + private $terminal; + /** + * @var string|null + */ + private $previousMessage; + /** + * @var \Symfony\Component\Console\Cursor + */ + private $cursor; + /** + * @var mixed[] + */ + private $placeholders = []; + /** + * @var mixed[] + */ + private static $formatters; + /** + * @var mixed[] + */ + private static $formats; + /** + * @param int $max Maximum steps (0 if unknown) + */ + public function __construct(OutputInterface $output, int $max = 0, float $minSecondsBetweenRedraws = 1 / 25) + { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $this->output = $output; + $this->setMaxSteps($max); + $this->terminal = new Terminal(); + if (0 < $minSecondsBetweenRedraws) { + $this->redrawFreq = null; + $this->minSecondsBetweenRedraws = $minSecondsBetweenRedraws; + } + if (!$this->output->isDecorated()) { + // disable overwrite when output does not support ANSI codes. + $this->overwrite = \false; + // set a reasonable redraw frequency so output isn't flooded + $this->redrawFreq = null; + } + $this->startTime = \time(); + $this->cursor = new Cursor($output); + } + /** + * Sets a placeholder formatter for a given name, globally for all instances of ProgressBar. + * + * This method also allow you to override an existing placeholder. + * + * @param string $name The placeholder name (including the delimiter char like %) + * @param callable(ProgressBar):string $callable A PHP callable + */ + public static function setPlaceholderFormatterDefinition(string $name, callable $callable) : void + { + self::$formatters = self::$formatters ?? self::initPlaceholderFormatters(); + self::$formatters[$name] = $callable; + } + /** + * Gets the placeholder formatter for a given name. + * + * @param string $name The placeholder name (including the delimiter char like %) + */ + public static function getPlaceholderFormatterDefinition(string $name) : ?callable + { + self::$formatters = self::$formatters ?? self::initPlaceholderFormatters(); + return self::$formatters[$name] ?? null; + } + /** + * Sets a placeholder formatter for a given name, for this instance only. + * + * @param callable(ProgressBar):string $callable A PHP callable + */ + public function setPlaceholderFormatter(string $name, callable $callable) : void + { + $this->placeholders[$name] = $callable; + } + /** + * Gets the placeholder formatter for a given name. + * + * @param string $name The placeholder name (including the delimiter char like %) + */ + public function getPlaceholderFormatter(string $name) : ?callable + { + return $this->placeholders[$name] ?? $this::getPlaceholderFormatterDefinition($name); + } + /** + * Sets a format for a given name. + * + * This method also allow you to override an existing format. + * + * @param string $name The format name + * @param string $format A format string + */ + public static function setFormatDefinition(string $name, string $format) : void + { + self::$formats = self::$formats ?? self::initFormats(); + self::$formats[$name] = $format; + } + /** + * Gets the format for a given name. + * + * @param string $name The format name + */ + public static function getFormatDefinition(string $name) : ?string + { + self::$formats = self::$formats ?? self::initFormats(); + return self::$formats[$name] ?? null; + } + /** + * Associates a text with a named placeholder. + * + * The text is displayed when the progress bar is rendered but only + * when the corresponding placeholder is part of the custom format line + * (by wrapping the name with %). + * + * @param string $message The text to associate with the placeholder + * @param string $name The name of the placeholder + */ + public function setMessage(string $message, string $name = 'message') : void + { + $this->messages[$name] = $message; + } + public function getMessage(string $name = 'message') : string + { + return $this->messages[$name]; + } + public function getStartTime() : int + { + return $this->startTime; + } + public function getMaxSteps() : int + { + return $this->max; + } + public function getProgress() : int + { + return $this->step; + } + private function getStepWidth() : int + { + return $this->stepWidth; + } + public function getProgressPercent() : float + { + return $this->percent; + } + public function getBarOffset() : float + { + return \floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (\min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth); + } + public function getEstimated() : float + { + if (0 === $this->step || $this->step === $this->startingStep) { + return 0; + } + return \round((\time() - $this->startTime) / ($this->step - $this->startingStep) * $this->max); + } + public function getRemaining() : float + { + if (!$this->step) { + return 0; + } + return \round((\time() - $this->startTime) / ($this->step - $this->startingStep) * ($this->max - $this->step)); + } + public function setBarWidth(int $size) : void + { + $this->barWidth = \max(1, $size); + } + public function getBarWidth() : int + { + return $this->barWidth; + } + public function setBarCharacter(string $char) : void + { + $this->barChar = $char; + } + public function getBarCharacter() : string + { + return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar); + } + public function setEmptyBarCharacter(string $char) : void + { + $this->emptyBarChar = $char; + } + public function getEmptyBarCharacter() : string + { + return $this->emptyBarChar; + } + public function setProgressCharacter(string $char) : void + { + $this->progressChar = $char; + } + public function getProgressCharacter() : string + { + return $this->progressChar; + } + public function setFormat(string $format) : void + { + $this->format = null; + $this->internalFormat = $format; + } + /** + * Sets the redraw frequency. + * + * @param int|null $freq The frequency in steps + */ + public function setRedrawFrequency(?int $freq) : void + { + $this->redrawFreq = null !== $freq ? \max(1, $freq) : null; + } + public function minSecondsBetweenRedraws(float $seconds) : void + { + $this->minSecondsBetweenRedraws = $seconds; + } + public function maxSecondsBetweenRedraws(float $seconds) : void + { + $this->maxSecondsBetweenRedraws = $seconds; + } + /** + * Returns an iterator that will automatically update the progress bar when iterated. + * + * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable + */ + public function iterate(iterable $iterable, int $max = null) : iterable + { + $this->start($max ?? (\is_array($iterable) || $iterable instanceof \Countable ? \count($iterable) : 0)); + foreach ($iterable as $key => $value) { + (yield $key => $value); + $this->advance(); + } + $this->finish(); + } + /** + * Starts the progress output. + * + * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged + * @param int $startAt The starting point of the bar (useful e.g. when resuming a previously started bar) + */ + public function start(int $max = null, int $startAt = 0) : void + { + $this->startTime = \time(); + $this->step = $startAt; + $this->startingStep = $startAt; + $startAt > 0 ? $this->setProgress($startAt) : ($this->percent = 0.0); + if (null !== $max) { + $this->setMaxSteps($max); + } + $this->display(); + } + /** + * Advances the progress output X steps. + * + * @param int $step Number of steps to advance + */ + public function advance(int $step = 1) : void + { + $this->setProgress($this->step + $step); + } + /** + * Sets whether to overwrite the progressbar, false for new line. + */ + public function setOverwrite(bool $overwrite) : void + { + $this->overwrite = $overwrite; + } + public function setProgress(int $step) : void + { + if ($this->max && $step > $this->max) { + $this->max = $step; + } elseif ($step < 0) { + $step = 0; + } + $redrawFreq = $this->redrawFreq ?? ($this->max ?: 10) / 10; + $prevPeriod = (int) ($this->step / $redrawFreq); + $currPeriod = (int) ($step / $redrawFreq); + $this->step = $step; + $this->percent = $this->max ? (float) $this->step / $this->max : 0; + $timeInterval = \microtime(\true) - $this->lastWriteTime; + // Draw regardless of other limits + if ($this->max === $step) { + $this->display(); + return; + } + // Throttling + if ($timeInterval < $this->minSecondsBetweenRedraws) { + return; + } + // Draw each step period, but not too late + if ($prevPeriod !== $currPeriod || $timeInterval >= $this->maxSecondsBetweenRedraws) { + $this->display(); + } + } + public function setMaxSteps(int $max) : void + { + $this->format = null; + $this->max = \max(0, $max); + $this->stepWidth = $this->max ? Helper::width((string) $this->max) : 4; + } + /** + * Finishes the progress output. + */ + public function finish() : void + { + if (!$this->max) { + $this->max = $this->step; + } + if ($this->step === $this->max && !$this->overwrite) { + // prevent double 100% output + return; + } + $this->setProgress($this->max); + } + /** + * Outputs the current progress string. + */ + public function display() : void + { + if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { + return; + } + if (null === $this->format) { + $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); + } + $this->overwrite($this->buildLine()); + } + /** + * Removes the progress bar from the current line. + * + * This is useful if you wish to write some output + * while a progress bar is running. + * Call display() to show the progress bar again. + */ + public function clear() : void + { + if (!$this->overwrite) { + return; + } + if (null === $this->format) { + $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); + } + $this->overwrite(''); + } + private function setRealFormat(string $format) : void + { + // try to use the _nomax variant if available + if (!$this->max && null !== self::getFormatDefinition($format . '_nomax')) { + $this->format = self::getFormatDefinition($format . '_nomax'); + } elseif (null !== self::getFormatDefinition($format)) { + $this->format = self::getFormatDefinition($format); + } else { + $this->format = $format; + } + } + /** + * Overwrites a previous message to the output. + */ + private function overwrite(string $message) : void + { + if ($this->previousMessage === $message) { + return; + } + $originalMessage = $message; + if ($this->overwrite) { + if (null !== $this->previousMessage) { + if ($this->output instanceof ConsoleSectionOutput) { + $messageLines = \explode("\n", $this->previousMessage); + $lineCount = \count($messageLines); + foreach ($messageLines as $messageLine) { + $messageLineLength = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $messageLine)); + if ($messageLineLength > $this->terminal->getWidth()) { + $lineCount += \floor($messageLineLength / $this->terminal->getWidth()); + } + } + $this->output->clear($lineCount); + } else { + $lineCount = \substr_count($this->previousMessage, "\n"); + for ($i = 0; $i < $lineCount; ++$i) { + $this->cursor->moveToColumn(1); + $this->cursor->clearLine(); + $this->cursor->moveUp(); + } + $this->cursor->moveToColumn(1); + $this->cursor->clearLine(); + } + } + } elseif ($this->step > 0) { + $message = \PHP_EOL . $message; + } + $this->previousMessage = $originalMessage; + $this->lastWriteTime = \microtime(\true); + $this->output->write($message); + ++$this->writeCount; + } + private function determineBestFormat() : string + { + switch ($this->output->getVerbosity()) { + case OutputInterface::VERBOSITY_VERBOSE: + return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX; + case OutputInterface::VERBOSITY_VERY_VERBOSE: + return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX; + case OutputInterface::VERBOSITY_DEBUG: + return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX; + default: + return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX; + } + } + private static function initPlaceholderFormatters() : array + { + return ['bar' => function (self $bar, OutputInterface $output) { + $completeBars = $bar->getBarOffset(); + $display = \str_repeat($bar->getBarCharacter(), $completeBars); + if ($completeBars < $bar->getBarWidth()) { + $emptyBars = $bar->getBarWidth() - $completeBars - Helper::length(Helper::removeDecoration($output->getFormatter(), $bar->getProgressCharacter())); + $display .= $bar->getProgressCharacter() . \str_repeat($bar->getEmptyBarCharacter(), $emptyBars); + } + return $display; + }, 'elapsed' => function (self $bar) { + return Helper::formatTime(\time() - $bar->getStartTime()); + }, 'remaining' => function (self $bar) { + if (!$bar->getMaxSteps()) { + throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.'); + } + return Helper::formatTime($bar->getRemaining()); + }, 'estimated' => function (self $bar) { + if (!$bar->getMaxSteps()) { + throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.'); + } + return Helper::formatTime($bar->getEstimated()); + }, 'memory' => function (self $bar) { + return Helper::formatMemory(\memory_get_usage(\true)); + }, 'current' => function (self $bar) { + return \str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT); + }, 'max' => function (self $bar) { + return $bar->getMaxSteps(); + }, 'percent' => function (self $bar) { + return \floor($bar->getProgressPercent() * 100); + }]; + } + private static function initFormats() : array + { + return [self::FORMAT_NORMAL => ' %current%/%max% [%bar%] %percent:3s%%', self::FORMAT_NORMAL_NOMAX => ' %current% [%bar%]', self::FORMAT_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%', self::FORMAT_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', self::FORMAT_VERY_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%', self::FORMAT_VERY_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', self::FORMAT_DEBUG => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%', self::FORMAT_DEBUG_NOMAX => ' %current% [%bar%] %elapsed:6s% %memory:6s%']; + } + private function buildLine() : string + { + \assert(null !== $this->format); + $regex = "{%([a-z\\-_]+)(?:\\:([^%]+))?%}i"; + $callback = function ($matches) { + if ($formatter = $this->getPlaceholderFormatter($matches[1])) { + $text = $formatter($this, $this->output); + } elseif (isset($this->messages[$matches[1]])) { + $text = $this->messages[$matches[1]]; + } else { + return $matches[0]; + } + if (isset($matches[2])) { + $text = \sprintf('%' . $matches[2], $text); + } + return $text; + }; + $line = \preg_replace_callback($regex, $callback, $this->format); + // gets string length for each sub line with multiline format + $linesLength = \array_map(function ($subLine) { + return Helper::width(Helper::removeDecoration($this->output->getFormatter(), \rtrim($subLine, "\r"))); + }, \explode("\n", $line)); + $linesWidth = \max($linesLength); + $terminalWidth = $this->terminal->getWidth(); + if ($linesWidth <= $terminalWidth) { + return $line; + } + $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth); + return \preg_replace_callback($regex, $callback, $this->format); + } +} diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php new file mode 100644 index 0000000000..687db19eee --- /dev/null +++ b/vendor/symfony/console/Helper/ProgressIndicator.php @@ -0,0 +1,225 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Kevin Bond + */ +class ProgressIndicator +{ + private const FORMATS = ['normal' => ' %indicator% %message%', 'normal_no_ansi' => ' %message%', 'verbose' => ' %indicator% %message% (%elapsed:6s%)', 'verbose_no_ansi' => ' %message% (%elapsed:6s%)', 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)', 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)']; + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + /** + * @var int + */ + private $startTime; + /** + * @var string|null + */ + private $format; + /** + * @var string|null + */ + private $message; + /** + * @var mixed[] + */ + private $indicatorValues; + /** + * @var int + */ + private $indicatorCurrent; + /** + * @var int + */ + private $indicatorChangeInterval; + /** + * @var float + */ + private $indicatorUpdateTime; + /** + * @var bool + */ + private $started = \false; + /** + * @var array + */ + private static $formatters; + /** + * @param int $indicatorChangeInterval Change interval in milliseconds + * @param array|null $indicatorValues Animated indicator characters + */ + public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null) + { + $this->output = $output; + $format = $format ?? $this->determineBestFormat(); + $indicatorValues = $indicatorValues ?? ['-', '\\', '|', '/']; + $indicatorValues = \array_values($indicatorValues); + if (2 > \count($indicatorValues)) { + throw new InvalidArgumentException('Must have at least 2 indicator value characters.'); + } + $this->format = self::getFormatDefinition($format); + $this->indicatorChangeInterval = $indicatorChangeInterval; + $this->indicatorValues = $indicatorValues; + $this->startTime = \time(); + } + /** + * Sets the current indicator message. + * + * @return void + */ + public function setMessage(?string $message) + { + $this->message = $message; + $this->display(); + } + /** + * Starts the indicator output. + * + * @return void + */ + public function start(string $message) + { + if ($this->started) { + throw new LogicException('Progress indicator already started.'); + } + $this->message = $message; + $this->started = \true; + $this->startTime = \time(); + $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval; + $this->indicatorCurrent = 0; + $this->display(); + } + /** + * Advances the indicator. + * + * @return void + */ + public function advance() + { + if (!$this->started) { + throw new LogicException('Progress indicator has not yet been started.'); + } + if (!$this->output->isDecorated()) { + return; + } + $currentTime = $this->getCurrentTimeInMilliseconds(); + if ($currentTime < $this->indicatorUpdateTime) { + return; + } + $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval; + ++$this->indicatorCurrent; + $this->display(); + } + /** + * Finish the indicator with message. + * + * @return void + */ + public function finish(string $message) + { + if (!$this->started) { + throw new LogicException('Progress indicator has not yet been started.'); + } + $this->message = $message; + $this->display(); + $this->output->writeln(''); + $this->started = \false; + } + /** + * Gets the format for a given name. + */ + public static function getFormatDefinition(string $name) : ?string + { + return self::FORMATS[$name] ?? null; + } + /** + * Sets a placeholder formatter for a given name. + * + * This method also allow you to override an existing placeholder. + * + * @return void + */ + public static function setPlaceholderFormatterDefinition(string $name, callable $callable) + { + self::$formatters = self::$formatters ?? self::initPlaceholderFormatters(); + self::$formatters[$name] = $callable; + } + /** + * Gets the placeholder formatter for a given name (including the delimiter char like %). + */ + public static function getPlaceholderFormatterDefinition(string $name) : ?callable + { + self::$formatters = self::$formatters ?? self::initPlaceholderFormatters(); + return self::$formatters[$name] ?? null; + } + private function display() : void + { + if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { + return; + } + $this->overwrite(\preg_replace_callback("{%([a-z\\-_]+)(?:\\:([^%]+))?%}i", function ($matches) { + if ($formatter = self::getPlaceholderFormatterDefinition($matches[1])) { + return $formatter($this); + } + return $matches[0]; + }, $this->format ?? '')); + } + private function determineBestFormat() : string + { + switch ($this->output->getVerbosity()) { + case OutputInterface::VERBOSITY_VERBOSE: + return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi'; + case OutputInterface::VERBOSITY_VERY_VERBOSE: + case OutputInterface::VERBOSITY_DEBUG: + return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi'; + default: + return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi'; + } + } + /** + * Overwrites a previous message to the output. + */ + private function overwrite(string $message) : void + { + if ($this->output->isDecorated()) { + $this->output->write("\r\x1b[2K"); + $this->output->write($message); + } else { + $this->output->writeln($message); + } + } + private function getCurrentTimeInMilliseconds() : float + { + return \round(\microtime(\true) * 1000); + } + /** + * @return array + */ + private static function initPlaceholderFormatters() : array + { + return ['indicator' => function (self $indicator) { + return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)]; + }, 'message' => function (self $indicator) { + return $indicator->message; + }, 'elapsed' => function (self $indicator) { + return Helper::formatTime(\time() - $indicator->startTime); + }, 'memory' => function () { + return Helper::formatMemory(\memory_get_usage(\true)); + }]; + } +} diff --git a/vendor/symfony/console/Helper/QuestionHelper.php b/vendor/symfony/console/Helper/QuestionHelper.php new file mode 100644 index 0000000000..6b98cef490 --- /dev/null +++ b/vendor/symfony/console/Helper/QuestionHelper.php @@ -0,0 +1,517 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Cursor; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\MissingInputException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterStyle; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\StreamableInputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleSectionOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\ChoiceQuestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\Question; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Terminal; +use function MonorepoBuilderPrefix202310\Symfony\Component\String\s; +/** + * The QuestionHelper class provides helpers to interact with the user. + * + * @author Fabien Potencier + */ +class QuestionHelper extends Helper +{ + /** + * @var resource|null + */ + private $inputStream; + /** + * @var bool + */ + private static $stty = \true; + /** + * @var bool + */ + private static $stdinIsInteractive; + /** + * Asks a question to the user. + * + * @return mixed The user answer + * + * @throws RuntimeException If there is no data to read in the input stream + */ + public function ask(InputInterface $input, OutputInterface $output, Question $question) + { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + if (!$input->isInteractive()) { + return $this->getDefaultAnswer($question); + } + if ($input instanceof StreamableInputInterface && ($stream = $input->getStream())) { + $this->inputStream = $stream; + } + try { + if (!$question->getValidator()) { + return $this->doAsk($output, $question); + } + $interviewer = function () use($output, $question) { + return $this->doAsk($output, $question); + }; + return $this->validateAttempts($interviewer, $output, $question); + } catch (MissingInputException $exception) { + $input->setInteractive(\false); + if (null === ($fallbackOutput = $this->getDefaultAnswer($question))) { + throw $exception; + } + return $fallbackOutput; + } + } + public function getName() : string + { + return 'question'; + } + /** + * Prevents usage of stty. + * + * @return void + */ + public static function disableStty() + { + self::$stty = \false; + } + /** + * Asks the question to the user. + * + * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden + * @return mixed + */ + private function doAsk(OutputInterface $output, Question $question) + { + $this->writePrompt($output, $question); + $inputStream = $this->inputStream ?: \STDIN; + $autocomplete = $question->getAutocompleterCallback(); + if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) { + $ret = \false; + if ($question->isHidden()) { + try { + $hiddenResponse = $this->getHiddenResponse($output, $inputStream, $question->isTrimmable()); + $ret = $question->isTrimmable() ? \trim($hiddenResponse) : $hiddenResponse; + } catch (RuntimeException $e) { + if (!$question->isHiddenFallback()) { + throw $e; + } + } + } + if (\false === $ret) { + $isBlocked = \stream_get_meta_data($inputStream)['blocked'] ?? \true; + if (!$isBlocked) { + \stream_set_blocking($inputStream, \true); + } + $ret = $this->readInput($inputStream, $question); + if (!$isBlocked) { + \stream_set_blocking($inputStream, \false); + } + if (\false === $ret) { + throw new MissingInputException('Aborted.'); + } + if ($question->isTrimmable()) { + $ret = \trim($ret); + } + } + } else { + $autocomplete = $this->autocomplete($output, $question, $inputStream, $autocomplete); + $ret = $question->isTrimmable() ? \trim($autocomplete) : $autocomplete; + } + if ($output instanceof ConsoleSectionOutput) { + $output->addContent(''); + // add EOL to the question + $output->addContent($ret); + } + $ret = \strlen($ret) > 0 ? $ret : $question->getDefault(); + if ($normalizer = $question->getNormalizer()) { + return $normalizer($ret); + } + return $ret; + } + /** + * @return mixed + */ + private function getDefaultAnswer(Question $question) + { + $default = $question->getDefault(); + if (null === $default) { + return $default; + } + if ($validator = $question->getValidator()) { + return \call_user_func($validator, $default); + } elseif ($question instanceof ChoiceQuestion) { + $choices = $question->getChoices(); + if (!$question->isMultiselect()) { + return $choices[$default] ?? $default; + } + $default = \explode(',', $default); + foreach ($default as $k => $v) { + $v = $question->isTrimmable() ? \trim($v) : $v; + $default[$k] = $choices[$v] ?? $v; + } + } + return $default; + } + /** + * Outputs the question prompt. + * + * @return void + */ + protected function writePrompt(OutputInterface $output, Question $question) + { + $message = $question->getQuestion(); + if ($question instanceof ChoiceQuestion) { + $output->writeln(\array_merge([$question->getQuestion()], $this->formatChoiceQuestionChoices($question, 'info'))); + $message = $question->getPrompt(); + } + $output->write($message); + } + /** + * @return string[] + */ + protected function formatChoiceQuestionChoices(ChoiceQuestion $question, string $tag) : array + { + $messages = []; + $maxWidth = \max(\array_map([__CLASS__, 'width'], \array_keys($choices = $question->getChoices()))); + foreach ($choices as $key => $value) { + $padding = \str_repeat(' ', $maxWidth - self::width($key)); + $messages[] = \sprintf(" [<{$tag}>%s{$padding}] %s", $key, $value); + } + return $messages; + } + /** + * Outputs an error message. + * + * @return void + */ + protected function writeError(OutputInterface $output, \Exception $error) + { + if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) { + $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'); + } else { + $message = '' . $error->getMessage() . ''; + } + $output->writeln($message); + } + /** + * Autocompletes a question. + * + * @param resource $inputStream + */ + private function autocomplete(OutputInterface $output, Question $question, $inputStream, callable $autocomplete) : string + { + $cursor = new Cursor($output, $inputStream); + $fullChoice = ''; + $ret = ''; + $i = 0; + $ofs = -1; + $matches = $autocomplete($ret); + $numMatches = \count($matches); + $sttyMode = \shell_exec('stty -g'); + $isStdin = 'php://stdin' === (\stream_get_meta_data($inputStream)['uri'] ?? null); + $r = [$inputStream]; + $w = []; + // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) + \shell_exec('stty -icanon -echo'); + // Add highlighted text style + $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); + // Read a keypress + while (!\feof($inputStream)) { + while ($isStdin && 0 === @\stream_select($r, $w, $w, 0, 100)) { + // Give signal handlers a chance to run + $r = [$inputStream]; + } + $c = \fread($inputStream, 1); + // as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false. + if (\false === $c || '' === $ret && '' === $c && null === $question->getDefault()) { + \shell_exec('stty ' . $sttyMode); + throw new MissingInputException('Aborted.'); + } elseif ("" === $c) { + // Backspace Character + if (0 === $numMatches && 0 !== $i) { + --$i; + $cursor->moveLeft(s($fullChoice)->slice(-1)->width(\false)); + $fullChoice = self::substr($fullChoice, 0, $i); + } + if (0 === $i) { + $ofs = -1; + $matches = $autocomplete($ret); + $numMatches = \count($matches); + } else { + $numMatches = 0; + } + // Pop the last character off the end of our string + $ret = self::substr($ret, 0, $i); + } elseif ("\x1b" === $c) { + // Did we read an escape sequence? + $c .= \fread($inputStream, 2); + // A = Up Arrow. B = Down Arrow + if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { + if ('A' === $c[2] && -1 === $ofs) { + $ofs = 0; + } + if (0 === $numMatches) { + continue; + } + $ofs += 'A' === $c[2] ? -1 : 1; + $ofs = ($numMatches + $ofs) % $numMatches; + } + } elseif (\ord($c) < 32) { + if ("\t" === $c || "\n" === $c) { + if ($numMatches > 0 && -1 !== $ofs) { + $ret = (string) $matches[$ofs]; + // Echo out remaining chars for current match + $remainingCharacters = \substr($ret, \strlen(\trim($this->mostRecentlyEnteredValue($fullChoice)))); + $output->write($remainingCharacters); + $fullChoice .= $remainingCharacters; + $i = \false === ($encoding = \mb_detect_encoding($fullChoice, null, \true)) ? \strlen($fullChoice) : \mb_strlen($fullChoice, $encoding); + $matches = \array_filter($autocomplete($ret), function ($match) use($ret) { + return '' === $ret || \strncmp($match, $ret, \strlen($ret)) === 0; + }); + $numMatches = \count($matches); + $ofs = -1; + } + if ("\n" === $c) { + $output->write($c); + break; + } + $numMatches = 0; + } + continue; + } else { + if ("\x80" <= $c) { + $c .= \fread($inputStream, ["\xc0" => 1, "\xd0" => 1, "\xe0" => 2, "\xf0" => 3][$c & "\xf0"]); + } + $output->write($c); + $ret .= $c; + $fullChoice .= $c; + ++$i; + $tempRet = $ret; + if ($question instanceof ChoiceQuestion && $question->isMultiselect()) { + $tempRet = $this->mostRecentlyEnteredValue($fullChoice); + } + $numMatches = 0; + $ofs = 0; + foreach ($autocomplete($ret) as $value) { + // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) + if (\strncmp($value, $tempRet, \strlen($tempRet)) === 0) { + $matches[$numMatches++] = $value; + } + } + } + $cursor->clearLineAfter(); + if ($numMatches > 0 && -1 !== $ofs) { + $cursor->savePosition(); + // Write highlighted text, complete the partially entered response + $charactersEntered = \strlen(\trim($this->mostRecentlyEnteredValue($fullChoice))); + $output->write('' . OutputFormatter::escapeTrailingBackslash(\substr($matches[$ofs], $charactersEntered)) . ''); + $cursor->restorePosition(); + } + } + // Reset stty so it behaves normally again + \shell_exec('stty ' . $sttyMode); + return $fullChoice; + } + private function mostRecentlyEnteredValue(string $entered) : string + { + // Determine the most recent value that the user entered + if (\strpos($entered, ',') === \false) { + return $entered; + } + $choices = \explode(',', $entered); + if ('' !== ($lastChoice = \trim($choices[\count($choices) - 1]))) { + return $lastChoice; + } + return $entered; + } + /** + * Gets a hidden response from user. + * + * @param resource $inputStream The handler resource + * @param bool $trimmable Is the answer trimmable + * + * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden + */ + private function getHiddenResponse(OutputInterface $output, $inputStream, bool $trimmable = \true) : string + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $exe = __DIR__ . '/../Resources/bin/hiddeninput.exe'; + // handle code running from a phar + if (\strncmp(__FILE__, 'phar:', \strlen('phar:')) === 0) { + $tmpExe = \sys_get_temp_dir() . '/hiddeninput.exe'; + \copy($exe, $tmpExe); + $exe = $tmpExe; + } + $sExec = \shell_exec('"' . $exe . '"'); + $value = $trimmable ? \rtrim($sExec) : $sExec; + $output->writeln(''); + if (isset($tmpExe)) { + \unlink($tmpExe); + } + return $value; + } + if (self::$stty && Terminal::hasSttyAvailable()) { + $sttyMode = \shell_exec('stty -g'); + \shell_exec('stty -echo'); + } elseif ($this->isInteractiveInput($inputStream)) { + throw new RuntimeException('Unable to hide the response.'); + } + $value = \fgets($inputStream, 4096); + if (4095 === \strlen($value)) { + $errOutput = $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output; + $errOutput->warning('The value was possibly truncated by your shell or terminal emulator'); + } + if (self::$stty && Terminal::hasSttyAvailable()) { + \shell_exec('stty ' . $sttyMode); + } + if (\false === $value) { + throw new MissingInputException('Aborted.'); + } + if ($trimmable) { + $value = \trim($value); + } + $output->writeln(''); + return $value; + } + /** + * Validates an attempt. + * + * @param callable $interviewer A callable that will ask for a question and return the result + * + * @throws \Exception In case the max number of attempts has been reached and no valid response has been given + * @return mixed + */ + private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question) + { + $error = null; + $attempts = $question->getMaxAttempts(); + while (null === $attempts || $attempts--) { + if (null !== $error) { + $this->writeError($output, $error); + } + try { + return $question->getValidator()($interviewer()); + } catch (RuntimeException $e) { + throw $e; + } catch (\Exception $error) { + } + } + throw $error; + } + private function isInteractiveInput($inputStream) : bool + { + if ('php://stdin' !== (\stream_get_meta_data($inputStream)['uri'] ?? null)) { + return \false; + } + if (isset(self::$stdinIsInteractive)) { + return self::$stdinIsInteractive; + } + if (\function_exists('stream_isatty')) { + return self::$stdinIsInteractive = @\stream_isatty(\fopen('php://stdin', 'r')); + } + if (\function_exists('posix_isatty')) { + return self::$stdinIsInteractive = @\posix_isatty(\fopen('php://stdin', 'r')); + } + if (!\function_exists('shell_exec')) { + return self::$stdinIsInteractive = \true; + } + return self::$stdinIsInteractive = (bool) \shell_exec('stty 2> ' . ('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null')); + } + /** + * Reads one or more lines of input and returns what is read. + * + * @param resource $inputStream The handler resource + * @param Question $question The question being asked + * @return string|false + */ + private function readInput($inputStream, Question $question) + { + if (!$question->isMultiline()) { + $cp = $this->setIOCodepage(); + $ret = \fgets($inputStream, 4096); + return $this->resetIOCodepage($cp, $ret); + } + $multiLineStreamReader = $this->cloneInputStream($inputStream); + if (null === $multiLineStreamReader) { + return \false; + } + $ret = ''; + $cp = $this->setIOCodepage(); + while (\false !== ($char = \fgetc($multiLineStreamReader))) { + if (\PHP_EOL === "{$ret}{$char}") { + break; + } + $ret .= $char; + } + return $this->resetIOCodepage($cp, $ret); + } + private function setIOCodepage() : int + { + if (\function_exists('sapi_windows_cp_set')) { + $cp = \sapi_windows_cp_get(); + \sapi_windows_cp_set(\sapi_windows_cp_get('oem')); + return $cp; + } + return 0; + } + /** + * Sets console I/O to the specified code page and converts the user input. + * @param string|false $input + * @return string|false + */ + private function resetIOCodepage(int $cp, $input) + { + if (0 !== $cp) { + \sapi_windows_cp_set($cp); + if (\false !== $input && '' !== $input) { + $input = \sapi_windows_cp_conv(\sapi_windows_cp_get('oem'), $cp, $input); + } + } + return $input; + } + /** + * Clones an input stream in order to act on one instance of the same + * stream without affecting the other instance. + * + * @param resource $inputStream The handler resource + * + * @return resource|null The cloned resource, null in case it could not be cloned + */ + private function cloneInputStream($inputStream) + { + $streamMetaData = \stream_get_meta_data($inputStream); + $seekable = $streamMetaData['seekable'] ?? \false; + $mode = $streamMetaData['mode'] ?? 'rb'; + $uri = $streamMetaData['uri'] ?? null; + if (null === $uri) { + return null; + } + $cloneStream = \fopen($uri, $mode); + // For seekable and writable streams, add all the same data to the + // cloned stream and then seek to the same offset. + if (\true === $seekable && !\in_array($mode, ['r', 'rb', 'rt'])) { + $offset = \ftell($inputStream); + \rewind($inputStream); + \stream_copy_to_stream($inputStream, $cloneStream); + \fseek($inputStream, $offset); + \fseek($cloneStream, $offset); + } + return $cloneStream; + } +} diff --git a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php new file mode 100644 index 0000000000..ca779c407a --- /dev/null +++ b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\ChoiceQuestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\ConfirmationQuestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\Question; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Style\SymfonyStyle; +/** + * Symfony Style Guide compliant question helper. + * + * @author Kevin Bond + */ +class SymfonyQuestionHelper extends QuestionHelper +{ + /** + * @return void + */ + protected function writePrompt(OutputInterface $output, Question $question) + { + $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion()); + $default = $question->getDefault(); + if ($question->isMultiline()) { + $text .= \sprintf(' (press %s to continue)', $this->getEofShortcut()); + } + switch (\true) { + case null === $default: + $text = \sprintf(' %s:', $text); + break; + case $question instanceof ConfirmationQuestion: + $text = \sprintf(' %s (yes/no) [%s]:', $text, $default ? 'yes' : 'no'); + break; + case $question instanceof ChoiceQuestion && $question->isMultiselect(): + $choices = $question->getChoices(); + $default = \explode(',', $default); + foreach ($default as $key => $value) { + $default[$key] = $choices[\trim($value)]; + } + $text = \sprintf(' %s [%s]:', $text, OutputFormatter::escape(\implode(', ', $default))); + break; + case $question instanceof ChoiceQuestion: + $choices = $question->getChoices(); + $text = \sprintf(' %s [%s]:', $text, OutputFormatter::escape($choices[$default] ?? $default)); + break; + default: + $text = \sprintf(' %s [%s]:', $text, OutputFormatter::escape($default)); + } + $output->writeln($text); + $prompt = ' > '; + if ($question instanceof ChoiceQuestion) { + $output->writeln($this->formatChoiceQuestionChoices($question, 'comment')); + $prompt = $question->getPrompt(); + } + $output->write($prompt); + } + /** + * @return void + */ + protected function writeError(OutputInterface $output, \Exception $error) + { + if ($output instanceof SymfonyStyle) { + $output->newLine(); + $output->error($error->getMessage()); + return; + } + parent::writeError($output, $error); + } + private function getEofShortcut() : string + { + if ('Windows' === \PHP_OS_FAMILY) { + return 'Ctrl+Z then Enter'; + } + return 'Ctrl+D'; + } +} diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php new file mode 100644 index 0000000000..a031ee7882 --- /dev/null +++ b/vendor/symfony/console/Helper/Table.php @@ -0,0 +1,801 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleSectionOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Provides helpers to display a table. + * + * @author Fabien Potencier + * @author Саша Стаменковић + * @author Abdellatif Ait boudad + * @author Max Grigorian + * @author Dany Maillard + */ +class Table +{ + private const SEPARATOR_TOP = 0; + private const SEPARATOR_TOP_BOTTOM = 1; + private const SEPARATOR_MID = 2; + private const SEPARATOR_BOTTOM = 3; + private const BORDER_OUTSIDE = 0; + private const BORDER_INSIDE = 1; + private const DISPLAY_ORIENTATION_DEFAULT = 'default'; + private const DISPLAY_ORIENTATION_HORIZONTAL = 'horizontal'; + private const DISPLAY_ORIENTATION_VERTICAL = 'vertical'; + /** + * @var string|null + */ + private $headerTitle; + /** + * @var string|null + */ + private $footerTitle; + /** + * @var mixed[] + */ + private $headers = []; + /** + * @var mixed[] + */ + private $rows = []; + /** + * @var mixed[] + */ + private $effectiveColumnWidths = []; + /** + * @var int + */ + private $numberOfColumns; + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + /** + * @var \Symfony\Component\Console\Helper\TableStyle + */ + private $style; + /** + * @var mixed[] + */ + private $columnStyles = []; + /** + * @var mixed[] + */ + private $columnWidths = []; + /** + * @var mixed[] + */ + private $columnMaxWidths = []; + /** + * @var bool + */ + private $rendered = \false; + /** + * @var string + */ + private $displayOrientation = self::DISPLAY_ORIENTATION_DEFAULT; + /** + * @var mixed[] + */ + private static $styles; + public function __construct(OutputInterface $output) + { + $this->output = $output; + self::$styles = self::$styles ?? self::initStyles(); + $this->setStyle('default'); + } + /** + * Sets a style definition. + * + * @return void + */ + public static function setStyleDefinition(string $name, TableStyle $style) + { + self::$styles = self::$styles ?? self::initStyles(); + self::$styles[$name] = $style; + } + /** + * Gets a style definition by name. + */ + public static function getStyleDefinition(string $name) : TableStyle + { + self::$styles = self::$styles ?? self::initStyles(); + if (!isset(self::$styles[$name])) { + throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name)); + } + return self::$styles[$name]; + } + /** + * Sets table style. + * + * @return $this + * @param \Symfony\Component\Console\Helper\TableStyle|string $name + */ + public function setStyle($name) + { + $this->style = $this->resolveStyle($name); + return $this; + } + /** + * Gets the current table style. + */ + public function getStyle() : TableStyle + { + return $this->style; + } + /** + * Sets table column style. + * + * @param TableStyle|string $name The style name or a TableStyle instance + * + * @return $this + */ + public function setColumnStyle(int $columnIndex, $name) + { + $this->columnStyles[$columnIndex] = $this->resolveStyle($name); + return $this; + } + /** + * Gets the current style for a column. + * + * If style was not set, it returns the global table style. + */ + public function getColumnStyle(int $columnIndex) : TableStyle + { + return $this->columnStyles[$columnIndex] ?? $this->getStyle(); + } + /** + * Sets the minimum width of a column. + * + * @return $this + */ + public function setColumnWidth(int $columnIndex, int $width) + { + $this->columnWidths[$columnIndex] = $width; + return $this; + } + /** + * Sets the minimum width of all columns. + * + * @return $this + */ + public function setColumnWidths(array $widths) + { + $this->columnWidths = []; + foreach ($widths as $index => $width) { + $this->setColumnWidth($index, $width); + } + return $this; + } + /** + * Sets the maximum width of a column. + * + * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while + * formatted strings are preserved. + * + * @return $this + */ + public function setColumnMaxWidth(int $columnIndex, int $width) + { + if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) { + throw new \LogicException(\sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, \get_debug_type($this->output->getFormatter()))); + } + $this->columnMaxWidths[$columnIndex] = $width; + return $this; + } + /** + * @return $this + */ + public function setHeaders(array $headers) + { + $headers = \array_values($headers); + if ($headers && !\is_array($headers[0])) { + $headers = [$headers]; + } + $this->headers = $headers; + return $this; + } + /** + * @return $this + */ + public function setRows(array $rows) + { + $this->rows = []; + return $this->addRows($rows); + } + /** + * @return $this + */ + public function addRows(array $rows) + { + foreach ($rows as $row) { + $this->addRow($row); + } + return $this; + } + /** + * @return $this + * @param \Symfony\Component\Console\Helper\TableSeparator|mixed[] $row + */ + public function addRow($row) + { + if ($row instanceof TableSeparator) { + $this->rows[] = $row; + return $this; + } + $this->rows[] = \array_values($row); + return $this; + } + /** + * Adds a row to the table, and re-renders the table. + * + * @return $this + * @param \Symfony\Component\Console\Helper\TableSeparator|mixed[] $row + */ + public function appendRow($row) + { + if (!$this->output instanceof ConsoleSectionOutput) { + throw new RuntimeException(\sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__)); + } + if ($this->rendered) { + $this->output->clear($this->calculateRowCount()); + } + $this->addRow($row); + $this->render(); + return $this; + } + /** + * @return $this + * @param int|string $column + */ + public function setRow($column, array $row) + { + $this->rows[$column] = $row; + return $this; + } + /** + * @return $this + */ + public function setHeaderTitle(?string $title) + { + $this->headerTitle = $title; + return $this; + } + /** + * @return $this + */ + public function setFooterTitle(?string $title) + { + $this->footerTitle = $title; + return $this; + } + /** + * @return $this + */ + public function setHorizontal(bool $horizontal = \true) + { + $this->displayOrientation = $horizontal ? self::DISPLAY_ORIENTATION_HORIZONTAL : self::DISPLAY_ORIENTATION_DEFAULT; + return $this; + } + /** + * @return $this + */ + public function setVertical(bool $vertical = \true) + { + $this->displayOrientation = $vertical ? self::DISPLAY_ORIENTATION_VERTICAL : self::DISPLAY_ORIENTATION_DEFAULT; + return $this; + } + /** + * Renders table to output. + * + * Example: + * + * +---------------+-----------------------+------------------+ + * | ISBN | Title | Author | + * +---------------+-----------------------+------------------+ + * | 99921-58-10-7 | Divine Comedy | Dante Alighieri | + * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | + * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | + * +---------------+-----------------------+------------------+ + * + * @return void + */ + public function render() + { + $divider = new TableSeparator(); + $isCellWithColspan = static function ($cell) { + return $cell instanceof TableCell && $cell->getColspan() >= 2; + }; + $horizontal = self::DISPLAY_ORIENTATION_HORIZONTAL === $this->displayOrientation; + $vertical = self::DISPLAY_ORIENTATION_VERTICAL === $this->displayOrientation; + $rows = []; + if ($horizontal) { + foreach ($this->headers[0] ?? [] as $i => $header) { + $rows[$i] = [$header]; + foreach ($this->rows as $row) { + if ($row instanceof TableSeparator) { + continue; + } + if (isset($row[$i])) { + $rows[$i][] = $row[$i]; + } elseif ($isCellWithColspan($rows[$i][0])) { + // Noop, there is a "title" + } else { + $rows[$i][] = null; + } + } + } + } elseif ($vertical) { + $formatter = $this->output->getFormatter(); + $maxHeaderLength = \array_reduce($this->headers[0] ?? [], static function ($max, $header) use($formatter) { + return \max($max, Helper::width(Helper::removeDecoration($formatter, $header))); + }, 0); + foreach ($this->rows as $row) { + if ($row instanceof TableSeparator) { + continue; + } + if ($rows) { + $rows[] = [$divider]; + } + $containsColspan = \false; + foreach ($row as $cell) { + if ($containsColspan = $isCellWithColspan($cell)) { + break; + } + } + $headers = $this->headers[0] ?? []; + $maxRows = \max(\count($headers), \count($row)); + for ($i = 0; $i < $maxRows; ++$i) { + $cell = (string) ($row[$i] ?? ''); + if ($headers && !$containsColspan) { + $rows[] = [\sprintf('%s: %s', \str_pad($headers[$i] ?? '', $maxHeaderLength, ' ', \STR_PAD_LEFT), $cell)]; + } elseif ('' !== $cell) { + $rows[] = [$cell]; + } + } + } + } else { + $rows = \array_merge($this->headers, [$divider], $this->rows); + } + $this->calculateNumberOfColumns($rows); + $rowGroups = $this->buildTableRows($rows); + $this->calculateColumnsWidth($rowGroups); + $isHeader = !$horizontal; + $isFirstRow = $horizontal; + $hasTitle = (bool) $this->headerTitle; + foreach ($rowGroups as $rowGroup) { + $isHeaderSeparatorRendered = \false; + foreach ($rowGroup as $row) { + if ($divider === $row) { + $isHeader = \false; + $isFirstRow = \true; + continue; + } + if ($row instanceof TableSeparator) { + $this->renderRowSeparator(); + continue; + } + if (!$row) { + continue; + } + if ($isHeader && !$isHeaderSeparatorRendered) { + $this->renderRowSeparator($isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, $hasTitle ? $this->headerTitle : null, $hasTitle ? $this->style->getHeaderTitleFormat() : null); + $hasTitle = \false; + $isHeaderSeparatorRendered = \true; + } + if ($isFirstRow) { + $this->renderRowSeparator($isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, $hasTitle ? $this->headerTitle : null, $hasTitle ? $this->style->getHeaderTitleFormat() : null); + $isFirstRow = \false; + $hasTitle = \false; + } + if ($vertical) { + $isHeader = \false; + $isFirstRow = \false; + } + if ($horizontal) { + $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat()); + } else { + $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat()); + } + } + } + $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat()); + $this->cleanup(); + $this->rendered = \true; + } + /** + * Renders horizontal header separator. + * + * Example: + * + * +-----+-----------+-------+ + */ + private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null) : void + { + if (!($count = $this->numberOfColumns)) { + return; + } + $borders = $this->style->getBorderChars(); + if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) { + return; + } + $crossings = $this->style->getCrossingChars(); + if (self::SEPARATOR_MID === $type) { + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[2], $crossings[8], $crossings[0], $crossings[4]]; + } elseif (self::SEPARATOR_TOP === $type) { + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[1], $crossings[2], $crossings[3]]; + } elseif (self::SEPARATOR_TOP_BOTTOM === $type) { + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[9], $crossings[10], $crossings[11]]; + } else { + [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[7], $crossings[6], $crossings[5]]; + } + $markup = $leftChar; + for ($column = 0; $column < $count; ++$column) { + $markup .= \str_repeat($horizontal, $this->effectiveColumnWidths[$column]); + $markup .= $column === $count - 1 ? $rightChar : $midChar; + } + if (null !== $title) { + $titleLength = Helper::width(Helper::removeDecoration($formatter = $this->output->getFormatter(), $formattedTitle = \sprintf($titleFormat, $title))); + $markupLength = Helper::width($markup); + if ($titleLength > ($limit = $markupLength - 4)) { + $titleLength = $limit; + $formatLength = Helper::width(Helper::removeDecoration($formatter, \sprintf($titleFormat, ''))); + $formattedTitle = \sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3) . '...'); + } + $titleStart = \intdiv($markupLength - $titleLength, 2); + if (\false === \mb_detect_encoding($markup, null, \true)) { + $markup = \substr_replace($markup, $formattedTitle, $titleStart, $titleLength); + } else { + $markup = \mb_substr($markup, 0, $titleStart) . $formattedTitle . \mb_substr($markup, $titleStart + $titleLength); + } + } + $this->output->writeln(\sprintf($this->style->getBorderFormat(), $markup)); + } + /** + * Renders vertical column separator. + */ + private function renderColumnSeparator(int $type = self::BORDER_OUTSIDE) : string + { + $borders = $this->style->getBorderChars(); + return \sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]); + } + /** + * Renders table row. + * + * Example: + * + * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | + */ + private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null) : void + { + $rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE); + $columns = $this->getRowColumns($row); + $last = \count($columns) - 1; + foreach ($columns as $i => $column) { + if ($firstCellFormat && 0 === $i) { + $rowContent .= $this->renderCell($row, $column, $firstCellFormat); + } else { + $rowContent .= $this->renderCell($row, $column, $cellFormat); + } + $rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE); + } + $this->output->writeln($rowContent); + } + /** + * Renders table cell with padding. + */ + private function renderCell(array $row, int $column, string $cellFormat) : string + { + $cell = $row[$column] ?? ''; + $width = $this->effectiveColumnWidths[$column]; + if ($cell instanceof TableCell && $cell->getColspan() > 1) { + // add the width of the following columns(numbers of colspan). + foreach (\range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) { + $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn]; + } + } + // str_pad won't work properly with multi-byte strings, we need to fix the padding + if (\false !== ($encoding = \mb_detect_encoding($cell, null, \true))) { + $width += \strlen($cell) - \mb_strwidth($cell, $encoding); + } + $style = $this->getColumnStyle($column); + if ($cell instanceof TableSeparator) { + return \sprintf($style->getBorderFormat(), \str_repeat($style->getBorderChars()[2], $width)); + } + $width += Helper::length($cell) - Helper::length(Helper::removeDecoration($this->output->getFormatter(), $cell)); + $content = \sprintf($style->getCellRowContentFormat(), $cell); + $padType = $style->getPadType(); + if ($cell instanceof TableCell && $cell->getStyle() instanceof TableCellStyle) { + $isNotStyledByTag = !\preg_match('/^<(\\w+|(\\w+=[\\w,]+;?)*)>.+<\\/(\\w+|(\\w+=\\w+;?)*)?>$/', $cell); + if ($isNotStyledByTag) { + $cellFormat = $cell->getStyle()->getCellFormat(); + if (!\is_string($cellFormat)) { + $tag = \http_build_query($cell->getStyle()->getTagOptions(), '', ';'); + $cellFormat = '<' . $tag . '>%s'; + } + if (\strpos($content, '') !== \false) { + $content = \str_replace('', '', $content); + $width -= 3; + } + if (\strpos($content, '') !== \false) { + $content = \str_replace('', '', $content); + $width -= \strlen(''); + } + } + $padType = $cell->getStyle()->getPadByAlign(); + } + return \sprintf($cellFormat, \str_pad($content, $width, $style->getPaddingChar(), $padType)); + } + /** + * Calculate number of columns for this table. + */ + private function calculateNumberOfColumns(array $rows) : void + { + $columns = [0]; + foreach ($rows as $row) { + if ($row instanceof TableSeparator) { + continue; + } + $columns[] = $this->getNumberOfColumns($row); + } + $this->numberOfColumns = \max($columns); + } + private function buildTableRows(array $rows) : TableRows + { + /** @var WrappableOutputFormatterInterface $formatter */ + $formatter = $this->output->getFormatter(); + $unmergedRows = []; + for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) { + $rows = $this->fillNextRows($rows, $rowKey); + // Remove any new line breaks and replace it with a new line + foreach ($rows[$rowKey] as $column => $cell) { + $colspan = $cell instanceof TableCell ? $cell->getColspan() : 1; + if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) { + $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan); + } + if (\strpos($cell ?? '', "\n") === \false) { + continue; + } + $escaped = \implode("\n", \array_map(\Closure::fromCallable([OutputFormatter::class, 'escapeTrailingBackslash']), \explode("\n", $cell))); + $cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped; + $lines = \explode("\n", \str_replace("\n", "\n", $cell)); + foreach ($lines as $lineKey => $line) { + if ($colspan > 1) { + $line = new TableCell($line, ['colspan' => $colspan]); + } + if (0 === $lineKey) { + $rows[$rowKey][$column] = $line; + } else { + if (!\array_key_exists($rowKey, $unmergedRows) || !\array_key_exists($lineKey, $unmergedRows[$rowKey])) { + $unmergedRows[$rowKey][$lineKey] = $this->copyRow($rows, $rowKey); + } + $unmergedRows[$rowKey][$lineKey][$column] = $line; + } + } + } + } + return new TableRows(function () use($rows, $unmergedRows) : \Traversable { + foreach ($rows as $rowKey => $row) { + $rowGroup = [$row instanceof TableSeparator ? $row : $this->fillCells($row)]; + if (isset($unmergedRows[$rowKey])) { + foreach ($unmergedRows[$rowKey] as $row) { + $rowGroup[] = $row instanceof TableSeparator ? $row : $this->fillCells($row); + } + } + (yield $rowGroup); + } + }); + } + private function calculateRowCount() : int + { + $numberOfRows = \count(\iterator_to_array($this->buildTableRows(\array_merge($this->headers, [new TableSeparator()], $this->rows)))); + if ($this->headers) { + ++$numberOfRows; + // Add row for header separator + } + if ($this->rows) { + ++$numberOfRows; + // Add row for footer separator + } + return $numberOfRows; + } + /** + * fill rows that contains rowspan > 1. + * + * @throws InvalidArgumentException + */ + private function fillNextRows(array $rows, int $line) : array + { + $unmergedRows = []; + foreach ($rows[$line] as $column => $cell) { + if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !$cell instanceof \Stringable) { + throw new InvalidArgumentException(\sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', \get_debug_type($cell))); + } + if ($cell instanceof TableCell && $cell->getRowspan() > 1) { + $nbLines = $cell->getRowspan() - 1; + $lines = [$cell]; + if (\strpos($cell, "\n") !== \false) { + $lines = \explode("\n", \str_replace("\n", "\n", $cell)); + $nbLines = \count($lines) > $nbLines ? \substr_count($cell, "\n") : $nbLines; + $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]); + unset($lines[0]); + } + // create a two dimensional array (rowspan x colspan) + $unmergedRows = \array_replace_recursive(\array_fill($line + 1, $nbLines, []), $unmergedRows); + foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { + $value = $lines[$unmergedRowKey - $line] ?? ''; + $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]); + if ($nbLines === $unmergedRowKey - $line) { + break; + } + } + } + } + foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { + // we need to know if $unmergedRow will be merged or inserted into $rows + if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && $this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns) { + foreach ($unmergedRow as $cellKey => $cell) { + // insert cell into row at cellKey position + \array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]); + } + } else { + $row = $this->copyRow($rows, $unmergedRowKey - 1); + foreach ($unmergedRow as $column => $cell) { + if (!empty($cell)) { + $row[$column] = $unmergedRow[$column]; + } + } + \array_splice($rows, $unmergedRowKey, 0, [$row]); + } + } + return $rows; + } + /** + * fill cells for a row that contains colspan > 1. + */ + private function fillCells(iterable $row) : iterable + { + $newRow = []; + foreach ($row as $column => $cell) { + $newRow[] = $cell; + if ($cell instanceof TableCell && $cell->getColspan() > 1) { + foreach (\range($column + 1, $column + $cell->getColspan() - 1) as $position) { + // insert empty value at column position + $newRow[] = ''; + } + } + } + return $newRow ?: $row; + } + private function copyRow(array $rows, int $line) : array + { + $row = $rows[$line]; + foreach ($row as $cellKey => $cellValue) { + $row[$cellKey] = ''; + if ($cellValue instanceof TableCell) { + $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]); + } + } + return $row; + } + /** + * Gets number of columns by row. + */ + private function getNumberOfColumns(array $row) : int + { + $columns = \count($row); + foreach ($row as $column) { + $columns += $column instanceof TableCell ? $column->getColspan() - 1 : 0; + } + return $columns; + } + /** + * Gets list of columns for the given row. + */ + private function getRowColumns(array $row) : array + { + $columns = \range(0, $this->numberOfColumns - 1); + foreach ($row as $cellKey => $cell) { + if ($cell instanceof TableCell && $cell->getColspan() > 1) { + // exclude grouped columns. + $columns = \array_diff($columns, \range($cellKey + 1, $cellKey + $cell->getColspan() - 1)); + } + } + return $columns; + } + /** + * Calculates columns widths. + */ + private function calculateColumnsWidth(iterable $groups) : void + { + for ($column = 0; $column < $this->numberOfColumns; ++$column) { + $lengths = []; + foreach ($groups as $group) { + foreach ($group as $row) { + if ($row instanceof TableSeparator) { + continue; + } + foreach ($row as $i => $cell) { + if ($cell instanceof TableCell) { + $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell); + $textLength = Helper::width($textContent); + if ($textLength > 0) { + $contentColumns = \mb_str_split($textContent, \ceil($textLength / $cell->getColspan())); + foreach ($contentColumns as $position => $content) { + $row[$i + $position] = $content; + } + } + } + } + $lengths[] = $this->getCellWidth($row, $column); + } + } + $this->effectiveColumnWidths[$column] = \max($lengths) + Helper::width($this->style->getCellRowContentFormat()) - 2; + } + } + private function getColumnSeparatorWidth() : int + { + return Helper::width(\sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3])); + } + private function getCellWidth(array $row, int $column) : int + { + $cellWidth = 0; + if (isset($row[$column])) { + $cell = $row[$column]; + $cellWidth = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $cell)); + } + $columnWidth = $this->columnWidths[$column] ?? 0; + $cellWidth = \max($cellWidth, $columnWidth); + return isset($this->columnMaxWidths[$column]) ? \min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth; + } + /** + * Called after rendering to cleanup cache data. + */ + private function cleanup() : void + { + $this->effectiveColumnWidths = []; + unset($this->numberOfColumns); + } + /** + * @return array + */ + private static function initStyles() : array + { + $borderless = new TableStyle(); + $borderless->setHorizontalBorderChars('=')->setVerticalBorderChars(' ')->setDefaultCrossingChar(' '); + $compact = new TableStyle(); + $compact->setHorizontalBorderChars('')->setVerticalBorderChars('')->setDefaultCrossingChar('')->setCellRowContentFormat('%s '); + $styleGuide = new TableStyle(); + $styleGuide->setHorizontalBorderChars('-')->setVerticalBorderChars(' ')->setDefaultCrossingChar(' ')->setCellHeaderFormat('%s'); + $box = (new TableStyle())->setHorizontalBorderChars('─')->setVerticalBorderChars('│')->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├'); + $boxDouble = (new TableStyle())->setHorizontalBorderChars('═', '─')->setVerticalBorderChars('║', '│')->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣'); + return ['default' => new TableStyle(), 'borderless' => $borderless, 'compact' => $compact, 'symfony-style-guide' => $styleGuide, 'box' => $box, 'box-double' => $boxDouble]; + } + /** + * @param \Symfony\Component\Console\Helper\TableStyle|string $name + */ + private function resolveStyle($name) : TableStyle + { + if ($name instanceof TableStyle) { + return $name; + } + if (!isset(self::$styles[$name])) { + throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name)); + } + return self::$styles[$name]; + } +} diff --git a/vendor/symfony/console/Helper/TableCell.php b/vendor/symfony/console/Helper/TableCell.php new file mode 100644 index 0000000000..123d557115 --- /dev/null +++ b/vendor/symfony/console/Helper/TableCell.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +/** + * @author Abdellatif Ait boudad + */ +class TableCell +{ + /** + * @var string + */ + private $value; + /** + * @var mixed[] + */ + private $options = ['rowspan' => 1, 'colspan' => 1, 'style' => null]; + public function __construct(string $value = '', array $options = []) + { + $this->value = $value; + // check option names + if ($diff = \array_diff(\array_keys($options), \array_keys($this->options))) { + throw new InvalidArgumentException(\sprintf('The TableCell does not support the following options: \'%s\'.', \implode('\', \'', $diff))); + } + if (isset($options['style']) && !$options['style'] instanceof TableCellStyle) { + throw new InvalidArgumentException('The style option must be an instance of "TableCellStyle".'); + } + $this->options = \array_merge($this->options, $options); + } + /** + * Returns the cell value. + */ + public function __toString() : string + { + return $this->value; + } + /** + * Gets number of colspan. + */ + public function getColspan() : int + { + return (int) $this->options['colspan']; + } + /** + * Gets number of rowspan. + */ + public function getRowspan() : int + { + return (int) $this->options['rowspan']; + } + public function getStyle() : ?TableCellStyle + { + return $this->options['style']; + } +} diff --git a/vendor/symfony/console/Helper/TableCellStyle.php b/vendor/symfony/console/Helper/TableCellStyle.php new file mode 100644 index 0000000000..32cafeb057 --- /dev/null +++ b/vendor/symfony/console/Helper/TableCellStyle.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +/** + * @author Yewhen Khoptynskyi + */ +class TableCellStyle +{ + public const DEFAULT_ALIGN = 'left'; + private const TAG_OPTIONS = ['fg', 'bg', 'options']; + private const ALIGN_MAP = ['left' => \STR_PAD_RIGHT, 'center' => \STR_PAD_BOTH, 'right' => \STR_PAD_LEFT]; + /** + * @var mixed[] + */ + private $options = ['fg' => 'default', 'bg' => 'default', 'options' => null, 'align' => self::DEFAULT_ALIGN, 'cellFormat' => null]; + public function __construct(array $options = []) + { + if ($diff = \array_diff(\array_keys($options), \array_keys($this->options))) { + throw new InvalidArgumentException(\sprintf('The TableCellStyle does not support the following options: \'%s\'.', \implode('\', \'', $diff))); + } + if (isset($options['align']) && !\array_key_exists($options['align'], self::ALIGN_MAP)) { + throw new InvalidArgumentException(\sprintf('Wrong align value. Value must be following: \'%s\'.', \implode('\', \'', \array_keys(self::ALIGN_MAP)))); + } + $this->options = \array_merge($this->options, $options); + } + public function getOptions() : array + { + return $this->options; + } + /** + * Gets options we need for tag for example fg, bg. + * + * @return string[] + */ + public function getTagOptions() : array + { + return \array_filter($this->getOptions(), function ($key) { + return \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]); + }, \ARRAY_FILTER_USE_KEY); + } + public function getPadByAlign() : int + { + return self::ALIGN_MAP[$this->getOptions()['align']]; + } + public function getCellFormat() : ?string + { + return $this->getOptions()['cellFormat']; + } +} diff --git a/vendor/symfony/console/Helper/TableRows.php b/vendor/symfony/console/Helper/TableRows.php new file mode 100644 index 0000000000..d935ea75cf --- /dev/null +++ b/vendor/symfony/console/Helper/TableRows.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +/** + * @internal + */ +class TableRows implements \IteratorAggregate +{ + /** + * @var \Closure + */ + private $generator; + public function __construct(\Closure $generator) + { + $this->generator = $generator; + } + public function getIterator() : \Traversable + { + return ($this->generator)(); + } +} diff --git a/vendor/symfony/console/Helper/TableSeparator.php b/vendor/symfony/console/Helper/TableSeparator.php new file mode 100644 index 0000000000..5b230aea4f --- /dev/null +++ b/vendor/symfony/console/Helper/TableSeparator.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +/** + * Marks a row as being a separator. + * + * @author Fabien Potencier + */ +class TableSeparator extends TableCell +{ + public function __construct(array $options = []) + { + parent::__construct('', $options); + } +} diff --git a/vendor/symfony/console/Helper/TableStyle.php b/vendor/symfony/console/Helper/TableStyle.php new file mode 100644 index 0000000000..921508f0f5 --- /dev/null +++ b/vendor/symfony/console/Helper/TableStyle.php @@ -0,0 +1,378 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +/** + * Defines the styles for a Table. + * + * @author Fabien Potencier + * @author Саша Стаменковић + * @author Dany Maillard + */ +class TableStyle +{ + /** + * @var string + */ + private $paddingChar = ' '; + /** + * @var string + */ + private $horizontalOutsideBorderChar = '-'; + /** + * @var string + */ + private $horizontalInsideBorderChar = '-'; + /** + * @var string + */ + private $verticalOutsideBorderChar = '|'; + /** + * @var string + */ + private $verticalInsideBorderChar = '|'; + /** + * @var string + */ + private $crossingChar = '+'; + /** + * @var string + */ + private $crossingTopRightChar = '+'; + /** + * @var string + */ + private $crossingTopMidChar = '+'; + /** + * @var string + */ + private $crossingTopLeftChar = '+'; + /** + * @var string + */ + private $crossingMidRightChar = '+'; + /** + * @var string + */ + private $crossingBottomRightChar = '+'; + /** + * @var string + */ + private $crossingBottomMidChar = '+'; + /** + * @var string + */ + private $crossingBottomLeftChar = '+'; + /** + * @var string + */ + private $crossingMidLeftChar = '+'; + /** + * @var string + */ + private $crossingTopLeftBottomChar = '+'; + /** + * @var string + */ + private $crossingTopMidBottomChar = '+'; + /** + * @var string + */ + private $crossingTopRightBottomChar = '+'; + /** + * @var string + */ + private $headerTitleFormat = ' %s '; + /** + * @var string + */ + private $footerTitleFormat = ' %s '; + /** + * @var string + */ + private $cellHeaderFormat = '%s'; + /** + * @var string + */ + private $cellRowFormat = '%s'; + /** + * @var string + */ + private $cellRowContentFormat = ' %s '; + /** + * @var string + */ + private $borderFormat = '%s'; + /** + * @var int + */ + private $padType = \STR_PAD_RIGHT; + /** + * Sets padding character, used for cell padding. + * + * @return $this + */ + public function setPaddingChar(string $paddingChar) + { + if (!$paddingChar) { + throw new LogicException('The padding char must not be empty.'); + } + $this->paddingChar = $paddingChar; + return $this; + } + /** + * Gets padding character, used for cell padding. + */ + public function getPaddingChar() : string + { + return $this->paddingChar; + } + /** + * Sets horizontal border characters. + * + * + * ╔═══════════════╤══════════════════════════╤══════════════════╗ + * 1 ISBN 2 Title │ Author ║ + * ╠═══════════════╪══════════════════════════╪══════════════════╣ + * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ + * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ + * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ + * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ + * ╚═══════════════╧══════════════════════════╧══════════════════╝ + * + * + * @return $this + */ + public function setHorizontalBorderChars(string $outside, string $inside = null) + { + $this->horizontalOutsideBorderChar = $outside; + $this->horizontalInsideBorderChar = $inside ?? $outside; + return $this; + } + /** + * Sets vertical border characters. + * + * + * ╔═══════════════╤══════════════════════════╤══════════════════╗ + * ║ ISBN │ Title │ Author ║ + * ╠═══════1═══════╪══════════════════════════╪══════════════════╣ + * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ + * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ + * ╟───────2───────┼──────────────────────────┼──────────────────╢ + * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ + * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ + * ╚═══════════════╧══════════════════════════╧══════════════════╝ + * + * + * @return $this + */ + public function setVerticalBorderChars(string $outside, string $inside = null) + { + $this->verticalOutsideBorderChar = $outside; + $this->verticalInsideBorderChar = $inside ?? $outside; + return $this; + } + /** + * Gets border characters. + * + * @internal + */ + public function getBorderChars() : array + { + return [$this->horizontalOutsideBorderChar, $this->verticalOutsideBorderChar, $this->horizontalInsideBorderChar, $this->verticalInsideBorderChar]; + } + /** + * Sets crossing characters. + * + * Example: + * + * 1═══════════════2══════════════════════════2══════════════════3 + * ║ ISBN │ Title │ Author ║ + * 8'══════════════0'═════════════════════════0'═════════════════4' + * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ + * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ + * 8───────────────0──────────────────────────0──────────────────4 + * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ + * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ + * 7═══════════════6══════════════════════════6══════════════════5 + * + * + * @param string $cross Crossing char (see #0 of example) + * @param string $topLeft Top left char (see #1 of example) + * @param string $topMid Top mid char (see #2 of example) + * @param string $topRight Top right char (see #3 of example) + * @param string $midRight Mid right char (see #4 of example) + * @param string $bottomRight Bottom right char (see #5 of example) + * @param string $bottomMid Bottom mid char (see #6 of example) + * @param string $bottomLeft Bottom left char (see #7 of example) + * @param string $midLeft Mid left char (see #8 of example) + * @param string|null $topLeftBottom Top left bottom char (see #8' of example), equals to $midLeft if null + * @param string|null $topMidBottom Top mid bottom char (see #0' of example), equals to $cross if null + * @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null + * + * @return $this + */ + public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null) + { + $this->crossingChar = $cross; + $this->crossingTopLeftChar = $topLeft; + $this->crossingTopMidChar = $topMid; + $this->crossingTopRightChar = $topRight; + $this->crossingMidRightChar = $midRight; + $this->crossingBottomRightChar = $bottomRight; + $this->crossingBottomMidChar = $bottomMid; + $this->crossingBottomLeftChar = $bottomLeft; + $this->crossingMidLeftChar = $midLeft; + $this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft; + $this->crossingTopMidBottomChar = $topMidBottom ?? $cross; + $this->crossingTopRightBottomChar = $topRightBottom ?? $midRight; + return $this; + } + /** + * Sets default crossing character used for each cross. + * + * @see {@link setCrossingChars()} for setting each crossing individually. + */ + public function setDefaultCrossingChar(string $char) : self + { + return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char); + } + /** + * Gets crossing character. + */ + public function getCrossingChar() : string + { + return $this->crossingChar; + } + /** + * Gets crossing characters. + * + * @internal + */ + public function getCrossingChars() : array + { + return [$this->crossingChar, $this->crossingTopLeftChar, $this->crossingTopMidChar, $this->crossingTopRightChar, $this->crossingMidRightChar, $this->crossingBottomRightChar, $this->crossingBottomMidChar, $this->crossingBottomLeftChar, $this->crossingMidLeftChar, $this->crossingTopLeftBottomChar, $this->crossingTopMidBottomChar, $this->crossingTopRightBottomChar]; + } + /** + * Sets header cell format. + * + * @return $this + */ + public function setCellHeaderFormat(string $cellHeaderFormat) + { + $this->cellHeaderFormat = $cellHeaderFormat; + return $this; + } + /** + * Gets header cell format. + */ + public function getCellHeaderFormat() : string + { + return $this->cellHeaderFormat; + } + /** + * Sets row cell format. + * + * @return $this + */ + public function setCellRowFormat(string $cellRowFormat) + { + $this->cellRowFormat = $cellRowFormat; + return $this; + } + /** + * Gets row cell format. + */ + public function getCellRowFormat() : string + { + return $this->cellRowFormat; + } + /** + * Sets row cell content format. + * + * @return $this + */ + public function setCellRowContentFormat(string $cellRowContentFormat) + { + $this->cellRowContentFormat = $cellRowContentFormat; + return $this; + } + /** + * Gets row cell content format. + */ + public function getCellRowContentFormat() : string + { + return $this->cellRowContentFormat; + } + /** + * Sets table border format. + * + * @return $this + */ + public function setBorderFormat(string $borderFormat) + { + $this->borderFormat = $borderFormat; + return $this; + } + /** + * Gets table border format. + */ + public function getBorderFormat() : string + { + return $this->borderFormat; + } + /** + * Sets cell padding type. + * + * @return $this + */ + public function setPadType(int $padType) + { + if (!\in_array($padType, [\STR_PAD_LEFT, \STR_PAD_RIGHT, \STR_PAD_BOTH], \true)) { + throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).'); + } + $this->padType = $padType; + return $this; + } + /** + * Gets cell padding type. + */ + public function getPadType() : int + { + return $this->padType; + } + public function getHeaderTitleFormat() : string + { + return $this->headerTitleFormat; + } + /** + * @return $this + */ + public function setHeaderTitleFormat(string $format) + { + $this->headerTitleFormat = $format; + return $this; + } + public function getFooterTitleFormat() : string + { + return $this->footerTitleFormat; + } + /** + * @return $this + */ + public function setFooterTitleFormat(string $format) + { + $this->footerTitleFormat = $format; + return $this; + } +} diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php new file mode 100644 index 0000000000..0d00e1a7f9 --- /dev/null +++ b/vendor/symfony/console/Input/ArgvInput.php @@ -0,0 +1,336 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +/** + * ArgvInput represents an input coming from the CLI arguments. + * + * Usage: + * + * $input = new ArgvInput(); + * + * By default, the `$_SERVER['argv']` array is used for the input values. + * + * This can be overridden by explicitly passing the input values in the constructor: + * + * $input = new ArgvInput($_SERVER['argv']); + * + * If you pass it yourself, don't forget that the first element of the array + * is the name of the running application. + * + * When passing an argument to the constructor, be sure that it respects + * the same rules as the argv one. It's almost always better to use the + * `StringInput` when you want to provide your own input. + * + * @author Fabien Potencier + * + * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html + * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02 + */ +class ArgvInput extends Input +{ + /** + * @var mixed[] + */ + private $tokens; + /** + * @var mixed[] + */ + private $parsed; + public function __construct(array $argv = null, InputDefinition $definition = null) + { + $argv = $argv ?? $_SERVER['argv'] ?? []; + // strip the application name + \array_shift($argv); + $this->tokens = $argv; + parent::__construct($definition); + } + /** + * @return void + */ + protected function setTokens(array $tokens) + { + $this->tokens = $tokens; + } + /** + * @return void + */ + protected function parse() + { + $parseOptions = \true; + $this->parsed = $this->tokens; + while (null !== ($token = \array_shift($this->parsed))) { + $parseOptions = $this->parseToken($token, $parseOptions); + } + } + protected function parseToken(string $token, bool $parseOptions) : bool + { + if ($parseOptions && '' == $token) { + $this->parseArgument($token); + } elseif ($parseOptions && '--' == $token) { + return \false; + } elseif ($parseOptions && \strncmp($token, '--', \strlen('--')) === 0) { + $this->parseLongOption($token); + } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { + $this->parseShortOption($token); + } else { + $this->parseArgument($token); + } + return $parseOptions; + } + /** + * Parses a short option. + */ + private function parseShortOption(string $token) : void + { + $name = \substr($token, 1); + if (\strlen($name) > 1) { + if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) { + // an option with a value (with no space) + $this->addShortOption($name[0], \substr($name, 1)); + } else { + $this->parseShortOptionSet($name); + } + } else { + $this->addShortOption($name, null); + } + } + /** + * Parses a short option set. + * + * @throws RuntimeException When option given doesn't exist + */ + private function parseShortOptionSet(string $name) : void + { + $len = \strlen($name); + for ($i = 0; $i < $len; ++$i) { + if (!$this->definition->hasShortcut($name[$i])) { + $encoding = \mb_detect_encoding($name, null, \true); + throw new RuntimeException(\sprintf('The "-%s" option does not exist.', \false === $encoding ? $name[$i] : \mb_substr($name, $i, 1, $encoding))); + } + $option = $this->definition->getOptionForShortcut($name[$i]); + if ($option->acceptValue()) { + $this->addLongOption($option->getName(), $i === $len - 1 ? null : \substr($name, $i + 1)); + break; + } else { + $this->addLongOption($option->getName(), null); + } + } + } + /** + * Parses a long option. + */ + private function parseLongOption(string $token) : void + { + $name = \substr($token, 2); + if (\false !== ($pos = \strpos($name, '='))) { + if ('' === ($value = \substr($name, $pos + 1))) { + \array_unshift($this->parsed, $value); + } + $this->addLongOption(\substr($name, 0, $pos), $value); + } else { + $this->addLongOption($name, null); + } + } + /** + * Parses an argument. + * + * @throws RuntimeException When too many arguments are given + */ + private function parseArgument(string $token) : void + { + $c = \count($this->arguments); + // if input is expecting another argument, add it + if ($this->definition->hasArgument($c)) { + $arg = $this->definition->getArgument($c); + $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token; + // if last argument isArray(), append token to last argument + } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { + $arg = $this->definition->getArgument($c - 1); + $this->arguments[$arg->getName()][] = $token; + // unexpected argument + } else { + $all = $this->definition->getArguments(); + $symfonyCommandName = null; + \reset($all); + if (($inputArgument = $all[$key = \key($all)] ?? null) && 'command' === $inputArgument->getName()) { + $symfonyCommandName = $this->arguments['command'] ?? null; + unset($all[$key]); + } + if (\count($all)) { + if ($symfonyCommandName) { + $message = \sprintf('Too many arguments to "%s" command, expected arguments "%s".', $symfonyCommandName, \implode('" "', \array_keys($all))); + } else { + $message = \sprintf('Too many arguments, expected arguments "%s".', \implode('" "', \array_keys($all))); + } + } elseif ($symfonyCommandName) { + $message = \sprintf('No arguments expected for "%s" command, got "%s".', $symfonyCommandName, $token); + } else { + $message = \sprintf('No arguments expected, got "%s".', $token); + } + throw new RuntimeException($message); + } + } + /** + * Adds a short option value. + * + * @throws RuntimeException When option given doesn't exist + * @param mixed $value + */ + private function addShortOption(string $shortcut, $value) : void + { + if (!$this->definition->hasShortcut($shortcut)) { + throw new RuntimeException(\sprintf('The "-%s" option does not exist.', $shortcut)); + } + $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); + } + /** + * Adds a long option value. + * + * @throws RuntimeException When option given doesn't exist + * @param mixed $value + */ + private function addLongOption(string $name, $value) : void + { + if (!$this->definition->hasOption($name)) { + if (!$this->definition->hasNegation($name)) { + throw new RuntimeException(\sprintf('The "--%s" option does not exist.', $name)); + } + $optionName = $this->definition->negationToName($name); + if (null !== $value) { + throw new RuntimeException(\sprintf('The "--%s" option does not accept a value.', $name)); + } + $this->options[$optionName] = \false; + return; + } + $option = $this->definition->getOption($name); + if (null !== $value && !$option->acceptValue()) { + throw new RuntimeException(\sprintf('The "--%s" option does not accept a value.', $name)); + } + if (\in_array($value, ['', null], \true) && $option->acceptValue() && \count($this->parsed)) { + // if option accepts an optional or mandatory argument + // let's see if there is one provided + $next = \array_shift($this->parsed); + if (isset($next[0]) && '-' !== $next[0] || \in_array($next, ['', null], \true)) { + $value = $next; + } else { + \array_unshift($this->parsed, $next); + } + } + if (null === $value) { + if ($option->isValueRequired()) { + throw new RuntimeException(\sprintf('The "--%s" option requires a value.', $name)); + } + if (!$option->isArray() && !$option->isValueOptional()) { + $value = \true; + } + } + if ($option->isArray()) { + $this->options[$name][] = $value; + } else { + $this->options[$name] = $value; + } + } + public function getFirstArgument() : ?string + { + $isOption = \false; + foreach ($this->tokens as $i => $token) { + if ($token && '-' === $token[0]) { + if (\strpos($token, '=') !== \false || !isset($this->tokens[$i + 1])) { + continue; + } + // If it's a long option, consider that everything after "--" is the option name. + // Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator) + $name = '-' === $token[1] ? \substr($token, 2) : \substr($token, -1); + if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) { + // noop + } elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) { + $isOption = \true; + } + continue; + } + if ($isOption) { + $isOption = \false; + continue; + } + return $token; + } + return null; + } + /** + * @param string|mixed[] $values + */ + public function hasParameterOption($values, bool $onlyParams = \false) : bool + { + $values = (array) $values; + foreach ($this->tokens as $token) { + if ($onlyParams && '--' === $token) { + return \false; + } + foreach ($values as $value) { + // Options with values: + // For long options, test for '--option=' at beginning + // For short options, test for '-o' at beginning + $leading = \strncmp($value, '--', \strlen('--')) === 0 ? $value . '=' : $value; + if ($token === $value || '' !== $leading && \strncmp($token, $leading, \strlen($leading)) === 0) { + return \true; + } + } + } + return \false; + } + /** + * @param string|mixed[] $values + * @param string|bool|int|float|mixed[]|null $default + * @return mixed + */ + public function getParameterOption($values, $default = \false, bool $onlyParams = \false) + { + $values = (array) $values; + $tokens = $this->tokens; + while (0 < \count($tokens)) { + $token = \array_shift($tokens); + if ($onlyParams && '--' === $token) { + return $default; + } + foreach ($values as $value) { + if ($token === $value) { + return \array_shift($tokens); + } + // Options with values: + // For long options, test for '--option=' at beginning + // For short options, test for '-o' at beginning + $leading = \strncmp($value, '--', \strlen('--')) === 0 ? $value . '=' : $value; + if ('' !== $leading && \strncmp($token, $leading, \strlen($leading)) === 0) { + return \substr($token, \strlen($leading)); + } + } + } + return $default; + } + /** + * Returns a stringified representation of the args passed to the command. + */ + public function __toString() : string + { + $tokens = \array_map(function ($token) { + if (\preg_match('{^(-[^=]+=)(.+)}', $token, $match)) { + return $match[1] . $this->escapeToken($match[2]); + } + if ($token && '-' !== $token[0]) { + return $this->escapeToken($token); + } + return $token; + }, $this->tokens); + return \implode(' ', $tokens); + } +} diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php new file mode 100644 index 0000000000..bc9f8ade3b --- /dev/null +++ b/vendor/symfony/console/Input/ArrayInput.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidOptionException; +/** + * ArrayInput represents an input provided as an array. + * + * Usage: + * + * $input = new ArrayInput(['command' => 'foo:bar', 'foo' => 'bar', '--bar' => 'foobar']); + * + * @author Fabien Potencier + */ +class ArrayInput extends Input +{ + /** + * @var mixed[] + */ + private $parameters; + public function __construct(array $parameters, InputDefinition $definition = null) + { + $this->parameters = $parameters; + parent::__construct($definition); + } + public function getFirstArgument() : ?string + { + foreach ($this->parameters as $param => $value) { + if ($param && \is_string($param) && '-' === $param[0]) { + continue; + } + return $value; + } + return null; + } + /** + * @param string|mixed[] $values + */ + public function hasParameterOption($values, bool $onlyParams = \false) : bool + { + $values = (array) $values; + foreach ($this->parameters as $k => $v) { + if (!\is_int($k)) { + $v = $k; + } + if ($onlyParams && '--' === $v) { + return \false; + } + if (\in_array($v, $values)) { + return \true; + } + } + return \false; + } + /** + * @param string|mixed[] $values + * @param string|bool|int|float|mixed[]|null $default + * @return mixed + */ + public function getParameterOption($values, $default = \false, bool $onlyParams = \false) + { + $values = (array) $values; + foreach ($this->parameters as $k => $v) { + if ($onlyParams && ('--' === $k || \is_int($k) && '--' === $v)) { + return $default; + } + if (\is_int($k)) { + if (\in_array($v, $values)) { + return \true; + } + } elseif (\in_array($k, $values)) { + return $v; + } + } + return $default; + } + /** + * Returns a stringified representation of the args passed to the command. + */ + public function __toString() : string + { + $params = []; + foreach ($this->parameters as $param => $val) { + if ($param && \is_string($param) && '-' === $param[0]) { + $glue = '-' === $param[1] ? '=' : ' '; + if (\is_array($val)) { + foreach ($val as $v) { + $params[] = $param . ('' != $v ? $glue . $this->escapeToken($v) : ''); + } + } else { + $params[] = $param . ('' != $val ? $glue . $this->escapeToken($val) : ''); + } + } else { + $params[] = \is_array($val) ? \implode(' ', \array_map(\Closure::fromCallable([$this, 'escapeToken']), $val)) : $this->escapeToken($val); + } + } + return \implode(' ', $params); + } + /** + * @return void + */ + protected function parse() + { + foreach ($this->parameters as $key => $value) { + if ('--' === $key) { + return; + } + if (\strncmp($key, '--', \strlen('--')) === 0) { + $this->addLongOption(\substr($key, 2), $value); + } elseif (\strncmp($key, '-', \strlen('-')) === 0) { + $this->addShortOption(\substr($key, 1), $value); + } else { + $this->addArgument($key, $value); + } + } + } + /** + * Adds a short option value. + * + * @throws InvalidOptionException When option given doesn't exist + * @param mixed $value + */ + private function addShortOption(string $shortcut, $value) : void + { + if (!$this->definition->hasShortcut($shortcut)) { + throw new InvalidOptionException(\sprintf('The "-%s" option does not exist.', $shortcut)); + } + $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); + } + /** + * Adds a long option value. + * + * @throws InvalidOptionException When option given doesn't exist + * @throws InvalidOptionException When a required value is missing + * @param mixed $value + */ + private function addLongOption(string $name, $value) : void + { + if (!$this->definition->hasOption($name)) { + if (!$this->definition->hasNegation($name)) { + throw new InvalidOptionException(\sprintf('The "--%s" option does not exist.', $name)); + } + $optionName = $this->definition->negationToName($name); + $this->options[$optionName] = \false; + return; + } + $option = $this->definition->getOption($name); + if (null === $value) { + if ($option->isValueRequired()) { + throw new InvalidOptionException(\sprintf('The "--%s" option requires a value.', $name)); + } + if (!$option->isValueOptional()) { + $value = \true; + } + } + $this->options[$name] = $value; + } + /** + * Adds an argument value. + * + * @throws InvalidArgumentException When argument given doesn't exist + * @param string|int $name + * @param mixed $value + */ + private function addArgument($name, $value) : void + { + if (!$this->definition->hasArgument($name)) { + throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name)); + } + $this->arguments[$name] = $value; + } +} diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php new file mode 100644 index 0000000000..8c0361c532 --- /dev/null +++ b/vendor/symfony/console/Input/Input.php @@ -0,0 +1,173 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +/** + * Input is the base class for all concrete Input classes. + * + * Three concrete classes are provided by default: + * + * * `ArgvInput`: The input comes from the CLI arguments (argv) + * * `StringInput`: The input is provided as a string + * * `ArrayInput`: The input is provided as an array + * + * @author Fabien Potencier + */ +abstract class Input implements InputInterface, StreamableInputInterface +{ + protected $definition; + protected $stream; + protected $options = []; + protected $arguments = []; + protected $interactive = \true; + public function __construct(InputDefinition $definition = null) + { + if (null === $definition) { + $this->definition = new InputDefinition(); + } else { + $this->bind($definition); + $this->validate(); + } + } + /** + * @return void + */ + public function bind(InputDefinition $definition) + { + $this->arguments = []; + $this->options = []; + $this->definition = $definition; + $this->parse(); + } + /** + * Processes command line arguments. + * + * @return void + */ + protected abstract function parse(); + /** + * @return void + */ + public function validate() + { + $definition = $this->definition; + $givenArguments = $this->arguments; + $missingArguments = \array_filter(\array_keys($definition->getArguments()), function ($argument) use($givenArguments, $definition) { + return !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired(); + }); + if (\count($missingArguments) > 0) { + throw new RuntimeException(\sprintf('Not enough arguments (missing: "%s").', \implode(', ', $missingArguments))); + } + } + public function isInteractive() : bool + { + return $this->interactive; + } + /** + * @return void + */ + public function setInteractive(bool $interactive) + { + $this->interactive = $interactive; + } + public function getArguments() : array + { + return \array_merge($this->definition->getArgumentDefaults(), $this->arguments); + } + /** + * @return mixed + */ + public function getArgument(string $name) + { + if (!$this->definition->hasArgument($name)) { + throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name)); + } + return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault(); + } + /** + * @return void + * @param mixed $value + */ + public function setArgument(string $name, $value) + { + if (!$this->definition->hasArgument($name)) { + throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name)); + } + $this->arguments[$name] = $value; + } + public function hasArgument(string $name) : bool + { + return $this->definition->hasArgument($name); + } + public function getOptions() : array + { + return \array_merge($this->definition->getOptionDefaults(), $this->options); + } + /** + * @return mixed + */ + public function getOption(string $name) + { + if ($this->definition->hasNegation($name)) { + if (null === ($value = $this->getOption($this->definition->negationToName($name)))) { + return $value; + } + return !$value; + } + if (!$this->definition->hasOption($name)) { + throw new InvalidArgumentException(\sprintf('The "%s" option does not exist.', $name)); + } + return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault(); + } + /** + * @return void + * @param mixed $value + */ + public function setOption(string $name, $value) + { + if ($this->definition->hasNegation($name)) { + $this->options[$this->definition->negationToName($name)] = !$value; + return; + } elseif (!$this->definition->hasOption($name)) { + throw new InvalidArgumentException(\sprintf('The "%s" option does not exist.', $name)); + } + $this->options[$name] = $value; + } + public function hasOption(string $name) : bool + { + return $this->definition->hasOption($name) || $this->definition->hasNegation($name); + } + /** + * Escapes a token through escapeshellarg if it contains unsafe chars. + */ + public function escapeToken(string $token) : string + { + return \preg_match('{^[\\w-]+$}', $token) ? $token : \escapeshellarg($token); + } + /** + * @param resource $stream + * + * @return void + */ + public function setStream($stream) + { + $this->stream = $stream; + } + /** + * @return resource + */ + public function getStream() + { + return $this->stream; + } +} diff --git a/vendor/symfony/console/Input/InputArgument.php b/vendor/symfony/console/Input/InputArgument.php new file mode 100644 index 0000000000..bd364424a3 --- /dev/null +++ b/vendor/symfony/console/Input/InputArgument.php @@ -0,0 +1,155 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Suggestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +/** + * Represents a command line argument. + * + * @author Fabien Potencier + */ +class InputArgument +{ + public const REQUIRED = 1; + public const OPTIONAL = 2; + public const IS_ARRAY = 4; + /** + * @var string + */ + private $name; + /** + * @var int + */ + private $mode; + /** + * @var string|int|bool|mixed[]|null|float + */ + private $default; + /** + * @var mixed[]|\Closure + */ + private $suggestedValues; + /** + * @var string + */ + private $description; + /** + * @param string $name The argument name + * @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY + * @param string $description A description text + * @param string|bool|int|float|mixed[] $default The default value (for self::OPTIONAL mode only) + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * + * @throws InvalidArgumentException When argument mode is not valid + */ + public function __construct(string $name, int $mode = null, string $description = '', $default = null, $suggestedValues = []) + { + if (null === $mode) { + $mode = self::OPTIONAL; + } elseif ($mode > 7 || $mode < 1) { + throw new InvalidArgumentException(\sprintf('Argument mode "%s" is not valid.', $mode)); + } + $this->name = $name; + $this->mode = $mode; + $this->description = $description; + $this->suggestedValues = $suggestedValues; + $this->setDefault($default); + } + /** + * Returns the argument name. + */ + public function getName() : string + { + return $this->name; + } + /** + * Returns true if the argument is required. + * + * @return bool true if parameter mode is self::REQUIRED, false otherwise + */ + public function isRequired() : bool + { + return self::REQUIRED === (self::REQUIRED & $this->mode); + } + /** + * Returns true if the argument can take multiple values. + * + * @return bool true if mode is self::IS_ARRAY, false otherwise + */ + public function isArray() : bool + { + return self::IS_ARRAY === (self::IS_ARRAY & $this->mode); + } + /** + * Sets the default value. + * + * @return void + * + * @throws LogicException When incorrect default value is given + * @param string|bool|int|float|mixed[] $default + */ + public function setDefault($default = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + if ($this->isRequired() && null !== $default) { + throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); + } + if ($this->isArray()) { + if (null === $default) { + $default = []; + } elseif (!\is_array($default)) { + throw new LogicException('A default value for an array argument must be an array.'); + } + } + $this->default = $default; + } + /** + * Returns the default value. + * @return string|bool|int|float|mixed[]|null + */ + public function getDefault() + { + return $this->default; + } + public function hasCompletion() : bool + { + return [] !== $this->suggestedValues; + } + /** + * Adds suggestions to $suggestions for the current completion input. + * + * @see Command::complete() + */ + public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void + { + $values = $this->suggestedValues; + if ($values instanceof \Closure && !\is_array($values = $values($input))) { + throw new LogicException(\sprintf('Closure for argument "%s" must return an array. Got "%s".', $this->name, \get_debug_type($values))); + } + if ($values) { + $suggestions->suggestValues($values); + } + } + /** + * Returns the description text. + */ + public function getDescription() : string + { + return $this->description; + } +} diff --git a/vendor/symfony/console/Input/InputAwareInterface.php b/vendor/symfony/console/Input/InputAwareInterface.php new file mode 100644 index 0000000000..a8c67623f7 --- /dev/null +++ b/vendor/symfony/console/Input/InputAwareInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +/** + * InputAwareInterface should be implemented by classes that depends on the + * Console Input. + * + * @author Wouter J + */ +interface InputAwareInterface +{ + /** + * Sets the Console Input. + * + * @return void + */ + public function setInput(InputInterface $input); +} diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php new file mode 100644 index 0000000000..43ed7ba889 --- /dev/null +++ b/vendor/symfony/console/Input/InputDefinition.php @@ -0,0 +1,384 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +/** + * A InputDefinition represents a set of valid command line arguments and options. + * + * Usage: + * + * $definition = new InputDefinition([ + * new InputArgument('name', InputArgument::REQUIRED), + * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED), + * ]); + * + * @author Fabien Potencier + */ +class InputDefinition +{ + /** + * @var mixed[] + */ + private $arguments = []; + /** + * @var int + */ + private $requiredCount = 0; + /** + * @var \Symfony\Component\Console\Input\InputArgument|null + */ + private $lastArrayArgument; + /** + * @var \Symfony\Component\Console\Input\InputArgument|null + */ + private $lastOptionalArgument; + /** + * @var mixed[] + */ + private $options = []; + /** + * @var mixed[] + */ + private $negations = []; + /** + * @var mixed[] + */ + private $shortcuts = []; + /** + * @param array $definition An array of InputArgument and InputOption instance + */ + public function __construct(array $definition = []) + { + $this->setDefinition($definition); + } + /** + * Sets the definition of the input. + * + * @return void + */ + public function setDefinition(array $definition) + { + $arguments = []; + $options = []; + foreach ($definition as $item) { + if ($item instanceof InputOption) { + $options[] = $item; + } else { + $arguments[] = $item; + } + } + $this->setArguments($arguments); + $this->setOptions($options); + } + /** + * Sets the InputArgument objects. + * + * @param InputArgument[] $arguments An array of InputArgument objects + * + * @return void + */ + public function setArguments(array $arguments = []) + { + $this->arguments = []; + $this->requiredCount = 0; + $this->lastOptionalArgument = null; + $this->lastArrayArgument = null; + $this->addArguments($arguments); + } + /** + * Adds an array of InputArgument objects. + * + * @param InputArgument[] $arguments An array of InputArgument objects + * + * @return void + */ + public function addArguments(?array $arguments = []) + { + if (null !== $arguments) { + foreach ($arguments as $argument) { + $this->addArgument($argument); + } + } + } + /** + * @return void + * + * @throws LogicException When incorrect argument is given + */ + public function addArgument(InputArgument $argument) + { + if (isset($this->arguments[$argument->getName()])) { + throw new LogicException(\sprintf('An argument with name "%s" already exists.', $argument->getName())); + } + if (null !== $this->lastArrayArgument) { + throw new LogicException(\sprintf('Cannot add a required argument "%s" after an array argument "%s".', $argument->getName(), $this->lastArrayArgument->getName())); + } + if ($argument->isRequired() && null !== $this->lastOptionalArgument) { + throw new LogicException(\sprintf('Cannot add a required argument "%s" after an optional one "%s".', $argument->getName(), $this->lastOptionalArgument->getName())); + } + if ($argument->isArray()) { + $this->lastArrayArgument = $argument; + } + if ($argument->isRequired()) { + ++$this->requiredCount; + } else { + $this->lastOptionalArgument = $argument; + } + $this->arguments[$argument->getName()] = $argument; + } + /** + * Returns an InputArgument by name or by position. + * + * @throws InvalidArgumentException When argument given doesn't exist + * @param string|int $name + */ + public function getArgument($name) : InputArgument + { + if (!$this->hasArgument($name)) { + throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name)); + } + $arguments = \is_int($name) ? \array_values($this->arguments) : $this->arguments; + return $arguments[$name]; + } + /** + * Returns true if an InputArgument object exists by name or position. + * @param string|int $name + */ + public function hasArgument($name) : bool + { + $arguments = \is_int($name) ? \array_values($this->arguments) : $this->arguments; + return isset($arguments[$name]); + } + /** + * Gets the array of InputArgument objects. + * + * @return InputArgument[] + */ + public function getArguments() : array + { + return $this->arguments; + } + /** + * Returns the number of InputArguments. + */ + public function getArgumentCount() : int + { + return null !== $this->lastArrayArgument ? \PHP_INT_MAX : \count($this->arguments); + } + /** + * Returns the number of required InputArguments. + */ + public function getArgumentRequiredCount() : int + { + return $this->requiredCount; + } + /** + * @return array + */ + public function getArgumentDefaults() : array + { + $values = []; + foreach ($this->arguments as $argument) { + $values[$argument->getName()] = $argument->getDefault(); + } + return $values; + } + /** + * Sets the InputOption objects. + * + * @param InputOption[] $options An array of InputOption objects + * + * @return void + */ + public function setOptions(array $options = []) + { + $this->options = []; + $this->shortcuts = []; + $this->negations = []; + $this->addOptions($options); + } + /** + * Adds an array of InputOption objects. + * + * @param InputOption[] $options An array of InputOption objects + * + * @return void + */ + public function addOptions(array $options = []) + { + foreach ($options as $option) { + $this->addOption($option); + } + } + /** + * @return void + * + * @throws LogicException When option given already exist + */ + public function addOption(InputOption $option) + { + if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { + throw new LogicException(\sprintf('An option named "%s" already exists.', $option->getName())); + } + if (isset($this->negations[$option->getName()])) { + throw new LogicException(\sprintf('An option named "%s" already exists.', $option->getName())); + } + if ($option->getShortcut()) { + foreach (\explode('|', $option->getShortcut()) as $shortcut) { + if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) { + throw new LogicException(\sprintf('An option with shortcut "%s" already exists.', $shortcut)); + } + } + } + $this->options[$option->getName()] = $option; + if ($option->getShortcut()) { + foreach (\explode('|', $option->getShortcut()) as $shortcut) { + $this->shortcuts[$shortcut] = $option->getName(); + } + } + if ($option->isNegatable()) { + $negatedName = 'no-' . $option->getName(); + if (isset($this->options[$negatedName])) { + throw new LogicException(\sprintf('An option named "%s" already exists.', $negatedName)); + } + $this->negations[$negatedName] = $option->getName(); + } + } + /** + * Returns an InputOption by name. + * + * @throws InvalidArgumentException When option given doesn't exist + */ + public function getOption(string $name) : InputOption + { + if (!$this->hasOption($name)) { + throw new InvalidArgumentException(\sprintf('The "--%s" option does not exist.', $name)); + } + return $this->options[$name]; + } + /** + * Returns true if an InputOption object exists by name. + * + * This method can't be used to check if the user included the option when + * executing the command (use getOption() instead). + */ + public function hasOption(string $name) : bool + { + return isset($this->options[$name]); + } + /** + * Gets the array of InputOption objects. + * + * @return InputOption[] + */ + public function getOptions() : array + { + return $this->options; + } + /** + * Returns true if an InputOption object exists by shortcut. + */ + public function hasShortcut(string $name) : bool + { + return isset($this->shortcuts[$name]); + } + /** + * Returns true if an InputOption object exists by negated name. + */ + public function hasNegation(string $name) : bool + { + return isset($this->negations[$name]); + } + /** + * Gets an InputOption by shortcut. + */ + public function getOptionForShortcut(string $shortcut) : InputOption + { + return $this->getOption($this->shortcutToName($shortcut)); + } + /** + * @return array + */ + public function getOptionDefaults() : array + { + $values = []; + foreach ($this->options as $option) { + $values[$option->getName()] = $option->getDefault(); + } + return $values; + } + /** + * Returns the InputOption name given a shortcut. + * + * @throws InvalidArgumentException When option given does not exist + * + * @internal + */ + public function shortcutToName(string $shortcut) : string + { + if (!isset($this->shortcuts[$shortcut])) { + throw new InvalidArgumentException(\sprintf('The "-%s" option does not exist.', $shortcut)); + } + return $this->shortcuts[$shortcut]; + } + /** + * Returns the InputOption name given a negation. + * + * @throws InvalidArgumentException When option given does not exist + * + * @internal + */ + public function negationToName(string $negation) : string + { + if (!isset($this->negations[$negation])) { + throw new InvalidArgumentException(\sprintf('The "--%s" option does not exist.', $negation)); + } + return $this->negations[$negation]; + } + /** + * Gets the synopsis. + */ + public function getSynopsis(bool $short = \false) : string + { + $elements = []; + if ($short && $this->getOptions()) { + $elements[] = '[options]'; + } elseif (!$short) { + foreach ($this->getOptions() as $option) { + $value = ''; + if ($option->acceptValue()) { + $value = \sprintf(' %s%s%s', $option->isValueOptional() ? '[' : '', \strtoupper($option->getName()), $option->isValueOptional() ? ']' : ''); + } + $shortcut = $option->getShortcut() ? \sprintf('-%s|', $option->getShortcut()) : ''; + $negation = $option->isNegatable() ? \sprintf('|--no-%s', $option->getName()) : ''; + $elements[] = \sprintf('[%s--%s%s%s]', $shortcut, $option->getName(), $value, $negation); + } + } + if (\count($elements) && $this->getArguments()) { + $elements[] = '[--]'; + } + $tail = ''; + foreach ($this->getArguments() as $argument) { + $element = '<' . $argument->getName() . '>'; + if ($argument->isArray()) { + $element .= '...'; + } + if (!$argument->isRequired()) { + $element = '[' . $element; + $tail .= ']'; + } + $elements[] = $element; + } + return \implode(' ', $elements) . $tail; + } +} diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php new file mode 100644 index 0000000000..9e93062a2c --- /dev/null +++ b/vendor/symfony/console/Input/InputInterface.php @@ -0,0 +1,136 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +/** + * InputInterface is the interface implemented by all input classes. + * + * @author Fabien Potencier + * + * @method string __toString() Returns a stringified representation of the args passed to the command. + * InputArguments MUST be escaped as well as the InputOption values passed to the command. + */ +interface InputInterface +{ + /** + * Returns the first argument from the raw parameters (not parsed). + */ + public function getFirstArgument() : ?string; + /** + * Returns true if the raw parameters (not parsed) contain a value. + * + * This method is to be used to introspect the input parameters + * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. + * + * @param string|array $values The values to look for in the raw parameters (can be an array) + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal + */ + public function hasParameterOption($values, bool $onlyParams = \false) : bool; + /** + * Returns the value of a raw option (not parsed). + * + * This method is to be used to introspect the input parameters + * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. + * + * @param string|array $values The value(s) to look for in the raw parameters (can be an array) + * @param string|bool|int|float|array|null $default The default value to return if no result is found + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal + * + * @return mixed + */ + public function getParameterOption($values, $default = \false, bool $onlyParams = \false); + /** + * Binds the current Input instance with the given arguments and options. + * + * @return void + * + * @throws RuntimeException + */ + public function bind(InputDefinition $definition); + /** + * Validates the input. + * + * @return void + * + * @throws RuntimeException When not enough arguments are given + */ + public function validate(); + /** + * Returns all the given arguments merged with the default values. + * + * @return array + */ + public function getArguments() : array; + /** + * Returns the argument value for a given argument name. + * + * @return mixed + * + * @throws InvalidArgumentException When argument given doesn't exist + */ + public function getArgument(string $name); + /** + * Sets an argument value by name. + * + * @return void + * + * @throws InvalidArgumentException When argument given doesn't exist + * @param mixed $value + */ + public function setArgument(string $name, $value); + /** + * Returns true if an InputArgument object exists by name or position. + */ + public function hasArgument(string $name) : bool; + /** + * Returns all the given options merged with the default values. + * + * @return array + */ + public function getOptions() : array; + /** + * Returns the option value for a given option name. + * + * @return mixed + * + * @throws InvalidArgumentException When option given doesn't exist + */ + public function getOption(string $name); + /** + * Sets an option value by name. + * + * @return void + * + * @throws InvalidArgumentException When option given doesn't exist + * @param mixed $value + */ + public function setOption(string $name, $value); + /** + * Returns true if an InputOption object exists by name. + */ + public function hasOption(string $name) : bool; + /** + * Is this input means interactive? + */ + public function isInteractive() : bool; + /** + * Sets the input interactivity. + * + * @return void + */ + public function setInteractive(bool $interactive); +} diff --git a/vendor/symfony/console/Input/InputOption.php b/vendor/symfony/console/Input/InputOption.php new file mode 100644 index 0000000000..27bd941ff8 --- /dev/null +++ b/vendor/symfony/console/Input/InputOption.php @@ -0,0 +1,237 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\Suggestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +/** + * Represents a command line option. + * + * @author Fabien Potencier + */ +class InputOption +{ + /** + * Do not accept input for the option (e.g. --yell). This is the default behavior of options. + */ + public const VALUE_NONE = 1; + /** + * A value must be passed when the option is used (e.g. --iterations=5 or -i5). + */ + public const VALUE_REQUIRED = 2; + /** + * The option may or may not have a value (e.g. --yell or --yell=loud). + */ + public const VALUE_OPTIONAL = 4; + /** + * The option accepts multiple values (e.g. --dir=/foo --dir=/bar). + */ + public const VALUE_IS_ARRAY = 8; + /** + * The option may have either positive or negative value (e.g. --ansi or --no-ansi). + */ + public const VALUE_NEGATABLE = 16; + /** + * @var string + */ + private $name; + /** + * @var string|mixed[]|null + */ + private $shortcut; + /** + * @var int + */ + private $mode; + /** + * @var string|int|bool|mixed[]|null|float + */ + private $default; + /** + * @var mixed[]|\Closure + */ + private $suggestedValues; + /** + * @var string + */ + private $description; + /** + * @param string|mixed[] $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the VALUE_* constants + * @param string|bool|int|float|mixed[] $default The default value (must be null for self::VALUE_NONE) + * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion + * + * @throws InvalidArgumentException If option mode is invalid or incompatible + */ + public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null, $suggestedValues = []) + { + if (\strncmp($name, '--', \strlen('--')) === 0) { + $name = \substr($name, 2); + } + if (empty($name)) { + throw new InvalidArgumentException('An option name cannot be empty.'); + } + if (empty($shortcut)) { + $shortcut = null; + } + if (null !== $shortcut) { + if (\is_array($shortcut)) { + $shortcut = \implode('|', $shortcut); + } + $shortcuts = \preg_split('{(\\|)-?}', \ltrim($shortcut, '-')); + $shortcuts = \array_filter($shortcuts); + $shortcut = \implode('|', $shortcuts); + if (empty($shortcut)) { + throw new InvalidArgumentException('An option shortcut cannot be empty.'); + } + } + if (null === $mode) { + $mode = self::VALUE_NONE; + } elseif ($mode >= self::VALUE_NEGATABLE << 1 || $mode < 1) { + throw new InvalidArgumentException(\sprintf('Option mode "%s" is not valid.', $mode)); + } + $this->name = $name; + $this->shortcut = $shortcut; + $this->mode = $mode; + $this->description = $description; + $this->suggestedValues = $suggestedValues; + if ($suggestedValues && !$this->acceptValue()) { + throw new LogicException('Cannot set suggested values if the option does not accept a value.'); + } + if ($this->isArray() && !$this->acceptValue()) { + throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.'); + } + if ($this->isNegatable() && $this->acceptValue()) { + throw new InvalidArgumentException('Impossible to have an option mode VALUE_NEGATABLE if the option also accepts a value.'); + } + $this->setDefault($default); + } + /** + * Returns the option shortcut. + */ + public function getShortcut() : ?string + { + return $this->shortcut; + } + /** + * Returns the option name. + */ + public function getName() : string + { + return $this->name; + } + /** + * Returns true if the option accepts a value. + * + * @return bool true if value mode is not self::VALUE_NONE, false otherwise + */ + public function acceptValue() : bool + { + return $this->isValueRequired() || $this->isValueOptional(); + } + /** + * Returns true if the option requires a value. + * + * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise + */ + public function isValueRequired() : bool + { + return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode); + } + /** + * Returns true if the option takes an optional value. + * + * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise + */ + public function isValueOptional() : bool + { + return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode); + } + /** + * Returns true if the option can take multiple values. + * + * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise + */ + public function isArray() : bool + { + return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); + } + public function isNegatable() : bool + { + return self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode); + } + /** + * @return void + * @param string|bool|int|float|mixed[] $default + */ + public function setDefault($default = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { + throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); + } + if ($this->isArray()) { + if (null === $default) { + $default = []; + } elseif (!\is_array($default)) { + throw new LogicException('A default value for an array option must be an array.'); + } + } + $this->default = $this->acceptValue() || $this->isNegatable() ? $default : \false; + } + /** + * Returns the default value. + * @return string|bool|int|float|mixed[]|null + */ + public function getDefault() + { + return $this->default; + } + /** + * Returns the description text. + */ + public function getDescription() : string + { + return $this->description; + } + public function hasCompletion() : bool + { + return [] !== $this->suggestedValues; + } + /** + * Adds suggestions to $suggestions for the current completion input. + * + * @see Command::complete() + */ + public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void + { + $values = $this->suggestedValues; + if ($values instanceof \Closure && !\is_array($values = $values($input))) { + throw new LogicException(\sprintf('Closure for option "%s" must return an array. Got "%s".', $this->name, \get_debug_type($values))); + } + if ($values) { + $suggestions->suggestValues($values); + } + } + /** + * Checks whether the given option equals this one. + */ + public function equals(self $option) : bool + { + return $option->getName() === $this->getName() && $option->getShortcut() === $this->getShortcut() && $option->getDefault() === $this->getDefault() && $option->isNegatable() === $this->isNegatable() && $option->isArray() === $this->isArray() && $option->isValueRequired() === $this->isValueRequired() && $option->isValueOptional() === $this->isValueOptional(); + } +} diff --git a/vendor/symfony/console/Input/StreamableInputInterface.php b/vendor/symfony/console/Input/StreamableInputInterface.php new file mode 100644 index 0000000000..db6103036d --- /dev/null +++ b/vendor/symfony/console/Input/StreamableInputInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +/** + * StreamableInputInterface is the interface implemented by all input classes + * that have an input stream. + * + * @author Robin Chalas + */ +interface StreamableInputInterface extends InputInterface +{ + /** + * Sets the input stream to read from when interacting with the user. + * + * This is mainly useful for testing purpose. + * + * @param resource $stream The input stream + * + * @return void + */ + public function setStream($stream); + /** + * Returns the input stream. + * + * @return resource|null + */ + public function getStream(); +} diff --git a/vendor/symfony/console/Input/StringInput.php b/vendor/symfony/console/Input/StringInput.php new file mode 100644 index 0000000000..10583e855b --- /dev/null +++ b/vendor/symfony/console/Input/StringInput.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Input; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +/** + * StringInput represents an input provided as a string. + * + * Usage: + * + * $input = new StringInput('foo --bar="foobar"'); + * + * @author Fabien Potencier + */ +class StringInput extends ArgvInput +{ + /** + * @deprecated since Symfony 6.1 + */ + public const REGEX_STRING = '([^\\s]+?)(?:\\s|(?setTokens($this->tokenize($input)); + } + /** + * Tokenizes a string. + * + * @throws InvalidArgumentException When unable to parse input (should never happen) + */ + private function tokenize(string $input) : array + { + $tokens = []; + $length = \strlen($input); + $cursor = 0; + $token = null; + while ($cursor < $length) { + if ('\\' === $input[$cursor]) { + $token .= $input[++$cursor] ?? ''; + ++$cursor; + continue; + } + if (\preg_match('/\\s+/A', $input, $match, 0, $cursor)) { + if (null !== $token) { + $tokens[] = $token; + $token = null; + } + } elseif (\preg_match('/([^="\'\\s]+?)(=?)(' . self::REGEX_QUOTED_STRING . '+)/A', $input, $match, 0, $cursor)) { + $token .= $match[1] . $match[2] . \stripcslashes(\str_replace(['"\'', '\'"', '\'\'', '""'], '', \substr($match[3], 1, -1))); + } elseif (\preg_match('/' . self::REGEX_QUOTED_STRING . '/A', $input, $match, 0, $cursor)) { + $token .= \stripcslashes(\substr($match[0], 1, -1)); + } elseif (\preg_match('/' . self::REGEX_UNQUOTED_STRING . '/A', $input, $match, 0, $cursor)) { + $token .= $match[1]; + } else { + // should never happen + throw new InvalidArgumentException(\sprintf('Unable to parse input near "... %s ...".', \substr($input, $cursor, 10))); + } + $cursor += \strlen($match[0]); + } + if (null !== $token) { + $tokens[] = $token; + } + return $tokens; + } +} diff --git a/vendor/symfony/console/LICENSE b/vendor/symfony/console/LICENSE new file mode 100644 index 0000000000..0138f8f071 --- /dev/null +++ b/vendor/symfony/console/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/console/Logger/ConsoleLogger.php b/vendor/symfony/console/Logger/ConsoleLogger.php new file mode 100644 index 0000000000..20fb68b097 --- /dev/null +++ b/vendor/symfony/console/Logger/ConsoleLogger.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Logger; + +use MonorepoBuilderPrefix202310\Psr\Log\AbstractLogger; +use MonorepoBuilderPrefix202310\Psr\Log\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Psr\Log\LogLevel; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * PSR-3 compliant console logger. + * + * @author Kévin Dunglas + * + * @see https://www.php-fig.org/psr/psr-3/ + */ +class ConsoleLogger extends AbstractLogger +{ + public const INFO = 'info'; + public const ERROR = 'error'; + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + /** + * @var mixed[] + */ + private $verbosityLevelMap = [LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL, LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL, LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL, LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL, LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL, LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE, LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE, LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG]; + /** + * @var mixed[] + */ + private $formatLevelMap = [LogLevel::EMERGENCY => self::ERROR, LogLevel::ALERT => self::ERROR, LogLevel::CRITICAL => self::ERROR, LogLevel::ERROR => self::ERROR, LogLevel::WARNING => self::INFO, LogLevel::NOTICE => self::INFO, LogLevel::INFO => self::INFO, LogLevel::DEBUG => self::INFO]; + /** + * @var bool + */ + private $errored = \false; + public function __construct(OutputInterface $output, array $verbosityLevelMap = [], array $formatLevelMap = []) + { + $this->output = $output; + $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap; + $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap; + } + public function log($level, $message, array $context = []) : void + { + if (!isset($this->verbosityLevelMap[$level])) { + throw new InvalidArgumentException(\sprintf('The log level "%s" does not exist.', $level)); + } + $output = $this->output; + // Write to the error output if necessary and available + if (self::ERROR === $this->formatLevelMap[$level]) { + if ($this->output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $this->errored = \true; + } + // the if condition check isn't necessary -- it's the same one that $output will do internally anyway. + // We only do it for efficiency here as the message formatting is relatively expensive. + if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) { + $output->writeln(\sprintf('<%1$s>[%2$s] %3$s', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)), $this->verbosityLevelMap[$level]); + } + } + /** + * Returns true when any messages have been logged at error levels. + */ + public function hasErrored() : bool + { + return $this->errored; + } + /** + * Interpolates context values into the message placeholders. + * + * @author PHP Framework Interoperability Group + */ + private function interpolate(string $message, array $context) : string + { + if (\strpos($message, '{') === \false) { + return $message; + } + $replacements = []; + foreach ($context as $key => $val) { + if (null === $val || \is_scalar($val) || $val instanceof \Stringable) { + $replacements["{{$key}}"] = $val; + } elseif ($val instanceof \DateTimeInterface) { + $replacements["{{$key}}"] = $val->format(\DateTimeInterface::RFC3339); + } elseif (\is_object($val)) { + $replacements["{{$key}}"] = '[object ' . \get_class($val) . ']'; + } else { + $replacements["{{$key}}"] = '[' . \gettype($val) . ']'; + } + } + return \strtr($message, $replacements); + } +} diff --git a/vendor/symfony/console/Output/AnsiColorMode.php b/vendor/symfony/console/Output/AnsiColorMode.php new file mode 100644 index 0000000000..34998ea557 --- /dev/null +++ b/vendor/symfony/console/Output/AnsiColorMode.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +class AnsiColorMode +{ + public const Ansi4 = 'ansi4'; + public const Ansi8 = 'ansi8'; + public const Ansi24 = 'ansi24'; + /** + * Converts an RGB hexadecimal color to the corresponding Ansi code. + */ + public function convertFromHexToAnsiColorCode(string $hexColor) : string + { + $hexColor = \str_replace('#', '', $hexColor); + if (3 === \strlen($hexColor)) { + $hexColor = $hexColor[0] . $hexColor[0] . $hexColor[1] . $hexColor[1] . $hexColor[2] . $hexColor[2]; + } + if (6 !== \strlen($hexColor)) { + throw new InvalidArgumentException(\sprintf('Invalid "#%s" color.', $hexColor)); + } + $color = \hexdec($hexColor); + $r = $color >> 16 & 255; + $g = $color >> 8 & 255; + $b = $color & 255; + switch ($this) { + case self::Ansi4: + return (string) $this->convertFromRGB($r, $g, $b); + case self::Ansi8: + return '8;5;' . (string) $this->convertFromRGB($r, $g, $b); + case self::Ansi24: + return \sprintf('8;2;%d;%d;%d', $r, $g, $b); + } + } + private function convertFromRGB(int $r, int $g, int $b) : int + { + switch ($this) { + case self::Ansi4: + return $this->degradeHexColorToAnsi4($r, $g, $b); + case self::Ansi8: + return $this->degradeHexColorToAnsi8($r, $g, $b); + default: + throw new InvalidArgumentException("RGB cannot be converted to {$this->name}."); + } + } + private function degradeHexColorToAnsi4(int $r, int $g, int $b) : int + { + return \round($b / 255) << 2 | \round($g / 255) << 1 | \round($r / 255); + } + /** + * Inspired from https://github.com/ajalt/colormath/blob/e464e0da1b014976736cf97250063248fc77b8e7/colormath/src/commonMain/kotlin/com/github/ajalt/colormath/model/Ansi256.kt code (MIT license). + */ + private function degradeHexColorToAnsi8(int $r, int $g, int $b) : int + { + if ($r === $g && $g === $b) { + if ($r < 8) { + return 16; + } + if ($r > 248) { + return 231; + } + return (int) \round(($r - 8) / 247 * 24) + 232; + } else { + return 16 + 36 * (int) \round($r / 255 * 5) + 6 * (int) \round($g / 255 * 5) + (int) \round($b / 255 * 5); + } + } +} diff --git a/vendor/symfony/console/Output/BufferedOutput.php b/vendor/symfony/console/Output/BufferedOutput.php new file mode 100644 index 0000000000..903a5e22f8 --- /dev/null +++ b/vendor/symfony/console/Output/BufferedOutput.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +/** + * @author Jean-François Simon + */ +class BufferedOutput extends Output +{ + /** + * @var string + */ + private $buffer = ''; + /** + * Empties buffer and returns its content. + */ + public function fetch() : string + { + $content = $this->buffer; + $this->buffer = ''; + return $content; + } + /** + * @return void + */ + protected function doWrite(string $message, bool $newline) + { + $this->buffer .= $message; + if ($newline) { + $this->buffer .= \PHP_EOL; + } + } +} diff --git a/vendor/symfony/console/Output/ConsoleOutput.php b/vendor/symfony/console/Output/ConsoleOutput.php new file mode 100644 index 0000000000..8ad323288c --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleOutput.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +/** + * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR. + * + * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR. + * + * $output = new ConsoleOutput(); + * + * This is equivalent to: + * + * $output = new StreamOutput(fopen('php://stdout', 'w')); + * $stdErr = new StreamOutput(fopen('php://stderr', 'w')); + * + * @author Fabien Potencier + */ +class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface +{ + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $stderr; + /** + * @var mixed[] + */ + private $consoleSectionOutputs = []; + /** + * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) + * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) + * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) + */ + public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null) + { + parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter); + if (null === $formatter) { + // for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter. + $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated); + return; + } + $actualDecorated = $this->isDecorated(); + $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter()); + if (null === $decorated) { + $this->setDecorated($actualDecorated && $this->stderr->isDecorated()); + } + } + /** + * Creates a new output section. + */ + public function section() : ConsoleSectionOutput + { + return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter()); + } + /** + * @return void + */ + public function setDecorated(bool $decorated) + { + parent::setDecorated($decorated); + $this->stderr->setDecorated($decorated); + } + /** + * @return void + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + parent::setFormatter($formatter); + $this->stderr->setFormatter($formatter); + } + /** + * @return void + */ + public function setVerbosity(int $level) + { + parent::setVerbosity($level); + $this->stderr->setVerbosity($level); + } + public function getErrorOutput() : OutputInterface + { + return $this->stderr; + } + /** + * @return void + */ + public function setErrorOutput(OutputInterface $error) + { + $this->stderr = $error; + } + /** + * Returns true if current environment supports writing console output to + * STDOUT. + */ + protected function hasStdoutSupport() : bool + { + return \false === $this->isRunningOS400(); + } + /** + * Returns true if current environment supports writing console output to + * STDERR. + */ + protected function hasStderrSupport() : bool + { + return \false === $this->isRunningOS400(); + } + /** + * Checks if current executing environment is IBM iSeries (OS400), which + * doesn't properly convert character-encodings between ASCII to EBCDIC. + */ + private function isRunningOS400() : bool + { + $checks = [\function_exists('php_uname') ? \php_uname('s') : '', \getenv('OSTYPE'), \PHP_OS]; + return \false !== \stripos(\implode(';', $checks), 'OS400'); + } + /** + * @return resource + */ + private function openOutputStream() + { + if (!$this->hasStdoutSupport()) { + return \fopen('php://output', 'w'); + } + // Use STDOUT when possible to prevent from opening too many file descriptors + return \defined('STDOUT') ? \STDOUT : (@\fopen('php://stdout', 'w') ?: \fopen('php://output', 'w')); + } + /** + * @return resource + */ + private function openErrorStream() + { + if (!$this->hasStderrSupport()) { + return \fopen('php://output', 'w'); + } + // Use STDERR when possible to prevent from opening too many file descriptors + return \defined('STDERR') ? \STDERR : (@\fopen('php://stderr', 'w') ?: \fopen('php://output', 'w')); + } +} diff --git a/vendor/symfony/console/Output/ConsoleOutputInterface.php b/vendor/symfony/console/Output/ConsoleOutputInterface.php new file mode 100644 index 0000000000..a3cf2e94f6 --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleOutputInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +/** + * ConsoleOutputInterface is the interface implemented by ConsoleOutput class. + * This adds information about stderr and section output stream. + * + * @author Dariusz Górecki + */ +interface ConsoleOutputInterface extends OutputInterface +{ + /** + * Gets the OutputInterface for errors. + */ + public function getErrorOutput() : OutputInterface; + /** + * @return void + */ + public function setErrorOutput(OutputInterface $error); + public function section() : ConsoleSectionOutput; +} diff --git a/vendor/symfony/console/Output/ConsoleSectionOutput.php b/vendor/symfony/console/Output/ConsoleSectionOutput.php new file mode 100644 index 0000000000..f4c2cdbacd --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleSectionOutput.php @@ -0,0 +1,222 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\Helper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Terminal; +/** + * @author Pierre du Plessis + * @author Gabriel Ostrolucký + */ +class ConsoleSectionOutput extends StreamOutput +{ + /** + * @var mixed[] + */ + private $content = []; + /** + * @var int + */ + private $lines = 0; + /** + * @var mixed[] + */ + private $sections; + /** + * @var \Symfony\Component\Console\Terminal + */ + private $terminal; + /** + * @var int + */ + private $maxHeight = 0; + /** + * @param resource $stream + * @param ConsoleSectionOutput[] $sections + */ + public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter) + { + parent::__construct($stream, $verbosity, $decorated, $formatter); + \array_unshift($sections, $this); + $this->sections =& $sections; + $this->terminal = new Terminal(); + } + /** + * Defines a maximum number of lines for this section. + * + * When more lines are added, the section will automatically scroll to the + * end (i.e. remove the first lines to comply with the max height). + */ + public function setMaxHeight(int $maxHeight) : void + { + // when changing max height, clear output of current section and redraw again with the new height + $previousMaxHeight = $this->maxHeight; + $this->maxHeight = $maxHeight; + $existingContent = $this->popStreamContentUntilCurrentSection($previousMaxHeight ? \min($previousMaxHeight, $this->lines) : $this->lines); + parent::doWrite($this->getVisibleContent(), \false); + parent::doWrite($existingContent, \false); + } + /** + * Clears previous output for this section. + * + * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared + * + * @return void + */ + public function clear(int $lines = null) + { + if (empty($this->content) || !$this->isDecorated()) { + return; + } + if ($lines) { + \array_splice($this->content, -$lines); + } else { + $lines = $this->lines; + $this->content = []; + } + $this->lines -= $lines; + parent::doWrite($this->popStreamContentUntilCurrentSection($this->maxHeight ? \min($this->maxHeight, $lines) : $lines), \false); + } + /** + * Overwrites the previous output with a new message. + * + * @return void + * @param string|iterable $message + */ + public function overwrite($message) + { + $this->clear(); + $this->writeln($message); + } + public function getContent() : string + { + return \implode('', $this->content); + } + public function getVisibleContent() : string + { + if (0 === $this->maxHeight) { + return $this->getContent(); + } + return \implode('', \array_slice($this->content, -$this->maxHeight)); + } + /** + * @internal + */ + public function addContent(string $input, bool $newline = \true) : int + { + $width = $this->terminal->getWidth(); + $lines = \explode(\PHP_EOL, $input); + $linesAdded = 0; + $count = \count($lines) - 1; + foreach ($lines as $i => $lineContent) { + // re-add the line break (that has been removed in the above `explode()` for + // - every line that is not the last line + // - if $newline is required, also add it to the last line + if ($i < $count || $newline) { + $lineContent .= \PHP_EOL; + } + // skip line if there is no text (or newline for that matter) + if ('' === $lineContent) { + continue; + } + // For the first line, check if the previous line (last entry of `$this->content`) + // needs to be continued (i.e. does not end with a line break). + if (0 === $i && \false !== ($lastLine = \end($this->content)) && \substr_compare($lastLine, \PHP_EOL, -\strlen(\PHP_EOL)) !== 0) { + // deduct the line count of the previous line + $this->lines -= (int) \ceil($this->getDisplayLength($lastLine) / $width) ?: 1; + // concatenate previous and new line + $lineContent = $lastLine . $lineContent; + // replace last entry of `$this->content` with the new expanded line + \array_splice($this->content, -1, 1, $lineContent); + } else { + // otherwise just add the new content + $this->content[] = $lineContent; + } + $linesAdded += (int) \ceil($this->getDisplayLength($lineContent) / $width) ?: 1; + } + $this->lines += $linesAdded; + return $linesAdded; + } + /** + * @internal + */ + public function addNewLineOfInputSubmit() : void + { + $this->content[] = \PHP_EOL; + ++$this->lines; + } + /** + * @return void + */ + protected function doWrite(string $message, bool $newline) + { + // Simulate newline behavior for consistent output formatting, avoiding extra logic + if (!$newline && \substr_compare($message, \PHP_EOL, -\strlen(\PHP_EOL)) === 0) { + $message = \substr($message, 0, -\strlen(\PHP_EOL)); + $newline = \true; + } + if (!$this->isDecorated()) { + parent::doWrite($message, $newline); + return; + } + // Check if the previous line (last entry of `$this->content`) needs to be continued + // (i.e. does not end with a line break). In which case, it needs to be erased first. + $linesToClear = $deleteLastLine = ($lastLine = \end($this->content) ?: '') && \substr_compare($lastLine, \PHP_EOL, -\strlen(\PHP_EOL)) !== 0 ? 1 : 0; + $linesAdded = $this->addContent($message, $newline); + if ($lineOverflow = $this->maxHeight > 0 && $this->lines > $this->maxHeight) { + // on overflow, clear the whole section and redraw again (to remove the first lines) + $linesToClear = $this->maxHeight; + } + $erasedContent = $this->popStreamContentUntilCurrentSection($linesToClear); + if ($lineOverflow) { + // redraw existing lines of the section + $previousLinesOfSection = \array_slice($this->content, $this->lines - $this->maxHeight, $this->maxHeight - $linesAdded); + parent::doWrite(\implode('', $previousLinesOfSection), \false); + } + // if the last line was removed, re-print its content together with the new content. + // otherwise, just print the new content. + parent::doWrite($deleteLastLine ? $lastLine . $message : $message, \true); + parent::doWrite($erasedContent, \false); + } + /** + * At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits + * current section. Then it erases content it crawled through. Optionally, it erases part of current section too. + */ + private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0) : string + { + $numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection; + $erasedContent = []; + foreach ($this->sections as $section) { + if ($section === $this) { + break; + } + $numberOfLinesToClear += $section->maxHeight ? \min($section->lines, $section->maxHeight) : $section->lines; + if ('' !== ($sectionContent = $section->getVisibleContent())) { + if (\substr_compare($sectionContent, \PHP_EOL, -\strlen(\PHP_EOL)) !== 0) { + $sectionContent .= \PHP_EOL; + } + $erasedContent[] = $sectionContent; + } + } + if ($numberOfLinesToClear > 0) { + // move cursor up n lines + parent::doWrite(\sprintf("\x1b[%dA", $numberOfLinesToClear), \false); + // erase to end of screen + parent::doWrite("\x1b[0J", \false); + } + return \implode('', \array_reverse($erasedContent)); + } + private function getDisplayLength(string $text) : int + { + return Helper::width(Helper::removeDecoration($this->getFormatter(), \str_replace("\t", ' ', $text))); + } +} diff --git a/vendor/symfony/console/Output/NullOutput.php b/vendor/symfony/console/Output/NullOutput.php new file mode 100644 index 0000000000..779f140752 --- /dev/null +++ b/vendor/symfony/console/Output/NullOutput.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\NullOutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +/** + * NullOutput suppresses all output. + * + * $output = new NullOutput(); + * + * @author Fabien Potencier + * @author Tobias Schultze + */ +class NullOutput implements OutputInterface +{ + /** + * @var \Symfony\Component\Console\Formatter\NullOutputFormatter + */ + private $formatter; + /** + * @return void + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + // do nothing + } + public function getFormatter() : OutputFormatterInterface + { + // to comply with the interface we must return a OutputFormatterInterface + return $this->formatter = $this->formatter ?? new NullOutputFormatter(); + } + /** + * @return void + */ + public function setDecorated(bool $decorated) + { + // do nothing + } + public function isDecorated() : bool + { + return \false; + } + /** + * @return void + */ + public function setVerbosity(int $level) + { + // do nothing + } + public function getVerbosity() : int + { + return self::VERBOSITY_QUIET; + } + public function isQuiet() : bool + { + return \true; + } + public function isVerbose() : bool + { + return \false; + } + public function isVeryVerbose() : bool + { + return \false; + } + public function isDebug() : bool + { + return \false; + } + /** + * @return void + * @param string|iterable $messages + */ + public function writeln($messages, int $options = self::OUTPUT_NORMAL) + { + // do nothing + } + /** + * @return void + * @param string|iterable $messages + */ + public function write($messages, bool $newline = \false, int $options = self::OUTPUT_NORMAL) + { + // do nothing + } +} diff --git a/vendor/symfony/console/Output/Output.php b/vendor/symfony/console/Output/Output.php new file mode 100644 index 0000000000..890061c3d3 --- /dev/null +++ b/vendor/symfony/console/Output/Output.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +/** + * Base class for output classes. + * + * There are five levels of verbosity: + * + * * normal: no option passed (normal output) + * * verbose: -v (more output) + * * very verbose: -vv (highly extended output) + * * debug: -vvv (all debug output) + * * quiet: -q (no output) + * + * @author Fabien Potencier + */ +abstract class Output implements OutputInterface +{ + /** + * @var int + */ + private $verbosity; + /** + * @var \Symfony\Component\Console\Formatter\OutputFormatterInterface + */ + private $formatter; + /** + * @param int|null $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) + * @param bool $decorated Whether to decorate messages + * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) + */ + public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = \false, OutputFormatterInterface $formatter = null) + { + $this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL; + $this->formatter = $formatter ?? new OutputFormatter(); + $this->formatter->setDecorated($decorated); + } + /** + * @return void + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + $this->formatter = $formatter; + } + public function getFormatter() : OutputFormatterInterface + { + return $this->formatter; + } + /** + * @return void + */ + public function setDecorated(bool $decorated) + { + $this->formatter->setDecorated($decorated); + } + public function isDecorated() : bool + { + return $this->formatter->isDecorated(); + } + /** + * @return void + */ + public function setVerbosity(int $level) + { + $this->verbosity = $level; + } + public function getVerbosity() : int + { + return $this->verbosity; + } + public function isQuiet() : bool + { + return self::VERBOSITY_QUIET === $this->verbosity; + } + public function isVerbose() : bool + { + return self::VERBOSITY_VERBOSE <= $this->verbosity; + } + public function isVeryVerbose() : bool + { + return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; + } + public function isDebug() : bool + { + return self::VERBOSITY_DEBUG <= $this->verbosity; + } + /** + * @return void + * @param string|iterable $messages + */ + public function writeln($messages, int $options = self::OUTPUT_NORMAL) + { + $this->write($messages, \true, $options); + } + /** + * @return void + * @param string|iterable $messages + */ + public function write($messages, bool $newline = \false, int $options = self::OUTPUT_NORMAL) + { + if (!\is_iterable($messages)) { + $messages = [$messages]; + } + $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN; + $type = $types & $options ?: self::OUTPUT_NORMAL; + $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG; + $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL; + if ($verbosity > $this->getVerbosity()) { + return; + } + foreach ($messages as $message) { + switch ($type) { + case OutputInterface::OUTPUT_NORMAL: + $message = $this->formatter->format($message); + break; + case OutputInterface::OUTPUT_RAW: + break; + case OutputInterface::OUTPUT_PLAIN: + $message = \strip_tags($this->formatter->format($message)); + break; + } + $this->doWrite($message ?? '', $newline); + } + } + /** + * Writes a message to the output. + * + * @return void + */ + protected abstract function doWrite(string $message, bool $newline); +} diff --git a/vendor/symfony/console/Output/OutputInterface.php b/vendor/symfony/console/Output/OutputInterface.php new file mode 100644 index 0000000000..7e543bfbc2 --- /dev/null +++ b/vendor/symfony/console/Output/OutputInterface.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +/** + * OutputInterface is the interface implemented by all Output classes. + * + * @author Fabien Potencier + */ +interface OutputInterface +{ + public const VERBOSITY_QUIET = 16; + public const VERBOSITY_NORMAL = 32; + public const VERBOSITY_VERBOSE = 64; + public const VERBOSITY_VERY_VERBOSE = 128; + public const VERBOSITY_DEBUG = 256; + public const OUTPUT_NORMAL = 1; + public const OUTPUT_RAW = 2; + public const OUTPUT_PLAIN = 4; + /** + * Writes a message to the output. + * + * @param bool $newline Whether to add a newline + * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), + * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL + * + * @return void + * @param string|iterable $messages + */ + public function write($messages, bool $newline = \false, int $options = 0); + /** + * Writes a message to the output and adds a newline at the end. + * + * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), + * 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL + * + * @return void + * @param string|iterable $messages + */ + public function writeln($messages, int $options = 0); + /** + * Sets the verbosity of the output. + * + * @return void + */ + public function setVerbosity(int $level); + /** + * Gets the current verbosity of the output. + */ + public function getVerbosity() : int; + /** + * Returns whether verbosity is quiet (-q). + */ + public function isQuiet() : bool; + /** + * Returns whether verbosity is verbose (-v). + */ + public function isVerbose() : bool; + /** + * Returns whether verbosity is very verbose (-vv). + */ + public function isVeryVerbose() : bool; + /** + * Returns whether verbosity is debug (-vvv). + */ + public function isDebug() : bool; + /** + * Sets the decorated flag. + * + * @return void + */ + public function setDecorated(bool $decorated); + /** + * Gets the decorated flag. + */ + public function isDecorated() : bool; + /** + * @return void + */ + public function setFormatter(OutputFormatterInterface $formatter); + /** + * Returns current output formatter instance. + */ + public function getFormatter() : OutputFormatterInterface; +} diff --git a/vendor/symfony/console/Output/StreamOutput.php b/vendor/symfony/console/Output/StreamOutput.php new file mode 100644 index 0000000000..42235b0fff --- /dev/null +++ b/vendor/symfony/console/Output/StreamOutput.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +/** + * StreamOutput writes the output to a given stream. + * + * Usage: + * + * $output = new StreamOutput(fopen('php://stdout', 'w')); + * + * As `StreamOutput` can use any stream, you can also use a file: + * + * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false)); + * + * @author Fabien Potencier + */ +class StreamOutput extends Output +{ + private $stream; + /** + * @param resource $stream A stream resource + * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) + * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) + * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) + * + * @throws InvalidArgumentException When first argument is not a real stream + */ + public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null) + { + if (!\is_resource($stream) || 'stream' !== \get_resource_type($stream)) { + throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.'); + } + $this->stream = $stream; + $decorated = $decorated ?? $this->hasColorSupport(); + parent::__construct($verbosity, $decorated, $formatter); + } + /** + * Gets the stream attached to this StreamOutput instance. + * + * @return resource + */ + public function getStream() + { + return $this->stream; + } + /** + * @return void + */ + protected function doWrite(string $message, bool $newline) + { + if ($newline) { + $message .= \PHP_EOL; + } + @\fwrite($this->stream, $message); + \fflush($this->stream); + } + /** + * Returns true if the stream supports colorization. + * + * Colorization is disabled if not supported by the stream: + * + * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo + * terminals via named pipes, so we can only check the environment. + * + * Reference: Composer\XdebugHandler\Process::supportsColor + * https://github.com/composer/xdebug-handler + * + * @return bool true if the stream supports colorization, false otherwise + */ + protected function hasColorSupport() : bool + { + // Follow https://no-color.org/ + if (isset($_SERVER['NO_COLOR']) || \false !== \getenv('NO_COLOR')) { + return \false; + } + if ('Hyper' === \getenv('TERM_PROGRAM')) { + return \true; + } + if (\DIRECTORY_SEPARATOR === '\\') { + return \function_exists('sapi_windows_vt100_support') && @\sapi_windows_vt100_support($this->stream) || \false !== \getenv('ANSICON') || 'ON' === \getenv('ConEmuANSI') || 'xterm' === \getenv('TERM'); + } + return \stream_isatty($this->stream); + } +} diff --git a/vendor/symfony/console/Output/TrimmedBufferOutput.php b/vendor/symfony/console/Output/TrimmedBufferOutput.php new file mode 100644 index 0000000000..14dafca5a1 --- /dev/null +++ b/vendor/symfony/console/Output/TrimmedBufferOutput.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Output; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +/** + * A BufferedOutput that keeps only the last N chars. + * + * @author Jérémy Derussé + */ +class TrimmedBufferOutput extends Output +{ + /** + * @var int + */ + private $maxLength; + /** + * @var string + */ + private $buffer = ''; + public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = \false, OutputFormatterInterface $formatter = null) + { + if ($maxLength <= 0) { + throw new InvalidArgumentException(\sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength)); + } + parent::__construct($verbosity, $decorated, $formatter); + $this->maxLength = $maxLength; + } + /** + * Empties buffer and returns its content. + */ + public function fetch() : string + { + $content = $this->buffer; + $this->buffer = ''; + return $content; + } + /** + * @return void + */ + protected function doWrite(string $message, bool $newline) + { + $this->buffer .= $message; + if ($newline) { + $this->buffer .= \PHP_EOL; + } + $this->buffer = \substr($this->buffer, 0 - $this->maxLength); + } +} diff --git a/vendor/symfony/console/Question/ChoiceQuestion.php b/vendor/symfony/console/Question/ChoiceQuestion.php new file mode 100644 index 0000000000..45da001292 --- /dev/null +++ b/vendor/symfony/console/Question/ChoiceQuestion.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Question; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +/** + * Represents a choice question. + * + * @author Fabien Potencier + */ +class ChoiceQuestion extends Question +{ + /** + * @var mixed[] + */ + private $choices; + /** + * @var bool + */ + private $multiselect = \false; + /** + * @var string + */ + private $prompt = ' > '; + /** + * @var string + */ + private $errorMessage = 'Value "%s" is invalid'; + /** + * @param string $question The question to ask to the user + * @param array $choices The list of available choices + * @param mixed $default The default answer to return + */ + public function __construct(string $question, array $choices, $default = null) + { + if (!$choices) { + throw new \LogicException('Choice question must have at least 1 choice available.'); + } + parent::__construct($question, $default); + $this->choices = $choices; + $this->setValidator($this->getDefaultValidator()); + $this->setAutocompleterValues($choices); + } + /** + * Returns available choices. + */ + public function getChoices() : array + { + return $this->choices; + } + /** + * Sets multiselect option. + * + * When multiselect is set to true, multiple choices can be answered. + * + * @return $this + */ + public function setMultiselect(bool $multiselect) + { + $this->multiselect = $multiselect; + $this->setValidator($this->getDefaultValidator()); + return $this; + } + /** + * Returns whether the choices are multiselect. + */ + public function isMultiselect() : bool + { + return $this->multiselect; + } + /** + * Gets the prompt for choices. + */ + public function getPrompt() : string + { + return $this->prompt; + } + /** + * Sets the prompt for choices. + * + * @return $this + */ + public function setPrompt(string $prompt) + { + $this->prompt = $prompt; + return $this; + } + /** + * Sets the error message for invalid values. + * + * The error message has a string placeholder (%s) for the invalid value. + * + * @return $this + */ + public function setErrorMessage(string $errorMessage) + { + $this->errorMessage = $errorMessage; + $this->setValidator($this->getDefaultValidator()); + return $this; + } + private function getDefaultValidator() : callable + { + $choices = $this->choices; + $errorMessage = $this->errorMessage; + $multiselect = $this->multiselect; + $isAssoc = $this->isAssoc($choices); + return function ($selected) use($choices, $errorMessage, $multiselect, $isAssoc) { + if ($multiselect) { + // Check for a separated comma values + if (!\preg_match('/^[^,]+(?:,[^,]+)*$/', (string) $selected, $matches)) { + throw new InvalidArgumentException(\sprintf($errorMessage, $selected)); + } + $selectedChoices = \explode(',', (string) $selected); + } else { + $selectedChoices = [$selected]; + } + if ($this->isTrimmable()) { + foreach ($selectedChoices as $k => $v) { + $selectedChoices[$k] = \trim((string) $v); + } + } + $multiselectChoices = []; + foreach ($selectedChoices as $value) { + $results = []; + foreach ($choices as $key => $choice) { + if ($choice === $value) { + $results[] = $key; + } + } + if (\count($results) > 1) { + throw new InvalidArgumentException(\sprintf('The provided answer is ambiguous. Value should be one of "%s".', \implode('" or "', $results))); + } + $result = \array_search($value, $choices); + if (!$isAssoc) { + if (\false !== $result) { + $result = $choices[$result]; + } elseif (isset($choices[$value])) { + $result = $choices[$value]; + } + } elseif (\false === $result && isset($choices[$value])) { + $result = $value; + } + if (\false === $result) { + throw new InvalidArgumentException(\sprintf($errorMessage, $value)); + } + // For associative choices, consistently return the key as string: + $multiselectChoices[] = $isAssoc ? (string) $result : $result; + } + if ($multiselect) { + return $multiselectChoices; + } + return \current($multiselectChoices); + }; + } +} diff --git a/vendor/symfony/console/Question/ConfirmationQuestion.php b/vendor/symfony/console/Question/ConfirmationQuestion.php new file mode 100644 index 0000000000..363e60adb6 --- /dev/null +++ b/vendor/symfony/console/Question/ConfirmationQuestion.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Question; + +/** + * Represents a yes/no question. + * + * @author Fabien Potencier + */ +class ConfirmationQuestion extends Question +{ + /** + * @var string + */ + private $trueAnswerRegex; + /** + * @param string $question The question to ask to the user + * @param bool $default The default answer to return, true or false + * @param string $trueAnswerRegex A regex to match the "yes" answer + */ + public function __construct(string $question, bool $default = \true, string $trueAnswerRegex = '/^y/i') + { + parent::__construct($question, $default); + $this->trueAnswerRegex = $trueAnswerRegex; + $this->setNormalizer($this->getDefaultNormalizer()); + } + /** + * Returns the default answer normalizer. + */ + private function getDefaultNormalizer() : callable + { + $default = $this->getDefault(); + $regex = $this->trueAnswerRegex; + return function ($answer) use($default, $regex) { + if (\is_bool($answer)) { + return $answer; + } + $answerIsTrue = (bool) \preg_match($regex, $answer); + if (\false === $default) { + return $answer && $answerIsTrue; + } + return '' === $answer || $answerIsTrue; + }; + } +} diff --git a/vendor/symfony/console/Question/Question.php b/vendor/symfony/console/Question/Question.php new file mode 100644 index 0000000000..5f4f739b30 --- /dev/null +++ b/vendor/symfony/console/Question/Question.php @@ -0,0 +1,285 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Question; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\LogicException; +/** + * Represents a Question. + * + * @author Fabien Potencier + */ +class Question +{ + /** + * @var string + */ + private $question; + /** + * @var int|null + */ + private $attempts; + /** + * @var bool + */ + private $hidden = \false; + /** + * @var bool + */ + private $hiddenFallback = \true; + /** + * @var \Closure|null + */ + private $autocompleterCallback; + /** + * @var \Closure|null + */ + private $validator; + /** + * @var string|int|bool|null|float + */ + private $default; + /** + * @var \Closure|null + */ + private $normalizer; + /** + * @var bool + */ + private $trimmable = \true; + /** + * @var bool + */ + private $multiline = \false; + /** + * @param string $question The question to ask to the user + * @param string|bool|int|float $default The default answer to return if the user enters nothing + */ + public function __construct(string $question, $default = null) + { + $this->question = $question; + $this->default = $default; + } + /** + * Returns the question. + */ + public function getQuestion() : string + { + return $this->question; + } + /** + * Returns the default answer. + * @return string|bool|int|float|null + */ + public function getDefault() + { + return $this->default; + } + /** + * Returns whether the user response accepts newline characters. + */ + public function isMultiline() : bool + { + return $this->multiline; + } + /** + * Sets whether the user response should accept newline characters. + * + * @return $this + */ + public function setMultiline(bool $multiline) + { + $this->multiline = $multiline; + return $this; + } + /** + * Returns whether the user response must be hidden. + */ + public function isHidden() : bool + { + return $this->hidden; + } + /** + * Sets whether the user response must be hidden or not. + * + * @return $this + * + * @throws LogicException In case the autocompleter is also used + */ + public function setHidden(bool $hidden) + { + if ($this->autocompleterCallback) { + throw new LogicException('A hidden question cannot use the autocompleter.'); + } + $this->hidden = $hidden; + return $this; + } + /** + * In case the response cannot be hidden, whether to fallback on non-hidden question or not. + */ + public function isHiddenFallback() : bool + { + return $this->hiddenFallback; + } + /** + * Sets whether to fallback on non-hidden question if the response cannot be hidden. + * + * @return $this + */ + public function setHiddenFallback(bool $fallback) + { + $this->hiddenFallback = $fallback; + return $this; + } + /** + * Gets values for the autocompleter. + */ + public function getAutocompleterValues() : ?iterable + { + $callback = $this->getAutocompleterCallback(); + return $callback ? $callback('') : null; + } + /** + * Sets values for the autocompleter. + * + * @return $this + * + * @throws LogicException + */ + public function setAutocompleterValues(?iterable $values) + { + if (\is_array($values)) { + $values = $this->isAssoc($values) ? \array_merge(\array_keys($values), \array_values($values)) : \array_values($values); + $callback = static function () use($values) { + return $values; + }; + } elseif ($values instanceof \Traversable) { + $callback = static function () use($values) { + static $valueCache; + return $valueCache = $valueCache ?? \iterator_to_array($values, \false); + }; + } else { + $callback = null; + } + return $this->setAutocompleterCallback($callback); + } + /** + * Gets the callback function used for the autocompleter. + */ + public function getAutocompleterCallback() : ?callable + { + return $this->autocompleterCallback; + } + /** + * Sets the callback function used for the autocompleter. + * + * The callback is passed the user input as argument and should return an iterable of corresponding suggestions. + * + * @return $this + */ + public function setAutocompleterCallback(callable $callback = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + if ($this->hidden && null !== $callback) { + throw new LogicException('A hidden question cannot use the autocompleter.'); + } + $this->autocompleterCallback = null === $callback ? null : \Closure::fromCallable($callback); + return $this; + } + /** + * Sets a validator for the question. + * + * @return $this + */ + public function setValidator(callable $validator = null) + { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } + $this->validator = null === $validator ? null : \Closure::fromCallable($validator); + return $this; + } + /** + * Gets the validator for the question. + */ + public function getValidator() : ?callable + { + return $this->validator; + } + /** + * Sets the maximum number of attempts. + * + * Null means an unlimited number of attempts. + * + * @return $this + * + * @throws InvalidArgumentException in case the number of attempts is invalid + */ + public function setMaxAttempts(?int $attempts) + { + if (null !== $attempts && $attempts < 1) { + throw new InvalidArgumentException('Maximum number of attempts must be a positive value.'); + } + $this->attempts = $attempts; + return $this; + } + /** + * Gets the maximum number of attempts. + * + * Null means an unlimited number of attempts. + */ + public function getMaxAttempts() : ?int + { + return $this->attempts; + } + /** + * Sets a normalizer for the response. + * + * The normalizer can be a callable (a string), a closure or a class implementing __invoke. + * + * @return $this + */ + public function setNormalizer(callable $normalizer) + { + $this->normalizer = \Closure::fromCallable($normalizer); + return $this; + } + /** + * Gets the normalizer for the response. + * + * The normalizer can ba a callable (a string), a closure or a class implementing __invoke. + */ + public function getNormalizer() : ?callable + { + return $this->normalizer; + } + /** + * @return bool + */ + protected function isAssoc(array $array) + { + return (bool) \count(\array_filter(\array_keys($array), 'is_string')); + } + public function isTrimmable() : bool + { + return $this->trimmable; + } + /** + * @return $this + */ + public function setTrimmable(bool $trimmable) + { + $this->trimmable = $trimmable; + return $this; + } +} diff --git a/vendor/symfony/console/README.md b/vendor/symfony/console/README.md new file mode 100644 index 0000000000..bfd4881092 --- /dev/null +++ b/vendor/symfony/console/README.md @@ -0,0 +1,36 @@ +Console Component +================= + +The Console component eases the creation of beautiful and testable command line +interfaces. + +Sponsor +------- + +The Console component for Symfony 6.3 is [backed][1] by [Les-Tilleuls.coop][2]. + +Les-Tilleuls.coop is a team of 70+ Symfony experts who can help you design, develop and +fix your projects. They provide a wide range of professional services including development, +consulting, coaching, training and audits. They also are highly skilled in JS, Go and DevOps. +They are a worker cooperative! + +Help Symfony by [sponsoring][3] its development! + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/console.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) + +Credits +------- + +`Resources/bin/hiddeninput.exe` is a third party binary provided within this +component. Find sources and license at https://github.com/Seldaek/hidden-input. + +[1]: https://symfony.com/backers +[2]: https://les-tilleuls.coop +[3]: https://symfony.com/sponsor diff --git a/vendor/symfony/console/Resources/bin/hiddeninput.exe b/vendor/symfony/console/Resources/bin/hiddeninput.exe new file mode 100644 index 0000000000000000000000000000000000000000..c8cf65e8d819e6e525121cf6b21f1c2429746038 GIT binary patch literal 9216 zcmeHNe{@sVeZR8hV88~S)=Hp|Mpn({rC^@)BwNOI{ERJXCYlx+k1K6PLHo z_e!z_fhOzeA3JTX&-Z@s{rFOgjEwBlqjr!)9f zjyHz`A+ni`!0Taby{Uj5Y>jQq(k5A+X})PLWAi|{IZbtc8n^^trM{GI=P_15U6d?l zJJ3PW8XjfHpR}6`k{&5@JcEeH_SqQoQbU62o2YS30W)p_t&Fjy*RXQCZt$gCf|ao| zx&3R}m6|-Lfi@pua=$26n(UlnWo$>K67*|+#(qL_An=?l0M02AhOSJDv3;~?1ORfw z76EdK#MpSHqACHLcnJLIYlCSiX4eS@Pr8rN)Xwz0dk7O*y^0_C(Yks2Kvg! z-d-fJ)F9@k?>)m(XqDKIe2OKfhCQde9fpO0ko24yn*4xzX7q+ze`Z*=aJgwV?D?73 zaJ8UkSk|NN>@-|mB*f`EIK7$ElgAB<7p&p`^Vuq$58#;?B^*Bz7&d$B#+AYUC z(^m|`7{lqx&b^5$;i`j|S!+u|lcaQplp_&Nb)!>r>vGh3wb!tW zLq6%bkSt8jO|(vWH>LiPV(Xkp%BiGhl1q!PXXNKVKE!>Y5cHc2%cJOJA{-&ZsSn`T z#8~TA#(HWH4m>uCd+kCMTFgMI*s*n3!iCOwEI`{vGcVhzDu!Lw%-Ea^JATtrF`q3`+#KvvYJ0vM~A}D#LOD zlw`4ncB0U*Jji=--Wz#>I&5?hy;MgYW2u91d8ob=7MWfY`u;7Xe-J{Qsb0=0p|SM2 zG|=~mERIj4?gi)Ew|{LIN#oAsh20k_khIYjJBBN6rrIJ=eQO=nE;rTnPSiaQS$1$# z+|JRh0!IbQIa*f1(TZ}QM;|WO0+jTy(e)ggN4>zqp2E>C>hGPLHjHBh--2%@{EZNE zbUk{<3MABX&20QwK{MxK8`1Vk>^%dO5i@VTfu>NG3$K4NC=hSPsj9UYy`rNO}sBnB9QdKdIk7G+2_amnWstdTYVg z7HgLJGC~XLZG`63GwH8PdO_+G(k6~?J8Wj5mQos#21kC4W#2)guQXI)!z^{@F)U)5 z*re+r(2dib3D4P~%Z6TL=$PIkpmm<_#isu%t=%DcIwNkJhMeJ|bpahHO%8h|y~Ccf zUg#xVk+dyu>Q1O7JZ~8KS>tqi0qK**X*y6yHM71`bT=kFZ=@E%oe2!Km1^2sa>v+onZ%x_>aOJF+N0{i~z|<(IzgT*{0PpQq}E zQpU35@bm;qI?t_znGI&5&4sZV>+%m}w$(4hSDvLk)l<{5XyMlnCl7C%AjM3XnWvVz z{NoFsX)JB)SoqABZxUa*Yq+^^(cbq4mL%^lO12c${z{pf+)|kTTI~nQywyYF6}6|8 zlsN9&{-vwTrTyu<5^90_AsIU-ID#ZG@6d%poU44<**%xVe?`uxf}_Mr$SLHLS|K_N zQnw>(Lr2U=%$-<2D~RSzbG)2W2u^KMDnFFE?GmmbQ)V)fty957F`4OvQ_25E68ITr z5?`suu`|v?r!y=gFOGj$%9IJ zuTP=&2GcnoZZ0qSe6YL-*-lg>Q#>?Ew`a=GDc4vI#<1sNdKn?n7iSj0Orl$-#FMFi zykr>X-Xvi>sVr;92+8*H!r|3L$#o~hXa0z>AmF=z z?|@FF;*S|S0yqsw0j>Z(3mX-HD!|{N-vYc9paC8Ld=|6?00!6(_%lERupO`&um*4k z0b~W>e*uhTe4;V;mq>(ox$9FB`wLt!*DKj~!aOh|fL&#Pg*b??tm%5~_6M#02wqeC zS~wO>TWGnSp^r<0&8f2V6W->w=C+p~daC5e5wNQM*(* z66^}b0(!q3)zq$mu&VnbR#nr3;h5DS*o7{y66=!#;Dy4$pd1ZH<6WEOi0oJ8SxRL* z*v-9@Z^2w%^S(w5dO{_9Duby%2RT~;ppxaE$l()x6&}>7Wcg=u_&>f`Vs8OJGTy{X z2HpG=ThJz<{%|4Qq-~ad0qcrc87n88DHpM(nypwXIkZn<{zIT$ul&BQ?{ApCAZtyr zs2YpNt@x(G*faTU*HCKnAk(G=Tl~>r1QK8LY~J8mFFGoN5iIkYSwlm4Lsj#g4dsE5 zU-4;*Kdh-zv!rT4N$O}Q&n)?v0-9Y)lRFz58^P-KtKonzrfQ1p@0V_10^0||cGRn9 zRG<-#_TEV2nn4{BOh{YVBR4e!V!D?0K%BAlQN!D%M#k1bHypiIHT)5tlj>p0Pp_;+ z!cqC-JIs@JRhB+#teGs$Cib_=(yjRo4OJg^YPg%58aJVsC(LQ?W6%pn!-#aMZwoPcopo^Rn6BE z3=c5&W5~pP(C(-2r;PnH-S0{F`runM0ERCf3rESX$+S(MKOXmKJL9zXF}9-lf^xUs z+bb)+P%L&gV@<4q{6w^xEJ>Y>TQFUeoz0o-yq)jUqww=?wjUO8Y{a5G;DJ0Jr!LL+ zWhgsLuzi&eDrGDn$2DJwpFfH-?SGWbr>qRb?v{P`_%)So)CQgzO^HQ%;y#tJ=knH4 z95jX;^bF#BiuTH^%-j}{9VrZD=R%Q%wselH^p>5 z7d>gWB-st&3Fj%Mt*|tR5iK3J=`xhs&G)I7E>`FO@o7L z@S$B!pYMuzz5DN@X!O4DPm5n@raPJn-Q#o*m*e^5lk$g?0esg%$;>g5QW-|;c=H2GM}bo2tW^D924wmOkrUbWxcQ# z#v6bP%Tdfe~jtCRzAL;-OahZ=#yvUixu2-9fD2j$*|YY`F?0wF-{a# ztr<&kZjZ+81}6ZESqtgW)8kP#s@VLTSUR{}6?U^R*x7RE3Rl&n=VnFFqg9Uqz1n@N9N|=9<4} zuJfy^+}|D9X&vm3MAdqmu0&UMd^=K>b1hLAm_E!$rZC2b;;T~Dl zI`Eo_yRY76uM})|6wk9->of(=9&4jLv5#p@OzS~Yl>@pG)^>6`R+KtL{<4ly4o9WiM!%p_pfROU354)e8PIeE z1_s?#;OX6waNvvb&UQRN(WLbR+}&b#jo&WY-LlwCX}Q*$jGuKYuOGoIoyR(>e}}ix z+t}Q^cEcC8Y{@h}>HmJ^gD!l@gzwHmiBKl26x_lZVZG2UY!`w;RJd122;US&geQdW z3Qq}R!gIo5;ka;0I4c-Jq5X6A6?VzK&c4y!ZXdAUYu{r}*!SBXw?Aor+J4-A(*COb zb^CwV-?3k`zi-cX*c`VzL`RLI(b4MgIrGN z%ojf`E*6)Gg1A9!7q^N##2zsss^V9~-Qt7d!{UDNZ^XY9pA^3@9ui*?e=7c5d`nD; z?}~R(p>y1Kw!>|X4ycYEAkcZa*n-R%y! zqi)Up756UpqwfE7=hfigw$k~G@25gaxF9UGTkV>C(7x1Rbx4jb#|}rxq0vQ!n-c#f J0sQ~1{4brj`U(I5 literal 0 HcmV?d00001 diff --git a/vendor/symfony/console/Resources/completion.bash b/vendor/symfony/console/Resources/completion.bash new file mode 100644 index 0000000000..0d76eacc3b --- /dev/null +++ b/vendor/symfony/console/Resources/completion.bash @@ -0,0 +1,94 @@ +# This file is part of the Symfony package. +# +# (c) Fabien Potencier +# +# For the full copyright and license information, please view +# https://symfony.com/doc/current/contributing/code/license.html + +_sf_{{ COMMAND_NAME }}() { + + # Use the default completion for shell redirect operators. + for w in '>' '>>' '&>' '<'; do + if [[ $w = "${COMP_WORDS[COMP_CWORD-1]}" ]]; then + compopt -o filenames + COMPREPLY=($(compgen -f -- "${COMP_WORDS[COMP_CWORD]}")) + return 0 + fi + done + + # Use newline as only separator to allow space in completion values + IFS=$'\n' + local sf_cmd="${COMP_WORDS[0]}" + + # for an alias, get the real script behind it + sf_cmd_type=$(type -t $sf_cmd) + if [[ $sf_cmd_type == "alias" ]]; then + sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/") + elif [[ $sf_cmd_type == "file" ]]; then + sf_cmd=$(type -p $sf_cmd) + fi + + if [[ $sf_cmd_type != "function" && ! -x $sf_cmd ]]; then + return 1 + fi + + local cur prev words cword + _get_comp_words_by_ref -n := cur prev words cword + + local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-a{{ VERSION }}") + for w in ${words[@]}; do + w=$(printf -- '%b' "$w") + # remove quotes from typed values + quote="${w:0:1}" + if [ "$quote" == \' ]; then + w="${w%\'}" + w="${w#\'}" + elif [ "$quote" == \" ]; then + w="${w%\"}" + w="${w#\"}" + fi + # empty values are ignored + if [ ! -z "$w" ]; then + completecmd+=("-i$w") + fi + done + + local sfcomplete + if sfcomplete=$(${completecmd[@]} 2>&1); then + local quote suggestions + quote=${cur:0:1} + + # Use single quotes by default if suggestions contains backslash (FQCN) + if [ "$quote" == '' ] && [[ "$sfcomplete" =~ \\ ]]; then + quote=\' + fi + + if [ "$quote" == \' ]; then + # single quotes: no additional escaping (does not accept ' in values) + suggestions=$(for s in $sfcomplete; do printf $'%q%q%q\n' "$quote" "$s" "$quote"; done) + elif [ "$quote" == \" ]; then + # double quotes: double escaping for \ $ ` " + suggestions=$(for s in $sfcomplete; do + s=${s//\\/\\\\} + s=${s//\$/\\\$} + s=${s//\`/\\\`} + s=${s//\"/\\\"} + printf $'%q%q%q\n' "$quote" "$s" "$quote"; + done) + else + # no quotes: double escaping + suggestions=$(for s in $sfcomplete; do printf $'%q\n' $(printf '%q' "$s"); done) + fi + COMPREPLY=($(IFS=$'\n' compgen -W "$suggestions" -- $(printf -- "%q" "$cur"))) + __ltrim_colon_completions "$cur" + else + if [[ "$sfcomplete" != *"Command \"_complete\" is not defined."* ]]; then + >&2 echo + >&2 echo $sfcomplete + fi + + return 1 + fi +} + +complete -F _sf_{{ COMMAND_NAME }} {{ COMMAND_NAME }} diff --git a/vendor/symfony/console/Resources/completion.fish b/vendor/symfony/console/Resources/completion.fish new file mode 100644 index 0000000000..1c34292aee --- /dev/null +++ b/vendor/symfony/console/Resources/completion.fish @@ -0,0 +1,29 @@ +# This file is part of the Symfony package. +# +# (c) Fabien Potencier +# +# For the full copyright and license information, please view +# https://symfony.com/doc/current/contributing/code/license.html + +function _sf_{{ COMMAND_NAME }} + set sf_cmd (commandline -o) + set c (count (commandline -oc)) + + set completecmd "$sf_cmd[1]" "_complete" "--no-interaction" "-sfish" "-a{{ VERSION }}" + + for i in $sf_cmd + if [ $i != "" ] + set completecmd $completecmd "-i$i" + end + end + + set completecmd $completecmd "-c$c" + + set sfcomplete ($completecmd) + + for i in $sfcomplete + echo $i + end +end + +complete -c '{{ COMMAND_NAME }}' -a '(_sf_{{ COMMAND_NAME }})' -f diff --git a/vendor/symfony/console/Resources/completion.zsh b/vendor/symfony/console/Resources/completion.zsh new file mode 100644 index 0000000000..ff76fe5fa9 --- /dev/null +++ b/vendor/symfony/console/Resources/completion.zsh @@ -0,0 +1,82 @@ +#compdef {{ COMMAND_NAME }} + +# This file is part of the Symfony package. +# +# (c) Fabien Potencier +# +# For the full copyright and license information, please view +# https://symfony.com/doc/current/contributing/code/license.html + +# +# zsh completions for {{ COMMAND_NAME }} +# +# References: +# - https://github.com/spf13/cobra/blob/master/zsh_completions.go +# - https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/Console/Resources/completion.bash +# +_sf_{{ COMMAND_NAME }}() { + local lastParam flagPrefix requestComp out comp + local -a completions + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $CURRENT location, so we need + # to truncate the command-line ($words) up to the $CURRENT location. + # (We cannot use $CURSOR as its value does not work when a command is an alias.) + words=("${=words[1,CURRENT]}") lastParam=${words[-1]} + + # For zsh, when completing a flag with an = (e.g., {{ COMMAND_NAME }} -n=) + # completions must be prefixed with the flag + setopt local_options BASH_REMATCH + if [[ "${lastParam}" =~ '-.*=' ]]; then + # We are dealing with a flag with an = + flagPrefix="-P ${BASH_REMATCH}" + fi + + # Prepare the command to obtain completions + requestComp="${words[0]} ${words[1]} _complete --no-interaction -szsh -a{{ VERSION }} -c$((CURRENT-1))" i="" + for w in ${words[@]}; do + w=$(printf -- '%b' "$w") + # remove quotes from typed values + quote="${w:0:1}" + if [ "$quote" = \' ]; then + w="${w%\'}" + w="${w#\'}" + elif [ "$quote" = \" ]; then + w="${w%\"}" + w="${w#\"}" + fi + # empty values are ignored + if [ ! -z "$w" ]; then + i="${i}-i${w} " + fi + done + + # Ensure at least 1 input + if [ "${i}" = "" ]; then + requestComp="${requestComp} -i\" \"" + else + requestComp="${requestComp} ${i}" + fi + + # Use eval to handle any environment variables and such + out=$(eval ${requestComp} 2>/dev/null) + + while IFS='\n' read -r comp; do + if [ -n "$comp" ]; then + # If requested, completions are returned with a description. + # The description is preceded by a TAB character. + # For zsh's _describe, we need to use a : instead of a TAB. + # We first need to escape any : as part of the completion itself. + comp=${comp//:/\\:} + local tab=$(printf '\t') + comp=${comp//$tab/:} + completions+=${comp} + fi + done < <(printf "%s\n" "${out[@]}") + + # Let inbuilt _describe handle completions + eval _describe "completions" completions $flagPrefix + return $? +} + +compdef _sf_{{ COMMAND_NAME }} {{ COMMAND_NAME }} diff --git a/vendor/symfony/console/SignalRegistry/SignalRegistry.php b/vendor/symfony/console/SignalRegistry/SignalRegistry.php new file mode 100644 index 0000000000..04537407e3 --- /dev/null +++ b/vendor/symfony/console/SignalRegistry/SignalRegistry.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\SignalRegistry; + +final class SignalRegistry +{ + /** + * @var mixed[] + */ + private $signalHandlers = []; + public function __construct() + { + if (\function_exists('pcntl_async_signals')) { + \pcntl_async_signals(\true); + } + } + public function register(int $signal, callable $signalHandler) : void + { + if (!isset($this->signalHandlers[$signal])) { + $previousCallback = \pcntl_signal_get_handler($signal); + if (\is_callable($previousCallback)) { + $this->signalHandlers[$signal][] = $previousCallback; + } + } + $this->signalHandlers[$signal][] = $signalHandler; + \pcntl_signal($signal, \Closure::fromCallable([$this, 'handle'])); + } + public static function isSupported() : bool + { + return \function_exists('pcntl_signal'); + } + /** + * @internal + */ + public function handle(int $signal) : void + { + $count = \count($this->signalHandlers[$signal]); + foreach ($this->signalHandlers[$signal] as $i => $signalHandler) { + $hasNext = $i !== $count - 1; + $signalHandler($signal, $hasNext); + } + } +} diff --git a/vendor/symfony/console/SingleCommandApplication.php b/vendor/symfony/console/SingleCommandApplication.php new file mode 100644 index 0000000000..ced3e1016f --- /dev/null +++ b/vendor/symfony/console/SingleCommandApplication.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * @author Grégoire Pineau + */ +class SingleCommandApplication extends Command +{ + /** + * @var string + */ + private $version = 'UNKNOWN'; + /** + * @var bool + */ + private $autoExit = \true; + /** + * @var bool + */ + private $running = \false; + /** + * @return $this + */ + public function setVersion(string $version) + { + $this->version = $version; + return $this; + } + /** + * @final + * + * @return $this + */ + public function setAutoExit(bool $autoExit) + { + $this->autoExit = $autoExit; + return $this; + } + public function run(InputInterface $input = null, OutputInterface $output = null) : int + { + if ($this->running) { + return parent::run($input, $output); + } + // We use the command name as the application name + $application = new Application($this->getName() ?: 'UNKNOWN', $this->version); + $application->setAutoExit($this->autoExit); + // Fix the usage of the command displayed with "--help" + $this->setName($_SERVER['argv'][0]); + $application->add($this); + $application->setDefaultCommand($this->getName(), \true); + $this->running = \true; + try { + $ret = $application->run($input, $output); + } finally { + $this->running = \false; + } + return $ret ?? 1; + } +} diff --git a/vendor/symfony/console/Style/OutputStyle.php b/vendor/symfony/console/Style/OutputStyle.php new file mode 100644 index 0000000000..a0df6ab6d0 --- /dev/null +++ b/vendor/symfony/console/Style/OutputStyle.php @@ -0,0 +1,118 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Style; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatterInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\ProgressBar; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +/** + * Decorates output to add console style guide helpers. + * + * @author Kevin Bond + */ +abstract class OutputStyle implements OutputInterface, StyleInterface +{ + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + public function __construct(OutputInterface $output) + { + $this->output = $output; + } + /** + * @return void + */ + public function newLine(int $count = 1) + { + $this->output->write(\str_repeat(\PHP_EOL, $count)); + } + public function createProgressBar(int $max = 0) : ProgressBar + { + return new ProgressBar($this->output, $max); + } + /** + * @return void + * @param string|iterable $messages + */ + public function write($messages, bool $newline = \false, int $type = self::OUTPUT_NORMAL) + { + $this->output->write($messages, $newline, $type); + } + /** + * @return void + * @param string|iterable $messages + */ + public function writeln($messages, int $type = self::OUTPUT_NORMAL) + { + $this->output->writeln($messages, $type); + } + /** + * @return void + */ + public function setVerbosity(int $level) + { + $this->output->setVerbosity($level); + } + public function getVerbosity() : int + { + return $this->output->getVerbosity(); + } + /** + * @return void + */ + public function setDecorated(bool $decorated) + { + $this->output->setDecorated($decorated); + } + public function isDecorated() : bool + { + return $this->output->isDecorated(); + } + /** + * @return void + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + $this->output->setFormatter($formatter); + } + public function getFormatter() : OutputFormatterInterface + { + return $this->output->getFormatter(); + } + public function isQuiet() : bool + { + return $this->output->isQuiet(); + } + public function isVerbose() : bool + { + return $this->output->isVerbose(); + } + public function isVeryVerbose() : bool + { + return $this->output->isVeryVerbose(); + } + public function isDebug() : bool + { + return $this->output->isDebug(); + } + /** + * @return OutputInterface + */ + protected function getErrorOutput() + { + if (!$this->output instanceof ConsoleOutputInterface) { + return $this->output; + } + return $this->output->getErrorOutput(); + } +} diff --git a/vendor/symfony/console/Style/StyleInterface.php b/vendor/symfony/console/Style/StyleInterface.php new file mode 100644 index 0000000000..cb759210d5 --- /dev/null +++ b/vendor/symfony/console/Style/StyleInterface.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Style; + +/** + * Output style helpers. + * + * @author Kevin Bond + */ +interface StyleInterface +{ + /** + * Formats a command title. + * + * @return void + */ + public function title(string $message); + /** + * Formats a section title. + * + * @return void + */ + public function section(string $message); + /** + * Formats a list. + * + * @return void + */ + public function listing(array $elements); + /** + * Formats informational text. + * + * @return void + * @param string|mixed[] $message + */ + public function text($message); + /** + * Formats a success result bar. + * + * @return void + * @param string|mixed[] $message + */ + public function success($message); + /** + * Formats an error result bar. + * + * @return void + * @param string|mixed[] $message + */ + public function error($message); + /** + * Formats an warning result bar. + * + * @return void + * @param string|mixed[] $message + */ + public function warning($message); + /** + * Formats a note admonition. + * + * @return void + * @param string|mixed[] $message + */ + public function note($message); + /** + * Formats a caution admonition. + * + * @return void + * @param string|mixed[] $message + */ + public function caution($message); + /** + * Formats a table. + * + * @return void + */ + public function table(array $headers, array $rows); + /** + * Asks a question. + * @return mixed + */ + public function ask(string $question, string $default = null, callable $validator = null); + /** + * Asks a question with the user input hidden. + * @return mixed + */ + public function askHidden(string $question, callable $validator = null); + /** + * Asks for confirmation. + */ + public function confirm(string $question, bool $default = \true) : bool; + /** + * Asks a choice question. + * @param mixed $default + * @return mixed + */ + public function choice(string $question, array $choices, $default = null); + /** + * Add newline(s). + * + * @return void + */ + public function newLine(int $count = 1); + /** + * Starts the progress output. + * + * @return void + */ + public function progressStart(int $max = 0); + /** + * Advances the progress output X steps. + * + * @return void + */ + public function progressAdvance(int $step = 1); + /** + * Finishes the progress output. + * + * @return void + */ + public function progressFinish(); +} diff --git a/vendor/symfony/console/Style/SymfonyStyle.php b/vendor/symfony/console/Style/SymfonyStyle.php new file mode 100644 index 0000000000..7e64f8ad25 --- /dev/null +++ b/vendor/symfony/console/Style/SymfonyStyle.php @@ -0,0 +1,462 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Style; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Formatter\OutputFormatter; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\Helper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\OutputWrapper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\ProgressBar; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\SymfonyQuestionHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\Table; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\TableCell; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Helper\TableSeparator; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleSectionOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\TrimmedBufferOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\ChoiceQuestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\ConfirmationQuestion; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Question\Question; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Terminal; +/** + * Output decorator helpers for the Symfony Style Guide. + * + * @author Kevin Bond + */ +class SymfonyStyle extends OutputStyle +{ + public const MAX_LINE_LENGTH = 120; + /** + * @var \Symfony\Component\Console\Input\InputInterface + */ + private $input; + /** + * @var \Symfony\Component\Console\Output\OutputInterface + */ + private $output; + /** + * @var \Symfony\Component\Console\Helper\SymfonyQuestionHelper + */ + private $questionHelper; + /** + * @var \Symfony\Component\Console\Helper\ProgressBar + */ + private $progressBar; + /** + * @var int + */ + private $lineLength; + /** + * @var \Symfony\Component\Console\Output\TrimmedBufferOutput + */ + private $bufferedOutput; + public function __construct(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->bufferedOutput = new TrimmedBufferOutput(\DIRECTORY_SEPARATOR === '\\' ? 4 : 2, $output->getVerbosity(), \false, clone $output->getFormatter()); + // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not. + $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; + $this->lineLength = \min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); + parent::__construct($this->output = $output); + } + /** + * Formats a message as a block of text. + * + * @return void + * @param string|mixed[] $messages + */ + public function block($messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = \false, bool $escape = \true) + { + $messages = \is_array($messages) ? \array_values($messages) : [$messages]; + $this->autoPrependBlock(); + $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape)); + $this->newLine(); + } + /** + * @return void + */ + public function title(string $message) + { + $this->autoPrependBlock(); + $this->writeln([\sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), \sprintf('%s', \str_repeat('=', Helper::width(Helper::removeDecoration($this->getFormatter(), $message))))]); + $this->newLine(); + } + /** + * @return void + */ + public function section(string $message) + { + $this->autoPrependBlock(); + $this->writeln([\sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), \sprintf('%s', \str_repeat('-', Helper::width(Helper::removeDecoration($this->getFormatter(), $message))))]); + $this->newLine(); + } + /** + * @return void + */ + public function listing(array $elements) + { + $this->autoPrependText(); + $elements = \array_map(function ($element) { + return \sprintf(' * %s', $element); + }, $elements); + $this->writeln($elements); + $this->newLine(); + } + /** + * @return void + * @param string|mixed[] $message + */ + public function text($message) + { + $this->autoPrependText(); + $messages = \is_array($message) ? \array_values($message) : [$message]; + foreach ($messages as $message) { + $this->writeln(\sprintf(' %s', $message)); + } + } + /** + * Formats a command comment. + * + * @return void + * @param string|mixed[] $message + */ + public function comment($message) + { + $this->block($message, null, null, ' // ', \false, \false); + } + /** + * @return void + * @param string|mixed[] $message + */ + public function success($message) + { + $this->block($message, 'OK', 'fg=black;bg=green', ' ', \true); + } + /** + * @return void + * @param string|mixed[] $message + */ + public function error($message) + { + $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', \true); + } + /** + * @return void + * @param string|mixed[] $message + */ + public function warning($message) + { + $this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ', \true); + } + /** + * @return void + * @param string|mixed[] $message + */ + public function note($message) + { + $this->block($message, 'NOTE', 'fg=yellow', ' ! '); + } + /** + * Formats an info message. + * + * @return void + * @param string|mixed[] $message + */ + public function info($message) + { + $this->block($message, 'INFO', 'fg=green', ' ', \true); + } + /** + * @return void + * @param string|mixed[] $message + */ + public function caution($message) + { + $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', \true); + } + /** + * @return void + */ + public function table(array $headers, array $rows) + { + $this->createTable()->setHeaders($headers)->setRows($rows)->render(); + $this->newLine(); + } + /** + * Formats a horizontal table. + * + * @return void + */ + public function horizontalTable(array $headers, array $rows) + { + $this->createTable()->setHorizontal(\true)->setHeaders($headers)->setRows($rows)->render(); + $this->newLine(); + } + /** + * Formats a list of key/value horizontally. + * + * Each row can be one of: + * * 'A title' + * * ['key' => 'value'] + * * new TableSeparator() + * + * @return void + * @param string|mixed[]|\Symfony\Component\Console\Helper\TableSeparator ...$list + */ + public function definitionList(...$list) + { + $headers = []; + $row = []; + foreach ($list as $value) { + if ($value instanceof TableSeparator) { + $headers[] = $value; + $row[] = $value; + continue; + } + if (\is_string($value)) { + $headers[] = new TableCell($value, ['colspan' => 2]); + $row[] = null; + continue; + } + if (!\is_array($value)) { + throw new InvalidArgumentException('Value should be an array, string, or an instance of TableSeparator.'); + } + $headers[] = \key($value); + $row[] = \current($value); + } + $this->horizontalTable($headers, [$row]); + } + /** + * @return mixed + */ + public function ask(string $question, string $default = null, callable $validator = null) + { + $question = new Question($question, $default); + $question->setValidator($validator); + return $this->askQuestion($question); + } + /** + * @return mixed + */ + public function askHidden(string $question, callable $validator = null) + { + $question = new Question($question); + $question->setHidden(\true); + $question->setValidator($validator); + return $this->askQuestion($question); + } + public function confirm(string $question, bool $default = \true) : bool + { + return $this->askQuestion(new ConfirmationQuestion($question, $default)); + } + /** + * @param mixed $default + * @return mixed + */ + public function choice(string $question, array $choices, $default = null, bool $multiSelect = \false) + { + if (null !== $default) { + $values = \array_flip($choices); + $default = $values[$default] ?? $default; + } + $questionChoice = new ChoiceQuestion($question, $choices, $default); + $questionChoice->setMultiselect($multiSelect); + return $this->askQuestion($questionChoice); + } + /** + * @return void + */ + public function progressStart(int $max = 0) + { + $this->progressBar = $this->createProgressBar($max); + $this->progressBar->start(); + } + /** + * @return void + */ + public function progressAdvance(int $step = 1) + { + $this->getProgressBar()->advance($step); + } + /** + * @return void + */ + public function progressFinish() + { + $this->getProgressBar()->finish(); + $this->newLine(2); + unset($this->progressBar); + } + public function createProgressBar(int $max = 0) : ProgressBar + { + $progressBar = parent::createProgressBar($max); + if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === \getenv('TERM_PROGRAM')) { + $progressBar->setEmptyBarCharacter('░'); + // light shade character \u2591 + $progressBar->setProgressCharacter(''); + $progressBar->setBarCharacter('▓'); + // dark shade character \u2593 + } + return $progressBar; + } + /** + * @see ProgressBar::iterate() + */ + public function progressIterate(iterable $iterable, int $max = null) : iterable + { + yield from $this->createProgressBar()->iterate($iterable, $max); + $this->newLine(2); + } + /** + * @return mixed + */ + public function askQuestion(Question $question) + { + if ($this->input->isInteractive()) { + $this->autoPrependBlock(); + } + $this->questionHelper = $this->questionHelper ?? new SymfonyQuestionHelper(); + $answer = $this->questionHelper->ask($this->input, $this, $question); + if ($this->input->isInteractive()) { + if ($this->output instanceof ConsoleSectionOutput) { + // add the new line of the `return` to submit the input to ConsoleSectionOutput, because ConsoleSectionOutput is holding all it's lines. + // this is relevant when a `ConsoleSectionOutput::clear` is called. + $this->output->addNewLineOfInputSubmit(); + } + $this->newLine(); + $this->bufferedOutput->write("\n"); + } + return $answer; + } + /** + * @return void + * @param string|iterable $messages + */ + public function writeln($messages, int $type = self::OUTPUT_NORMAL) + { + if (!\is_iterable($messages)) { + $messages = [$messages]; + } + foreach ($messages as $message) { + parent::writeln($message, $type); + $this->writeBuffer($message, \true, $type); + } + } + /** + * @return void + * @param string|iterable $messages + */ + public function write($messages, bool $newline = \false, int $type = self::OUTPUT_NORMAL) + { + if (!\is_iterable($messages)) { + $messages = [$messages]; + } + foreach ($messages as $message) { + parent::write($message, $newline, $type); + $this->writeBuffer($message, $newline, $type); + } + } + /** + * @return void + */ + public function newLine(int $count = 1) + { + parent::newLine($count); + $this->bufferedOutput->write(\str_repeat("\n", $count)); + } + /** + * Returns a new instance which makes use of stderr if available. + */ + public function getErrorStyle() : self + { + return new self($this->input, $this->getErrorOutput()); + } + public function createTable() : Table + { + $output = $this->output instanceof ConsoleOutputInterface ? $this->output->section() : $this->output; + $style = clone Table::getStyleDefinition('symfony-style-guide'); + $style->setCellHeaderFormat('%s'); + return (new Table($output))->setStyle($style); + } + private function getProgressBar() : ProgressBar + { + if (!isset($this->progressBar)) { + throw new RuntimeException('The ProgressBar is not started.'); + } + return $this->progressBar; + } + private function autoPrependBlock() : void + { + $chars = \substr(\str_replace(\PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2); + if (!isset($chars[0])) { + $this->newLine(); + // empty history, so we should start with a new line. + return; + } + // Prepend new line for each non LF chars (This means no blank line was output before) + $this->newLine(2 - \substr_count($chars, "\n")); + } + private function autoPrependText() : void + { + $fetched = $this->bufferedOutput->fetch(); + // Prepend new line if last char isn't EOL: + if ($fetched && \substr_compare($fetched, "\n", -\strlen("\n")) !== 0) { + $this->newLine(); + } + } + private function writeBuffer(string $message, bool $newLine, int $type) : void + { + // We need to know if the last chars are PHP_EOL + $this->bufferedOutput->write($message, $newLine, $type); + } + private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = \false, bool $escape = \false) : array + { + $indentLength = 0; + $prefixLength = Helper::width(Helper::removeDecoration($this->getFormatter(), $prefix)); + $lines = []; + if (null !== $type) { + $type = \sprintf('[%s] ', $type); + $indentLength = Helper::width($type); + $lineIndentation = \str_repeat(' ', $indentLength); + } + // wrap and add newlines for each element + $outputWrapper = new OutputWrapper(); + foreach ($messages as $key => $message) { + if ($escape) { + $message = OutputFormatter::escape($message); + } + $lines = \array_merge($lines, \explode(\PHP_EOL, $outputWrapper->wrap($message, $this->lineLength - $prefixLength - $indentLength, \PHP_EOL))); + if (\count($messages) > 1 && $key < \count($messages) - 1) { + $lines[] = ''; + } + } + $firstLineIndex = 0; + if ($padding && $this->isDecorated()) { + $firstLineIndex = 1; + \array_unshift($lines, ''); + $lines[] = ''; + } + foreach ($lines as $i => &$line) { + if (null !== $type) { + $line = $firstLineIndex === $i ? $type . $line : $lineIndentation . $line; + } + $line = $prefix . $line; + $line .= \str_repeat(' ', \max($this->lineLength - Helper::width(Helper::removeDecoration($this->getFormatter(), $line)), 0)); + if ($style) { + $line = \sprintf('<%s>%s', $style, $line); + } + } + return $lines; + } +} diff --git a/vendor/symfony/console/Terminal.php b/vendor/symfony/console/Terminal.php new file mode 100644 index 0000000000..cda79dd104 --- /dev/null +++ b/vendor/symfony/console/Terminal.php @@ -0,0 +1,209 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\AnsiColorMode; +class Terminal +{ + public const DEFAULT_COLOR_MODE = AnsiColorMode::Ansi4; + /** + * @var \Symfony\Component\Console\Output\AnsiColorMode|null + */ + private static $colorMode; + /** + * @var int|null + */ + private static $width; + /** + * @var int|null + */ + private static $height; + /** + * @var bool|null + */ + private static $stty; + /** + * About Ansi color types: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors + * For more information about true color support with terminals https://github.com/termstandard/colors/. + */ + public static function getColorMode() : AnsiColorMode + { + // Use Cache from previous run (or user forced mode) + if (null !== self::$colorMode) { + return self::$colorMode; + } + // Try with $COLORTERM first + if (\is_string($colorterm = \getenv('COLORTERM'))) { + $colorterm = \strtolower($colorterm); + if (\strpos($colorterm, 'truecolor') !== \false) { + self::setColorMode(AnsiColorMode::Ansi24); + return self::$colorMode; + } + if (\strpos($colorterm, '256color') !== \false) { + self::setColorMode(AnsiColorMode::Ansi8); + return self::$colorMode; + } + } + // Try with $TERM + if (\is_string($term = \getenv('TERM'))) { + $term = \strtolower($term); + if (\strpos($term, 'truecolor') !== \false) { + self::setColorMode(AnsiColorMode::Ansi24); + return self::$colorMode; + } + if (\strpos($term, '256color') !== \false) { + self::setColorMode(AnsiColorMode::Ansi8); + return self::$colorMode; + } + } + self::setColorMode(self::DEFAULT_COLOR_MODE); + return self::$colorMode; + } + /** + * Force a terminal color mode rendering. + * @param ?\Symfony\Component\Console\Output\AnsiColorMode::* $colorMode + */ + public static function setColorMode($colorMode) : void + { + self::$colorMode = $colorMode; + } + /** + * Gets the terminal width. + */ + public function getWidth() : int + { + $width = \getenv('COLUMNS'); + if (\false !== $width) { + return (int) \trim($width); + } + if (null === self::$width) { + self::initDimensions(); + } + return self::$width ?: 80; + } + /** + * Gets the terminal height. + */ + public function getHeight() : int + { + $height = \getenv('LINES'); + if (\false !== $height) { + return (int) \trim($height); + } + if (null === self::$height) { + self::initDimensions(); + } + return self::$height ?: 50; + } + /** + * @internal + */ + public static function hasSttyAvailable() : bool + { + if (null !== self::$stty) { + return self::$stty; + } + // skip check if shell_exec function is disabled + if (!\function_exists('shell_exec')) { + return \false; + } + return self::$stty = (bool) \shell_exec('stty 2> ' . ('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null')); + } + private static function initDimensions() : void + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $ansicon = \getenv('ANSICON'); + if (\false !== $ansicon && \preg_match('/^(\\d+)x(\\d+)(?: \\((\\d+)x(\\d+)\\))?$/', \trim($ansicon), $matches)) { + // extract [w, H] from "wxh (WxH)" + // or [w, h] from "wxh" + self::$width = (int) $matches[1]; + self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2]; + } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) { + // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash) + // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT + self::initDimensionsUsingStty(); + } elseif (null !== ($dimensions = self::getConsoleMode())) { + // extract [w, h] from "wxh" + self::$width = (int) $dimensions[0]; + self::$height = (int) $dimensions[1]; + } + } else { + self::initDimensionsUsingStty(); + } + } + /** + * Returns whether STDOUT has vt100 support (some Windows 10+ configurations). + */ + private static function hasVt100Support() : bool + { + return \function_exists('sapi_windows_vt100_support') && \sapi_windows_vt100_support(\fopen('php://stdout', 'w')); + } + /** + * Initializes dimensions using the output of an stty columns line. + */ + private static function initDimensionsUsingStty() : void + { + if ($sttyString = self::getSttyColumns()) { + if (\preg_match('/rows.(\\d+);.columns.(\\d+);/is', $sttyString, $matches)) { + // extract [w, h] from "rows h; columns w;" + self::$width = (int) $matches[2]; + self::$height = (int) $matches[1]; + } elseif (\preg_match('/;.(\\d+).rows;.(\\d+).columns/is', $sttyString, $matches)) { + // extract [w, h] from "; h rows; w columns" + self::$width = (int) $matches[2]; + self::$height = (int) $matches[1]; + } + } + } + /** + * Runs and parses mode CON if it's available, suppressing any error output. + * + * @return int[]|null An array composed of the width and the height or null if it could not be parsed + */ + private static function getConsoleMode() : ?array + { + $info = self::readFromProcess('mode CON'); + if (null === $info || !\preg_match('/--------+\\r?\\n.+?(\\d+)\\r?\\n.+?(\\d+)\\r?\\n/', $info, $matches)) { + return null; + } + return [(int) $matches[2], (int) $matches[1]]; + } + /** + * Runs and parses stty -a if it's available, suppressing any error output. + */ + private static function getSttyColumns() : ?string + { + return self::readFromProcess(['stty', '-a']); + } + /** + * @param string|mixed[] $command + */ + private static function readFromProcess($command) : ?string + { + if (!\function_exists('proc_open')) { + return null; + } + $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']]; + $cp = \function_exists('sapi_windows_cp_set') ? \sapi_windows_cp_get() : 0; + $process = \proc_open(\is_array($command) ? \implode(' ', $command) : $command, $descriptorspec, $pipes, null, null, ['suppress_errors' => \true]); + if (!\is_resource($process)) { + return null; + } + $info = \stream_get_contents($pipes[1]); + \fclose($pipes[1]); + \fclose($pipes[2]); + \proc_close($process); + if ($cp) { + \sapi_windows_cp_set($cp); + } + return $info; + } +} diff --git a/vendor/symfony/console/Tester/ApplicationTester.php b/vendor/symfony/console/Tester/ApplicationTester.php new file mode 100644 index 0000000000..9b9070036f --- /dev/null +++ b/vendor/symfony/console/Tester/ApplicationTester.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Tester; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Application; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\ArrayInput; +/** + * Eases the testing of console applications. + * + * When testing an application, don't forget to disable the auto exit flag: + * + * $application = new Application(); + * $application->setAutoExit(false); + * + * @author Fabien Potencier + */ +class ApplicationTester +{ + use TesterTrait; + /** + * @var \Symfony\Component\Console\Application + */ + private $application; + public function __construct(Application $application) + { + $this->application = $application; + } + /** + * Executes the application. + * + * Available options: + * + * * interactive: Sets the input interactive flag + * * decorated: Sets the output decorated flag + * * verbosity: Sets the output verbosity flag + * * capture_stderr_separately: Make output of stdOut and stdErr separately available + * + * @return int The command exit code + */ + public function run(array $input, array $options = []) : int + { + $prevShellVerbosity = \getenv('SHELL_VERBOSITY'); + try { + $this->input = new ArrayInput($input); + if (isset($options['interactive'])) { + $this->input->setInteractive($options['interactive']); + } + if ($this->inputs) { + $this->input->setStream(self::createStream($this->inputs)); + } + $this->initOutput($options); + return $this->statusCode = $this->application->run($this->input, $this->output); + } finally { + // SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it + // to its previous value to avoid one test's verbosity to spread to the following tests + if (\false === $prevShellVerbosity) { + if (\function_exists('putenv')) { + @\putenv('SHELL_VERBOSITY'); + } + unset($_ENV['SHELL_VERBOSITY']); + unset($_SERVER['SHELL_VERBOSITY']); + } else { + if (\function_exists('putenv')) { + @\putenv('SHELL_VERBOSITY=' . $prevShellVerbosity); + } + $_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity; + $_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity; + } + } + } +} diff --git a/vendor/symfony/console/Tester/CommandCompletionTester.php b/vendor/symfony/console/Tester/CommandCompletionTester.php new file mode 100644 index 0000000000..62e394cc34 --- /dev/null +++ b/vendor/symfony/console/Tester/CommandCompletionTester.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Tester; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionInput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Completion\CompletionSuggestions; +/** + * Eases the testing of command completion. + * + * @author Jérôme Tamarelle + */ +class CommandCompletionTester +{ + private $command; + public function __construct(Command $command) + { + $this->command = $command; + } + /** + * Create completion suggestions from input tokens. + */ + public function complete(array $input) : array + { + $currentIndex = \count($input); + if ('' === \end($input)) { + \array_pop($input); + } + \array_unshift($input, $this->command->getName()); + $completionInput = CompletionInput::fromTokens($input, $currentIndex); + $completionInput->bind($this->command->getDefinition()); + $suggestions = new CompletionSuggestions(); + $this->command->complete($completionInput, $suggestions); + $options = []; + foreach ($suggestions->getOptionSuggestions() as $option) { + $options[] = '--' . $option->getName(); + } + return \array_map('strval', \array_merge($options, $suggestions->getValueSuggestions())); + } +} diff --git a/vendor/symfony/console/Tester/CommandTester.php b/vendor/symfony/console/Tester/CommandTester.php new file mode 100644 index 0000000000..1d7fc2d9a7 --- /dev/null +++ b/vendor/symfony/console/Tester/CommandTester.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Tester; + +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\ArrayInput; +/** + * Eases the testing of console commands. + * + * @author Fabien Potencier + * @author Robin Chalas + */ +class CommandTester +{ + use TesterTrait; + /** + * @var \Symfony\Component\Console\Command\Command + */ + private $command; + public function __construct(Command $command) + { + $this->command = $command; + } + /** + * Executes the command. + * + * Available execution options: + * + * * interactive: Sets the input interactive flag + * * decorated: Sets the output decorated flag + * * verbosity: Sets the output verbosity flag + * * capture_stderr_separately: Make output of stdOut and stdErr separately available + * + * @param array $input An array of command arguments and options + * @param array $options An array of execution options + * + * @return int The command exit code + */ + public function execute(array $input, array $options = []) : int + { + // set the command name automatically if the application requires + // this argument and no command name was passed + if (!isset($input['command']) && null !== ($application = $this->command->getApplication()) && $application->getDefinition()->hasArgument('command')) { + $input = \array_merge(['command' => $this->command->getName()], $input); + } + $this->input = new ArrayInput($input); + // Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN. + $this->input->setStream(self::createStream($this->inputs)); + if (isset($options['interactive'])) { + $this->input->setInteractive($options['interactive']); + } + if (!isset($options['decorated'])) { + $options['decorated'] = \false; + } + $this->initOutput($options); + return $this->statusCode = $this->command->run($this->input, $this->output); + } +} diff --git a/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php b/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php new file mode 100644 index 0000000000..f4a432a5b9 --- /dev/null +++ b/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Tester\Constraint; + +use MonorepoBuilderPrefix202310\PHPUnit\Framework\Constraint\Constraint; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Command\Command; +final class CommandIsSuccessful extends Constraint +{ + public function toString() : string + { + return 'is successful'; + } + protected function matches($other) : bool + { + return Command::SUCCESS === $other; + } + protected function failureDescription($other) : string + { + return 'the command ' . $this->toString(); + } + protected function additionalFailureDescription($other) : string + { + $mapping = [Command::FAILURE => 'Command failed.', Command::INVALID => 'Command was invalid.']; + return $mapping[$other] ?? \sprintf('Command returned exit status %d.', $other); + } +} diff --git a/vendor/symfony/console/Tester/TesterTrait.php b/vendor/symfony/console/Tester/TesterTrait.php new file mode 100644 index 0000000000..3ea7bfd098 --- /dev/null +++ b/vendor/symfony/console/Tester/TesterTrait.php @@ -0,0 +1,167 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Console\Tester; + +use MonorepoBuilderPrefix202310\PHPUnit\Framework\Assert; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Input\InputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\ConsoleOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\OutputInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Output\StreamOutput; +use MonorepoBuilderPrefix202310\Symfony\Component\Console\Tester\Constraint\CommandIsSuccessful; +/** + * @author Amrouche Hamza + */ +trait TesterTrait +{ + /** + * @var \Symfony\Component\Console\Output\StreamOutput + */ + private $output; + /** + * @var mixed[] + */ + private $inputs = []; + /** + * @var bool + */ + private $captureStreamsIndependently = \false; + /** + * @var \Symfony\Component\Console\Input\InputInterface + */ + private $input; + /** + * @var int + */ + private $statusCode; + /** + * Gets the display returned by the last execution of the command or application. + * + * @throws \RuntimeException If it's called before the execute method + */ + public function getDisplay(bool $normalize = \false) : string + { + if (!isset($this->output)) { + throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?'); + } + \rewind($this->output->getStream()); + $display = \stream_get_contents($this->output->getStream()); + if ($normalize) { + $display = \str_replace(\PHP_EOL, "\n", $display); + } + return $display; + } + /** + * Gets the output written to STDERR by the application. + * + * @param bool $normalize Whether to normalize end of lines to \n or not + */ + public function getErrorOutput(bool $normalize = \false) : string + { + if (!$this->captureStreamsIndependently) { + throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.'); + } + \rewind($this->output->getErrorOutput()->getStream()); + $display = \stream_get_contents($this->output->getErrorOutput()->getStream()); + if ($normalize) { + $display = \str_replace(\PHP_EOL, "\n", $display); + } + return $display; + } + /** + * Gets the input instance used by the last execution of the command or application. + */ + public function getInput() : InputInterface + { + return $this->input; + } + /** + * Gets the output instance used by the last execution of the command or application. + */ + public function getOutput() : OutputInterface + { + return $this->output; + } + /** + * Gets the status code returned by the last execution of the command or application. + * + * @throws \RuntimeException If it's called before the execute method + */ + public function getStatusCode() : int + { + if (!isset($this->statusCode)) { + throw new \RuntimeException('Status code not initialized, did you execute the command before requesting the status code?'); + } + return $this->statusCode; + } + public function assertCommandIsSuccessful(string $message = '') : void + { + Assert::assertThat($this->statusCode, new CommandIsSuccessful(), $message); + } + /** + * Sets the user inputs. + * + * @param array $inputs An array of strings representing each input + * passed to the command input stream + * + * @return $this + */ + public function setInputs(array $inputs) + { + $this->inputs = $inputs; + return $this; + } + /** + * Initializes the output property. + * + * Available options: + * + * * decorated: Sets the output decorated flag + * * verbosity: Sets the output verbosity flag + * * capture_stderr_separately: Make output of stdOut and stdErr separately available + */ + private function initOutput(array $options) : void + { + $this->captureStreamsIndependently = \array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately']; + if (!$this->captureStreamsIndependently) { + $this->output = new StreamOutput(\fopen('php://memory', 'w', \false)); + if (isset($options['decorated'])) { + $this->output->setDecorated($options['decorated']); + } + if (isset($options['verbosity'])) { + $this->output->setVerbosity($options['verbosity']); + } + } else { + $this->output = new ConsoleOutput($options['verbosity'] ?? ConsoleOutput::VERBOSITY_NORMAL, $options['decorated'] ?? null); + $errorOutput = new StreamOutput(\fopen('php://memory', 'w', \false)); + $errorOutput->setFormatter($this->output->getFormatter()); + $errorOutput->setVerbosity($this->output->getVerbosity()); + $errorOutput->setDecorated($this->output->isDecorated()); + $reflectedOutput = new \ReflectionObject($this->output); + $strErrProperty = $reflectedOutput->getProperty('stderr'); + $strErrProperty->setValue($this->output, $errorOutput); + $reflectedParent = $reflectedOutput->getParentClass(); + $streamProperty = $reflectedParent->getProperty('stream'); + $streamProperty->setValue($this->output, \fopen('php://memory', 'w', \false)); + } + } + /** + * @return resource + */ + private static function createStream(array $inputs) + { + $stream = \fopen('php://memory', 'r+', \false); + foreach ($inputs as $input) { + \fwrite($stream, $input . \PHP_EOL); + } + \rewind($stream); + return $stream; + } +} diff --git a/vendor/symfony/console/composer.json b/vendor/symfony/console/composer.json new file mode 100644 index 0000000000..8327c6a147 --- /dev/null +++ b/vendor/symfony/console/composer.json @@ -0,0 +1,58 @@ +{ + "name": "symfony\/console", + "type": "library", + "description": "Eases the creation of beautiful and testable command line interfaces", + "keywords": [ + "console", + "cli", + "command-line", + "terminal" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1", + "symfony\/deprecation-contracts": "^2.5|^3", + "symfony\/polyfill-mbstring": "~1.0", + "symfony\/service-contracts": "^2.5|^3", + "symfony\/string": "^5.4|^6.0" + }, + "require-dev": { + "symfony\/config": "^5.4|^6.0", + "symfony\/event-dispatcher": "^5.4|^6.0", + "symfony\/dependency-injection": "^5.4|^6.0", + "symfony\/lock": "^5.4|^6.0", + "symfony\/process": "^5.4|^6.0", + "symfony\/var-dumper": "^5.4|^6.0", + "psr\/log": "^1|^2|^3" + }, + "provide": { + "psr\/log-implementation": "1.0|2.0|3.0" + }, + "conflict": { + "symfony\/dependency-injection": "<5.4", + "symfony\/dotenv": "<5.4", + "symfony\/event-dispatcher": "<5.4", + "symfony\/lock": "<5.4", + "symfony\/process": "<5.4" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/vendor/symfony/dependency-injection/Alias.php b/vendor/symfony/dependency-injection/Alias.php new file mode 100644 index 0000000000..d06b2f6943 --- /dev/null +++ b/vendor/symfony/dependency-injection/Alias.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +class Alias +{ + private const DEFAULT_DEPRECATION_TEMPLATE = 'The "%alias_id%" service alias is deprecated. You should stop using it, as it will be removed in the future.'; + /** + * @var string + */ + private $id; + /** + * @var bool + */ + private $public; + /** + * @var mixed[] + */ + private $deprecation = []; + public function __construct(string $id, bool $public = \false) + { + $this->id = $id; + $this->public = $public; + } + /** + * Checks if this DI Alias should be public or not. + */ + public function isPublic() : bool + { + return $this->public; + } + /** + * Sets if this Alias is public. + * + * @return $this + */ + public function setPublic(bool $boolean) + { + $this->public = $boolean; + return $this; + } + /** + * Whether this alias is private. + */ + public function isPrivate() : bool + { + return !$this->public; + } + /** + * Whether this alias is deprecated, that means it should not be referenced + * anymore. + * + * @param string $package The name of the composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message The deprecation message to use + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + public function setDeprecated(string $package, string $version, string $message) + { + if ('' !== $message) { + if (\preg_match('#[\\r\\n]|\\*/#', $message)) { + throw new InvalidArgumentException('Invalid characters found in deprecation template.'); + } + if (\strpos($message, '%alias_id%') === \false) { + throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.'); + } + } + $this->deprecation = ['package' => $package, 'version' => $version, 'message' => $message ?: self::DEFAULT_DEPRECATION_TEMPLATE]; + return $this; + } + public function isDeprecated() : bool + { + return (bool) $this->deprecation; + } + /** + * @param string $id Service id relying on this definition + */ + public function getDeprecation(string $id) : array + { + return ['package' => $this->deprecation['package'], 'version' => $this->deprecation['version'], 'message' => \str_replace('%alias_id%', $id, $this->deprecation['message'])]; + } + public function __toString() : string + { + return $this->id; + } +} diff --git a/vendor/symfony/dependency-injection/Argument/AbstractArgument.php b/vendor/symfony/dependency-injection/Argument/AbstractArgument.php new file mode 100644 index 0000000000..b58abad0de --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/AbstractArgument.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +/** + * Represents an abstract service argument, which have to be set by a compiler pass or a DI extension. + */ +final class AbstractArgument +{ + /** + * @var string + */ + private $text; + /** + * @var string + */ + private $context = ''; + public function __construct(string $text = '') + { + $this->text = \trim($text, '. '); + } + public function setContext(string $context) : void + { + $this->context = $context . ' is abstract' . ('' === $this->text ? '' : ': '); + } + public function getText() : string + { + return $this->text; + } + public function getTextWithContext() : string + { + return $this->context . $this->text . '.'; + } +} diff --git a/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php b/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php new file mode 100644 index 0000000000..81258efb56 --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a complex argument containing nested values. + * + * @author Titouan Galopin + */ +interface ArgumentInterface +{ + public function getValues() : array; + public function setValues(array $values); +} diff --git a/vendor/symfony/dependency-injection/Argument/BoundArgument.php b/vendor/symfony/dependency-injection/Argument/BoundArgument.php new file mode 100644 index 0000000000..9e8b949fa8 --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/BoundArgument.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +/** + * @author Guilhem Niot + */ +final class BoundArgument implements ArgumentInterface +{ + public const SERVICE_BINDING = 0; + public const DEFAULTS_BINDING = 1; + public const INSTANCEOF_BINDING = 2; + /** + * @var int + */ + private static $sequence = 0; + /** + * @var mixed + */ + private $value; + /** + * @var int|null + */ + private $identifier; + /** + * @var bool|null + */ + private $used; + /** + * @var int + */ + private $type; + /** + * @var string|null + */ + private $file; + /** + * @param mixed $value + */ + public function __construct($value, bool $trackUsage = \true, int $type = 0, string $file = null) + { + $this->value = $value; + if ($trackUsage) { + $this->identifier = ++self::$sequence; + } else { + $this->used = \true; + } + $this->type = $type; + $this->file = $file; + } + /** + * {@inheritdoc} + */ + public function getValues() : array + { + return [$this->value, $this->identifier, $this->used, $this->type, $this->file]; + } + /** + * {@inheritdoc} + */ + public function setValues(array $values) + { + if (5 === \count($values)) { + [$this->value, $this->identifier, $this->used, $this->type, $this->file] = $values; + } else { + [$this->value, $this->identifier, $this->used] = $values; + } + } +} diff --git a/vendor/symfony/dependency-injection/Argument/IteratorArgument.php b/vendor/symfony/dependency-injection/Argument/IteratorArgument.php new file mode 100644 index 0000000000..f92d5233fa --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/IteratorArgument.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a collection of values to lazily iterate over. + * + * @author Titouan Galopin + */ +class IteratorArgument implements ArgumentInterface +{ + /** + * @var mixed[] + */ + private $values; + public function __construct(array $values) + { + $this->setValues($values); + } + public function getValues() : array + { + return $this->values; + } + public function setValues(array $values) + { + $this->values = $values; + } +} diff --git a/vendor/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php b/vendor/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php new file mode 100644 index 0000000000..bebd45c73c --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/ReferenceSetArgumentTrait.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +trigger_deprecation('symfony/dependency-injection', '6.1', '"%s" is deprecated.', ReferenceSetArgumentTrait::class); +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * @author Titouan Galopin + * @author Nicolas Grekas + * + * @deprecated since Symfony 6.1 + */ +trait ReferenceSetArgumentTrait +{ + /** + * @var mixed[] + */ + private $values; + /** + * @param Reference[] $values + */ + public function __construct(array $values) + { + $this->setValues($values); + } + /** + * @return Reference[] + */ + public function getValues() : array + { + return $this->values; + } + /** + * @param Reference[] $values The service references to put in the set + */ + public function setValues(array $values) + { + foreach ($values as $k => $v) { + if (null !== $v && !$v instanceof Reference) { + throw new InvalidArgumentException(\sprintf('A "%s" must hold only Reference instances, "%s" given.', __CLASS__, \get_debug_type($v))); + } + } + $this->values = $values; + } +} diff --git a/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php b/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php new file mode 100644 index 0000000000..25050fd917 --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +/** + * @internal + */ +class RewindableGenerator implements \IteratorAggregate, \Countable +{ + /** + * @var \Closure + */ + private $generator; + /** + * @var \Closure|int + */ + private $count; + /** + * @param int|callable $count + */ + public function __construct(callable $generator, $count) + { + $this->generator = \Closure::fromCallable($generator); + $this->count = \is_int($count) ? $count : \Closure::fromCallable($count); + } + public function getIterator() : \Traversable + { + $g = $this->generator; + return $g(); + } + public function count() : int + { + if (!\is_int($count = $this->count)) { + $this->count = $count(); + } + return $this->count; + } +} diff --git a/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php b/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php new file mode 100644 index 0000000000..8a0a6808a1 --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * Represents a service wrapped in a memoizing closure. + * + * @author Nicolas Grekas + */ +class ServiceClosureArgument implements ArgumentInterface +{ + /** + * @var mixed[] + */ + private $values; + /** + * @param mixed $value + */ + public function __construct($value) + { + $this->values = [$value]; + } + /** + * {@inheritdoc} + */ + public function getValues() : array + { + return $this->values; + } + /** + * {@inheritdoc} + */ + public function setValues(array $values) + { + if ([0] !== \array_keys($values)) { + throw new InvalidArgumentException('A ServiceClosureArgument must hold one and only one value.'); + } + $this->values = $values; + } +} diff --git a/vendor/symfony/dependency-injection/Argument/ServiceLocator.php b/vendor/symfony/dependency-injection/Argument/ServiceLocator.php new file mode 100644 index 0000000000..8de5762915 --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/ServiceLocator.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator; +/** + * @author Nicolas Grekas + * + * @internal + */ +class ServiceLocator extends BaseServiceLocator +{ + /** + * @var \Closure + */ + private $factory; + /** + * @var mixed[] + */ + private $serviceMap; + /** + * @var mixed[]|null + */ + private $serviceTypes; + public function __construct(\Closure $factory, array $serviceMap, array $serviceTypes = null) + { + $this->factory = $factory; + $this->serviceMap = $serviceMap; + $this->serviceTypes = $serviceTypes; + parent::__construct($serviceMap); + } + /** + * {@inheritdoc} + * @return mixed + */ + public function get(string $id) + { + switch (\count($this->serviceMap[$id] ?? [])) { + case 0: + return parent::get($id); + case 1: + return $this->serviceMap[$id][0]; + default: + return ($this->factory)(...$this->serviceMap[$id]); + } + } + /** + * {@inheritdoc} + */ + public function getProvidedServices() : array + { + return $this->serviceTypes = $this->serviceTypes ?? \array_map(function () { + return '?'; + }, $this->serviceMap); + } +} diff --git a/vendor/symfony/dependency-injection/Argument/ServiceLocatorArgument.php b/vendor/symfony/dependency-injection/Argument/ServiceLocatorArgument.php new file mode 100644 index 0000000000..694a0c532c --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/ServiceLocatorArgument.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a closure acting as a service locator. + * + * @author Nicolas Grekas + */ +class ServiceLocatorArgument implements ArgumentInterface +{ + /** + * @var mixed[] + */ + private $values; + /** + * @var \Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument|null + */ + private $taggedIteratorArgument; + /** + * @param mixed[]|\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument $values + */ + public function __construct($values = []) + { + if ($values instanceof TaggedIteratorArgument) { + $this->taggedIteratorArgument = $values; + $values = []; + } + $this->setValues($values); + } + public function getTaggedIteratorArgument() : ?TaggedIteratorArgument + { + return $this->taggedIteratorArgument; + } + public function getValues() : array + { + return $this->values; + } + public function setValues(array $values) + { + $this->values = $values; + } +} diff --git a/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php b/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php new file mode 100644 index 0000000000..2fccfb5b1b --- /dev/null +++ b/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a collection of services found by tag name to lazily iterate over. + * + * @author Roland Franssen + */ +class TaggedIteratorArgument extends IteratorArgument +{ + /** + * @var string + */ + private $tag; + /** + * @var mixed + */ + private $indexAttribute; + /** + * @var string|null + */ + private $defaultIndexMethod; + /** + * @var string|null + */ + private $defaultPriorityMethod; + /** + * @var bool + */ + private $needsIndexes; + /** + * @var mixed[] + */ + private $exclude; + /** + * @param string $tag The name of the tag identifying the target services + * @param string|null $indexAttribute The name of the attribute that defines the key referencing each service in the tagged collection + * @param string|null $defaultIndexMethod The static method that should be called to get each service's key when their tag doesn't define the previous attribute + * @param bool $needsIndexes Whether indexes are required and should be generated when computing the map + * @param string|null $defaultPriorityMethod The static method that should be called to get each service's priority when their tag doesn't define the "priority" attribute + * @param array $exclude Services to exclude from the iterator + */ + public function __construct(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, bool $needsIndexes = \false, string $defaultPriorityMethod = null, array $exclude = []) + { + parent::__construct([]); + if (null === $indexAttribute && $needsIndexes) { + $indexAttribute = \preg_match('/[^.]++$/', $tag, $m) ? $m[0] : $tag; + } + $this->tag = $tag; + $this->indexAttribute = $indexAttribute; + $this->defaultIndexMethod = $defaultIndexMethod ?: ($indexAttribute ? 'getDefault' . \str_replace(' ', '', \ucwords(\preg_replace('/[^a-zA-Z0-9\\x7f-\\xff]++/', ' ', $indexAttribute))) . 'Name' : null); + $this->needsIndexes = $needsIndexes; + $this->defaultPriorityMethod = $defaultPriorityMethod ?: ($indexAttribute ? 'getDefault' . \str_replace(' ', '', \ucwords(\preg_replace('/[^a-zA-Z0-9\\x7f-\\xff]++/', ' ', $indexAttribute))) . 'Priority' : null); + $this->exclude = $exclude; + } + public function getTag() + { + return $this->tag; + } + public function getIndexAttribute() : ?string + { + return $this->indexAttribute; + } + public function getDefaultIndexMethod() : ?string + { + return $this->defaultIndexMethod; + } + public function needsIndexes() : bool + { + return $this->needsIndexes; + } + public function getDefaultPriorityMethod() : ?string + { + return $this->defaultPriorityMethod; + } + public function getExclude() : array + { + return $this->exclude; + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/AsDecorator.php b/vendor/symfony/dependency-injection/Attribute/AsDecorator.php new file mode 100644 index 0000000000..7b84b71850 --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/AsDecorator.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +#[\Attribute(\Attribute::TARGET_CLASS)] +class AsDecorator +{ + /** + * @var string + */ + public $decorates; + /** + * @var int + */ + public $priority = 0; + /** + * @var int + */ + public $onInvalid = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + public function __construct(string $decorates, int $priority = 0, int $onInvalid = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + $this->decorates = $decorates; + $this->priority = $priority; + $this->onInvalid = $onInvalid; + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/AsTaggedItem.php b/vendor/symfony/dependency-injection/Attribute/AsTaggedItem.php new file mode 100644 index 0000000000..21b6964a91 --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/AsTaggedItem.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +/** + * An attribute to tell under which index and priority a service class should be found in tagged iterators/locators. + * + * @author Nicolas Grekas + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class AsTaggedItem +{ + /** + * @var string|null + */ + public $index; + /** + * @var int|null + */ + public $priority; + public function __construct(?string $index = null, ?int $priority = null) + { + $this->index = $index; + $this->priority = $priority; + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/Autoconfigure.php b/vendor/symfony/dependency-injection/Attribute/Autoconfigure.php new file mode 100644 index 0000000000..53fcbedb2c --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/Autoconfigure.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +/** + * An attribute to tell how a base type should be autoconfigured. + * + * @author Nicolas Grekas + */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)] +class Autoconfigure +{ + /** + * @var mixed[]|null + */ + public $tags; + /** + * @var mixed[]|null + */ + public $calls; + /** + * @var mixed[]|null + */ + public $bind; + /** + * @var bool|string|null + */ + public $lazy = null; + /** + * @var bool|null + */ + public $public; + /** + * @var bool|null + */ + public $shared; + /** + * @var bool|null + */ + public $autowire; + /** + * @var mixed[]|null + */ + public $properties; + /** + * @var mixed[]|string|null + */ + public $configurator = null; + /** + * @param bool|string|null $lazy + * @param mixed[]|string|null $configurator + */ + public function __construct(?array $tags = null, ?array $calls = null, ?array $bind = null, $lazy = null, ?bool $public = null, ?bool $shared = null, ?bool $autowire = null, ?array $properties = null, $configurator = null) + { + $this->tags = $tags; + $this->calls = $calls; + $this->bind = $bind; + $this->lazy = $lazy; + $this->public = $public; + $this->shared = $shared; + $this->autowire = $autowire; + $this->properties = $properties; + $this->configurator = $configurator; + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/AutoconfigureTag.php b/vendor/symfony/dependency-injection/Attribute/AutoconfigureTag.php new file mode 100644 index 0000000000..82ea6183ec --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/AutoconfigureTag.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +/** + * An attribute to tell how a base type should be tagged. + * + * @author Nicolas Grekas + */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)] +class AutoconfigureTag extends Autoconfigure +{ + public function __construct(string $name = null, array $attributes = []) + { + parent::__construct([[$name ?? 0 => $attributes]]); + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/Autowire.php b/vendor/symfony/dependency-injection/Attribute/Autowire.php new file mode 100644 index 0000000000..bc18e727ed --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/Autowire.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * Attribute to tell a parameter how to be autowired. + * + * @author Kevin Bond + */ +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class Autowire +{ + /** + * @readonly + * @var string|\Symfony\Component\ExpressionLanguage\Expression|\Symfony\Component\DependencyInjection\Reference + */ + public $value; + /** + * Use only ONE of the following. + * + * @param string|null $value Parameter value (ie "%kernel.project_dir%/some/path") + * @param string|null $service Service ID (ie "some.service") + * @param string|null $expression Expression (ie 'service("some.service").someMethod()') + */ + public function __construct(string $value = null, string $service = null, string $expression = null) + { + if (!($service xor $expression xor null !== $value)) { + throw new LogicException('#[Autowire] attribute must declare exactly one of $service, $expression, or $value.'); + } + if (null !== $value && \strncmp($value, '@', \strlen('@')) === 0) { + switch (\true) { + case \strncmp($value, '@@', \strlen('@@')) === 0: + $value = \substr($value, 1); + break; + case \strncmp($value, '@=', \strlen('@=')) === 0: + $expression = \substr($value, 2); + break; + default: + $service = \substr($value, 1); + break; + } + } + switch (\true) { + case null !== $service: + $this->value = new Reference($service); + break; + case null !== $expression: + if (!\class_exists(Expression::class)) { + throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".'); + } + $this->value = new Expression($expression); + break; + case null !== $value: + $this->value = $value; + break; + } + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/MapDecorated.php b/vendor/symfony/dependency-injection/Attribute/MapDecorated.php new file mode 100644 index 0000000000..7039009092 --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/MapDecorated.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class MapDecorated +{ +} diff --git a/vendor/symfony/dependency-injection/Attribute/TaggedIterator.php b/vendor/symfony/dependency-injection/Attribute/TaggedIterator.php new file mode 100644 index 0000000000..68e23cf123 --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/TaggedIterator.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class TaggedIterator +{ + /** + * @var string + */ + public $tag; + /** + * @var string|null + */ + public $indexAttribute; + /** + * @var string|null + */ + public $defaultIndexMethod; + /** + * @var string|null + */ + public $defaultPriorityMethod; + /** + * @var string|mixed[] + */ + public $exclude = []; + /** + * @param string|mixed[] $exclude + */ + public function __construct(string $tag, ?string $indexAttribute = null, ?string $defaultIndexMethod = null, ?string $defaultPriorityMethod = null, $exclude = []) + { + $this->tag = $tag; + $this->indexAttribute = $indexAttribute; + $this->defaultIndexMethod = $defaultIndexMethod; + $this->defaultPriorityMethod = $defaultPriorityMethod; + $this->exclude = $exclude; + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/TaggedLocator.php b/vendor/symfony/dependency-injection/Attribute/TaggedLocator.php new file mode 100644 index 0000000000..c817c77fb0 --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/TaggedLocator.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +#[\Attribute(\Attribute::TARGET_PARAMETER)] +class TaggedLocator +{ + /** + * @var string + */ + public $tag; + /** + * @var string|null + */ + public $indexAttribute; + /** + * @var string|null + */ + public $defaultIndexMethod; + /** + * @var string|null + */ + public $defaultPriorityMethod; + /** + * @var string|mixed[] + */ + public $exclude = []; + /** + * @param string|mixed[] $exclude + */ + public function __construct(string $tag, ?string $indexAttribute = null, ?string $defaultIndexMethod = null, ?string $defaultPriorityMethod = null, $exclude = []) + { + $this->tag = $tag; + $this->indexAttribute = $indexAttribute; + $this->defaultIndexMethod = $defaultIndexMethod; + $this->defaultPriorityMethod = $defaultPriorityMethod; + $this->exclude = $exclude; + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/Target.php b/vendor/symfony/dependency-injection/Attribute/Target.php new file mode 100644 index 0000000000..d672e3f201 --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/Target.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * An attribute to tell how a dependency is used and hint named autowiring aliases. + * + * @author Nicolas Grekas + */ +#[\Attribute(\Attribute::TARGET_PARAMETER)] +final class Target +{ + /** + * @var string + */ + public $name; + public function __construct(string $name) + { + $this->name = \lcfirst(\str_replace(' ', '', \ucwords(\preg_replace('/[^a-zA-Z0-9\\x7f-\\xff]++/', ' ', $name)))); + } + public static function parseName(\ReflectionParameter $parameter) : string + { + if (!($target = (\method_exists($parameter, 'getAttributes') ? $parameter->getAttributes(self::class) : [])[0] ?? null)) { + return $parameter->name; + } + $name = $target->newInstance()->name; + if (!\preg_match('/^[a-zA-Z_\\x7f-\\xff]/', $name)) { + if (($function = $parameter->getDeclaringFunction()) instanceof \ReflectionMethod) { + $function = $function->class . '::' . $function->name; + } else { + $function = $function->name; + } + throw new InvalidArgumentException(\sprintf('Invalid #[Target] name "%s" on parameter "$%s" of "%s()": the first character must be a letter.', $name, $parameter->name, $function)); + } + return $name; + } +} diff --git a/vendor/symfony/dependency-injection/Attribute/When.php b/vendor/symfony/dependency-injection/Attribute/When.php new file mode 100644 index 0000000000..016bfb96e1 --- /dev/null +++ b/vendor/symfony/dependency-injection/Attribute/When.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute; + +/** + * An attribute to tell under which environment this class should be registered as a service. + * + * @author Nicolas Grekas + */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_FUNCTION | \Attribute::IS_REPEATABLE)] +class When +{ + /** + * @var string + */ + public $env; + public function __construct(string $env) + { + $this->env = $env; + } +} diff --git a/vendor/symfony/dependency-injection/CHANGELOG.md b/vendor/symfony/dependency-injection/CHANGELOG.md new file mode 100644 index 0000000000..ced60bd357 --- /dev/null +++ b/vendor/symfony/dependency-injection/CHANGELOG.md @@ -0,0 +1,325 @@ +CHANGELOG +========= + +6.1 +--- + + * Add `#[MapDecorated]` attribute telling to which parameter the decorated service should be mapped in a decorator + * Add `#[AsDecorator]` attribute to make a service decorates another + * Add `$exclude` to `TaggedIterator` and `TaggedLocator` attributes + * Add `$exclude` to `tagged_iterator` and `tagged_locator` configurator + * Add an `env` function to the expression language provider + * Add an `Autowire` attribute to tell a parameter how to be autowired + * Allow using expressions as service factories + * Add argument type `closure` to help passing closures to services + * Deprecate `ReferenceSetArgumentTrait` + * Add `AbstractExtension` class for DI configuration/definition on a single file + +6.0 +--- + + * Remove `Definition::setPrivate()` and `Alias::setPrivate()`, use `setPublic()` instead + * Remove `inline()` in favor of `inline_service()` and `ref()` in favor of `service()` when using the PHP-DSL + * Remove `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead + * Remove `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead + * Remove the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service + +5.4 +--- + * Add `$defaultIndexMethod` and `$defaultPriorityMethod` to `TaggedIterator` and `TaggedLocator` attributes + * Add `service_closure()` to the PHP-DSL + * Add support for autoconfigurable attributes on methods, properties and parameters + * Make auto-aliases private by default + * Add support for autowiring union and intersection types + +5.3 +--- + + * Add `ServicesConfigurator::remove()` in the PHP-DSL + * Add `%env(not:...)%` processor to negate boolean values + * Add support for loading autoconfiguration rules via the `#[Autoconfigure]` and `#[AutoconfigureTag]` attributes on PHP 8 + * Add `#[AsTaggedItem]` attribute for defining the index and priority of classes found in tagged iterators/locators + * Add autoconfigurable attributes + * Add support for autowiring tagged iterators and locators via attributes on PHP 8 + * Add support for per-env configuration in XML and Yaml loaders + * Add `ContainerBuilder::willBeAvailable()` to help with conditional configuration + * Add support an integer return value for default_index_method + * Add `#[When(env: 'foo')]` to skip autoregistering a class when the env doesn't match + * Add `env()` and `EnvConfigurator` in the PHP-DSL + * Add support for `ConfigBuilder` in the `PhpFileLoader` + * Add `ContainerConfigurator::env()` to get the current environment + * Add `#[Target]` to tell how a dependency is used and hint named autowiring aliases + +5.2.0 +----- + + * added `param()` and `abstract_arg()` in the PHP-DSL + * deprecated `Definition::setPrivate()` and `Alias::setPrivate()`, use `setPublic()` instead + * added support for the `#[Required]` attribute + +5.1.0 +----- + + * deprecated `inline()` in favor of `inline_service()` and `ref()` in favor of `service()` when using the PHP-DSL + * allow decorators to reference their decorated service using the special `.inner` id + * added support to autowire public typed properties in php 7.4 + * added support for defining method calls, a configurator, and property setters in `InlineServiceConfigurator` + * added possibility to define abstract service arguments + * allowed mixing "parent" and instanceof-conditionals/defaults/bindings + * updated the signature of method `Definition::setDeprecated()` to `Definition::setDeprecation(string $package, string $version, string $message)` + * updated the signature of method `Alias::setDeprecated()` to `Alias::setDeprecation(string $package, string $version, string $message)` + * updated the signature of method `DeprecateTrait::deprecate()` to `DeprecateTrait::deprecation(string $package, string $version, string $message)` + * deprecated the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service, + configure them explicitly instead + * added class `Symfony\Component\DependencyInjection\Dumper\Preloader` to help with preloading on PHP 7.4+ + * added tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload + * allowed loading and dumping tags with an attribute named "name" + * deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead + * deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead + * added support of PHP8 static return type for withers + * added `AliasDeprecatedPublicServicesPass` to deprecate public services to private + +5.0.0 +----- + + * removed support for auto-discovered extension configuration class which does not implement `ConfigurationInterface` + * removed support for non-string default env() parameters + * moved `ServiceSubscriberInterface` to the `Symfony\Contracts\Service` namespace + * removed `RepeatedPass` and `RepeatablePassInterface` + * removed support for short factory/configurator syntax from `YamlFileLoader` + * removed `ResettableContainerInterface`, use `ResetInterface` instead + * added argument `$returnsClone` to `Definition::addMethodCall()` + * removed `tagged`, use `tagged_iterator` instead + +4.4.0 +----- + + * added `CheckTypeDeclarationsPass` to check injected parameters type during compilation + * added support for opcache.preload by generating a preloading script in the cache folder + * added support for dumping the container in one file instead of many files + * deprecated support for short factories and short configurators in Yaml + * added `tagged_iterator` alias for `tagged` which might be deprecated in a future version + * deprecated passing an instance of `Symfony\Component\DependencyInjection\Parameter` as class name to `Symfony\Component\DependencyInjection\Definition` + * added support for binding iterable and tagged services + * made singly-implemented interfaces detection be scoped by file + * added ability to define a static priority method for tagged service + * added support for improved syntax to define method calls in Yaml + * made the `%env(base64:...)%` processor able to decode base64url + * added ability to choose behavior of decorations on non existent decorated services + +4.3.0 +----- + + * added `%env(trim:...)%` processor to trim a string value + * added `%env(default:param_name:...)%` processor to fallback to a parameter or to null when using `%env(default::...)%` + * added `%env(url:...)%` processor to convert an URL or DNS into an array of components + * added `%env(query_string:...)%` processor to convert a query string into an array of key values + * added support for deprecating aliases + * made `ContainerParametersResource` final and not implement `Serializable` anymore + * added `ReverseContainer`: a container that turns services back to their ids + * added ability to define an index for a tagged collection + * added ability to define an index for services in an injected service locator argument + * made `ServiceLocator` implement `ServiceProviderInterface` + * deprecated support for non-string default env() parameters + * added `%env(require:...)%` processor to `require()` a PHP file and use the value returned from it + +4.2.0 +----- + + * added `ContainerBuilder::registerAliasForArgument()` to support autowiring by type+name + * added support for binding by type+name + * added `ServiceSubscriberTrait` to ease implementing `ServiceSubscriberInterface` using methods' return types + * added `ServiceLocatorArgument` and `!service_locator` config tag for creating optimized service-locators + * added support for autoconfiguring bindings + * added `%env(key:...)%` processor to fetch a specific key from an array + * deprecated `ServiceSubscriberInterface`, use the same interface from the `Symfony\Contracts\Service` namespace instead + * deprecated `ResettableContainerInterface`, use `Symfony\Contracts\Service\ResetInterface` instead + +4.1.0 +----- + + * added support for variadics in named arguments + * added PSR-11 `ContainerBagInterface` and its `ContainerBag` implementation to access parameters as-a-service + * added support for service's decorators autowiring + * deprecated the `TypedReference::canBeAutoregistered()` and `TypedReference::getRequiringClass()` methods + * environment variables are validated when used in extension configuration + * deprecated support for auto-discovered extension configuration class which does not implement `ConfigurationInterface` + +4.0.0 +----- + + * Relying on service auto-registration while autowiring is not supported anymore. + Explicitly inject your dependencies or create services whose ids are + their fully-qualified class name. + + Before: + + ```php + namespace App\Controller; + + use App\Mailer; + + class DefaultController + { + public function __construct(Mailer $mailer) { + // ... + } + + // ... + } + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + ``` + + After: + + ```php + // same PHP code + ``` + ```yml + services: + App\Controller\DefaultController: + autowire: true + + # or + # App\Controller\DefaultController: + # arguments: { $mailer: "@App\Mailer" } + + App\Mailer: + autowire: true + ``` + * removed autowiring services based on the types they implement + * added a third `$methodName` argument to the `getProxyFactoryCode()` method + of the `DumperInterface` + * removed support for autowiring types + * removed `Container::isFrozen` + * removed support for dumping an ucompiled container in `PhpDumper` + * removed support for generating a dumped `Container` without populating the method map + * removed support for case insensitive service identifiers + * removed the `DefinitionDecorator` class, replaced by `ChildDefinition` + * removed the `AutowireServiceResource` class and related `AutowirePass::createResourceForClass()` method + * removed `LoggingFormatter`, `Compiler::getLoggingFormatter()` and `addLogMessage()` class and methods, use the `ContainerBuilder::log()` method instead + * removed `FactoryReturnTypePass` + * removed `ContainerBuilder::addClassResource()`, use the `addObjectResource()` or the `getReflectionClass()` method instead. + * removed support for top-level anonymous services + * removed silent behavior for unused attributes and elements + * removed support for setting and accessing private services in `Container` + * removed support for setting pre-defined services in `Container` + * removed support for case insensitivity of parameter names + * removed `AutowireExceptionPass` and `AutowirePass::getAutowiringExceptions()`, use `Definition::addError()` and the `DefinitionErrorExceptionPass` instead + +3.4.0 +----- + + * moved the `ExtensionCompilerPass` to before-optimization passes with priority -1000 + * deprecated "public-by-default" definitions and aliases, the new default will be "private" in 4.0 + * added `EnvVarProcessorInterface` and corresponding "container.env_var_processor" tag for processing env vars + * added support for ignore-on-uninitialized references + * deprecated service auto-registration while autowiring + * deprecated the ability to check for the initialization of a private service with the `Container::initialized()` method + * deprecated support for top-level anonymous services in XML + * deprecated case insensitivity of parameter names + * deprecated the `ResolveDefinitionTemplatesPass` class in favor of `ResolveChildDefinitionsPass` + * added `TaggedIteratorArgument` with YAML (`!tagged foo`) and XML (``) support + * deprecated `AutowireExceptionPass` and `AutowirePass::getAutowiringExceptions()`, use `Definition::addError()` and the `DefinitionErrorExceptionPass` instead + +3.3.0 +----- + + * deprecated autowiring services based on the types they implement; + rename (or alias) your services to their FQCN id to make them autowirable + * added "ServiceSubscriberInterface" - to allow for per-class explicit service-locator definitions + * added "container.service_locator" tag for defining service-locator services + * added anonymous services support in YAML configuration files using the `!service` tag. + * added "TypedReference" and "ServiceClosureArgument" for creating service-locator services + * added `ServiceLocator` - a PSR-11 container holding a set of services to be lazily loaded + * added "instanceof" section for local interface-defined configs + * added prototype services for PSR4-based discovery and registration + * added `ContainerBuilder::getReflectionClass()` for retrieving and tracking reflection class info + * deprecated `ContainerBuilder::getClassResource()`, use `ContainerBuilder::getReflectionClass()` or `ContainerBuilder::addObjectResource()` instead + * added `ContainerBuilder::fileExists()` for checking and tracking file or directory existence + * deprecated autowiring-types, use aliases instead + * added support for omitting the factory class name in a service definition if the definition class is set + * deprecated case insensitivity of service identifiers + * added "iterator" argument type for lazy iteration over a set of values and services + * added file-wide configurable defaults for service attributes "public", "tags", + "autowire" and "autoconfigure" + * made the "class" attribute optional, using the "id" as fallback + * using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and + will not be supported anymore in 4.0 + * deprecated the `DefinitionDecorator` class in favor of `ChildDefinition` + * allow config files to be loaded using a glob pattern + * [BC BREAK] the `NullDumper` class is now final + +3.2.0 +----- + + * allowed to prioritize compiler passes by introducing a third argument to `PassConfig::addPass()`, to `Compiler::addPass` and to `ContainerBuilder::addCompilerPass()` + * added support for PHP constants in YAML configuration files + * deprecated the ability to set or unset a private service with the `Container::set()` method + * deprecated the ability to check for the existence of a private service with the `Container::has()` method + * deprecated the ability to request a private service with the `Container::get()` method + * deprecated support for generating a dumped `Container` without populating the method map + +3.0.0 +----- + + * removed all deprecated codes from 2.x versions + +2.8.0 +----- + + * deprecated the abstract ContainerAware class in favor of ContainerAwareTrait + * deprecated IntrospectableContainerInterface, to be merged with ContainerInterface in 3.0 + * allowed specifying a directory to recursively load all configuration files it contains + * deprecated the concept of scopes + * added `Definition::setShared()` and `Definition::isShared()` + * added ResettableContainerInterface to be able to reset the container to release memory on shutdown + * added a way to define the priority of service decoration + * added support for service autowiring + +2.7.0 +----- + + * deprecated synchronized services + +2.6.0 +----- + + * added new factory syntax and deprecated the old one + +2.5.0 +----- + + * added DecoratorServicePass and a way to override a service definition (Definition::setDecoratedService()) + * deprecated SimpleXMLElement class. + +2.4.0 +----- + + * added support for expressions in service definitions + * added ContainerAwareTrait to add default container aware behavior to a class + +2.2.0 +----- + + * added Extension::isConfigEnabled() to ease working with enableable configurations + * added an Extension base class with sensible defaults to be used in conjunction + with the Config component. + * added PrependExtensionInterface (to be able to allow extensions to prepend + application configuration settings for any Bundle) + +2.1.0 +----- + + * added IntrospectableContainerInterface (to be able to check if a service + has been initialized or not) + * added ConfigurationExtensionInterface + * added Definition::clearTag() + * component exceptions that inherit base SPL classes are now used exclusively + (this includes dumped containers) + * [BC BREAK] fixed unescaping of class arguments, method + ParameterBag::unescapeValue() was made public diff --git a/vendor/symfony/dependency-injection/ChildDefinition.php b/vendor/symfony/dependency-injection/ChildDefinition.php new file mode 100644 index 0000000000..f2ca99f07a --- /dev/null +++ b/vendor/symfony/dependency-injection/ChildDefinition.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; +/** + * This definition extends another definition. + * + * @author Johannes M. Schmitt + */ +class ChildDefinition extends Definition +{ + /** + * @var string + */ + private $parent; + /** + * @param string $parent The id of Definition instance to decorate + */ + public function __construct(string $parent) + { + $this->parent = $parent; + } + /** + * Returns the Definition to inherit from. + */ + public function getParent() : string + { + return $this->parent; + } + /** + * Sets the Definition to inherit from. + * + * @return $this + */ + public function setParent(string $parent) + { + $this->parent = $parent; + return $this; + } + /** + * Gets an argument to pass to the service constructor/factory method. + * + * If replaceArgument() has been used to replace an argument, this method + * will return the replacement value. + * + * @throws OutOfBoundsException When the argument does not exist + * @param int|string $index + * @return mixed + */ + public function getArgument($index) + { + if (\array_key_exists('index_' . $index, $this->arguments)) { + return $this->arguments['index_' . $index]; + } + return parent::getArgument($index); + } + /** + * You should always use this method when overwriting existing arguments + * of the parent definition. + * + * If you directly call setArguments() keep in mind that you must follow + * certain conventions when you want to overwrite the arguments of the + * parent definition, otherwise your arguments will only be appended. + * + * @return $this + * + * @throws InvalidArgumentException when $index isn't an integer + * @param int|string $index + * @param mixed $value + */ + public function replaceArgument($index, $value) + { + if (\is_int($index)) { + $this->arguments['index_' . $index] = $value; + } elseif (\strncmp($index, '$', \strlen('$')) === 0) { + $this->arguments[$index] = $value; + } else { + throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.'); + } + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php b/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php new file mode 100644 index 0000000000..86c0ca9128 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php @@ -0,0 +1,226 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ExpressionLanguage; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * @author Nicolas Grekas + */ +abstract class AbstractRecursivePass implements CompilerPassInterface +{ + /** + * @var ContainerBuilder + */ + protected $container; + protected $currentId; + /** + * @var bool + */ + private $processExpressions = \false; + /** + * @var \Symfony\Component\DependencyInjection\ExpressionLanguage + */ + private $expressionLanguage; + /** + * @var bool + */ + private $inExpression = \false; + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + try { + $this->processValue($container->getDefinitions(), \true); + } finally { + $this->container = null; + } + } + protected function enableExpressionProcessing() + { + $this->processExpressions = \true; + } + protected function inExpression(bool $reset = \true) : bool + { + $inExpression = $this->inExpression; + if ($reset) { + $this->inExpression = \false; + } + return $inExpression; + } + /** + * Processes a value found in a definition tree. + * + * @return mixed + * @param mixed $value + */ + protected function processValue($value, bool $isRoot = \false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + if ($isRoot) { + $this->currentId = $k; + } + if ($v !== ($processedValue = $this->processValue($v, $isRoot))) { + $value[$k] = $processedValue; + } + } + } elseif ($value instanceof ArgumentInterface) { + $value->setValues($this->processValue($value->getValues())); + } elseif ($value instanceof Expression && $this->processExpressions) { + $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container', 'args' => 'args']); + } elseif ($value instanceof Definition) { + $value->setArguments($this->processValue($value->getArguments())); + $value->setProperties($this->processValue($value->getProperties())); + $value->setMethodCalls($this->processValue($value->getMethodCalls())); + $changes = $value->getChanges(); + if (isset($changes['factory'])) { + if (\is_string($factory = $value->getFactory()) && \strncmp($factory, '@=', \strlen('@=')) === 0) { + if (!\class_exists(Expression::class)) { + throw new LogicException('Expressions cannot be used in service factories without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); + } + $factory = new Expression(\substr($factory, 2)); + } + if (($factory = $this->processValue($factory)) instanceof Expression) { + $factory = '@=' . $factory; + } + $value->setFactory($factory); + } + if (isset($changes['configurator'])) { + $value->setConfigurator($this->processValue($value->getConfigurator())); + } + } + return $value; + } + /** + * @throws RuntimeException + */ + protected function getConstructor(Definition $definition, bool $required) : ?\ReflectionFunctionAbstract + { + if ($definition->isSynthetic()) { + return null; + } + if (\is_string($factory = $definition->getFactory())) { + if (\strncmp($factory, '@=', \strlen('@=')) === 0) { + return new \ReflectionFunction(static function (...$args) { + }); + } + if (!\function_exists($factory)) { + throw new RuntimeException(\sprintf('Invalid service "%s": function "%s" does not exist.', $this->currentId, $factory)); + } + $r = new \ReflectionFunction($factory); + if (\false !== $r->getFileName() && \file_exists($r->getFileName())) { + $this->container->fileExists($r->getFileName()); + } + return $r; + } + if ($factory) { + [$class, $method] = $factory; + if ('__construct' === $method) { + throw new RuntimeException(\sprintf('Invalid service "%s": "__construct()" cannot be used as a factory method.', $this->currentId)); + } + if ($class instanceof Reference) { + $factoryDefinition = $this->container->findDefinition((string) $class); + while (null === ($class = $factoryDefinition->getClass()) && $factoryDefinition instanceof ChildDefinition) { + $factoryDefinition = $this->container->findDefinition($factoryDefinition->getParent()); + } + } elseif ($class instanceof Definition) { + $class = $class->getClass(); + } elseif (null === $class) { + $class = $definition->getClass(); + } + return $this->getReflectionMethod(new Definition($class), $method); + } + while (null === ($class = $definition->getClass()) && $definition instanceof ChildDefinition) { + $definition = $this->container->findDefinition($definition->getParent()); + } + try { + if (!($r = $this->container->getReflectionClass($class))) { + if (null === $class) { + throw new RuntimeException(\sprintf('Invalid service "%s": the class is not set.', $this->currentId)); + } + throw new RuntimeException(\sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + } + } catch (\ReflectionException $e) { + throw new RuntimeException(\sprintf('Invalid service "%s": ', $this->currentId) . \lcfirst($e->getMessage())); + } + if (!($r = $r->getConstructor())) { + if ($required) { + throw new RuntimeException(\sprintf('Invalid service "%s": class%s has no constructor.', $this->currentId, \sprintf($class !== $this->currentId ? ' "%s"' : '', $class))); + } + } elseif (!$r->isPublic()) { + throw new RuntimeException(\sprintf('Invalid service "%s": ', $this->currentId) . \sprintf($class !== $this->currentId ? 'constructor of class "%s"' : 'its constructor', $class) . ' must be public.'); + } + return $r; + } + /** + * @throws RuntimeException + */ + protected function getReflectionMethod(Definition $definition, string $method) : \ReflectionFunctionAbstract + { + if ('__construct' === $method) { + return $this->getConstructor($definition, \true); + } + while (null === ($class = $definition->getClass()) && $definition instanceof ChildDefinition) { + $definition = $this->container->findDefinition($definition->getParent()); + } + if (null === $class) { + throw new RuntimeException(\sprintf('Invalid service "%s": the class is not set.', $this->currentId)); + } + if (!($r = $this->container->getReflectionClass($class))) { + throw new RuntimeException(\sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + } + if (!$r->hasMethod($method)) { + if ($r->hasMethod('__call') && ($r = $r->getMethod('__call')) && $r->isPublic()) { + return new \ReflectionMethod(static function (...$arguments) { + }, '__invoke'); + } + throw new RuntimeException(\sprintf('Invalid service "%s": method "%s()" does not exist.', $this->currentId, $class !== $this->currentId ? $class . '::' . $method : $method)); + } + $r = $r->getMethod($method); + if (!$r->isPublic()) { + throw new RuntimeException(\sprintf('Invalid service "%s": method "%s()" must be public.', $this->currentId, $class !== $this->currentId ? $class . '::' . $method : $method)); + } + return $r; + } + private function getExpressionLanguage() : ExpressionLanguage + { + if (!isset($this->expressionLanguage)) { + if (!\class_exists(ExpressionLanguage::class)) { + throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".'); + } + $providers = $this->container->getExpressionLanguageProviders(); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function (string $arg) : string { + if ('""' === \substr_replace($arg, '', 1, -1)) { + $id = \stripcslashes(\substr($arg, 1, -1)); + $this->inExpression = \true; + $arg = $this->processValue(new Reference($id)); + $this->inExpression = \false; + if (!$arg instanceof Reference) { + throw new RuntimeException(\sprintf('"%s::processValue()" must return a Reference when processing an expression, "%s" returned for service("%s").', static::class, \get_debug_type($arg), $id)); + } + $arg = \sprintf('"%s"', $arg); + } + return \sprintf('$this->get(%s)', $arg); + }); + } + return $this->expressionLanguage; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AliasDeprecatedPublicServicesPass.php b/vendor/symfony/dependency-injection/Compiler/AliasDeprecatedPublicServicesPass.php new file mode 100644 index 0000000000..97eb51cce5 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AliasDeprecatedPublicServicesPass.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +final class AliasDeprecatedPublicServicesPass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $aliases = []; + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof Reference && isset($this->aliases[$id = (string) $value])) { + return new Reference($this->aliases[$id], $value->getInvalidBehavior()); + } + return parent::processValue($value, $isRoot); + } + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->findTaggedServiceIds('container.private') as $id => $tags) { + if (null === ($package = $tags[0]['package'] ?? null)) { + throw new InvalidArgumentException(\sprintf('The "package" attribute is mandatory for the "container.private" tag on the "%s" service.', $id)); + } + if (null === ($version = $tags[0]['version'] ?? null)) { + throw new InvalidArgumentException(\sprintf('The "version" attribute is mandatory for the "container.private" tag on the "%s" service.', $id)); + } + $definition = $container->getDefinition($id); + if (!$definition->isPublic() || $definition->isPrivate()) { + continue; + } + $container->setAlias($id, $aliasId = '.container.private.' . $id)->setPublic(\true)->setDeprecated($package, $version, 'Accessing the "%alias_id%" service directly from the container is deprecated, use dependency injection instead.'); + $container->setDefinition($aliasId, $definition); + $this->aliases[$id] = $aliasId; + } + parent::process($container); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php b/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php new file mode 100644 index 0000000000..ec26e858eb --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * Run this pass before passes that need to know more about the relation of + * your services. + * + * This class will populate the ServiceReferenceGraph with information. You can + * retrieve the graph in other passes from the compiler. + * + * @author Johannes M. Schmitt + * @author Nicolas Grekas + */ +class AnalyzeServiceReferencesPass extends AbstractRecursivePass +{ + /** + * @var \Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraph + */ + private $graph; + /** + * @var \Symfony\Component\DependencyInjection\Definition|null + */ + private $currentDefinition; + /** + * @var bool + */ + private $onlyConstructorArguments; + /** + * @var bool + */ + private $hasProxyDumper; + /** + * @var bool + */ + private $lazy; + /** + * @var bool + */ + private $byConstructor; + /** + * @var bool + */ + private $byFactory; + /** + * @var mixed[] + */ + private $definitions; + /** + * @var mixed[] + */ + private $aliases; + /** + * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls + */ + public function __construct(bool $onlyConstructorArguments = \false, bool $hasProxyDumper = \true) + { + $this->onlyConstructorArguments = $onlyConstructorArguments; + $this->hasProxyDumper = $hasProxyDumper; + $this->enableExpressionProcessing(); + } + /** + * Processes a ContainerBuilder object to populate the service reference graph. + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->graph = $container->getCompiler()->getServiceReferenceGraph(); + $this->graph->clear(); + $this->lazy = \false; + $this->byConstructor = \false; + $this->byFactory = \false; + $this->definitions = $container->getDefinitions(); + $this->aliases = $container->getAliases(); + foreach ($this->aliases as $id => $alias) { + $targetId = $this->getDefinitionId((string) $alias); + $this->graph->connect($id, $alias, $targetId, null !== $targetId ? $this->container->getDefinition($targetId) : null, null); + } + try { + parent::process($container); + } finally { + $this->aliases = $this->definitions = []; + } + } + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + $lazy = $this->lazy; + $inExpression = $this->inExpression(); + if ($value instanceof ArgumentInterface) { + $this->lazy = !$this->byFactory || !$value instanceof IteratorArgument; + parent::processValue($value->getValues()); + $this->lazy = $lazy; + return $value; + } + if ($value instanceof Reference) { + $targetId = $this->getDefinitionId((string) $value); + $targetDefinition = null !== $targetId ? $this->container->getDefinition($targetId) : null; + $this->graph->connect($this->currentId, $this->currentDefinition, $targetId, $targetDefinition, $value, $this->lazy || $this->hasProxyDumper && (($nullsafeVariable1 = $targetDefinition) ? $nullsafeVariable1->isLazy() : null), ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(), $this->byConstructor); + if ($inExpression) { + $this->graph->connect('.internal.reference_in_expression', null, $targetId, $targetDefinition, $value, $this->lazy || (($nullsafeVariable2 = $targetDefinition) ? $nullsafeVariable2->isLazy() : null), \true); + } + return $value; + } + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + if ($isRoot) { + if ($value->isSynthetic() || $value->isAbstract()) { + return $value; + } + $this->currentDefinition = $value; + } elseif ($this->currentDefinition === $value) { + return $value; + } + $this->lazy = \false; + $byConstructor = $this->byConstructor; + $this->byConstructor = $isRoot || $byConstructor; + $byFactory = $this->byFactory; + $this->byFactory = \true; + if (\is_string($factory = $value->getFactory()) && \strncmp($factory, '@=', \strlen('@=')) === 0) { + if (!\class_exists(Expression::class)) { + throw new LogicException('Expressions cannot be used in service factories without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); + } + $factory = new Expression(\substr($factory, 2)); + } + $this->processValue($factory); + $this->byFactory = $byFactory; + $this->processValue($value->getArguments()); + $properties = $value->getProperties(); + $setters = $value->getMethodCalls(); + // Any references before a "wither" are part of the constructor-instantiation graph + $lastWitherIndex = null; + foreach ($setters as $k => $call) { + if ($call[2] ?? \false) { + $lastWitherIndex = $k; + } + } + if (null !== $lastWitherIndex) { + $this->processValue($properties); + $setters = $properties = []; + foreach ($value->getMethodCalls() as $k => $call) { + if (null === $lastWitherIndex) { + $setters[] = $call; + continue; + } + if ($lastWitherIndex === $k) { + $lastWitherIndex = null; + } + $this->processValue($call); + } + } + $this->byConstructor = $byConstructor; + if (!$this->onlyConstructorArguments) { + $this->processValue($properties); + $this->processValue($setters); + $this->processValue($value->getConfigurator()); + } + $this->lazy = $lazy; + return $value; + } + private function getDefinitionId(string $id) : ?string + { + while (isset($this->aliases[$id])) { + $id = (string) $this->aliases[$id]; + } + return isset($this->definitions[$id]) ? $id : null; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php b/vendor/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php new file mode 100644 index 0000000000..30a3a7bcb2 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AttributeAutoconfigurationPass.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * @author Alexander M. Turek + */ +final class AttributeAutoconfigurationPass extends AbstractRecursivePass +{ + private $classAttributeConfigurators = []; + private $methodAttributeConfigurators = []; + private $propertyAttributeConfigurators = []; + private $parameterAttributeConfigurators = []; + public function process(ContainerBuilder $container) : void + { + if (!$container->getAutoconfiguredAttributes()) { + return; + } + foreach ($container->getAutoconfiguredAttributes() as $attributeName => $callable) { + $callableReflector = new \ReflectionFunction(\Closure::fromCallable($callable)); + if ($callableReflector->getNumberOfParameters() <= 2) { + $this->classAttributeConfigurators[$attributeName] = $callable; + continue; + } + $reflectorParameter = $callableReflector->getParameters()[2]; + $parameterType = $reflectorParameter->getType(); + $types = []; + if ($parameterType instanceof \ReflectionUnionType) { + foreach ($parameterType->getTypes() as $type) { + $types[] = $type->getName(); + } + } elseif ($parameterType instanceof \ReflectionNamedType) { + $types[] = $parameterType->getName(); + } else { + throw new LogicException(\sprintf('Argument "$%s" of attribute autoconfigurator should have a type, use one or more of "\\ReflectionClass|\\ReflectionMethod|\\ReflectionProperty|\\ReflectionParameter|\\Reflector" in "%s" on line "%d".', $reflectorParameter->getName(), $callableReflector->getFileName(), $callableReflector->getStartLine())); + } + try { + $attributeReflector = new \ReflectionClass($attributeName); + } catch (\ReflectionException $exception) { + continue; + } + $targets = (\method_exists($attributeReflector, 'getAttributes') ? $attributeReflector->getAttributes(\Attribute::class) : [])[0] ?? 0; + $targets = $targets ? $targets->getArguments()[0] ?? -1 : 0; + foreach (['class', 'method', 'property', 'parameter'] as $symbol) { + if (['Reflector'] !== $types) { + if (!\in_array('Reflection' . \ucfirst($symbol), $types, \true)) { + continue; + } + if (!($targets & \constant('Attribute::TARGET_' . \strtoupper($symbol)))) { + throw new LogicException(\sprintf('Invalid type "Reflection%s" on argument "$%s": attribute "%s" cannot target a ' . $symbol . ' in "%s" on line "%d".', \ucfirst($symbol), $reflectorParameter->getName(), $attributeName, $callableReflector->getFileName(), $callableReflector->getStartLine())); + } + } + $this->{$symbol . 'AttributeConfigurators'}[$attributeName] = $callable; + } + } + parent::process($container); + } + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Definition || !$value->isAutoconfigured() || $value->isAbstract() || $value->hasTag('container.ignore_attributes') || !($classReflector = $this->container->getReflectionClass($value->getClass(), \false))) { + return parent::processValue($value, $isRoot); + } + $instanceof = $value->getInstanceofConditionals(); + $conditionals = $instanceof[$classReflector->getName()] ?? new ChildDefinition(''); + if ($this->classAttributeConfigurators) { + foreach (\method_exists($classReflector, 'getAttributes') ? $classReflector->getAttributes() : [] as $attribute) { + if ($configurator = $this->classAttributeConfigurators[$attribute->getName()] ?? null) { + $configurator($conditionals, $attribute->newInstance(), $classReflector); + } + } + } + if ($this->parameterAttributeConfigurators) { + try { + $constructorReflector = $this->getConstructor($value, \false); + } catch (RuntimeException $exception) { + $constructorReflector = null; + } + if ($constructorReflector) { + foreach ($constructorReflector->getParameters() as $parameterReflector) { + foreach (\method_exists($parameterReflector, 'getAttributes') ? $parameterReflector->getAttributes() : [] as $attribute) { + if ($configurator = $this->parameterAttributeConfigurators[$attribute->getName()] ?? null) { + $configurator($conditionals, $attribute->newInstance(), $parameterReflector); + } + } + } + } + } + if ($this->methodAttributeConfigurators || $this->parameterAttributeConfigurators) { + foreach ($classReflector->getMethods(\ReflectionMethod::IS_PUBLIC) as $methodReflector) { + if ($methodReflector->isStatic() || $methodReflector->isConstructor() || $methodReflector->isDestructor()) { + continue; + } + if ($this->methodAttributeConfigurators) { + foreach (\method_exists($methodReflector, 'getAttributes') ? $methodReflector->getAttributes() : [] as $attribute) { + if ($configurator = $this->methodAttributeConfigurators[$attribute->getName()] ?? null) { + $configurator($conditionals, $attribute->newInstance(), $methodReflector); + } + } + } + if ($this->parameterAttributeConfigurators) { + foreach ($methodReflector->getParameters() as $parameterReflector) { + foreach (\method_exists($parameterReflector, 'getAttributes') ? $parameterReflector->getAttributes() : [] as $attribute) { + if ($configurator = $this->parameterAttributeConfigurators[$attribute->getName()] ?? null) { + $configurator($conditionals, $attribute->newInstance(), $parameterReflector); + } + } + } + } + } + } + if ($this->propertyAttributeConfigurators) { + foreach ($classReflector->getProperties(\ReflectionProperty::IS_PUBLIC) as $propertyReflector) { + if ($propertyReflector->isStatic()) { + continue; + } + foreach (\method_exists($propertyReflector, 'getAttributes') ? $propertyReflector->getAttributes() : [] as $attribute) { + if ($configurator = $this->propertyAttributeConfigurators[$attribute->getName()] ?? null) { + $configurator($conditionals, $attribute->newInstance(), $propertyReflector); + } + } + } + } + if (!isset($instanceof[$classReflector->getName()]) && new ChildDefinition('') != $conditionals) { + $instanceof[$classReflector->getName()] = $conditionals; + $value->setInstanceofConditionals($instanceof); + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php b/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php new file mode 100644 index 0000000000..0b66e26196 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * Sets a service to be an alias of another one, given a format pattern. + */ +class AutoAliasServicePass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->findTaggedServiceIds('auto_alias') as $serviceId => $tags) { + foreach ($tags as $tag) { + if (!isset($tag['format'])) { + throw new InvalidArgumentException(\sprintf('Missing tag information "format" on auto_alias service "%s".', $serviceId)); + } + $aliasId = $container->getParameterBag()->resolveValue($tag['format']); + if ($container->hasDefinition($aliasId) || $container->hasAlias($aliasId)) { + $alias = new Alias($aliasId, $container->getDefinition($serviceId)->isPublic()); + $container->setAlias($serviceId, $alias); + } + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AutowireAsDecoratorPass.php b/vendor/symfony/dependency-injection/Compiler/AutowireAsDecoratorPass.php new file mode 100644 index 0000000000..3dda30ed74 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AutowireAsDecoratorPass.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\AsDecorator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * Reads #[AsDecorator] attributes on definitions that are autowired + * and don't have the "container.ignore_attributes" tag. + */ +final class AutowireAsDecoratorPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $definition) { + if ($this->accept($definition) && ($reflectionClass = $container->getReflectionClass($definition->getClass(), \false))) { + $this->processClass($definition, $reflectionClass); + } + } + } + private function accept(Definition $definition) : bool + { + return !$definition->hasTag('container.ignore_attributes') && $definition->isAutowired(); + } + private function processClass(Definition $definition, \ReflectionClass $reflectionClass) + { + foreach (\method_exists($reflectionClass, 'getAttributes') ? $reflectionClass->getAttributes(AsDecorator::class, \ReflectionAttribute::IS_INSTANCEOF) : [] as $attribute) { + $attribute = $attribute->newInstance(); + $definition->setDecoratedService($attribute->decorates, null, $attribute->priority, $attribute->onInvalid); + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AutowirePass.php b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php new file mode 100644 index 0000000000..48ae4d791e --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php @@ -0,0 +1,588 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ClassExistenceResource; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\Autowire; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\MapDecorated; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\TaggedIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\TaggedLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\Target; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\AutowiringFailedException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +/** + * Inspects existing service definitions and wires the autowired ones using the type hints of their classes. + * + * @author Kévin Dunglas + * @author Nicolas Grekas + */ +class AutowirePass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $types; + /** + * @var mixed[] + */ + private $ambiguousServiceTypes; + /** + * @var mixed[] + */ + private $autowiringAliases; + /** + * @var string|null + */ + private $lastFailure; + /** + * @var bool + */ + private $throwOnAutowiringException; + /** + * @var string|null + */ + private $decoratedClass; + /** + * @var string|null + */ + private $decoratedId; + /** + * @var mixed[]|null + */ + private $methodCalls; + /** + * @var object + */ + private $defaultArgument; + /** + * @var \Closure|null + */ + private $getPreviousValue; + /** + * @var int|null + */ + private $decoratedMethodIndex; + /** + * @var int|null + */ + private $decoratedMethodArgumentIndex; + /** + * @var $this|null + */ + private $typesClone; + /** + * @var mixed[] + */ + private $combinedAliases; + public function __construct(bool $throwOnAutowireException = \true) + { + $this->throwOnAutowiringException = $throwOnAutowireException; + $this->defaultArgument = new class + { + public $value; + public $names; + }; + } + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->populateCombinedAliases($container); + try { + $this->typesClone = clone $this; + parent::process($container); + } finally { + $this->decoratedClass = null; + $this->decoratedId = null; + $this->methodCalls = null; + $this->defaultArgument->names = null; + $this->getPreviousValue = null; + $this->decoratedMethodIndex = null; + $this->decoratedMethodArgumentIndex = null; + $this->typesClone = null; + $this->combinedAliases = []; + } + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + try { + return $this->doProcessValue($value, $isRoot); + } catch (AutowiringFailedException $e) { + if ($this->throwOnAutowiringException) { + throw $e; + } + $this->container->getDefinition($this->currentId)->addError($e->getMessageCallback() ?? $e->getMessage()); + return parent::processValue($value, $isRoot); + } + } + /** + * @param mixed $value + * @return mixed + */ + private function doProcessValue($value, bool $isRoot = \false) + { + if ($value instanceof TypedReference) { + if ($ref = $this->getAutowiredReference($value, \true)) { + return $ref; + } + if (ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) { + $message = $this->createTypeNotFoundMessageCallback($value, 'it'); + // since the error message varies by referenced id and $this->currentId, so should the id of the dummy errored definition + $this->container->register($id = \sprintf('.errored.%s.%s', $this->currentId, (string) $value), $value->getType())->addError($message); + return new TypedReference($id, $value->getType(), $value->getInvalidBehavior(), $value->getName()); + } + } + $value = parent::processValue($value, $isRoot); + if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) { + return $value; + } + if (!($reflectionClass = $this->container->getReflectionClass($value->getClass(), \false))) { + $this->container->log($this, \sprintf('Skipping service "%s": Class or interface "%s" cannot be loaded.', $this->currentId, $value->getClass())); + return $value; + } + $this->methodCalls = $value->getMethodCalls(); + try { + $constructor = $this->getConstructor($value, \false); + } catch (RuntimeException $e) { + throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e); + } + if ($constructor) { + \array_unshift($this->methodCalls, [$constructor, $value->getArguments()]); + } + $checkAttributes = !$value->hasTag('container.ignore_attributes'); + $this->methodCalls = $this->autowireCalls($reflectionClass, $isRoot, $checkAttributes); + if ($constructor) { + [, $arguments] = \array_shift($this->methodCalls); + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + } + if ($this->methodCalls !== $value->getMethodCalls()) { + $value->setMethodCalls($this->methodCalls); + } + return $value; + } + private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot, bool $checkAttributes) : array + { + $this->decoratedId = null; + $this->decoratedClass = null; + $this->getPreviousValue = null; + if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && null !== ($this->decoratedId = $definition->innerServiceId) && $this->container->has($this->decoratedId)) { + $this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass(); + } + $patchedIndexes = []; + foreach ($this->methodCalls as $i => $call) { + [$method, $arguments] = $call; + if ($method instanceof \ReflectionFunctionAbstract) { + $reflectionMethod = $method; + } else { + $definition = new Definition($reflectionClass->name); + try { + $reflectionMethod = $this->getReflectionMethod($definition, $method); + } catch (RuntimeException $e) { + if ($definition->getFactory()) { + continue; + } + throw $e; + } + } + $arguments = $this->autowireMethod($reflectionMethod, $arguments, $checkAttributes, $i); + if ($arguments !== $call[1]) { + $this->methodCalls[$i][1] = $arguments; + $patchedIndexes[] = $i; + } + } + // use named arguments to skip complex default values + foreach ($patchedIndexes as $i) { + $namedArguments = null; + $arguments = $this->methodCalls[$i][1]; + foreach ($arguments as $j => $value) { + if ($namedArguments && !$value instanceof $this->defaultArgument) { + unset($arguments[$j]); + $arguments[$namedArguments[$j]] = $value; + } + if ($namedArguments || !$value instanceof $this->defaultArgument) { + continue; + } + if (\is_array($value->value) ? $value->value : \is_object($value->value)) { + unset($arguments[$j]); + $namedArguments = $value->names; + } else { + $arguments[$j] = $value->value; + } + } + $this->methodCalls[$i][1] = $arguments; + } + return $this->methodCalls; + } + /** + * Autowires the constructor or a method. + * + * @throws AutowiringFailedException + */ + private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments, bool $checkAttributes, int $methodIndex) : array + { + $class = $reflectionMethod instanceof \ReflectionMethod ? $reflectionMethod->class : $this->currentId; + $method = $reflectionMethod->name; + $parameters = $reflectionMethod->getParameters(); + if ($reflectionMethod->isVariadic()) { + \array_pop($parameters); + } + $this->defaultArgument->names = new \ArrayObject(); + foreach ($parameters as $index => $parameter) { + $this->defaultArgument->names[$index] = $parameter->name; + if (\array_key_exists($parameter->name, $arguments)) { + $arguments[$index] = $arguments[$parameter->name]; + unset($arguments[$parameter->name]); + } + if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) { + continue; + } + $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, \true); + if ($checkAttributes) { + foreach (\method_exists($parameter, 'getAttributes') ? $parameter->getAttributes() : [] as $attribute) { + if (TaggedIterator::class === $attribute->getName()) { + $attribute = $attribute->newInstance(); + $arguments[$index] = new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, $attribute->defaultIndexMethod, \false, $attribute->defaultPriorityMethod, (array) $attribute->exclude); + break; + } + if (TaggedLocator::class === $attribute->getName()) { + $attribute = $attribute->newInstance(); + $arguments[$index] = new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, $attribute->defaultIndexMethod, \true, $attribute->defaultPriorityMethod, (array) $attribute->exclude)); + break; + } + if (Autowire::class === $attribute->getName()) { + $value = $attribute->newInstance()->value; + $value = $this->container->getParameterBag()->resolveValue($value); + if ($value instanceof Reference && $parameter->allowsNull()) { + $value = new Reference($value, ContainerInterface::NULL_ON_INVALID_REFERENCE); + } + $arguments[$index] = $value; + break; + } + if (MapDecorated::class === $attribute->getName()) { + $definition = $this->container->getDefinition($this->currentId); + $arguments[$index] = new Reference($definition->innerServiceId ?? $this->currentId . '.inner', $definition->decorationOnInvalid ?? ContainerInterface::NULL_ON_INVALID_REFERENCE); + break; + } + } + if ('' !== ($arguments[$index] ?? '')) { + continue; + } + } + if (!$type) { + if (isset($arguments[$index])) { + continue; + } + // no default value? Then fail + if (!$parameter->isDefaultValueAvailable()) { + // For core classes, isDefaultValueAvailable() can + // be false when isOptional() returns true. If the + // argument *is* optional, allow it to be missing + if ($parameter->isOptional()) { + --$index; + break; + } + $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, \false); + $type = $type ? \sprintf('is type-hinted "%s"', \ltrim($type, '\\')) : 'has no type-hint'; + throw new AutowiringFailedException($this->currentId, \sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class . '::' . $method : $method, $type)); + } + // specifically pass the default value + $arguments[$index] = clone $this->defaultArgument; + $arguments[$index]->value = $parameter->getDefaultValue(); + continue; + } + $getValue = function () use($type, $parameter, $class, $method) { + if (!($value = $this->getAutowiredReference($ref = new TypedReference($type, $type, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, Target::parseName($parameter)), \true))) { + $failureMessage = $this->createTypeNotFoundMessageCallback($ref, \sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class . '::' . $method : $method)); + if ($parameter->isDefaultValueAvailable()) { + $value = clone $this->defaultArgument; + $value->value = $parameter->getDefaultValue(); + } elseif (!$parameter->allowsNull()) { + throw new AutowiringFailedException($this->currentId, $failureMessage); + } + } + return $value; + }; + if ($this->decoratedClass && ($isDecorated = \is_a($this->decoratedClass, $type, \true))) { + if ($this->getPreviousValue) { + // The inner service is injected only if there is only 1 argument matching the type of the decorated class + // across all arguments of all autowired methods. + // If a second matching argument is found, the default behavior is restored. + $getPreviousValue = $this->getPreviousValue; + $this->methodCalls[$this->decoratedMethodIndex][1][$this->decoratedMethodArgumentIndex] = $getPreviousValue(); + $this->decoratedClass = null; + // Prevent further checks + } else { + $arguments[$index] = new TypedReference($this->decoratedId, $this->decoratedClass); + $this->getPreviousValue = $getValue; + $this->decoratedMethodIndex = $methodIndex; + $this->decoratedMethodArgumentIndex = $index; + continue; + } + } + $arguments[$index] = $getValue(); + } + if ($parameters && !isset($arguments[++$index])) { + while (0 <= --$index) { + if (!$arguments[$index] instanceof $this->defaultArgument) { + break; + } + unset($arguments[$index]); + } + } + // it's possible index 1 was set, then index 0, then 2, etc + // make sure that we re-order so they're injected as expected + \ksort($arguments, \SORT_NATURAL); + return $arguments; + } + /** + * Returns a reference to the service matching the given type, if any. + */ + private function getAutowiredReference(TypedReference $reference, bool $filterType) : ?TypedReference + { + $this->lastFailure = null; + $type = $reference->getType(); + if ($type !== (string) $reference) { + return $reference; + } + if ($filterType && \false !== ($m = \strpbrk($type, '&|'))) { + $types = \array_diff(\explode($m[0], $type), ['int', 'string', 'array', 'bool', 'float', 'iterable', 'object', 'callable', 'null']); + \sort($types); + $type = \implode($m[0], $types); + } + if (null !== ($name = $reference->getName())) { + if ($this->container->has($alias = $type . ' $' . $name) && !$this->container->findDefinition($alias)->isAbstract()) { + return new TypedReference($alias, $type, $reference->getInvalidBehavior()); + } + if (null !== ($alias = $this->combinedAliases[$alias] ?? null) && !$this->container->findDefinition($alias)->isAbstract()) { + return new TypedReference($alias, $type, $reference->getInvalidBehavior()); + } + if ($this->container->has($name) && !$this->container->findDefinition($name)->isAbstract()) { + foreach ($this->container->getAliases() + $this->combinedAliases as $id => $alias) { + if ($name === (string) $alias && \strncmp($id, $type . ' $', \strlen($type . ' $')) === 0) { + return new TypedReference($name, $type, $reference->getInvalidBehavior()); + } + } + } + } + if ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract()) { + return new TypedReference($type, $type, $reference->getInvalidBehavior()); + } + if (null !== ($alias = $this->combinedAliases[$type] ?? null) && !$this->container->findDefinition($alias)->isAbstract()) { + return new TypedReference($alias, $type, $reference->getInvalidBehavior()); + } + return null; + } + /** + * Populates the list of available types. + */ + private function populateAvailableTypes(ContainerBuilder $container) + { + $this->types = []; + $this->ambiguousServiceTypes = []; + $this->autowiringAliases = []; + foreach ($container->getDefinitions() as $id => $definition) { + $this->populateAvailableType($container, $id, $definition); + } + foreach ($container->getAliases() as $id => $alias) { + $this->populateAutowiringAlias($id); + } + } + /** + * Populates the list of available types for a given definition. + */ + private function populateAvailableType(ContainerBuilder $container, string $id, Definition $definition) + { + // Never use abstract services + if ($definition->isAbstract()) { + return; + } + if ('' === $id || '.' === $id[0] || $definition->isDeprecated() || !($reflectionClass = $container->getReflectionClass($definition->getClass(), \false))) { + return; + } + foreach ($reflectionClass->getInterfaces() as $reflectionInterface) { + $this->set($reflectionInterface->name, $id); + } + do { + $this->set($reflectionClass->name, $id); + } while ($reflectionClass = $reflectionClass->getParentClass()); + $this->populateAutowiringAlias($id); + } + /** + * Associates a type and a service id if applicable. + */ + private function set(string $type, string $id) + { + // is this already a type/class that is known to match multiple services? + if (isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type][] = $id; + return; + } + // check to make sure the type doesn't match multiple services + if (!isset($this->types[$type]) || $this->types[$type] === $id) { + $this->types[$type] = $id; + return; + } + // keep an array of all services matching this type + if (!isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type] = [$this->types[$type]]; + unset($this->types[$type]); + } + $this->ambiguousServiceTypes[$type][] = $id; + } + private function createTypeNotFoundMessageCallback(TypedReference $reference, string $label) : \Closure + { + if (null === $this->typesClone->container) { + $this->typesClone->container = new ContainerBuilder($this->container->getParameterBag()); + $this->typesClone->container->setAliases($this->container->getAliases()); + $this->typesClone->container->setDefinitions($this->container->getDefinitions()); + $this->typesClone->container->setResourceTracking(\false); + } + $currentId = $this->currentId; + return (function () use($reference, $label, $currentId) { + return $this->createTypeNotFoundMessage($reference, $label, $currentId); + })->bindTo($this->typesClone); + } + private function createTypeNotFoundMessage(TypedReference $reference, string $label, string $currentId) : string + { + if (!($r = $this->container->getReflectionClass($type = $reference->getType(), \false))) { + // either $type does not exist or a parent class does not exist + try { + $resource = new ClassExistenceResource($type, \false); + // isFresh() will explode ONLY if a parent class/trait does not exist + $resource->isFresh(0); + $parentMsg = \false; + } catch (\ReflectionException $e) { + $parentMsg = $e->getMessage(); + } + $message = \sprintf('has type "%s" but this class %s.', $type, $parentMsg ? \sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found'); + } else { + $alternatives = $this->createTypeAlternatives($this->container, $reference); + $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists'; + $message = \sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives); + if ($r->isInterface() && !$alternatives) { + $message .= ' Did you create a class that implements this interface?'; + } + } + $message = \sprintf('Cannot autowire service "%s": %s %s', $currentId, $label, $message); + if (null !== $this->lastFailure) { + $message = $this->lastFailure . "\n" . $message; + $this->lastFailure = null; + } + return $message; + } + private function createTypeAlternatives(ContainerBuilder $container, TypedReference $reference) : string + { + // try suggesting available aliases first + if ($message = $this->getAliasesSuggestionForType($container, $type = $reference->getType())) { + return ' ' . $message; + } + if (!isset($this->ambiguousServiceTypes)) { + $this->populateAvailableTypes($container); + } + $servicesAndAliases = $container->getServiceIds(); + if (null !== ($autowiringAliases = $this->autowiringAliases[$type] ?? null) && !isset($autowiringAliases[''])) { + return \sprintf(' Available autowiring aliases for this %s are: "$%s".', \class_exists($type, \false) ? 'class' : 'interface', \implode('", "$', $autowiringAliases)); + } + if (!$container->has($type) && \false !== ($key = \array_search(\strtolower($type), \array_map('strtolower', $servicesAndAliases)))) { + return \sprintf(' Did you mean "%s"?', $servicesAndAliases[$key]); + } elseif (isset($this->ambiguousServiceTypes[$type])) { + $message = \sprintf('one of these existing services: "%s"', \implode('", "', $this->ambiguousServiceTypes[$type])); + } elseif (isset($this->types[$type])) { + $message = \sprintf('the existing "%s" service', $this->types[$type]); + } else { + return ''; + } + return \sprintf(' You should maybe alias this %s to %s.', \class_exists($type, \false) ? 'class' : 'interface', $message); + } + private function getAliasesSuggestionForType(ContainerBuilder $container, string $type) : ?string + { + $aliases = []; + foreach (\class_parents($type) + \class_implements($type) as $parent) { + if ($container->has($parent) && !$container->findDefinition($parent)->isAbstract()) { + $aliases[] = $parent; + } + } + if (1 < ($len = \count($aliases))) { + $message = 'Try changing the type-hint to one of its parents: '; + for ($i = 0, --$len; $i < $len; ++$i) { + $message .= \sprintf('%s "%s", ', \class_exists($aliases[$i], \false) ? 'class' : 'interface', $aliases[$i]); + } + $message .= \sprintf('or %s "%s".', \class_exists($aliases[$i], \false) ? 'class' : 'interface', $aliases[$i]); + return $message; + } + if ($aliases) { + return \sprintf('Try changing the type-hint to "%s" instead.', $aliases[0]); + } + return null; + } + private function populateAutowiringAlias(string $id) : void + { + if (!\preg_match('/(?(DEFINE)(?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+))^((?&V)(?:\\\\(?&V))*+)(?: \\$((?&V)))?$/', $id, $m)) { + return; + } + $type = $m[2]; + $name = $m[3] ?? ''; + if (\class_exists($type, \false) || \interface_exists($type, \false)) { + $this->autowiringAliases[$type][$name] = $name; + } + } + private function populateCombinedAliases(ContainerBuilder $container) : void + { + $this->combinedAliases = []; + $reverseAliases = []; + foreach ($container->getAliases() as $id => $alias) { + if (!\preg_match('/(?(DEFINE)(?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+))^((?&V)(?:\\\\(?&V))*+)(?: \\$((?&V)))?$/', $id, $m)) { + continue; + } + $type = $m[2]; + $name = $m[3] ?? ''; + $reverseAliases[(string) $alias][$name][] = $type; + } + foreach ($reverseAliases as $alias => $names) { + foreach ($names as $name => $types) { + if (2 > ($count = \count($types))) { + continue; + } + \sort($types); + $i = 1 << $count; + // compute the powerset of the list of types + while ($i--) { + $set = []; + for ($j = 0; $j < $count; ++$j) { + if ($i & 1 << $j) { + $set[] = $types[$j]; + } + } + if (2 <= \count($set)) { + $this->combinedAliases[\implode('&', $set) . ('' === $name ? '' : ' $' . $name)] = $alias; + $this->combinedAliases[\implode('|', $set) . ('' === $name ? '' : ' $' . $name)] = $alias; + } + } + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php b/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php new file mode 100644 index 0000000000..be35480073 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Attribute\Required; +/** + * Looks for definitions with autowiring enabled and registers their corresponding "@required" methods as setters. + * + * @author Nicolas Grekas + */ +class AutowireRequiredMethodsPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + $value = parent::processValue($value, $isRoot); + if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) { + return $value; + } + if (!($reflectionClass = $this->container->getReflectionClass($value->getClass(), \false))) { + return $value; + } + $alreadyCalledMethods = []; + $withers = []; + foreach ($value->getMethodCalls() as [$method]) { + $alreadyCalledMethods[\strtolower($method)] = \true; + } + foreach ($reflectionClass->getMethods() as $reflectionMethod) { + $r = $reflectionMethod; + if ($r->isConstructor() || isset($alreadyCalledMethods[\strtolower($r->name)])) { + continue; + } + while (\true) { + if (\method_exists($r, 'getAttributes') ? $r->getAttributes(Required::class) : []) { + if ($this->isWither($r, $r->getDocComment() ?: '')) { + $withers[] = [$r->name, [], \true]; + } else { + $value->addMethodCall($r->name, []); + } + break; + } + if (\false !== ($doc = $r->getDocComment())) { + if (\false !== \stripos($doc, '@required') && \preg_match('#(?:^/\\*\\*|\\n\\s*+\\*)\\s*+@required(?:\\s|\\*/$)#i', $doc)) { + if ($this->isWither($reflectionMethod, $doc)) { + $withers[] = [$reflectionMethod->name, [], \true]; + } else { + $value->addMethodCall($reflectionMethod->name, []); + } + break; + } + if (\false === \stripos($doc, '@inheritdoc') || !\preg_match('#(?:^/\\*\\*|\\n\\s*+\\*)\\s*+(?:\\{@inheritdoc\\}|@inheritdoc)(?:\\s|\\*/$)#i', $doc)) { + break; + } + } + try { + $r = $r->getPrototype(); + } catch (\ReflectionException $exception) { + break; + // method has no prototype + } + } + } + if ($withers) { + // Prepend withers to prevent creating circular loops + $setters = $value->getMethodCalls(); + $value->setMethodCalls($withers); + foreach ($setters as $call) { + $value->addMethodCall($call[0], $call[1], $call[2] ?? \false); + } + } + return $value; + } + private function isWither(\ReflectionMethod $reflectionMethod, string $doc) : bool + { + $match = \preg_match('#(?:^/\\*\\*|\\n\\s*+\\*)\\s*+@return\\s++(static|\\$this)[\\s\\*]#i', $doc, $matches); + if ($match && 'static' === $matches[1]) { + return \true; + } + if ($match && '$this' === $matches[1]) { + return \false; + } + $reflectionType = $reflectionMethod->hasReturnType() ? $reflectionMethod->getReturnType() : null; + return $reflectionType instanceof \ReflectionNamedType && 'static' === $reflectionType->getName(); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/AutowireRequiredPropertiesPass.php b/vendor/symfony/dependency-injection/Compiler/AutowireRequiredPropertiesPass.php new file mode 100644 index 0000000000..78a344694c --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/AutowireRequiredPropertiesPass.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Attribute\Required; +/** + * Looks for definitions with autowiring enabled and registers their corresponding "@required" properties. + * + * @author Sebastien Morel (Plopix) + * @author Nicolas Grekas + */ +class AutowireRequiredPropertiesPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + $value = parent::processValue($value, $isRoot); + if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) { + return $value; + } + if (!($reflectionClass = $this->container->getReflectionClass($value->getClass(), \false))) { + return $value; + } + $properties = $value->getProperties(); + foreach ($reflectionClass->getProperties() as $reflectionProperty) { + if (!($type = \method_exists($reflectionProperty, 'getType') ? $reflectionProperty->getType() : null) instanceof \ReflectionNamedType) { + continue; + } + if (!(\method_exists($reflectionProperty, 'getAttributes') ? $reflectionProperty->getAttributes(Required::class) : []) && (\false === ($doc = $reflectionProperty->getDocComment()) || \false === \stripos($doc, '@required') || !\preg_match('#(?:^/\\*\\*|\\n\\s*+\\*)\\s*+@required(?:\\s|\\*/$)#i', $doc))) { + continue; + } + if (\array_key_exists($name = $reflectionProperty->getName(), $properties)) { + continue; + } + $type = $type->getName(); + $value->setProperty($name, new TypedReference($type, $type, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name)); + } + return $value; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php b/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php new file mode 100644 index 0000000000..8795e7013c --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * Checks if arguments of methods are properly configured. + * + * @author Kévin Dunglas + * @author Nicolas Grekas + */ +class CheckArgumentsValidityPass extends AbstractRecursivePass +{ + /** + * @var bool + */ + private $throwExceptions; + public function __construct(bool $throwExceptions = \true) + { + $this->throwExceptions = $throwExceptions; + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + $i = 0; + $hasNamedArgs = \false; + foreach ($value->getArguments() as $k => $v) { + if (\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $k)) { + $hasNamedArgs = \true; + continue; + } + if ($k !== $i++) { + if (!\is_int($k)) { + $msg = \sprintf('Invalid constructor argument for service "%s": integer expected but found string "%s". Check your service definition.', $this->currentId, $k); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + break; + } + $msg = \sprintf('Invalid constructor argument %d for service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $this->currentId, $i); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + } + if ($hasNamedArgs) { + $msg = \sprintf('Invalid constructor argument for service "%s": cannot use positional argument after named argument. Check your service definition.', $this->currentId); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + break; + } + } + foreach ($value->getMethodCalls() as $methodCall) { + $i = 0; + $hasNamedArgs = \false; + foreach ($methodCall[1] as $k => $v) { + if (\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $k)) { + $hasNamedArgs = \true; + continue; + } + if ($k !== $i++) { + if (!\is_int($k)) { + $msg = \sprintf('Invalid argument for method call "%s" of service "%s": integer expected but found string "%s". Check your service definition.', $methodCall[0], $this->currentId, $k); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + break; + } + $msg = \sprintf('Invalid argument %d for method call "%s" of service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $methodCall[0], $this->currentId, $i); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + } + if ($hasNamedArgs) { + $msg = \sprintf('Invalid argument for method call "%s" of service "%s": cannot use positional argument after named argument. Check your service definition.', $methodCall[0], $this->currentId); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + break; + } + } + } + return null; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php b/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php new file mode 100644 index 0000000000..a097182312 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +/** + * Checks your services for circular references. + * + * References from method calls are ignored since we might be able to resolve + * these references depending on the order in which services are called. + * + * Circular reference from method calls will only be detected at run-time. + * + * @author Johannes M. Schmitt + */ +class CheckCircularReferencesPass implements CompilerPassInterface +{ + /** + * @var mixed[] + */ + private $currentPath; + /** + * @var mixed[] + */ + private $checkedNodes; + /** + * Checks the ContainerBuilder object for circular references. + */ + public function process(ContainerBuilder $container) + { + $graph = $container->getCompiler()->getServiceReferenceGraph(); + $this->checkedNodes = []; + foreach ($graph->getNodes() as $id => $node) { + $this->currentPath = [$id]; + $this->checkOutEdges($node->getOutEdges()); + } + } + /** + * Checks for circular references. + * + * @param ServiceReferenceGraphEdge[] $edges An array of Edges + * + * @throws ServiceCircularReferenceException when a circular reference is found + */ + private function checkOutEdges(array $edges) + { + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $id = $node->getId(); + if (empty($this->checkedNodes[$id])) { + // Don't check circular references for lazy edges + if (!$node->getValue() || !$edge->isLazy() && !$edge->isWeak()) { + $searchKey = \array_search($id, $this->currentPath); + $this->currentPath[] = $id; + if (\false !== $searchKey) { + throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey)); + } + $this->checkOutEdges($node->getOutEdges()); + } + $this->checkedNodes[$id] = \true; + \array_pop($this->currentPath); + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php b/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php new file mode 100644 index 0000000000..ab7c15d79c --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\EnvParameterException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\FileLoader; +/** + * This pass validates each definition individually only taking the information + * into account which is contained in the definition itself. + * + * Later passes can rely on the following, and specifically do not need to + * perform these checks themselves: + * + * - non synthetic, non abstract services always have a class set + * - synthetic services are always public + * + * @author Johannes M. Schmitt + */ +class CheckDefinitionValidityPass implements CompilerPassInterface +{ + /** + * Processes the ContainerBuilder to validate the Definition. + * + * @throws RuntimeException When the Definition is invalid + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + // synthetic service is public + if ($definition->isSynthetic() && !$definition->isPublic()) { + throw new RuntimeException(\sprintf('A synthetic service ("%s") must be public.', $id)); + } + // non-synthetic, non-abstract service has class + if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass() && !$definition->hasTag('container.service_locator') && (!$definition->getFactory() || !\preg_match(FileLoader::ANONYMOUS_ID_REGEXP, $id))) { + if ($definition->getFactory()) { + throw new RuntimeException(\sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id)); + } + if (\class_exists($id) || \interface_exists($id, \false)) { + if (\strncmp($id, '\\', \strlen('\\')) === 0 && 1 < \substr_count($id, '\\')) { + throw new RuntimeException(\sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "%s" to get rid of this error.', $id, \substr($id, 1))); + } + throw new RuntimeException(\sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface in the global namespace. Leaving out the "class" attribute is only allowed for namespaced classes. Please specify the class attribute explicitly to get rid of this error.', $id)); + } + throw new RuntimeException(\sprintf('The definition for "%s" has no class. If you intend to inject this service dynamically at runtime, please mark it as synthetic=true. If this is an abstract definition solely used by child definitions, please add abstract=true, otherwise specify a class to get rid of this error.', $id)); + } + // tag attribute values must be scalars + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + foreach ($attributes as $attribute => $value) { + if (!\is_scalar($value) && null !== $value) { + throw new RuntimeException(\sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $id, $name, $attribute)); + } + } + } + } + if ($definition->isPublic() && !$definition->isPrivate()) { + $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); + if (null !== $usedEnvs) { + throw new EnvParameterException([$resolvedId], null, 'A service name ("%s") cannot contain dynamic values.'); + } + } + } + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPublic() && !$alias->isPrivate()) { + $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); + if (null !== $usedEnvs) { + throw new EnvParameterException([$resolvedId], null, 'An alias name ("%s") cannot contain dynamic values.'); + } + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php b/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php new file mode 100644 index 0000000000..1f495e0e65 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Checks that all references are pointing to a valid service. + * + * @author Johannes M. Schmitt + */ +class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $serviceLocatorContextIds = []; + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->serviceLocatorContextIds = []; + foreach ($container->findTaggedServiceIds('container.service_locator_context') as $id => $tags) { + $this->serviceLocatorContextIds[$id] = $tags[0]['id']; + $container->getDefinition($id)->clearTag('container.service_locator_context'); + } + try { + return parent::process($container); + } finally { + $this->serviceLocatorContextIds = []; + } + } + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $value->getInvalidBehavior() || $this->container->has($id = (string) $value)) { + return $value; + } + $currentId = $this->currentId; + $graph = $this->container->getCompiler()->getServiceReferenceGraph(); + if (isset($this->serviceLocatorContextIds[$currentId])) { + $currentId = $this->serviceLocatorContextIds[$currentId]; + $locator = $this->container->getDefinition($this->currentId)->getFactory()[0]; + foreach ($locator->getArgument(0) as $k => $v) { + if ($v->getValues()[0] === $value) { + if ($k !== $id) { + $currentId = $k . '" in the container provided to "' . $currentId; + } + throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id)); + } + } + } + if ('.' === $currentId[0] && $graph->hasNode($currentId)) { + foreach ($graph->getNode($currentId)->getInEdges() as $edge) { + if (!$edge->getValue() instanceof Reference || ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $edge->getValue()->getInvalidBehavior()) { + continue; + } + $sourceId = $edge->getSourceNode()->getId(); + if ('.' !== $sourceId[0]) { + $currentId = $sourceId; + break; + } + } + } + throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id)); + } + private function getAlternatives(string $id) : array + { + $alternatives = []; + foreach ($this->container->getServiceIds() as $knownId) { + if ('' === $knownId || '.' === $knownId[0]) { + continue; + } + $lev = \levenshtein($id, $knownId); + if ($lev <= \strlen($id) / 3 || \strpos($knownId, $id) !== \false) { + $alternatives[] = $knownId; + } + } + return $alternatives; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php b/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php new file mode 100644 index 0000000000..3c6264d956 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Checks the validity of references. + * + * The following checks are performed by this pass: + * - target definitions are not abstract + * + * @author Johannes M. Schmitt + */ +class CheckReferenceValidityPass extends AbstractRecursivePass +{ + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($isRoot && $value instanceof Definition && ($value->isSynthetic() || $value->isAbstract())) { + return $value; + } + if ($value instanceof Reference && $this->container->hasDefinition((string) $value)) { + $targetDefinition = $this->container->getDefinition((string) $value); + if ($targetDefinition->isAbstract()) { + throw new RuntimeException(\sprintf('The definition "%s" has a reference to an abstract definition "%s". Abstract definitions cannot be the target of references.', $this->currentId, $value)); + } + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php b/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php new file mode 100644 index 0000000000..84dd33f85b --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/CheckTypeDeclarationsPass.php @@ -0,0 +1,270 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Container; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ExpressionLanguage; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Parameter; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ServiceLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * Checks whether injected parameters are compatible with type declarations. + * + * This pass should be run after all optimization passes. + * + * It can be added either: + * * before removing passes to check all services even if they are not currently used, + * * after removing passes to check only services are used in the app. + * + * @author Nicolas Grekas + * @author Julien Maulny + */ +final class CheckTypeDeclarationsPass extends AbstractRecursivePass +{ + private const SCALAR_TYPES = ['int' => \true, 'float' => \true, 'bool' => \true, 'string' => \true]; + private const BUILTIN_TYPES = ['array' => \true, 'bool' => \true, 'callable' => \true, 'float' => \true, 'int' => \true, 'iterable' => \true, 'object' => \true, 'string' => \true]; + /** + * @var bool + */ + private $autoload; + /** + * @var mixed[] + */ + private $skippedIds; + /** + * @var \Symfony\Component\DependencyInjection\ExpressionLanguage + */ + private $expressionLanguage; + /** + * @param bool $autoload Whether services who's class in not loaded should be checked or not. + * Defaults to false to save loading code during compilation. + * @param array $skippedIds An array indexed by the service ids to skip + */ + public function __construct(bool $autoload = \false, array $skippedIds = []) + { + $this->autoload = $autoload; + $this->skippedIds = $skippedIds; + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (isset($this->skippedIds[$this->currentId])) { + return $value; + } + if (!$value instanceof Definition || $value->hasErrors() || $value->isDeprecated()) { + return parent::processValue($value, $isRoot); + } + if (!$this->autoload) { + if (!($class = $value->getClass())) { + return parent::processValue($value, $isRoot); + } + if (!\class_exists($class, \false) && !\interface_exists($class, \false)) { + return parent::processValue($value, $isRoot); + } + } + if (ServiceLocator::class === $value->getClass()) { + return parent::processValue($value, $isRoot); + } + if ($constructor = $this->getConstructor($value, \false)) { + $this->checkTypeDeclarations($value, $constructor, $value->getArguments()); + } + foreach ($value->getMethodCalls() as $methodCall) { + try { + $reflectionMethod = $this->getReflectionMethod($value, $methodCall[0]); + } catch (RuntimeException $e) { + if ($value->getFactory()) { + continue; + } + throw $e; + } + $this->checkTypeDeclarations($value, $reflectionMethod, $methodCall[1]); + } + return parent::processValue($value, $isRoot); + } + /** + * @throws InvalidArgumentException When not enough parameters are defined for the method + */ + private function checkTypeDeclarations(Definition $checkedDefinition, \ReflectionFunctionAbstract $reflectionFunction, array $values) : void + { + $numberOfRequiredParameters = $reflectionFunction->getNumberOfRequiredParameters(); + if (\count($values) < $numberOfRequiredParameters) { + throw new InvalidArgumentException(\sprintf('Invalid definition for service "%s": "%s::%s()" requires %d arguments, %d passed.', $this->currentId, $reflectionFunction->class, $reflectionFunction->name, $numberOfRequiredParameters, \count($values))); + } + $reflectionParameters = $reflectionFunction->getParameters(); + $checksCount = \min($reflectionFunction->getNumberOfParameters(), \count($values)); + $envPlaceholderUniquePrefix = $this->container->getParameterBag() instanceof EnvPlaceholderParameterBag ? $this->container->getParameterBag()->getEnvPlaceholderUniquePrefix() : null; + for ($i = 0; $i < $checksCount; ++$i) { + if (!$reflectionParameters[$i]->hasType() || $reflectionParameters[$i]->isVariadic()) { + continue; + } + $this->checkType($checkedDefinition, $values[$i], $reflectionParameters[$i], $envPlaceholderUniquePrefix); + } + if ($reflectionFunction->isVariadic() && ($lastParameter = \end($reflectionParameters))->hasType()) { + $variadicParameters = \array_slice($values, $lastParameter->getPosition()); + foreach ($variadicParameters as $variadicParameter) { + $this->checkType($checkedDefinition, $variadicParameter, $lastParameter, $envPlaceholderUniquePrefix); + } + } + } + /** + * @throws InvalidParameterTypeException When a parameter is not compatible with the declared type + * @param mixed $value + */ + private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix, \ReflectionType $reflectionType = null) : void + { + $reflectionType = $reflectionType ?? $parameter->getType(); + if ($reflectionType instanceof \ReflectionUnionType) { + foreach ($reflectionType->getTypes() as $t) { + try { + $this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $t); + return; + } catch (InvalidParameterTypeException $e) { + } + } + throw new InvalidParameterTypeException($this->currentId, $e->getCode(), $parameter); + } + if ($reflectionType instanceof \ReflectionIntersectionType) { + foreach ($reflectionType->getTypes() as $t) { + $this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $t); + } + return; + } + if (!$reflectionType instanceof \ReflectionNamedType) { + return; + } + $type = $reflectionType->getName(); + if ($value instanceof Reference) { + if (!$this->container->has($value = (string) $value)) { + return; + } + if ('service_container' === $value && \is_a($type, Container::class, \true)) { + return; + } + $value = $this->container->findDefinition($value); + } + if ('self' === $type) { + $type = $parameter->getDeclaringClass()->getName(); + } + if ('static' === $type) { + $type = $checkedDefinition->getClass(); + } + $class = null; + if ($value instanceof Definition) { + if ($value->getFactory()) { + return; + } + $class = $value->getClass(); + if ($class && isset(self::BUILTIN_TYPES[\strtolower($class)])) { + $class = \strtolower($class); + } elseif (!$class || !$this->autoload && !\class_exists($class, \false) && !\interface_exists($class, \false)) { + return; + } + } elseif ($value instanceof Parameter) { + $value = $this->container->getParameter($value); + } elseif ($value instanceof Expression) { + try { + $value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this->container]); + } catch (\Exception $exception) { + // If a service from the expression cannot be fetched from the container, we skip the validation. + return; + } + } elseif (\is_string($value)) { + if ('%' === ($value[0] ?? '') && \preg_match('/^%([^%]+)%$/', $value, $match)) { + $value = $this->container->getParameter(\substr($value, 1, -1)); + } + if ($envPlaceholderUniquePrefix && \is_string($value) && \strpos($value, 'env_') !== \false) { + // If the value is an env placeholder that is either mixed with a string or with another env placeholder, then its resolved value will always be a string, so we don't need to resolve it. + // We don't need to change the value because it is already a string. + if ('' === \preg_replace('/' . $envPlaceholderUniquePrefix . '_\\w+_[a-f0-9]{32}/U', '', $value, -1, $c) && 1 === $c) { + try { + $value = $this->container->resolveEnvPlaceholders($value, \true); + } catch (\Exception $exception) { + // If an env placeholder cannot be resolved, we skip the validation. + return; + } + } + } + } + if (null === $value && $parameter->allowsNull()) { + return; + } + if (null === $class) { + if ($value instanceof IteratorArgument) { + $class = RewindableGenerator::class; + } elseif ($value instanceof ServiceClosureArgument) { + $class = \Closure::class; + } elseif ($value instanceof ServiceLocatorArgument) { + $class = ServiceLocator::class; + } elseif (\is_object($value)) { + $class = \get_class($value); + } else { + $class = \gettype($value); + $class = ['integer' => 'int', 'double' => 'float', 'boolean' => 'bool'][$class] ?? $class; + } + } + if (isset(self::SCALAR_TYPES[$type]) && isset(self::SCALAR_TYPES[$class])) { + return; + } + if ('string' === $type && \method_exists($class, '__toString')) { + return; + } + if ('callable' === $type && (\Closure::class === $class || \method_exists($class, '__invoke'))) { + return; + } + if ('callable' === $type && \is_array($value) && isset($value[0]) && ($value[0] instanceof Reference || $value[0] instanceof Definition || \is_string($value[0]))) { + return; + } + if ('iterable' === $type && (\is_array($value) || 'array' === $class || \is_subclass_of($class, \Traversable::class))) { + return; + } + if ($type === $class) { + return; + } + if ('object' === $type && !isset(self::BUILTIN_TYPES[$class])) { + return; + } + if ('mixed' === $type) { + return; + } + if (\is_a($class, $type, \true)) { + return; + } + if ('false' === $type) { + if (\false === $value) { + return; + } + } elseif ($reflectionType->isBuiltin()) { + $checkFunction = \sprintf('is_%s', $type); + if ($checkFunction($value)) { + return; + } + } + throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? $class : \get_debug_type($value), $parameter); + } + private function getExpressionLanguage() : ExpressionLanguage + { + return $this->expressionLanguage = $this->expressionLanguage ?? new ExpressionLanguage(null, $this->container->getExpressionLanguageProviders()); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/Compiler.php b/vendor/symfony/dependency-injection/Compiler/Compiler.php new file mode 100644 index 0000000000..f26e4dc0e2 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/Compiler.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\EnvParameterException; +/** + * This class is used to remove circular dependencies between individual passes. + * + * @author Johannes M. Schmitt + */ +class Compiler +{ + /** + * @var \Symfony\Component\DependencyInjection\Compiler\PassConfig + */ + private $passConfig; + /** + * @var mixed[] + */ + private $log = []; + /** + * @var \Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraph + */ + private $serviceReferenceGraph; + public function __construct() + { + $this->passConfig = new PassConfig(); + $this->serviceReferenceGraph = new ServiceReferenceGraph(); + } + public function getPassConfig() : PassConfig + { + return $this->passConfig; + } + public function getServiceReferenceGraph() : ServiceReferenceGraph + { + return $this->serviceReferenceGraph; + } + public function addPass(CompilerPassInterface $pass, string $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0) + { + $this->passConfig->addPass($pass, $type, $priority); + } + /** + * @final + */ + public function log(CompilerPassInterface $pass, string $message) + { + if (\strpos($message, "\n") !== \false) { + $message = \str_replace("\n", "\n" . \get_class($pass) . ': ', \trim($message)); + } + $this->log[] = \get_class($pass) . ': ' . $message; + } + public function getLog() : array + { + return $this->log; + } + /** + * Run the Compiler and process all Passes. + */ + public function compile(ContainerBuilder $container) + { + try { + foreach ($this->passConfig->getPasses() as $pass) { + $pass->process($container); + } + } catch (\Exception $e) { + $usedEnvs = []; + $prev = $e; + do { + $msg = $prev->getMessage(); + if ($msg !== ($resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs))) { + $r = new \ReflectionProperty($prev, 'message'); + $r->setAccessible(\true); + $r->setValue($prev, $resolvedMsg); + } + } while ($prev = $prev->getPrevious()); + if ($usedEnvs) { + $e = new EnvParameterException($usedEnvs, $e); + } + throw $e; + } finally { + $this->getServiceReferenceGraph()->clear(); + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php b/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php new file mode 100644 index 0000000000..fd6b517465 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * Interface that must be implemented by compilation passes. + * + * @author Johannes M. Schmitt + */ +interface CompilerPassInterface +{ + /** + * You can modify the container here before it is dumped to PHP code. + */ + public function process(ContainerBuilder $container); +} diff --git a/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php b/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php new file mode 100644 index 0000000000..865e20fb1b --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Overwrites a service but keeps the overridden one. + * + * @author Christophe Coevoet + * @author Fabien Potencier + * @author Diego Saint Esteben + */ +class DecoratorServicePass extends AbstractRecursivePass +{ + public function process(ContainerBuilder $container) + { + $definitions = new \SplPriorityQueue(); + $order = \PHP_INT_MAX; + foreach ($container->getDefinitions() as $id => $definition) { + if (!($decorated = $definition->getDecoratedService())) { + continue; + } + $definitions->insert([$id, $definition], [$decorated[2], --$order]); + } + $decoratingDefinitions = []; + $tagsToKeep = $container->hasParameter('container.behavior_describing_tags') ? $container->getParameter('container.behavior_describing_tags') : ['container.do_not_inline', 'container.service_locator', 'container.service_subscriber', 'container.service_subscriber.locator']; + foreach ($definitions as [$id, $definition]) { + $decoratedService = $definition->getDecoratedService(); + [$inner, $renamedId] = $decoratedService; + $invalidBehavior = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + $definition->setDecoratedService(null); + if (!$renamedId) { + $renamedId = $id . '.inner'; + } + $this->currentId = $renamedId; + $this->processValue($definition); + $definition->innerServiceId = $renamedId; + $definition->decorationOnInvalid = $invalidBehavior; + // we create a new alias/service for the service we are replacing + // to be able to reference it in the new one + if ($container->hasAlias($inner)) { + $alias = $container->getAlias($inner); + $public = $alias->isPublic(); + $container->setAlias($renamedId, new Alias((string) $alias, \false)); + $decoratedDefinition = $container->findDefinition($alias); + } elseif ($container->hasDefinition($inner)) { + $decoratedDefinition = $container->getDefinition($inner); + $public = $decoratedDefinition->isPublic(); + $decoratedDefinition->setPublic(\false); + $container->setDefinition($renamedId, $decoratedDefinition); + $decoratingDefinitions[$inner] = $decoratedDefinition; + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { + $container->removeDefinition($id); + continue; + } elseif (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { + $public = $definition->isPublic(); + $decoratedDefinition = null; + } else { + throw new ServiceNotFoundException($inner, $id); + } + if (($nullsafeVariable1 = $decoratedDefinition) ? $nullsafeVariable1->isSynthetic() : null) { + throw new InvalidArgumentException(\sprintf('A synthetic service cannot be decorated: service "%s" cannot decorate "%s".', $id, $inner)); + } + if (isset($decoratingDefinitions[$inner])) { + $decoratingDefinition = $decoratingDefinitions[$inner]; + $decoratingTags = $decoratingDefinition->getTags(); + $resetTags = []; + // Behavior-describing tags must not be transferred out to decorators + foreach ($tagsToKeep as $containerTag) { + if (isset($decoratingTags[$containerTag])) { + $resetTags[$containerTag] = $decoratingTags[$containerTag]; + unset($decoratingTags[$containerTag]); + } + } + $definition->setTags(\array_merge($decoratingTags, $definition->getTags())); + $decoratingDefinition->setTags($resetTags); + $decoratingDefinitions[$inner] = $definition; + } + $container->setAlias($inner, $id)->setPublic($public); + } + } + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof Reference && '.inner' === (string) $value) { + return new Reference($this->currentId, $value->getInvalidBehavior()); + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php b/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php new file mode 100644 index 0000000000..ff2a8d159f --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Throws an exception for any Definitions that have errors and still exist. + * + * @author Ryan Weaver + */ +class DefinitionErrorExceptionPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Definition || !$value->hasErrors()) { + return parent::processValue($value, $isRoot); + } + if ($isRoot && !$value->isPublic()) { + $graph = $this->container->getCompiler()->getServiceReferenceGraph(); + $runtimeException = \false; + foreach ($graph->getNode($this->currentId)->getInEdges() as $edge) { + if (!$edge->getValue() instanceof Reference || ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE !== $edge->getValue()->getInvalidBehavior()) { + $runtimeException = \false; + break; + } + $runtimeException = \true; + } + if ($runtimeException) { + return parent::processValue($value, $isRoot); + } + } + // only show the first error so the user can focus on it + $errors = $value->getErrors(); + $message = \reset($errors); + throw new RuntimeException($message); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php b/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php new file mode 100644 index 0000000000..4be5b04573 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * A pass to automatically process extensions if they implement + * CompilerPassInterface. + * + * @author Wouter J + */ +class ExtensionCompilerPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getExtensions() as $extension) { + if (!$extension instanceof CompilerPassInterface) { + continue; + } + $extension->process($container); + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php b/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php new file mode 100644 index 0000000000..f7b2dfd845 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php @@ -0,0 +1,214 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Inline service definitions where this is possible. + * + * @author Johannes M. Schmitt + */ +class InlineServiceDefinitionsPass extends AbstractRecursivePass +{ + /** + * @var \Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass|null + */ + private $analyzingPass; + /** + * @var mixed[] + */ + private $cloningIds = []; + /** + * @var mixed[] + */ + private $connectedIds = []; + /** + * @var mixed[] + */ + private $notInlinedIds = []; + /** + * @var mixed[] + */ + private $inlinedIds = []; + /** + * @var mixed[] + */ + private $notInlinableIds = []; + /** + * @var \Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraph|null + */ + private $graph; + public function __construct(AnalyzeServiceReferencesPass $analyzingPass = null) + { + $this->analyzingPass = $analyzingPass; + } + public function process(ContainerBuilder $container) + { + $this->container = $container; + if ($this->analyzingPass) { + $analyzedContainer = new ContainerBuilder(); + $analyzedContainer->setAliases($container->getAliases()); + $analyzedContainer->setDefinitions($container->getDefinitions()); + foreach ($container->getExpressionLanguageProviders() as $provider) { + $analyzedContainer->addExpressionLanguageProvider($provider); + } + } else { + $analyzedContainer = $container; + } + try { + $remainingInlinedIds = []; + $this->connectedIds = $this->notInlinedIds = $container->getDefinitions(); + do { + if ($this->analyzingPass) { + $analyzedContainer->setDefinitions(\array_intersect_key($analyzedContainer->getDefinitions(), $this->connectedIds)); + $this->analyzingPass->process($analyzedContainer); + } + $this->graph = $analyzedContainer->getCompiler()->getServiceReferenceGraph(); + $notInlinedIds = $this->notInlinedIds; + $this->connectedIds = $this->notInlinedIds = $this->inlinedIds = []; + foreach ($analyzedContainer->getDefinitions() as $id => $definition) { + if (!$this->graph->hasNode($id)) { + continue; + } + foreach ($this->graph->getNode($id)->getOutEdges() as $edge) { + if (isset($notInlinedIds[$edge->getSourceNode()->getId()])) { + $this->currentId = $id; + $this->processValue($definition, \true); + break; + } + } + } + foreach ($this->inlinedIds as $id => $isPublicOrNotShared) { + if ($isPublicOrNotShared) { + $remainingInlinedIds[$id] = $id; + } else { + $container->removeDefinition($id); + $analyzedContainer->removeDefinition($id); + } + } + } while ($this->inlinedIds && $this->analyzingPass); + foreach ($remainingInlinedIds as $id) { + if (isset($this->notInlinableIds[$id])) { + continue; + } + $definition = $container->getDefinition($id); + if (!$definition->isShared() && !$definition->isPublic()) { + $container->removeDefinition($id); + } + } + } finally { + $this->container = null; + $this->connectedIds = $this->notInlinedIds = $this->inlinedIds = []; + $this->notInlinableIds = []; + $this->graph = null; + } + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof ArgumentInterface) { + // References found in ArgumentInterface::getValues() are not inlineable + return $value; + } + if ($value instanceof Definition && $this->cloningIds) { + if ($value->isShared()) { + return $value; + } + $value = clone $value; + } + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } elseif (!$this->container->hasDefinition($id = (string) $value)) { + return $value; + } + $definition = $this->container->getDefinition($id); + if (!$this->isInlineableDefinition($id, $definition)) { + $this->notInlinableIds[$id] = \true; + return $value; + } + $this->container->log($this, \sprintf('Inlined service "%s" to "%s".', $id, $this->currentId)); + $this->inlinedIds[$id] = $definition->isPublic() || !$definition->isShared(); + $this->notInlinedIds[$this->currentId] = \true; + if ($definition->isShared()) { + return $definition; + } + if (isset($this->cloningIds[$id])) { + $ids = \array_keys($this->cloningIds); + $ids[] = $id; + throw new ServiceCircularReferenceException($id, \array_slice($ids, \array_search($id, $ids))); + } + $this->cloningIds[$id] = \true; + try { + return $this->processValue($definition); + } finally { + unset($this->cloningIds[$id]); + } + } + /** + * Checks if the definition is inlineable. + */ + private function isInlineableDefinition(string $id, Definition $definition) : bool + { + if ($definition->hasErrors() || $definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic() || $definition->hasTag('container.do_not_inline')) { + return \false; + } + if (!$definition->isShared()) { + if (!$this->graph->hasNode($id)) { + return \true; + } + foreach ($this->graph->getNode($id)->getInEdges() as $edge) { + $srcId = $edge->getSourceNode()->getId(); + $this->connectedIds[$srcId] = \true; + if ($edge->isWeak() || $edge->isLazy()) { + return !($this->connectedIds[$id] = \true); + } + } + return \true; + } + if ($definition->isPublic()) { + return \false; + } + if (!$this->graph->hasNode($id)) { + return \true; + } + if ($this->currentId == $id) { + return \false; + } + $this->connectedIds[$id] = \true; + $srcIds = []; + $srcCount = 0; + foreach ($this->graph->getNode($id)->getInEdges() as $edge) { + $srcId = $edge->getSourceNode()->getId(); + $this->connectedIds[$srcId] = \true; + if ($edge->isWeak() || $edge->isLazy()) { + return \false; + } + $srcIds[$srcId] = \true; + ++$srcCount; + } + if (1 !== \count($srcIds)) { + $this->notInlinedIds[$id] = \true; + return \false; + } + if ($srcCount > 1 && \is_array($factory = $definition->getFactory()) && ($factory[0] instanceof Reference || $factory[0] instanceof Definition)) { + return \false; + } + return $this->container->getDefinition($srcId)->isShared(); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php b/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php new file mode 100644 index 0000000000..4d984b6402 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php @@ -0,0 +1,197 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BaseNode; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\Extension; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +/** + * Merges extension configs into the container builder. + * + * @author Fabien Potencier + */ +class MergeExtensionConfigurationPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $parameters = $container->getParameterBag()->all(); + $definitions = $container->getDefinitions(); + $aliases = $container->getAliases(); + $exprLangProviders = $container->getExpressionLanguageProviders(); + $configAvailable = \class_exists(BaseNode::class); + foreach ($container->getExtensions() as $extension) { + if ($extension instanceof PrependExtensionInterface) { + $extension->prepend($container); + } + } + foreach ($container->getExtensions() as $name => $extension) { + if (!($config = $container->getExtensionConfig($name))) { + // this extension was not called + continue; + } + $resolvingBag = $container->getParameterBag(); + if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) { + // create a dedicated bag so that we can track env vars per-extension + $resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag); + if ($configAvailable) { + BaseNode::setPlaceholderUniquePrefix($resolvingBag->getEnvPlaceholderUniquePrefix()); + } + } + $config = $resolvingBag->resolveValue($config); + try { + $tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag); + $tmpContainer->setResourceTracking($container->isTrackingResources()); + $tmpContainer->addObjectResource($extension); + if ($extension instanceof ConfigurationExtensionInterface && null !== ($configuration = $extension->getConfiguration($config, $tmpContainer))) { + $tmpContainer->addObjectResource($configuration); + } + foreach ($exprLangProviders as $provider) { + $tmpContainer->addExpressionLanguageProvider($provider); + } + $extension->load($config, $tmpContainer); + } catch (\Exception $e) { + if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { + $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag); + } + throw $e; + } + if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { + // don't keep track of env vars that are *overridden* when configs are merged + $resolvingBag->freezeAfterProcessing($extension, $tmpContainer); + } + $container->merge($tmpContainer); + $container->getParameterBag()->add($parameters); + } + $container->addDefinitions($definitions); + $container->addAliases($aliases); + } +} +/** + * @internal + */ +class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag +{ + /** + * @var mixed[] + */ + private $processedEnvPlaceholders; + public function __construct(parent $parameterBag) + { + parent::__construct($parameterBag->all()); + $this->mergeEnvPlaceholders($parameterBag); + } + public function freezeAfterProcessing(Extension $extension, ContainerBuilder $container) + { + if (!($config = $extension->getProcessedConfigs())) { + // Extension::processConfiguration() wasn't called, we cannot know how configs were merged + return; + } + $this->processedEnvPlaceholders = []; + // serialize config and container to catch env vars nested in object graphs + $config = \serialize($config) . \serialize($container->getDefinitions()) . \serialize($container->getAliases()) . \serialize($container->getParameterBag()->all()); + foreach (parent::getEnvPlaceholders() as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (\false !== \stripos($config, $placeholder)) { + $this->processedEnvPlaceholders[$env] = $placeholders; + break; + } + } + } + } + /** + * {@inheritdoc} + */ + public function getEnvPlaceholders() : array + { + return $this->processedEnvPlaceholders ?? parent::getEnvPlaceholders(); + } + public function getUnusedEnvPlaceholders() : array + { + return !isset($this->processedEnvPlaceholders) ? [] : \array_diff_key(parent::getEnvPlaceholders(), $this->processedEnvPlaceholders); + } +} +/** + * A container builder preventing using methods that wouldn't have any effect from extensions. + * + * @internal + */ +class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder +{ + /** + * @var string + */ + private $extensionClass; + public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null) + { + parent::__construct($parameterBag); + $this->extensionClass = \get_class($extension); + } + /** + * {@inheritdoc} + * @return static + */ + public function addCompilerPass(CompilerPassInterface $pass, string $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0) + { + throw new LogicException(\sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', \get_debug_type($pass), $this->extensionClass)); + } + /** + * {@inheritdoc} + */ + public function registerExtension(ExtensionInterface $extension) + { + throw new LogicException(\sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', \get_debug_type($extension), $this->extensionClass)); + } + /** + * {@inheritdoc} + */ + public function compile(bool $resolveEnvPlaceholders = \false) + { + throw new LogicException(\sprintf('Cannot compile the container in extension "%s".', $this->extensionClass)); + } + /** + * {@inheritdoc} + * @param string|bool $format + * @param mixed $value + * @return mixed + */ + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) + { + if (\true !== $format || !\is_string($value)) { + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } + $bag = $this->getParameterBag(); + $value = $bag->resolveValue($value); + if (!$bag instanceof EnvPlaceholderParameterBag) { + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } + foreach ($bag->getEnvPlaceholders() as $env => $placeholders) { + if (\strpos($env, ':') === \false) { + continue; + } + foreach ($placeholders as $placeholder) { + if (\false !== \stripos($value, $placeholder)) { + throw new RuntimeException(\sprintf('Using a cast in "env(%s)" is incompatible with resolution at compile time in "%s". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.', $env, $this->extensionClass)); + } + } + } + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/PassConfig.php b/vendor/symfony/dependency-injection/Compiler/PassConfig.php new file mode 100644 index 0000000000..23397ba42f --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/PassConfig.php @@ -0,0 +1,203 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * Compiler Pass Configuration. + * + * This class has a default configuration embedded. + * + * @author Johannes M. Schmitt + */ +class PassConfig +{ + public const TYPE_AFTER_REMOVING = 'afterRemoving'; + public const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization'; + public const TYPE_BEFORE_REMOVING = 'beforeRemoving'; + public const TYPE_OPTIMIZE = 'optimization'; + public const TYPE_REMOVE = 'removing'; + /** + * @var \Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass + */ + private $mergePass; + /** + * @var mixed[] + */ + private $afterRemovingPasses; + /** + * @var mixed[] + */ + private $beforeOptimizationPasses; + /** + * @var mixed[] + */ + private $beforeRemovingPasses = []; + /** + * @var mixed[] + */ + private $optimizationPasses; + /** + * @var mixed[] + */ + private $removingPasses; + public function __construct() + { + $this->mergePass = new MergeExtensionConfigurationPass(); + $this->beforeOptimizationPasses = [100 => [new ResolveClassPass(), new RegisterAutoconfigureAttributesPass(), new AutowireAsDecoratorPass(), new AttributeAutoconfigurationPass(), new ResolveInstanceofConditionalsPass(), new RegisterEnvVarProcessorsPass()], -1000 => [new ExtensionCompilerPass()]]; + $this->optimizationPasses = [[new AutoAliasServicePass(), new ValidateEnvPlaceholdersPass(), new ResolveDecoratorStackPass(), new ResolveChildDefinitionsPass(), new RegisterServiceSubscribersPass(), new ResolveParameterPlaceHoldersPass(\false, \false), new ResolveFactoryClassPass(), new ResolveNamedArgumentsPass(), new AutowireRequiredMethodsPass(), new AutowireRequiredPropertiesPass(), new ResolveBindingsPass(), new ServiceLocatorTagPass(), new DecoratorServicePass(), new CheckDefinitionValidityPass(), new AutowirePass(\false), new ServiceLocatorTagPass(), new ResolveTaggedIteratorArgumentPass(), new ResolveServiceSubscribersPass(), new ResolveReferencesToAliasesPass(), new ResolveInvalidReferencesPass(), new AnalyzeServiceReferencesPass(\true), new CheckCircularReferencesPass(), new CheckReferenceValidityPass(), new CheckArgumentsValidityPass(\false)]]; + $this->removingPasses = [[new RemovePrivateAliasesPass(), new ReplaceAliasByActualDefinitionPass(), new RemoveAbstractDefinitionsPass(), new RemoveUnusedDefinitionsPass(), new AnalyzeServiceReferencesPass(), new CheckExceptionOnInvalidReferenceBehaviorPass(), new InlineServiceDefinitionsPass(new AnalyzeServiceReferencesPass()), new AnalyzeServiceReferencesPass(), new DefinitionErrorExceptionPass()]]; + $this->afterRemovingPasses = [[new ResolveHotPathPass(), new ResolveNoPreloadPass(), new AliasDeprecatedPublicServicesPass()]]; + } + /** + * Returns all passes in order to be processed. + * + * @return CompilerPassInterface[] + */ + public function getPasses() : array + { + return \array_merge([$this->mergePass], $this->getBeforeOptimizationPasses(), $this->getOptimizationPasses(), $this->getBeforeRemovingPasses(), $this->getRemovingPasses(), $this->getAfterRemovingPasses()); + } + /** + * Adds a pass. + * + * @throws InvalidArgumentException when a pass type doesn't exist + */ + public function addPass(CompilerPassInterface $pass, string $type = self::TYPE_BEFORE_OPTIMIZATION, int $priority = 0) + { + $property = $type . 'Passes'; + if (!isset($this->{$property})) { + throw new InvalidArgumentException(\sprintf('Invalid type "%s".', $type)); + } + $passes =& $this->{$property}; + if (!isset($passes[$priority])) { + $passes[$priority] = []; + } + $passes[$priority][] = $pass; + } + /** + * Gets all passes for the AfterRemoving pass. + * + * @return CompilerPassInterface[] + */ + public function getAfterRemovingPasses() : array + { + return $this->sortPasses($this->afterRemovingPasses); + } + /** + * Gets all passes for the BeforeOptimization pass. + * + * @return CompilerPassInterface[] + */ + public function getBeforeOptimizationPasses() : array + { + return $this->sortPasses($this->beforeOptimizationPasses); + } + /** + * Gets all passes for the BeforeRemoving pass. + * + * @return CompilerPassInterface[] + */ + public function getBeforeRemovingPasses() : array + { + return $this->sortPasses($this->beforeRemovingPasses); + } + /** + * Gets all passes for the Optimization pass. + * + * @return CompilerPassInterface[] + */ + public function getOptimizationPasses() : array + { + return $this->sortPasses($this->optimizationPasses); + } + /** + * Gets all passes for the Removing pass. + * + * @return CompilerPassInterface[] + */ + public function getRemovingPasses() : array + { + return $this->sortPasses($this->removingPasses); + } + /** + * Gets the Merge pass. + */ + public function getMergePass() : CompilerPassInterface + { + return $this->mergePass; + } + public function setMergePass(CompilerPassInterface $pass) + { + $this->mergePass = $pass; + } + /** + * Sets the AfterRemoving passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setAfterRemovingPasses(array $passes) + { + $this->afterRemovingPasses = [$passes]; + } + /** + * Sets the BeforeOptimization passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setBeforeOptimizationPasses(array $passes) + { + $this->beforeOptimizationPasses = [$passes]; + } + /** + * Sets the BeforeRemoving passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setBeforeRemovingPasses(array $passes) + { + $this->beforeRemovingPasses = [$passes]; + } + /** + * Sets the Optimization passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setOptimizationPasses(array $passes) + { + $this->optimizationPasses = [$passes]; + } + /** + * Sets the Removing passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setRemovingPasses(array $passes) + { + $this->removingPasses = [$passes]; + } + /** + * Sort passes by priority. + * + * @param array $passes CompilerPassInterface instances with their priority as key + * + * @return CompilerPassInterface[] + */ + private function sortPasses(array $passes) : array + { + if (0 === \count($passes)) { + return []; + } + \krsort($passes); + // Flatten the array + return \array_merge(...$passes); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php b/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php new file mode 100644 index 0000000000..715f5f2902 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\AsTaggedItem; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +/** + * Trait that allows a generic method to find and sort service by priority option in the tag. + * + * @author Iltar van der Berg + */ +trait PriorityTaggedServiceTrait +{ + /** + * Finds all services with the given tag name and order them by their priority. + * + * The order of additions must be respected for services having the same priority, + * and knowing that the \SplPriorityQueue class does not respect the FIFO method, + * we should not use that class. + * + * @see https://bugs.php.net/53710 + * @see https://bugs.php.net/60926 + * + * @return Reference[] + * @param string|\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument $tagName + */ + private function findAndSortTaggedServices($tagName, ContainerBuilder $container) : array + { + $exclude = []; + $indexAttribute = $defaultIndexMethod = $needsIndexes = $defaultPriorityMethod = null; + if ($tagName instanceof TaggedIteratorArgument) { + $indexAttribute = $tagName->getIndexAttribute(); + $defaultIndexMethod = $tagName->getDefaultIndexMethod(); + $needsIndexes = $tagName->needsIndexes(); + $defaultPriorityMethod = $tagName->getDefaultPriorityMethod() ?? 'getDefaultPriority'; + $exclude = $tagName->getExclude(); + $tagName = $tagName->getTag(); + } + $i = 0; + $services = []; + foreach ($container->findTaggedServiceIds($tagName, \true) as $serviceId => $attributes) { + if (\in_array($serviceId, $exclude, \true)) { + continue; + } + $defaultPriority = null; + $defaultIndex = null; + $definition = $container->getDefinition($serviceId); + $class = $definition->getClass(); + $class = $container->getParameterBag()->resolveValue($class) ?: null; + $checkTaggedItem = !$definition->hasTag($definition->isAutoconfigured() ? 'container.ignore_attributes' : $tagName); + foreach ($attributes as $attribute) { + $index = $priority = null; + if (isset($attribute['priority'])) { + $priority = $attribute['priority']; + } elseif (null === $defaultPriority && $defaultPriorityMethod && $class) { + $defaultPriority = PriorityTaggedServiceUtil::getDefault($container, $serviceId, $class, $defaultPriorityMethod, $tagName, 'priority', $checkTaggedItem); + } + $priority = $priority ?? ($defaultPriority = $defaultPriority ?? 0); + if (null === $indexAttribute && !$defaultIndexMethod && !$needsIndexes) { + $services[] = [$priority, ++$i, null, $serviceId, null]; + continue 2; + } + if (null !== $indexAttribute && isset($attribute[$indexAttribute])) { + $index = $attribute[$indexAttribute]; + } elseif (null === $defaultIndex && $defaultPriorityMethod && $class) { + $defaultIndex = PriorityTaggedServiceUtil::getDefault($container, $serviceId, $class, $defaultIndexMethod ?? 'getDefaultName', $tagName, $indexAttribute, $checkTaggedItem); + } + $index = $index ?? ($defaultIndex = $defaultIndex ?? $serviceId); + $services[] = [$priority, ++$i, $index, $serviceId, $class]; + } + } + \uasort($services, static function ($a, $b) { + return $b[0] <=> $a[0] ?: $a[1] <=> $b[1]; + }); + $refs = []; + foreach ($services as [, , $index, $serviceId, $class]) { + if (!$class) { + $reference = new Reference($serviceId); + } elseif ($index === $serviceId) { + $reference = new TypedReference($serviceId, $class); + } else { + $reference = new TypedReference($serviceId, $class, ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, $index); + } + if (null === $index) { + $refs[] = $reference; + } else { + $refs[$index] = $reference; + } + } + return $refs; + } +} +/** + * @internal + */ +class PriorityTaggedServiceUtil +{ + /** + * @return string|int|null + */ + public static function getDefault(ContainerBuilder $container, string $serviceId, string $class, string $defaultMethod, string $tagName, ?string $indexAttribute, bool $checkTaggedItem) + { + if (!($r = $container->getReflectionClass($class)) || !$checkTaggedItem && !$r->hasMethod($defaultMethod)) { + return null; + } + if ($checkTaggedItem && !$r->hasMethod($defaultMethod)) { + foreach (\method_exists($r, 'getAttributes') ? $r->getAttributes(AsTaggedItem::class) : [] as $attribute) { + return 'priority' === $indexAttribute ? $attribute->newInstance()->priority : $attribute->newInstance()->index; + } + return null; + } + if (null !== $indexAttribute) { + $service = $class !== $serviceId ? \sprintf('service "%s"', $serviceId) : 'on the corresponding service'; + $message = [\sprintf('Either method "%s::%s()" should ', $class, $defaultMethod), \sprintf(' or tag "%s" on %s is missing attribute "%s".', $tagName, $service, $indexAttribute)]; + } else { + $message = [\sprintf('Method "%s::%s()" should ', $class, $defaultMethod), '.']; + } + if (!($rm = $r->getMethod($defaultMethod))->isStatic()) { + throw new InvalidArgumentException(\implode('be static', $message)); + } + if (!$rm->isPublic()) { + throw new InvalidArgumentException(\implode('be public', $message)); + } + $default = $rm->invoke(null); + if ('priority' === $indexAttribute) { + if (!\is_int($default)) { + throw new InvalidArgumentException(\implode(\sprintf('return int (got "%s")', \get_debug_type($default)), $message)); + } + return $default; + } + if (\is_int($default)) { + $default = (string) $default; + } + if (!\is_string($default)) { + throw new InvalidArgumentException(\implode(\sprintf('return string|int (got "%s")', \get_debug_type($default)), $message)); + } + return $default; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RegisterAutoconfigureAttributesPass.php b/vendor/symfony/dependency-injection/Compiler/RegisterAutoconfigureAttributesPass.php new file mode 100644 index 0000000000..fcae5e8df2 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/RegisterAutoconfigureAttributesPass.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\Autoconfigure; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +/** + * Reads #[Autoconfigure] attributes on definitions that are autoconfigured + * and don't have the "container.ignore_attributes" tag. + * + * @author Nicolas Grekas + */ +final class RegisterAutoconfigureAttributesPass implements CompilerPassInterface +{ + private static $registerForAutoconfiguration; + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($this->accept($definition) && ($class = $container->getReflectionClass($definition->getClass(), \false))) { + $this->processClass($container, $class); + } + } + } + public function accept(Definition $definition) : bool + { + return $definition->isAutoconfigured() && !$definition->hasTag('container.ignore_attributes'); + } + public function processClass(ContainerBuilder $container, \ReflectionClass $class) + { + foreach (\method_exists($class, 'getAttributes') ? $class->getAttributes(Autoconfigure::class, \ReflectionAttribute::IS_INSTANCEOF) : [] as $attribute) { + self::registerForAutoconfiguration($container, $class, $attribute); + } + } + private static function registerForAutoconfiguration(ContainerBuilder $container, \ReflectionClass $class, \ReflectionAttribute $attribute) + { + if (self::$registerForAutoconfiguration) { + return (self::$registerForAutoconfiguration)($container, $class, $attribute); + } + $parseDefinitions = new \ReflectionMethod(YamlFileLoader::class, 'parseDefinitions'); + $yamlLoader = $parseDefinitions->getDeclaringClass()->newInstanceWithoutConstructor(); + self::$registerForAutoconfiguration = static function (ContainerBuilder $container, \ReflectionClass $class, \ReflectionAttribute $attribute) use($parseDefinitions, $yamlLoader) { + $attribute = (array) $attribute->newInstance(); + foreach ($attribute['tags'] ?? [] as $i => $tag) { + if (\is_array($tag) && [0] === \array_keys($tag)) { + $attribute['tags'][$i] = [$class->name => $tag[0]]; + } + } + $parseDefinitions->invoke($yamlLoader, ['services' => ['_instanceof' => [$class->name => [$container->registerForAutoconfiguration($class->name)] + $attribute]]], $class->getFileName(), \false); + }; + return (self::$registerForAutoconfiguration)($container, $class, $attribute); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php b/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php new file mode 100644 index 0000000000..cad1d86fee --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\EnvVarProcessor; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\EnvVarProcessorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Creates the container.env_var_processors_locator service. + * + * @author Nicolas Grekas + */ +class RegisterEnvVarProcessorsPass implements CompilerPassInterface +{ + private const ALLOWED_TYPES = ['array', 'bool', 'float', 'int', 'string']; + public function process(ContainerBuilder $container) + { + $bag = $container->getParameterBag(); + $types = []; + $processors = []; + foreach ($container->findTaggedServiceIds('container.env_var_processor') as $id => $tags) { + if (!($r = $container->getReflectionClass($class = $container->getDefinition($id)->getClass()))) { + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } elseif (!$r->isSubclassOf(EnvVarProcessorInterface::class)) { + throw new InvalidArgumentException(\sprintf('Service "%s" must implement interface "%s".', $id, EnvVarProcessorInterface::class)); + } + foreach ($class::getProvidedTypes() as $prefix => $type) { + $processors[$prefix] = new Reference($id); + $types[$prefix] = self::validateProvidedTypes($type, $class); + } + } + if ($bag instanceof EnvPlaceholderParameterBag) { + foreach (EnvVarProcessor::getProvidedTypes() as $prefix => $type) { + if (!isset($types[$prefix])) { + $types[$prefix] = self::validateProvidedTypes($type, EnvVarProcessor::class); + } + } + $bag->setProvidedTypes($types); + } + if ($processors) { + $container->setAlias('container.env_var_processors_locator', (string) ServiceLocatorTagPass::register($container, $processors))->setPublic(\true); + } + } + private static function validateProvidedTypes(string $types, string $class) : array + { + $types = \explode('|', $types); + foreach ($types as $type) { + if (!\in_array($type, self::ALLOWED_TYPES)) { + throw new InvalidArgumentException(\sprintf('Invalid type "%s" returned by "%s::getProvidedTypes()", expected one of "%s".', $type, $class, \implode('", "', self::ALLOWED_TYPES))); + } + } + return $types; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php b/vendor/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php new file mode 100644 index 0000000000..5dfd2dd484 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/RegisterReverseContainerPass.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * @author Nicolas Grekas + */ +class RegisterReverseContainerPass implements CompilerPassInterface +{ + /** + * @var bool + */ + private $beforeRemoving; + public function __construct(bool $beforeRemoving) + { + $this->beforeRemoving = $beforeRemoving; + } + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('reverse_container')) { + return; + } + $refType = $this->beforeRemoving ? ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE : ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + $services = []; + foreach ($container->findTaggedServiceIds('container.reversible') as $id => $tags) { + $services[$id] = new Reference($id, $refType); + } + if ($this->beforeRemoving) { + // prevent inlining of the reverse container + $services['reverse_container'] = new Reference('reverse_container', $refType); + } + $locator = $container->getDefinition('reverse_container')->getArgument(1); + if ($locator instanceof Reference) { + $locator = $container->getDefinition((string) $locator); + } + if ($locator instanceof Definition) { + foreach ($services as $id => $ref) { + $services[$id] = new ServiceClosureArgument($ref); + } + $locator->replaceArgument(0, $services); + } else { + $locator->setValues($services); + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php b/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php new file mode 100644 index 0000000000..9f4ee35560 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface as PsrContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\BoundArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +use MonorepoBuilderPrefix202310\Symfony\Component\HttpFoundation\Session\SessionInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceProviderInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceSubscriberInterface; +/** + * Compiler pass to register tagged services that require a service locator. + * + * @author Nicolas Grekas + */ +class RegisterServiceSubscribersPass extends AbstractRecursivePass +{ + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) { + return parent::processValue($value, $isRoot); + } + $serviceMap = []; + $autowire = $value->isAutowired(); + foreach ($value->getTag('container.service_subscriber') as $attributes) { + if (!$attributes) { + $autowire = \true; + continue; + } + \ksort($attributes); + if ([] !== \array_diff(\array_keys($attributes), ['id', 'key'])) { + throw new InvalidArgumentException(\sprintf('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "%s" given for service "%s".', \implode('", "', \array_keys($attributes)), $this->currentId)); + } + if (!\array_key_exists('id', $attributes)) { + throw new InvalidArgumentException(\sprintf('Missing "id" attribute on "container.service_subscriber" tag with key="%s" for service "%s".', $attributes['key'], $this->currentId)); + } + if (!\array_key_exists('key', $attributes)) { + $attributes['key'] = $attributes['id']; + } + if (isset($serviceMap[$attributes['key']])) { + continue; + } + $serviceMap[$attributes['key']] = new Reference($attributes['id']); + } + $class = $value->getClass(); + if (!($r = $this->container->getReflectionClass($class))) { + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId)); + } + if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) { + throw new InvalidArgumentException(\sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class)); + } + $class = $r->name; + // to remove when symfony/dependency-injection will stop being compatible with symfony/framework-bundle<6.0 + $replaceDeprecatedSession = $this->container->has('.session.deprecated') && $r->isSubclassOf(AbstractController::class); + $subscriberMap = []; + foreach ($class::getSubscribedServices() as $key => $type) { + if (!\is_string($type) || !\preg_match('/(?(DEFINE)(?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+))(?(DEFINE)(?(?&cn)(?:\\\\(?&cn))*+))^\\??(?&fqcn)(?:(?:\\|(?&fqcn))*+|(?:&(?&fqcn))*+)$/', $type)) { + throw new InvalidArgumentException(\sprintf('"%s::getSubscribedServices()" must return valid PHP types for service "%s" key "%s", "%s" returned.', $class, $this->currentId, $key, \is_string($type) ? $type : \get_debug_type($type))); + } + if ($optionalBehavior = '?' === $type[0]) { + $type = \substr($type, 1); + $optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } + if (\is_int($name = $key)) { + $key = $type; + $name = null; + } + if (!isset($serviceMap[$key])) { + if (!$autowire) { + throw new InvalidArgumentException(\sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class)); + } + if ($replaceDeprecatedSession && SessionInterface::class === $type) { + // This prevents triggering the deprecation when building the container + // to remove when symfony/dependency-injection will stop being compatible with symfony/framework-bundle<6.0 + $type = '.session.deprecated'; + } + $serviceMap[$key] = new Reference($type); + } + if ($name) { + if (\false !== ($i = \strpos($name, '::get'))) { + $name = \lcfirst(\substr($name, 5 + $i)); + } elseif (\strpos($name, '::') !== \false) { + $name = null; + } + } + if (null !== $name && !$this->container->has($name) && !$this->container->has($type . ' $' . $name)) { + $camelCaseName = \lcfirst(\str_replace(' ', '', \ucwords(\preg_replace('/[^a-zA-Z0-9\\x7f-\\xff]++/', ' ', $name)))); + $name = $this->container->has($type . ' $' . $camelCaseName) ? $camelCaseName : $name; + } + $subscriberMap[$key] = new TypedReference((string) $serviceMap[$key], $type, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $name); + unset($serviceMap[$key]); + } + if ($serviceMap = \array_keys($serviceMap)) { + $message = \sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', \str_replace('%', '%%', \implode('", "', $serviceMap))); + throw new InvalidArgumentException(\sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId)); + } + $locatorRef = ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId); + $value->addTag('container.service_subscriber.locator', ['id' => (string) $locatorRef]); + $value->setBindings([PsrContainerInterface::class => new BoundArgument($locatorRef, \false), ServiceProviderInterface::class => new BoundArgument($locatorRef, \false)] + $value->getBindings()); + return parent::processValue($value); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php b/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php new file mode 100644 index 0000000000..fa15dcf2b0 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * Removes abstract Definitions. + */ +class RemoveAbstractDefinitionsPass implements CompilerPassInterface +{ + /** + * Removes abstract definitions from the ContainerBuilder. + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isAbstract()) { + $container->removeDefinition($id); + $container->log($this, \sprintf('Removed service "%s"; reason: abstract.', $id)); + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php b/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php new file mode 100644 index 0000000000..3ca9c3b89e --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * Remove private aliases from the container. They were only used to establish + * dependencies between services, and these dependencies have been resolved in + * one of the previous passes. + * + * @author Johannes M. Schmitt + */ +class RemovePrivateAliasesPass implements CompilerPassInterface +{ + /** + * Removes private aliases from the ContainerBuilder. + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPublic()) { + continue; + } + $container->removeAlias($id); + $container->log($this, \sprintf('Removed service "%s"; reason: private alias.', $id)); + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php b/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php new file mode 100644 index 0000000000..1bd443b053 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Removes unused service definitions from the container. + * + * @author Johannes M. Schmitt + * @author Nicolas Grekas + */ +class RemoveUnusedDefinitionsPass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $connectedIds = []; + /** + * Processes the ContainerBuilder to remove unused definitions. + */ + public function process(ContainerBuilder $container) + { + try { + $this->enableExpressionProcessing(); + $this->container = $container; + $connectedIds = []; + $aliases = $container->getAliases(); + foreach ($aliases as $id => $alias) { + if ($alias->isPublic()) { + $this->connectedIds[] = (string) $aliases[$id]; + } + } + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isPublic()) { + $connectedIds[$id] = \true; + $this->processValue($definition); + } + } + while ($this->connectedIds) { + $ids = $this->connectedIds; + $this->connectedIds = []; + foreach ($ids as $id) { + if (!isset($connectedIds[$id]) && $container->hasDefinition($id)) { + $connectedIds[$id] = \true; + $this->processValue($container->getDefinition($id)); + } + } + } + foreach ($container->getDefinitions() as $id => $definition) { + if (!isset($connectedIds[$id])) { + $container->removeDefinition($id); + $container->resolveEnvPlaceholders(!$definition->hasErrors() ? \serialize($definition) : $definition); + $container->log($this, \sprintf('Removed service "%s"; reason: unused.', $id)); + } + } + } finally { + $this->container = null; + $this->connectedIds = []; + } + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } + if (ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior()) { + $this->connectedIds[] = (string) $value; + } + return $value; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php b/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php new file mode 100644 index 0000000000..feb6f6cb09 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Replaces aliases with actual service definitions, effectively removing these + * aliases. + * + * @author Johannes M. Schmitt + */ +class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $replacements; + /** + * Process the Container to replace aliases with service definitions. + * + * @throws InvalidArgumentException if the service definition does not exist + */ + public function process(ContainerBuilder $container) + { + // First collect all alias targets that need to be replaced + $seenAliasTargets = []; + $replacements = []; + foreach ($container->getAliases() as $definitionId => $target) { + $targetId = (string) $target; + // Special case: leave this target alone + if ('service_container' === $targetId) { + continue; + } + // Check if target needs to be replaced + if (isset($replacements[$targetId])) { + $container->setAlias($definitionId, $replacements[$targetId])->setPublic($target->isPublic()); + if ($target->isDeprecated()) { + $container->getAlias($definitionId)->setDeprecated(...\array_values($target->getDeprecation('%alias_id%'))); + } + } + // No need to process the same target twice + if (isset($seenAliasTargets[$targetId])) { + continue; + } + // Process new target + $seenAliasTargets[$targetId] = \true; + try { + $definition = $container->getDefinition($targetId); + } catch (ServiceNotFoundException $e) { + if ('' !== $e->getId() && '@' === $e->getId()[0]) { + throw new ServiceNotFoundException($e->getId(), $e->getSourceId(), null, [\substr($e->getId(), 1)]); + } + throw $e; + } + if ($definition->isPublic()) { + continue; + } + // Remove private definition and schedule for replacement + $definition->setPublic($target->isPublic()); + $container->setDefinition($definitionId, $definition); + $container->removeDefinition($targetId); + $replacements[$targetId] = $definitionId; + if ($target->isPublic() && $target->isDeprecated()) { + $definition->addTag('container.private', $target->getDeprecation('%service_id%')); + } + } + $this->replacements = $replacements; + parent::process($container); + $this->replacements = []; + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof Reference && isset($this->replacements[$referenceId = (string) $value])) { + // Perform the replacement + $newId = $this->replacements[$referenceId]; + $value = new Reference($newId, $value->getInvalidBehavior()); + $this->container->log($this, \sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $this->currentId, $referenceId, $newId)); + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php new file mode 100644 index 0000000000..dee1d1d37a --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php @@ -0,0 +1,222 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\BoundArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\Target; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +/** + * @author Guilhem Niot + */ +class ResolveBindingsPass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $usedBindings = []; + /** + * @var mixed[] + */ + private $unusedBindings = []; + /** + * @var mixed[] + */ + private $errorMessages = []; + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->usedBindings = $container->getRemovedBindingIds(); + try { + parent::process($container); + foreach ($this->unusedBindings as [$key, $serviceId, $bindingType, $file]) { + $argumentType = $argumentName = $message = null; + if (\strpos($key, ' ') !== \false) { + [$argumentType, $argumentName] = \explode(' ', $key, 2); + } elseif ('$' === $key[0]) { + $argumentName = $key; + } else { + $argumentType = $key; + } + if ($argumentType) { + $message .= \sprintf('of type "%s" ', $argumentType); + } + if ($argumentName) { + $message .= \sprintf('named "%s" ', $argumentName); + } + if (BoundArgument::DEFAULTS_BINDING === $bindingType) { + $message .= 'under "_defaults"'; + } elseif (BoundArgument::INSTANCEOF_BINDING === $bindingType) { + $message .= 'under "_instanceof"'; + } else { + $message .= \sprintf('for service "%s"', $serviceId); + } + if ($file) { + $message .= \sprintf(' in file "%s"', $file); + } + $message = \sprintf('A binding is configured for an argument %s, but no corresponding argument has been found. It may be unused and should be removed, or it may have a typo.', $message); + if ($this->errorMessages) { + $message .= \sprintf("\nCould be related to%s:", 1 < \count($this->errorMessages) ? ' one of' : ''); + } + foreach ($this->errorMessages as $m) { + $message .= "\n - " . $m; + } + throw new InvalidArgumentException($message); + } + } finally { + $this->usedBindings = []; + $this->unusedBindings = []; + $this->errorMessages = []; + } + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof TypedReference && $value->getType() === (string) $value) { + // Already checked + $bindings = $this->container->getDefinition($this->currentId)->getBindings(); + $name = $value->getName(); + if (isset($name, $bindings[$name = $value . ' $' . $name])) { + return $this->getBindingValue($bindings[$name]); + } + if (isset($bindings[$value->getType()])) { + return $this->getBindingValue($bindings[$value->getType()]); + } + return parent::processValue($value, $isRoot); + } + if (!$value instanceof Definition || !($bindings = $value->getBindings())) { + return parent::processValue($value, $isRoot); + } + $bindingNames = []; + foreach ($bindings as $key => $binding) { + [$bindingValue, $bindingId, $used, $bindingType, $file] = $binding->getValues(); + if ($used) { + $this->usedBindings[$bindingId] = \true; + unset($this->unusedBindings[$bindingId]); + } elseif (!isset($this->usedBindings[$bindingId])) { + $this->unusedBindings[$bindingId] = [$key, $this->currentId, $bindingType, $file]; + } + if (\preg_match('/^(?:(?:array|bool|float|int|string|iterable|([^ $]++)) )\\$/', $key, $m)) { + $bindingNames[\substr($key, \strlen($m[0]))] = $binding; + } + if (!isset($m[1])) { + continue; + } + if (\is_subclass_of($m[1], \UnitEnum::class)) { + $bindingNames[\substr($key, \strlen($m[0]))] = $binding; + continue; + } + if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition && !$bindingValue instanceof TaggedIteratorArgument && !$bindingValue instanceof ServiceLocatorArgument) { + throw new InvalidArgumentException(\sprintf('Invalid value for binding key "%s" for service "%s": expected "%s", "%s", "%s", "%s" or null, "%s" given.', $key, $this->currentId, Reference::class, Definition::class, TaggedIteratorArgument::class, ServiceLocatorArgument::class, \get_debug_type($bindingValue))); + } + } + if ($value->isAbstract()) { + return parent::processValue($value, $isRoot); + } + $calls = $value->getMethodCalls(); + try { + if ($constructor = $this->getConstructor($value, \false)) { + $calls[] = [$constructor, $value->getArguments()]; + } + } catch (RuntimeException $e) { + $this->errorMessages[] = $e->getMessage(); + $this->container->getDefinition($this->currentId)->addError($e->getMessage()); + return parent::processValue($value, $isRoot); + } + foreach ($calls as $i => $call) { + [$method, $arguments] = $call; + if ($method instanceof \ReflectionFunctionAbstract) { + $reflectionMethod = $method; + } else { + try { + $reflectionMethod = $this->getReflectionMethod($value, $method); + } catch (RuntimeException $e) { + if ($value->getFactory()) { + continue; + } + throw $e; + } + } + $names = []; + foreach ($reflectionMethod->getParameters() as $key => $parameter) { + $names[$key] = $parameter->name; + if (\array_key_exists($key, $arguments) && '' !== $arguments[$key]) { + continue; + } + if (\array_key_exists($parameter->name, $arguments) && '' !== $arguments[$parameter->name]) { + continue; + } + $typeHint = ProxyHelper::getTypeHint($reflectionMethod, $parameter); + $name = Target::parseName($parameter); + if ($typeHint && \array_key_exists($k = \ltrim($typeHint, '\\') . ' $' . $name, $bindings)) { + $arguments[$key] = $this->getBindingValue($bindings[$k]); + continue; + } + if (\array_key_exists('$' . $name, $bindings)) { + $arguments[$key] = $this->getBindingValue($bindings['$' . $name]); + continue; + } + if ($typeHint && '\\' === $typeHint[0] && isset($bindings[$typeHint = \substr($typeHint, 1)])) { + $arguments[$key] = $this->getBindingValue($bindings[$typeHint]); + continue; + } + if (isset($bindingNames[$name]) || isset($bindingNames[$parameter->name])) { + $bindingKey = \array_search($binding, $bindings, \true); + $argumentType = \substr($bindingKey, 0, \strpos($bindingKey, ' ')); + $this->errorMessages[] = \sprintf('Did you forget to add the type "%s" to argument "$%s" of method "%s::%s()"?', $argumentType, $parameter->name, $reflectionMethod->class, $reflectionMethod->name); + } + } + foreach ($names as $key => $name) { + if (\array_key_exists($name, $arguments) && (0 === $key || \array_key_exists($key - 1, $arguments))) { + $arguments[$key] = $arguments[$name]; + unset($arguments[$name]); + } + } + if ($arguments !== $call[1]) { + \ksort($arguments, \SORT_NATURAL); + $calls[$i][1] = $arguments; + } + } + if ($constructor) { + [, $arguments] = \array_pop($calls); + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + } + if ($calls !== $value->getMethodCalls()) { + $value->setMethodCalls($calls); + } + return parent::processValue($value, $isRoot); + } + /** + * @return mixed + */ + private function getBindingValue(BoundArgument $binding) + { + [$bindingValue, $bindingId] = $binding->getValues(); + $this->usedBindings[$bindingId] = \true; + unset($this->unusedBindings[$bindingId]); + return $bindingValue; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php new file mode 100644 index 0000000000..375a4e9250 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php @@ -0,0 +1,185 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +/** + * This replaces all ChildDefinition instances with their equivalent fully + * merged Definition instance. + * + * @author Johannes M. Schmitt + * @author Nicolas Grekas + */ +class ResolveChildDefinitionsPass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $currentPath; + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + if ($isRoot) { + // yes, we are specifically fetching the definition from the + // container to ensure we are not operating on stale data + $value = $this->container->getDefinition($this->currentId); + } + if ($value instanceof ChildDefinition) { + $this->currentPath = []; + $value = $this->resolveDefinition($value); + if ($isRoot) { + $this->container->setDefinition($this->currentId, $value); + } + } + return parent::processValue($value, $isRoot); + } + /** + * Resolves the definition. + * + * @throws RuntimeException When the definition is invalid + */ + private function resolveDefinition(ChildDefinition $definition) : Definition + { + try { + return $this->doResolveDefinition($definition); + } catch (ServiceCircularReferenceException $e) { + throw $e; + } catch (ExceptionInterface $e) { + $r = new \ReflectionProperty($e, 'message'); + $r->setAccessible(\true); + $r->setValue($e, \sprintf('Service "%s": %s', $this->currentId, $e->getMessage())); + throw $e; + } + } + private function doResolveDefinition(ChildDefinition $definition) : Definition + { + if (!$this->container->has($parent = $definition->getParent())) { + throw new RuntimeException(\sprintf('Parent definition "%s" does not exist.', $parent)); + } + $searchKey = \array_search($parent, $this->currentPath); + $this->currentPath[] = $parent; + if (\false !== $searchKey) { + throw new ServiceCircularReferenceException($parent, \array_slice($this->currentPath, $searchKey)); + } + $parentDef = $this->container->findDefinition($parent); + if ($parentDef instanceof ChildDefinition) { + $id = $this->currentId; + $this->currentId = $parent; + $parentDef = $this->resolveDefinition($parentDef); + $this->container->setDefinition($parent, $parentDef); + $this->currentId = $id; + } + $this->container->log($this, \sprintf('Resolving inheritance for "%s" (parent: %s).', $this->currentId, $parent)); + $def = new Definition(); + // merge in parent definition + // purposely ignored attributes: abstract, shared, tags, autoconfigured + $def->setClass($parentDef->getClass()); + $def->setArguments($parentDef->getArguments()); + $def->setMethodCalls($parentDef->getMethodCalls()); + $def->setProperties($parentDef->getProperties()); + if ($parentDef->isDeprecated()) { + $deprecation = $parentDef->getDeprecation('%service_id%'); + $def->setDeprecated($deprecation['package'], $deprecation['version'], $deprecation['message']); + } + $def->setFactory($parentDef->getFactory()); + $def->setConfigurator($parentDef->getConfigurator()); + $def->setFile($parentDef->getFile()); + $def->setPublic($parentDef->isPublic()); + $def->setLazy($parentDef->isLazy()); + $def->setAutowired($parentDef->isAutowired()); + $def->setChanges($parentDef->getChanges()); + $def->setBindings($definition->getBindings() + $parentDef->getBindings()); + $def->setSynthetic($definition->isSynthetic()); + // overwrite with values specified in the decorator + $changes = $definition->getChanges(); + if (isset($changes['class'])) { + $def->setClass($definition->getClass()); + } + if (isset($changes['factory'])) { + $def->setFactory($definition->getFactory()); + } + if (isset($changes['configurator'])) { + $def->setConfigurator($definition->getConfigurator()); + } + if (isset($changes['file'])) { + $def->setFile($definition->getFile()); + } + if (isset($changes['public'])) { + $def->setPublic($definition->isPublic()); + } else { + $def->setPublic($parentDef->isPublic()); + } + if (isset($changes['lazy'])) { + $def->setLazy($definition->isLazy()); + } + if (isset($changes['deprecated']) && $definition->isDeprecated()) { + $deprecation = $definition->getDeprecation('%service_id%'); + $def->setDeprecated($deprecation['package'], $deprecation['version'], $deprecation['message']); + } + if (isset($changes['autowired'])) { + $def->setAutowired($definition->isAutowired()); + } + if (isset($changes['shared'])) { + $def->setShared($definition->isShared()); + } + if (isset($changes['decorated_service'])) { + $decoratedService = $definition->getDecoratedService(); + if (null === $decoratedService) { + $def->setDecoratedService($decoratedService); + } else { + $def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2], $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } + } + // merge arguments + foreach ($definition->getArguments() as $k => $v) { + if (\is_numeric($k)) { + $def->addArgument($v); + } elseif (\strncmp($k, 'index_', \strlen('index_')) === 0) { + $def->replaceArgument((int) \substr($k, \strlen('index_')), $v); + } else { + $def->setArgument($k, $v); + } + } + // merge properties + foreach ($definition->getProperties() as $k => $v) { + $def->setProperty($k, $v); + } + // append method calls + if ($calls = $definition->getMethodCalls()) { + $def->setMethodCalls(\array_merge($def->getMethodCalls(), $calls)); + } + $def->addError($parentDef); + $def->addError($definition); + // these attributes are always taken from the child + $def->setAbstract($definition->isAbstract()); + $def->setTags($definition->getTags()); + // autoconfigure is never taken from parent (on purpose) + // and it's not legal on an instanceof + $def->setAutoconfigured($definition->isAutoconfigured()); + if (!$def->hasTag('proxy')) { + foreach ($parentDef->getTag('proxy') as $v) { + $def->addTag('proxy', $v); + } + } + return $def; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php new file mode 100644 index 0000000000..ae796184a7 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * @author Nicolas Grekas + */ +class ResolveClassPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isSynthetic() || null !== $definition->getClass()) { + continue; + } + if (\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:\\\\[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)++$/', $id)) { + if ($definition instanceof ChildDefinition && !\class_exists($id)) { + throw new InvalidArgumentException(\sprintf('Service definition "%s" has a parent but no class, and its name looks like an FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.', $id)); + } + $definition->setClass($id); + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveDecoratorStackPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveDecoratorStackPass.php new file mode 100644 index 0000000000..13ced40fde --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveDecoratorStackPass.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * @author Nicolas Grekas + */ +class ResolveDecoratorStackPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $stacks = []; + foreach ($container->findTaggedServiceIds('container.stack') as $id => $tags) { + $definition = $container->getDefinition($id); + if (!$definition instanceof ChildDefinition) { + throw new InvalidArgumentException(\sprintf('Invalid service "%s": only definitions with a "parent" can have the "container.stack" tag.', $id)); + } + if (!($stack = $definition->getArguments())) { + throw new InvalidArgumentException(\sprintf('Invalid service "%s": the stack of decorators is empty.', $id)); + } + $stacks[$id] = $stack; + } + if (!$stacks) { + return; + } + $resolvedDefinitions = []; + foreach ($container->getDefinitions() as $id => $definition) { + if (!isset($stacks[$id])) { + $resolvedDefinitions[$id] = $definition; + continue; + } + foreach (\array_reverse($this->resolveStack($stacks, [$id]), \true) as $k => $v) { + $resolvedDefinitions[$k] = $v; + } + $alias = $container->setAlias($id, $k); + if ($definition->getChanges()['public'] ?? \false) { + $alias->setPublic($definition->isPublic()); + } + if ($definition->isDeprecated()) { + $alias->setDeprecated(...\array_values($definition->getDeprecation('%alias_id%'))); + } + } + $container->setDefinitions($resolvedDefinitions); + } + private function resolveStack(array $stacks, array $path) : array + { + $definitions = []; + $id = \end($path); + $prefix = '.' . $id . '.'; + if (!isset($stacks[$id])) { + return [$id => new ChildDefinition($id)]; + } + if (\key($path) !== ($searchKey = \array_search($id, $path))) { + throw new ServiceCircularReferenceException($id, \array_slice($path, $searchKey)); + } + foreach ($stacks[$id] as $k => $definition) { + if ($definition instanceof ChildDefinition && isset($stacks[$definition->getParent()])) { + $path[] = $definition->getParent(); + $definition = \unserialize(\serialize($definition)); + // deep clone + } elseif ($definition instanceof Definition) { + $definitions[$decoratedId = $prefix . $k] = $definition; + continue; + } elseif ($definition instanceof Reference || $definition instanceof Alias) { + $path[] = (string) $definition; + } else { + throw new InvalidArgumentException(\sprintf('Invalid service "%s": unexpected value of type "%s" found in the stack of decorators.', $id, \get_debug_type($definition))); + } + $p = $prefix . $k; + foreach ($this->resolveStack($stacks, $path) as $k => $v) { + $definitions[$decoratedId = $p . $k] = $definition instanceof ChildDefinition ? $definition->setParent($k) : new ChildDefinition($k); + $definition = null; + } + \array_pop($path); + } + if (1 === \count($path)) { + foreach ($definitions as $k => $definition) { + $definition->setPublic(\false)->setTags([])->setDecoratedService($decoratedId); + } + $definition->setDecoratedService(null); + } + return $definitions; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php new file mode 100644 index 0000000000..fb9f2cc007 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * Replaces env var placeholders by their current values. + */ +class ResolveEnvPlaceholdersPass extends AbstractRecursivePass +{ + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (\is_string($value)) { + return $this->container->resolveEnvPlaceholders($value, \true); + } + if ($value instanceof Definition) { + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->container->resolveEnvPlaceholders($value->getClass(), \true)); + } + if (isset($changes['file'])) { + $value->setFile($this->container->resolveEnvPlaceholders($value->getFile(), \true)); + } + } + $value = parent::processValue($value, $isRoot); + if ($value && \is_array($value) && !$isRoot) { + $value = \array_combine($this->container->resolveEnvPlaceholders(\array_keys($value), \true), $value); + } + return $value; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php new file mode 100644 index 0000000000..9bd30af320 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * @author Maxime Steinhausser + */ +class ResolveFactoryClassPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof Definition && \is_array($factory = $value->getFactory()) && null === $factory[0]) { + if (null === ($class = $value->getClass())) { + throw new RuntimeException(\sprintf('The "%s" service is defined to be created by a factory, but is missing the factory class. Did you forget to define the factory or service class?', $this->currentId)); + } + $factory[0] = $class; + $value->setFactory($factory); + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php new file mode 100644 index 0000000000..d1955d6dfa --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Propagate "container.hot_path" tags to referenced services. + * + * @author Nicolas Grekas + */ +class ResolveHotPathPass extends AbstractRecursivePass +{ + /** + * @var mixed[] + */ + private $resolvedIds = []; + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + try { + parent::process($container); + $container->getDefinition('service_container')->clearTag('container.hot_path'); + } finally { + $this->resolvedIds = []; + } + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof ArgumentInterface) { + return $value; + } + if ($value instanceof Definition && $isRoot) { + if ($value->isDeprecated()) { + return $value->clearTag('container.hot_path'); + } + $this->resolvedIds[$this->currentId] = \true; + if (!$value->hasTag('container.hot_path')) { + return $value; + } + } + if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->hasDefinition($id = (string) $value)) { + $definition = $this->container->getDefinition($id); + if ($definition->isDeprecated() || $definition->hasTag('container.hot_path')) { + return $value; + } + $definition->addTag('container.hot_path'); + if (isset($this->resolvedIds[$id])) { + parent::processValue($definition, \false); + } + return $value; + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php new file mode 100644 index 0000000000..282f1ce455 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * Applies instanceof conditionals to definitions. + * + * @author Nicolas Grekas + */ +class ResolveInstanceofConditionalsPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) { + if ($definition->getArguments()) { + throw new InvalidArgumentException(\sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface)); + } + } + $tagsToKeep = []; + if ($container->hasParameter('container.behavior_describing_tags')) { + $tagsToKeep = $container->getParameter('container.behavior_describing_tags'); + } + foreach ($container->getDefinitions() as $id => $definition) { + $container->setDefinition($id, $this->processDefinition($container, $id, $definition, $tagsToKeep)); + } + if ($container->hasParameter('container.behavior_describing_tags')) { + $container->getParameterBag()->remove('container.behavior_describing_tags'); + } + } + private function processDefinition(ContainerBuilder $container, string $id, Definition $definition, array $tagsToKeep) : Definition + { + $instanceofConditionals = $definition->getInstanceofConditionals(); + $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : []; + if (!$instanceofConditionals && !$autoconfiguredInstanceof) { + return $definition; + } + if (!($class = $container->getParameterBag()->resolveValue($definition->getClass()))) { + return $definition; + } + $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container); + $definition->setInstanceofConditionals([]); + $shared = null; + $instanceofTags = []; + $instanceofCalls = []; + $instanceofBindings = []; + $reflectionClass = null; + $parent = $definition instanceof ChildDefinition ? $definition->getParent() : null; + foreach ($conditionals as $interface => $instanceofDefs) { + if ($interface !== $class && !($reflectionClass = $reflectionClass ?? ($container->getReflectionClass($class, \false) ?: \false))) { + continue; + } + if ($interface !== $class && !\is_subclass_of($class, $interface)) { + continue; + } + foreach ($instanceofDefs as $key => $instanceofDef) { + /** @var ChildDefinition $instanceofDef */ + $instanceofDef = clone $instanceofDef; + $instanceofDef->setAbstract(\true)->setParent($parent ?: '.abstract.instanceof.' . $id); + $parent = '.instanceof.' . $interface . '.' . $key . '.' . $id; + $container->setDefinition($parent, $instanceofDef); + $instanceofTags[] = $instanceofDef->getTags(); + $instanceofBindings = $instanceofDef->getBindings() + $instanceofBindings; + foreach ($instanceofDef->getMethodCalls() as $methodCall) { + $instanceofCalls[] = $methodCall; + } + $instanceofDef->setTags([]); + $instanceofDef->setMethodCalls([]); + $instanceofDef->setBindings([]); + if (isset($instanceofDef->getChanges()['shared'])) { + $shared = $instanceofDef->isShared(); + } + } + } + if ($parent) { + $bindings = $definition->getBindings(); + $abstract = $container->setDefinition('.abstract.instanceof.' . $id, $definition); + $definition->setBindings([]); + $definition = \serialize($definition); + if (Definition::class === \get_class($abstract)) { + // cast Definition to ChildDefinition + $definition = \substr_replace($definition, '53', 2, 2); + $definition = \substr_replace($definition, 'Child', 44, 0); + } + /** @var ChildDefinition $definition */ + $definition = \unserialize($definition); + $definition->setParent($parent); + if (null !== $shared && !isset($definition->getChanges()['shared'])) { + $definition->setShared($shared); + } + // Don't add tags to service decorators + $i = \count($instanceofTags); + while (0 <= --$i) { + foreach ($instanceofTags[$i] as $k => $v) { + if (null === $definition->getDecoratedService() || \in_array($k, $tagsToKeep, \true)) { + foreach ($v as $v) { + if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) { + continue; + } + $definition->addTag($k, $v); + } + } + } + } + $definition->setMethodCalls(\array_merge($instanceofCalls, $definition->getMethodCalls())); + $definition->setBindings($bindings + $instanceofBindings); + // reset fields with "merge" behavior + $abstract->setBindings([])->setArguments([])->setMethodCalls([])->setDecoratedService(null)->setTags([])->setAbstract(\true); + } + return $definition; + } + private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container) : array + { + // make each value an array of ChildDefinition + $conditionals = \array_map(function ($childDef) { + return [$childDef]; + }, $autoconfiguredInstanceof); + foreach ($instanceofConditionals as $interface => $instanceofDef) { + // make sure the interface/class exists (but don't validate automaticInstanceofConditionals) + if (!$container->getReflectionClass($interface)) { + throw new RuntimeException(\sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface)); + } + if (!isset($autoconfiguredInstanceof[$interface])) { + $conditionals[$interface] = []; + } + $conditionals[$interface][] = $instanceofDef; + } + return $conditionals; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php new file mode 100644 index 0000000000..e71d522763 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +/** + * Emulates the invalid behavior if the reference is not found within the + * container. + * + * @author Johannes M. Schmitt + */ +class ResolveInvalidReferencesPass implements CompilerPassInterface +{ + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder + */ + private $container; + /** + * @var \Symfony\Component\DependencyInjection\Exception\RuntimeException + */ + private $signalingException; + /** + * @var string + */ + private $currentId; + /** + * Process the ContainerBuilder to resolve invalid references. + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->signalingException = new RuntimeException('Invalid reference.'); + try { + foreach ($container->getDefinitions() as $this->currentId => $definition) { + $this->processValue($definition); + } + } finally { + unset($this->container, $this->signalingException); + } + } + /** + * Processes arguments to determine invalid references. + * + * @throws RuntimeException When an invalid reference is found + * @param mixed $value + * @return mixed + */ + private function processValue($value, int $rootLevel = 0, int $level = 0) + { + if ($value instanceof ServiceClosureArgument) { + $value->setValues($this->processValue($value->getValues(), 1, 1)); + } elseif ($value instanceof ArgumentInterface) { + $value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level)); + } elseif ($value instanceof Definition) { + if ($value->isSynthetic() || $value->isAbstract()) { + return $value; + } + $value->setArguments($this->processValue($value->getArguments(), 0)); + $value->setProperties($this->processValue($value->getProperties(), 1)); + $value->setMethodCalls($this->processValue($value->getMethodCalls(), 2)); + } elseif (\is_array($value)) { + $i = 0; + foreach ($value as $k => $v) { + try { + if (\false !== $i && $k !== $i++) { + $i = \false; + } + if ($v !== ($processedValue = $this->processValue($v, $rootLevel, 1 + $level))) { + $value[$k] = $processedValue; + } + } catch (RuntimeException $e) { + if ($rootLevel < $level || $rootLevel && !$level) { + unset($value[$k]); + } elseif ($rootLevel) { + throw $e; + } else { + $value[$k] = null; + } + } + } + // Ensure numerically indexed arguments have sequential numeric keys. + if (\false !== $i) { + $value = \array_values($value); + } + } elseif ($value instanceof Reference) { + if ($this->container->has($id = (string) $value)) { + return $value; + } + $currentDefinition = $this->container->getDefinition($this->currentId); + // resolve decorated service behavior depending on decorator service + if ($currentDefinition->innerServiceId === $id && ContainerInterface::NULL_ON_INVALID_REFERENCE === $currentDefinition->decorationOnInvalid) { + return null; + } + $invalidBehavior = $value->getInvalidBehavior(); + if (ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior && $value instanceof TypedReference && !$this->container->has($id)) { + $e = new ServiceNotFoundException($id, $this->currentId); + // since the error message varies by $id and $this->currentId, so should the id of the dummy errored definition + $this->container->register($id = \sprintf('.errored.%s.%s', $this->currentId, $id), $value->getType())->addError($e->getMessage()); + return new TypedReference($id, $value->getType(), $value->getInvalidBehavior()); + } + // resolve invalid behavior + if (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { + $value = null; + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { + if (0 < $level || $rootLevel) { + throw $this->signalingException; + } + $value = null; + } + } + return $value; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php new file mode 100644 index 0000000000..7f7e7b1f6f --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Resolves named arguments to their corresponding numeric index. + * + * @author Kévin Dunglas + */ +class ResolveNamedArgumentsPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof AbstractArgument && $value->getText() . '.' === $value->getTextWithContext()) { + $value->setContext(\sprintf('A value found in service "%s"', $this->currentId)); + } + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + $calls = $value->getMethodCalls(); + $calls[] = ['__construct', $value->getArguments()]; + foreach ($calls as $i => $call) { + [$method, $arguments] = $call; + $parameters = null; + $resolvedKeys = []; + $resolvedArguments = []; + foreach ($arguments as $key => $argument) { + if ($argument instanceof AbstractArgument && $argument->getText() . '.' === $argument->getTextWithContext()) { + $argument->setContext(\sprintf('Argument ' . (\is_int($key) ? 1 + $key : '"%3$s"') . ' of ' . ('__construct' === $method ? 'service "%s"' : 'method call "%s::%s()"'), $this->currentId, $method, $key)); + } + if (\is_int($key)) { + $resolvedKeys[$key] = $key; + $resolvedArguments[$key] = $argument; + continue; + } + if (null === $parameters) { + $r = $this->getReflectionMethod($value, $method); + $class = $r instanceof \ReflectionMethod ? $r->class : $this->currentId; + $method = $r->getName(); + $parameters = $r->getParameters(); + } + if (isset($key[0]) && '$' !== $key[0] && !\class_exists($key) && !\interface_exists($key, \false)) { + throw new InvalidArgumentException(\sprintf('Invalid service "%s": did you forget to add the "$" prefix to argument "%s"?', $this->currentId, $key)); + } + if (isset($key[0]) && '$' === $key[0]) { + foreach ($parameters as $j => $p) { + if ($key === '$' . $p->name) { + if ($p->isVariadic() && \is_array($argument)) { + foreach ($argument as $variadicArgument) { + $resolvedKeys[$j] = $j; + $resolvedArguments[$j++] = $variadicArgument; + } + } else { + $resolvedKeys[$j] = $p->name; + $resolvedArguments[$j] = $argument; + } + continue 2; + } + } + throw new InvalidArgumentException(\sprintf('Invalid service "%s": method "%s()" has no argument named "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class . '::' . $method : $method, $key)); + } + if (null !== $argument && !$argument instanceof Reference && !$argument instanceof Definition) { + throw new InvalidArgumentException(\sprintf('Invalid service "%s": the value of argument "%s" of method "%s()" must be null, an instance of "%s" or an instance of "%s", "%s" given.', $this->currentId, $key, $class !== $this->currentId ? $class . '::' . $method : $method, Reference::class, Definition::class, \get_debug_type($argument))); + } + $typeFound = \false; + foreach ($parameters as $j => $p) { + if (!\array_key_exists($j, $resolvedArguments) && ProxyHelper::getTypeHint($r, $p, \true) === $key) { + $resolvedKeys[$j] = $p->name; + $resolvedArguments[$j] = $argument; + $typeFound = \true; + } + } + if (!$typeFound) { + throw new InvalidArgumentException(\sprintf('Invalid service "%s": method "%s()" has no argument type-hinted as "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class . '::' . $method : $method, $key)); + } + } + if ($resolvedArguments !== $call[1]) { + \ksort($resolvedArguments); + $arrayIsListFunction = function (array $array) : bool { + if (\function_exists('array_is_list')) { + return \array_is_list($array); + } + if ($array === []) { + return \true; + } + $current_key = 0; + foreach ($array as $key => $noop) { + if ($key !== $current_key) { + return \false; + } + ++$current_key; + } + return \true; + }; + if (!$value->isAutowired() && !$arrayIsListFunction($resolvedArguments)) { + \ksort($resolvedKeys); + $resolvedArguments = \array_combine($resolvedKeys, $resolvedArguments); + } + $calls[$i][1] = $resolvedArguments; + } + } + [, $arguments] = \array_pop($calls); + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + if ($calls !== $value->getMethodCalls()) { + $value->setMethodCalls($calls); + } + foreach ($value->getProperties() as $key => $argument) { + if ($argument instanceof AbstractArgument && $argument->getText() . '.' === $argument->getTextWithContext()) { + $argument->setContext(\sprintf('Property "%s" of service "%s"', $key, $this->currentId)); + } + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveNoPreloadPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveNoPreloadPass.php new file mode 100644 index 0000000000..25241c22b3 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveNoPreloadPass.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Propagate the "container.no_preload" tag. + * + * @author Nicolas Grekas + */ +class ResolveNoPreloadPass extends AbstractRecursivePass +{ + private const DO_PRELOAD_TAG = '.container.do_preload'; + /** + * @var mixed[] + */ + private $resolvedIds = []; + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + try { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isPublic() && !$definition->isPrivate() && !isset($this->resolvedIds[$id])) { + $this->resolvedIds[$id] = \true; + $this->processValue($definition, \true); + } + } + foreach ($container->getAliases() as $alias) { + if ($alias->isPublic() && !$alias->isPrivate() && !isset($this->resolvedIds[$id = (string) $alias]) && $container->hasDefinition($id)) { + $this->resolvedIds[$id] = \true; + $this->processValue($container->getDefinition($id), \true); + } + } + } finally { + $this->resolvedIds = []; + $this->container = null; + } + foreach ($container->getDefinitions() as $definition) { + if ($definition->hasTag(self::DO_PRELOAD_TAG)) { + $definition->clearTag(self::DO_PRELOAD_TAG); + } elseif (!$definition->isDeprecated() && !$definition->hasErrors()) { + $definition->addTag('container.no_preload'); + } + } + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->hasDefinition($id = (string) $value)) { + $definition = $this->container->getDefinition($id); + if (!isset($this->resolvedIds[$id]) && (!$definition->isPublic() || $definition->isPrivate())) { + $this->resolvedIds[$id] = \true; + $this->processValue($definition, \true); + } + return $value; + } + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + if ($value->hasTag('container.no_preload') || $value->isDeprecated() || $value->hasErrors()) { + return $value; + } + if ($isRoot) { + $value->addTag(self::DO_PRELOAD_TAG); + } + return parent::processValue($value, $isRoot); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php new file mode 100644 index 0000000000..0f4c6dc683 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +/** + * Resolves all parameter placeholders "%somevalue%" to their real values. + * + * @author Johannes M. Schmitt + */ +class ResolveParameterPlaceHoldersPass extends AbstractRecursivePass +{ + /** + * @var bool + */ + private $resolveArrays = \true; + /** + * @var bool + */ + private $throwOnResolveException = \true; + /** + * @var \Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface + */ + private $bag; + public function __construct(bool $resolveArrays = \true, bool $throwOnResolveException = \true) + { + $this->resolveArrays = $resolveArrays; + $this->throwOnResolveException = $throwOnResolveException; + } + /** + * {@inheritdoc} + * + * @throws ParameterNotFoundException + */ + public function process(ContainerBuilder $container) + { + $this->bag = $container->getParameterBag(); + try { + parent::process($container); + $aliases = []; + foreach ($container->getAliases() as $name => $target) { + $this->currentId = $name; + $aliases[$this->bag->resolveValue($name)] = $target; + } + $container->setAliases($aliases); + } catch (ParameterNotFoundException $e) { + $e->setSourceId($this->currentId); + throw $e; + } + $this->bag->resolve(); + unset($this->bag); + } + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (\is_string($value)) { + try { + $v = $this->bag->resolveValue($value); + } catch (ParameterNotFoundException $e) { + if ($this->throwOnResolveException) { + throw $e; + } + $v = null; + $this->container->getDefinition($this->currentId)->addError($e->getMessage()); + } + return $this->resolveArrays || !$v || !\is_array($v) ? $v : $value; + } + if ($value instanceof Definition) { + $value->setBindings($this->processValue($value->getBindings())); + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->bag->resolveValue($value->getClass())); + } + if (isset($changes['file'])) { + $value->setFile($this->bag->resolveValue($value->getFile())); + } + $tags = $value->getTags(); + if (isset($tags['proxy'])) { + $tags['proxy'] = $this->bag->resolveValue($tags['proxy']); + $value->setTags($tags); + } + } + $value = parent::processValue($value, $isRoot); + if ($value && \is_array($value)) { + $value = \array_combine($this->bag->resolveValue(\array_keys($value)), $value); + } + return $value; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php new file mode 100644 index 0000000000..a6d5fc0483 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * Replaces all references to aliases with references to the actual service. + * + * @author Johannes M. Schmitt + */ +class ResolveReferencesToAliasesPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + parent::process($container); + foreach ($container->getAliases() as $id => $alias) { + $aliasId = (string) $alias; + $this->currentId = $id; + if ($aliasId !== ($defId = $this->getDefinitionId($aliasId, $container))) { + $container->setAlias($id, $defId)->setPublic($alias->isPublic()); + } + } + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } + $defId = $this->getDefinitionId($id = (string) $value, $this->container); + return $defId !== $id ? new Reference($defId, $value->getInvalidBehavior()) : $value; + } + private function getDefinitionId(string $id, ContainerBuilder $container) : string + { + if (!$container->hasAlias($id)) { + return $id; + } + $alias = $container->getAlias($id); + if ($alias->isDeprecated()) { + $referencingDefinition = $container->hasDefinition($this->currentId) ? $container->getDefinition($this->currentId) : $container->getAlias($this->currentId); + if (!$referencingDefinition->isDeprecated()) { + $deprecation = $alias->getDeprecation($id); + trigger_deprecation($deprecation['package'], $deprecation['version'], \rtrim($deprecation['message'], '. ') . '. It is being referenced by the "%s" ' . ($container->hasDefinition($this->currentId) ? 'service.' : 'alias.'), $this->currentId); + } + } + $seen = []; + do { + if (isset($seen[$id])) { + throw new ServiceCircularReferenceException($id, \array_merge(\array_keys($seen), [$id])); + } + $seen[$id] = \true; + $id = (string) $container->getAlias($id); + } while ($container->hasAlias($id)); + return $id; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php new file mode 100644 index 0000000000..b7d7ec10bc --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceProviderInterface; +/** + * Compiler pass to inject their service locator to service subscribers. + * + * @author Nicolas Grekas + */ +class ResolveServiceSubscribersPass extends AbstractRecursivePass +{ + /** + * @var string|null + */ + private $serviceLocator; + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof Reference && $this->serviceLocator && \in_array((string) $value, [ContainerInterface::class, ServiceProviderInterface::class], \true)) { + return new Reference($this->serviceLocator); + } + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + $serviceLocator = $this->serviceLocator; + $this->serviceLocator = null; + if ($value->hasTag('container.service_subscriber.locator')) { + $this->serviceLocator = $value->getTag('container.service_subscriber.locator')[0]['id']; + $value->clearTag('container.service_subscriber.locator'); + } + try { + return parent::processValue($value); + } finally { + $this->serviceLocator = $serviceLocator; + } + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php new file mode 100644 index 0000000000..a3d97e1747 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +/** + * Resolves all TaggedIteratorArgument arguments. + * + * @author Roland Franssen + */ +class ResolveTaggedIteratorArgumentPass extends AbstractRecursivePass +{ + use PriorityTaggedServiceTrait; + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if (!$value instanceof TaggedIteratorArgument) { + return parent::processValue($value, $isRoot); + } + $value->setValues($this->findAndSortTaggedServices($value, $this->container)); + return $value; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php b/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php new file mode 100644 index 0000000000..70b1d90ccb --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ServiceLocator; +/** + * Applies the "container.service_locator" tag by wrapping references into ServiceClosureArgument instances. + * + * @author Nicolas Grekas + */ +final class ServiceLocatorTagPass extends AbstractRecursivePass +{ + use PriorityTaggedServiceTrait; + /** + * @param mixed $value + * @return mixed + */ + protected function processValue($value, bool $isRoot = \false) + { + if ($value instanceof ServiceLocatorArgument) { + if ($value->getTaggedIteratorArgument()) { + $value->setValues($this->findAndSortTaggedServices($value->getTaggedIteratorArgument(), $this->container)); + } + return self::register($this->container, $value->getValues()); + } + if ($value instanceof Definition) { + $value->setBindings(parent::processValue($value->getBindings())); + } + if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) { + return parent::processValue($value, $isRoot); + } + if (!$value->getClass()) { + $value->setClass(ServiceLocator::class); + } + $services = $value->getArguments()[0] ?? null; + if ($services instanceof TaggedIteratorArgument) { + $services = $this->findAndSortTaggedServices($services, $this->container); + } + if (!\is_array($services)) { + throw new InvalidArgumentException(\sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId)); + } + $i = 0; + foreach ($services as $k => $v) { + if ($v instanceof ServiceClosureArgument) { + continue; + } + if ($i === $k) { + if ($v instanceof Reference) { + unset($services[$k]); + $k = (string) $v; + } + ++$i; + } elseif (\is_int($k)) { + $i = null; + } + $services[$k] = new ServiceClosureArgument($v); + } + \ksort($services); + $value->setArgument(0, $services); + $id = '.service_locator.' . ContainerBuilder::hash($value); + if ($isRoot) { + if ($id !== $this->currentId) { + $this->container->setAlias($id, new Alias($this->currentId, \false)); + } + return $value; + } + $this->container->setDefinition($id, $value->setPublic(\false)); + return new Reference($id); + } + public static function register(ContainerBuilder $container, array $map, string $callerId = null) : Reference + { + foreach ($map as $k => $v) { + $map[$k] = new ServiceClosureArgument($v); + } + $locator = (new Definition(ServiceLocator::class))->addArgument($map)->addTag('container.service_locator'); + if (null !== $callerId && $container->hasDefinition($callerId)) { + $locator->setBindings($container->getDefinition($callerId)->getBindings()); + } + if (!$container->hasDefinition($id = '.service_locator.' . ContainerBuilder::hash($locator))) { + $container->setDefinition($id, $locator); + } + if (null !== $callerId) { + $locatorId = $id; + // Locators are shared when they hold the exact same list of factories; + // to have them specialized per consumer service, we use a cloning factory + // to derivate customized instances from the prototype one. + $container->register($id .= '.' . $callerId, ServiceLocator::class)->setFactory([new Reference($locatorId), 'withContext'])->addTag('container.service_locator_context', ['id' => $callerId])->addArgument($callerId)->addArgument(new Reference('service_container')); + } + return new Reference($id); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php b/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php new file mode 100644 index 0000000000..43d1938837 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * This is a directed graph of your services. + * + * This information can be used by your compiler passes instead of collecting + * it themselves which improves performance quite a lot. + * + * @author Johannes M. Schmitt + * + * @final + */ +class ServiceReferenceGraph +{ + /** + * @var ServiceReferenceGraphNode[] + */ + private $nodes = []; + public function hasNode(string $id) : bool + { + return isset($this->nodes[$id]); + } + /** + * Gets a node by identifier. + * + * @throws InvalidArgumentException if no node matches the supplied identifier + */ + public function getNode(string $id) : ServiceReferenceGraphNode + { + if (!isset($this->nodes[$id])) { + throw new InvalidArgumentException(\sprintf('There is no node with id "%s".', $id)); + } + return $this->nodes[$id]; + } + /** + * Returns all nodes. + * + * @return ServiceReferenceGraphNode[] + */ + public function getNodes() : array + { + return $this->nodes; + } + /** + * Clears all nodes. + */ + public function clear() + { + foreach ($this->nodes as $node) { + $node->clear(); + } + $this->nodes = []; + } + /** + * Connects 2 nodes together in the Graph. + * @param mixed $sourceValue + * @param mixed $destValue + */ + public function connect(?string $sourceId, $sourceValue, ?string $destId, $destValue = null, Reference $reference = null, bool $lazy = \false, bool $weak = \false, bool $byConstructor = \false) + { + if (null === $sourceId || null === $destId) { + return; + } + $sourceNode = $this->createNode($sourceId, $sourceValue); + $destNode = $this->createNode($destId, $destValue); + $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor); + $sourceNode->addOutEdge($edge); + $destNode->addInEdge($edge); + } + /** + * @param mixed $value + */ + private function createNode(string $id, $value) : ServiceReferenceGraphNode + { + if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) { + return $this->nodes[$id]; + } + return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value); + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php b/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php new file mode 100644 index 0000000000..a64efc1147 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +/** + * Represents an edge in your service graph. + * + * Value is typically a reference. + * + * @author Johannes M. Schmitt + */ +class ServiceReferenceGraphEdge +{ + /** + * @var \Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphNode + */ + private $sourceNode; + /** + * @var \Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphNode + */ + private $destNode; + /** + * @var mixed + */ + private $value; + /** + * @var bool + */ + private $lazy; + /** + * @var bool + */ + private $weak; + /** + * @var bool + */ + private $byConstructor; + /** + * @param mixed $value + */ + public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, bool $lazy = \false, bool $weak = \false, bool $byConstructor = \false) + { + $this->sourceNode = $sourceNode; + $this->destNode = $destNode; + $this->value = $value; + $this->lazy = $lazy; + $this->weak = $weak; + $this->byConstructor = $byConstructor; + } + /** + * Returns the value of the edge. + * @return mixed + */ + public function getValue() + { + return $this->value; + } + /** + * Returns the source node. + */ + public function getSourceNode() : ServiceReferenceGraphNode + { + return $this->sourceNode; + } + /** + * Returns the destination node. + */ + public function getDestNode() : ServiceReferenceGraphNode + { + return $this->destNode; + } + /** + * Returns true if the edge is lazy, meaning it's a dependency not requiring direct instantiation. + */ + public function isLazy() : bool + { + return $this->lazy; + } + /** + * Returns true if the edge is weak, meaning it shouldn't prevent removing the target service. + */ + public function isWeak() : bool + { + return $this->weak; + } + /** + * Returns true if the edge links with a constructor argument. + */ + public function isReferencedByConstructor() : bool + { + return $this->byConstructor; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php b/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php new file mode 100644 index 0000000000..53037ef7a3 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * Represents a node in your service graph. + * + * Value is typically a definition, or an alias. + * + * @author Johannes M. Schmitt + */ +class ServiceReferenceGraphNode +{ + /** + * @var string + */ + private $id; + /** + * @var mixed[] + */ + private $inEdges = []; + /** + * @var mixed[] + */ + private $outEdges = []; + /** + * @var mixed + */ + private $value; + /** + * @param mixed $value + */ + public function __construct(string $id, $value) + { + $this->id = $id; + $this->value = $value; + } + public function addInEdge(ServiceReferenceGraphEdge $edge) + { + $this->inEdges[] = $edge; + } + public function addOutEdge(ServiceReferenceGraphEdge $edge) + { + $this->outEdges[] = $edge; + } + /** + * Checks if the value of this node is an Alias. + */ + public function isAlias() : bool + { + return $this->value instanceof Alias; + } + /** + * Checks if the value of this node is a Definition. + */ + public function isDefinition() : bool + { + return $this->value instanceof Definition; + } + /** + * Returns the identifier. + */ + public function getId() : string + { + return $this->id; + } + /** + * Returns the in edges. + * + * @return ServiceReferenceGraphEdge[] + */ + public function getInEdges() : array + { + return $this->inEdges; + } + /** + * Returns the out edges. + * + * @return ServiceReferenceGraphEdge[] + */ + public function getOutEdges() : array + { + return $this->outEdges; + } + /** + * Returns the value of this Node. + * @return mixed + */ + public function getValue() + { + return $this->value; + } + /** + * Clears all edges. + */ + public function clear() + { + $this->inEdges = $this->outEdges = []; + } +} diff --git a/vendor/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php b/vendor/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php new file mode 100644 index 0000000000..d53ef275c8 --- /dev/null +++ b/vendor/symfony/dependency-injection/Compiler/ValidateEnvPlaceholdersPass.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\BaseNode; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Processor; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +/** + * Validates environment variable placeholders used in extension configuration with dummy values. + * + * @author Roland Franssen + */ +class ValidateEnvPlaceholdersPass implements CompilerPassInterface +{ + private const TYPE_FIXTURES = ['array' => [], 'bool' => \false, 'float' => 0.0, 'int' => 0, 'string' => '']; + /** + * @var mixed[] + */ + private $extensionConfig = []; + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->extensionConfig = []; + if (!\class_exists(BaseNode::class) || !($extensions = $container->getExtensions())) { + return; + } + $resolvingBag = $container->getParameterBag(); + if (!$resolvingBag instanceof EnvPlaceholderParameterBag) { + return; + } + $defaultBag = new ParameterBag($resolvingBag->all()); + $envTypes = $resolvingBag->getProvidedTypes(); + foreach ($resolvingBag->getEnvPlaceholders() + $resolvingBag->getUnusedEnvPlaceholders() as $env => $placeholders) { + $values = []; + if (\false === ($i = \strpos($env, ':'))) { + $default = $defaultBag->has("env({$env})") ? $defaultBag->get("env({$env})") : self::TYPE_FIXTURES['string']; + $defaultType = null !== $default ? \get_debug_type($default) : 'string'; + $values[$defaultType] = $default; + } else { + $prefix = \substr($env, 0, $i); + foreach ($envTypes[$prefix] ?? ['string'] as $type) { + $values[$type] = self::TYPE_FIXTURES[$type] ?? null; + } + } + foreach ($placeholders as $placeholder) { + BaseNode::setPlaceholder($placeholder, $values); + } + } + $processor = new Processor(); + foreach ($extensions as $name => $extension) { + if (!($extension instanceof ConfigurationExtensionInterface || $extension instanceof ConfigurationInterface) || !($config = \array_filter($container->getExtensionConfig($name)))) { + // this extension has no semantic configuration or was not called + continue; + } + $config = $resolvingBag->resolveValue($config); + if ($extension instanceof ConfigurationInterface) { + $configuration = $extension; + } elseif (null === ($configuration = $extension->getConfiguration($config, $container))) { + continue; + } + $this->extensionConfig[$name] = $processor->processConfiguration($configuration, $config); + } + $resolvingBag->clearUnusedEnvPlaceholders(); + } + /** + * @internal + */ + public function getExtensionConfig() : array + { + try { + return $this->extensionConfig; + } finally { + $this->extensionConfig = []; + } + } +} diff --git a/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php b/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php new file mode 100644 index 0000000000..bf62d33e41 --- /dev/null +++ b/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ResourceInterface; +/** + * Tracks container parameters. + * + * @author Maxime Steinhausser + * + * @final + */ +class ContainerParametersResource implements ResourceInterface +{ + /** + * @var mixed[] + */ + private $parameters; + /** + * @param array $parameters The container parameters to track + */ + public function __construct(array $parameters) + { + $this->parameters = $parameters; + } + public function __toString() : string + { + return 'container_parameters_' . \md5(\serialize($this->parameters)); + } + public function getParameters() : array + { + return $this->parameters; + } +} diff --git a/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php b/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php new file mode 100644 index 0000000000..e745829a5d --- /dev/null +++ b/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Config; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ResourceInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\ResourceCheckerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +/** + * @author Maxime Steinhausser + */ +class ContainerParametersResourceChecker implements ResourceCheckerInterface +{ + /** + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + private $container; + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + /** + * {@inheritdoc} + */ + public function supports(ResourceInterface $metadata) : bool + { + return $metadata instanceof ContainerParametersResource; + } + /** + * {@inheritdoc} + */ + public function isFresh(ResourceInterface $resource, int $timestamp) : bool + { + foreach ($resource->getParameters() as $key => $value) { + if (!$this->container->hasParameter($key) || $this->container->getParameter($key) !== $value) { + return \false; + } + } + return \true; + } +} diff --git a/vendor/symfony/dependency-injection/Container.php b/vendor/symfony/dependency-injection/Container.php new file mode 100644 index 0000000000..a2510fa8b1 --- /dev/null +++ b/vendor/symfony/dependency-injection/Container.php @@ -0,0 +1,362 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocator as ArgumentServiceLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ResetInterface; +// Help opcache.preload discover always-needed symbols +\class_exists(RewindableGenerator::class); +\class_exists(ArgumentServiceLocator::class); +/** + * Container is a dependency injection container. + * + * It gives access to object instances (services). + * Services and parameters are simple key/pair stores. + * The container can have four possible behaviors when a service + * does not exist (or is not initialized for the last case): + * + * * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default) + * * NULL_ON_INVALID_REFERENCE: Returns null + * * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference + * (for instance, ignore a setter if the service does not exist) + * * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class Container implements ContainerInterface, ResetInterface +{ + protected $parameterBag; + protected $services = []; + protected $privates = []; + protected $fileMap = []; + protected $methodMap = []; + protected $factories = []; + protected $aliases = []; + protected $loading = []; + protected $resolving = []; + protected $syntheticIds = []; + /** + * @var mixed[] + */ + private $envCache = []; + /** + * @var bool + */ + private $compiled = \false; + /** + * @var \Closure + */ + private $getEnv; + public function __construct(ParameterBagInterface $parameterBag = null) + { + $this->parameterBag = $parameterBag ?? new EnvPlaceholderParameterBag(); + } + /** + * Compiles the container. + * + * This method does two things: + * + * * Parameter values are resolved; + * * The parameter bag is frozen. + */ + public function compile() + { + $this->parameterBag->resolve(); + $this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); + $this->compiled = \true; + } + /** + * Returns true if the container is compiled. + */ + public function isCompiled() : bool + { + return $this->compiled; + } + /** + * Gets the service container parameter bag. + */ + public function getParameterBag() : ParameterBagInterface + { + return $this->parameterBag; + } + /** + * Gets a parameter. + * + * @return array|bool|string|int|float|\UnitEnum|null + * + * @throws InvalidArgumentException if the parameter is not defined + */ + public function getParameter(string $name) + { + return $this->parameterBag->get($name); + } + public function hasParameter(string $name) : bool + { + return $this->parameterBag->has($name); + } + /** + * @param mixed[]|bool|string|int|float|\UnitEnum|null $value + */ + public function setParameter(string $name, $value) + { + $this->parameterBag->set($name, $value); + } + /** + * Sets a service. + * + * Setting a synthetic service to null resets it: has() returns false and get() + * behaves in the same way as if the service was never created. + */ + public function set(string $id, ?object $service) + { + // Runs the internal initializer; used by the dumped container to include always-needed files + if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) { + $initialize = $this->privates['service_container']; + unset($this->privates['service_container']); + $initialize(); + } + if ('service_container' === $id) { + throw new InvalidArgumentException('You cannot set service "service_container".'); + } + if (!(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) { + if (isset($this->syntheticIds[$id]) || !isset($this->getRemovedIds()[$id])) { + // no-op + } elseif (null === $service) { + throw new InvalidArgumentException(\sprintf('The "%s" service is private, you cannot unset it.', $id)); + } else { + throw new InvalidArgumentException(\sprintf('The "%s" service is private, you cannot replace it.', $id)); + } + } elseif (isset($this->services[$id])) { + throw new InvalidArgumentException(\sprintf('The "%s" service is already initialized, you cannot replace it.', $id)); + } + if (isset($this->aliases[$id])) { + unset($this->aliases[$id]); + } + if (null === $service) { + unset($this->services[$id]); + return; + } + $this->services[$id] = $service; + } + public function has(string $id) : bool + { + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + if (isset($this->services[$id])) { + return \true; + } + if ('service_container' === $id) { + return \true; + } + return isset($this->fileMap[$id]) || isset($this->methodMap[$id]); + } + /** + * Gets a service. + * + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * @throws \Exception if an exception has been thrown when the service has been resolved + * + * @see Reference + */ + public function get(string $id, int $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) : ?object + { + return $this->services[$id] ?? $this->services[$id = $this->aliases[$id] ?? $id] ?? ('service_container' === $id ? $this : ($this->factories[$id] ?? \Closure::fromCallable([$this, 'make']))($id, $invalidBehavior)); + } + /** + * Creates a service. + * + * As a separate method to allow "get()" to use the really fast `??` operator. + */ + private function make(string $id, int $invalidBehavior) + { + if (isset($this->loading[$id])) { + throw new ServiceCircularReferenceException($id, \array_merge(\array_keys($this->loading), [$id])); + } + $this->loading[$id] = \true; + try { + if (isset($this->fileMap[$id])) { + return 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]); + } elseif (isset($this->methodMap[$id])) { + return 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}(); + } + } catch (\Exception $e) { + unset($this->services[$id]); + throw $e; + } finally { + unset($this->loading[$id]); + } + if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) { + if (!$id) { + throw new ServiceNotFoundException($id); + } + if (isset($this->syntheticIds[$id])) { + throw new ServiceNotFoundException($id, null, null, [], \sprintf('The "%s" service is synthetic, it needs to be set at boot time before it can be used.', $id)); + } + if (isset($this->getRemovedIds()[$id])) { + throw new ServiceNotFoundException($id, null, null, [], \sprintf('The "%s" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.', $id)); + } + $alternatives = []; + foreach ($this->getServiceIds() as $knownId) { + if ('' === $knownId || '.' === $knownId[0]) { + continue; + } + $lev = \levenshtein($id, $knownId); + if ($lev <= \strlen($id) / 3 || \strpos($knownId, $id) !== \false) { + $alternatives[] = $knownId; + } + } + throw new ServiceNotFoundException($id, null, null, $alternatives); + } + return null; + } + /** + * Returns true if the given service has actually been initialized. + */ + public function initialized(string $id) : bool + { + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + if ('service_container' === $id) { + return \false; + } + return isset($this->services[$id]); + } + /** + * {@inheritdoc} + */ + public function reset() + { + $services = $this->services + $this->privates; + $this->services = $this->factories = $this->privates = []; + foreach ($services as $service) { + try { + if ($service instanceof ResetInterface) { + $service->reset(); + } + } catch (\Throwable $exception) { + continue; + } + } + } + /** + * Gets all service ids. + * + * @return string[] + */ + public function getServiceIds() : array + { + return \array_map('strval', \array_unique(\array_merge(['service_container'], \array_keys($this->fileMap), \array_keys($this->methodMap), \array_keys($this->aliases), \array_keys($this->services)))); + } + /** + * Gets service ids that existed at compile time. + */ + public function getRemovedIds() : array + { + return []; + } + /** + * Camelizes a string. + */ + public static function camelize(string $id) : string + { + return \strtr(\ucwords(\strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']); + } + /** + * A string to underscore. + */ + public static function underscore(string $id) : string + { + return \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], \str_replace('_', '.', $id))); + } + /** + * Creates a service by requiring its factory file. + */ + protected function load(string $file) + { + return require $file; + } + /** + * Fetches a variable from the environment. + * + * @throws EnvNotFoundException When the environment variable is not found and has no default value + * @return mixed + */ + protected function getEnv(string $name) + { + if (isset($this->resolving[$envName = "env({$name})"])) { + throw new ParameterCircularReferenceException(\array_keys($this->resolving)); + } + if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) { + return $this->envCache[$name]; + } + if (!$this->has($id = 'container.env_var_processors_locator')) { + $this->set($id, new ServiceLocator([])); + } + $this->getEnv = $this->getEnv ?? \Closure::fromCallable([$this, 'getEnv']); + $processors = $this->get($id); + if (\false !== ($i = \strpos($name, ':'))) { + $prefix = \substr($name, 0, $i); + $localName = \substr($name, 1 + $i); + } else { + $prefix = 'string'; + $localName = $name; + } + $processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this); + $this->resolving[$envName] = \true; + try { + return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv); + } finally { + unset($this->resolving[$envName]); + } + } + /** + * @internal + * @param string|false $registry + * @param string|bool $load + * @return mixed + */ + protected final function getService($registry, string $id, ?string $method, $load) + { + if ('service_container' === $id) { + return $this; + } + if (\is_string($load)) { + throw new RuntimeException($load); + } + if (null === $method) { + return \false !== $registry ? $this->{$registry}[$id] ?? null : null; + } + if (\false !== $registry) { + return $this->{$registry}[$id] = $this->{$registry}[$id] ?? ($load ? $this->load($method) : $this->{$method}()); + } + if (!$load) { + return $this->{$method}(); + } + return ($factory = $this->factories[$id] ?? $this->factories['service_container'][$id] ?? null) ? $factory() : $this->load($method); + } + private function __clone() + { + } +} diff --git a/vendor/symfony/dependency-injection/ContainerAwareInterface.php b/vendor/symfony/dependency-injection/ContainerAwareInterface.php new file mode 100644 index 0000000000..b113eb56d9 --- /dev/null +++ b/vendor/symfony/dependency-injection/ContainerAwareInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * ContainerAwareInterface should be implemented by classes that depends on a Container. + * + * @author Fabien Potencier + */ +interface ContainerAwareInterface +{ + /** + * Sets the container. + */ + public function setContainer(ContainerInterface $container = null); +} diff --git a/vendor/symfony/dependency-injection/ContainerAwareTrait.php b/vendor/symfony/dependency-injection/ContainerAwareTrait.php new file mode 100644 index 0000000000..73408c584f --- /dev/null +++ b/vendor/symfony/dependency-injection/ContainerAwareTrait.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * ContainerAware trait. + * + * @author Fabien Potencier + */ +trait ContainerAwareTrait +{ + /** + * @var ContainerInterface + */ + protected $container; + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/vendor/symfony/dependency-injection/ContainerBuilder.php b/vendor/symfony/dependency-injection/ContainerBuilder.php new file mode 100644 index 0000000000..9e71670015 --- /dev/null +++ b/vendor/symfony/dependency-injection/ContainerBuilder.php @@ -0,0 +1,1426 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Composer\InstalledVersions; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ClassExistenceResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ComposerResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\DirectoryResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\FileExistenceResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\FileResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\GlobResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ReflectionClassResource; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\ResourceInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\Target; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\Compiler; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\PassConfig; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; +/** + * ContainerBuilder is a DI container that provides an API to easily describe services. + * + * @author Fabien Potencier + */ +class ContainerBuilder extends Container implements TaggedContainerInterface +{ + /** + * @var array + */ + private $extensions = []; + /** + * @var array + */ + private $extensionsByNs = []; + /** + * @var array + */ + private $definitions = []; + /** + * @var array + */ + private $aliasDefinitions = []; + /** + * @var array + */ + private $resources = []; + /** + * @var array>> + */ + private $extensionConfigs = []; + /** + * @var \Symfony\Component\DependencyInjection\Compiler\Compiler + */ + private $compiler; + /** + * @var bool + */ + private $trackResources; + /** + * @var \Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface|null + */ + private $proxyInstantiator; + /** + * @var \Symfony\Component\DependencyInjection\ExpressionLanguage + */ + private $expressionLanguage; + /** + * @var ExpressionFunctionProviderInterface[] + */ + private $expressionLanguageProviders = []; + /** + * @var string[] with tag names used by findTaggedServiceIds + */ + private $usedTags = []; + /** + * @var string[][] a map of env var names to their placeholders + */ + private $envPlaceholders = []; + /** + * @var int[] a map of env vars to their resolution counter + */ + private $envCounters = []; + /** + * @var string[] the list of vendor directories + */ + private $vendors; + /** + * @var array + */ + private $autoconfiguredInstanceof = []; + /** + * @var array + */ + private $autoconfiguredAttributes = []; + /** + * @var array + */ + private $removedIds = []; + /** + * @var array + */ + private $removedBindingIds = []; + private const INTERNAL_TYPES = ['int' => \true, 'float' => \true, 'string' => \true, 'bool' => \true, 'resource' => \true, 'object' => \true, 'array' => \true, 'null' => \true, 'callable' => \true, 'iterable' => \true, 'mixed' => \true]; + public function __construct(ParameterBagInterface $parameterBag = null) + { + parent::__construct($parameterBag); + $this->trackResources = \interface_exists(ResourceInterface::class); + $this->setDefinition('service_container', (new Definition(ContainerInterface::class))->setSynthetic(\true)->setPublic(\true)); + } + /** + * @var array + */ + private $classReflectors; + /** + * Sets the track resources flag. + * + * If you are not using the loaders and therefore don't want + * to depend on the Config component, set this flag to false. + */ + public function setResourceTracking(bool $track) + { + $this->trackResources = $track; + } + /** + * Checks if resources are tracked. + */ + public function isTrackingResources() : bool + { + return $this->trackResources; + } + /** + * Sets the instantiator to be used when fetching proxies. + */ + public function setProxyInstantiator(InstantiatorInterface $proxyInstantiator) + { + $this->proxyInstantiator = $proxyInstantiator; + } + public function registerExtension(ExtensionInterface $extension) + { + $this->extensions[$extension->getAlias()] = $extension; + if (\false !== $extension->getNamespace()) { + $this->extensionsByNs[$extension->getNamespace()] = $extension; + } + } + /** + * Returns an extension by alias or namespace. + * + * @throws LogicException if the extension is not registered + */ + public function getExtension(string $name) : ExtensionInterface + { + if (isset($this->extensions[$name])) { + return $this->extensions[$name]; + } + if (isset($this->extensionsByNs[$name])) { + return $this->extensionsByNs[$name]; + } + throw new LogicException(\sprintf('Container extension "%s" is not registered.', $name)); + } + /** + * Returns all registered extensions. + * + * @return array + */ + public function getExtensions() : array + { + return $this->extensions; + } + /** + * Checks if we have an extension. + */ + public function hasExtension(string $name) : bool + { + return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]); + } + /** + * Returns an array of resources loaded to build this configuration. + * + * @return ResourceInterface[] + */ + public function getResources() : array + { + return \array_values($this->resources); + } + /** + * @return $this + */ + public function addResource(ResourceInterface $resource) + { + if (!$this->trackResources) { + return $this; + } + if ($resource instanceof GlobResource && $this->inVendors($resource->getPrefix())) { + return $this; + } + $this->resources[(string) $resource] = $resource; + return $this; + } + /** + * Sets the resources for this configuration. + * + * @param array $resources + * + * @return $this + */ + public function setResources(array $resources) + { + if (!$this->trackResources) { + return $this; + } + $this->resources = $resources; + return $this; + } + /** + * Adds the object class hierarchy as resources. + * + * @param object|string $object An object instance or class name + * + * @return $this + */ + public function addObjectResource($object) + { + if ($this->trackResources) { + if (\is_object($object)) { + $object = \get_class($object); + } + if (!isset($this->classReflectors[$object])) { + $this->classReflectors[$object] = new \ReflectionClass($object); + } + $class = $this->classReflectors[$object]; + foreach ($class->getInterfaceNames() as $name) { + if (null === ($interface =& $this->classReflectors[$name])) { + $interface = new \ReflectionClass($name); + } + $file = $interface->getFileName(); + if (\false !== $file && \file_exists($file)) { + $this->fileExists($file); + } + } + do { + $file = $class->getFileName(); + if (\false !== $file && \file_exists($file)) { + $this->fileExists($file); + } + foreach ($class->getTraitNames() as $name) { + $this->addObjectResource($name); + } + } while ($class = $class->getParentClass()); + } + return $this; + } + /** + * Retrieves the requested reflection class and registers it for resource tracking. + * + * @throws \ReflectionException when a parent class/interface/trait is not found and $throw is true + * + * @final + */ + public function getReflectionClass(?string $class, bool $throw = \true) : ?\ReflectionClass + { + if (!($class = $this->getParameterBag()->resolveValue($class))) { + return null; + } + if (isset(self::INTERNAL_TYPES[$class])) { + return null; + } + $resource = $classReflector = null; + try { + if (isset($this->classReflectors[$class])) { + $classReflector = $this->classReflectors[$class]; + } elseif (\class_exists(ClassExistenceResource::class)) { + $resource = new ClassExistenceResource($class, \false); + $classReflector = $resource->isFresh(0) ? \false : new \ReflectionClass($class); + } else { + $classReflector = \class_exists($class) ? new \ReflectionClass($class) : \false; + } + } catch (\ReflectionException $e) { + if ($throw) { + throw $e; + } + } + if ($this->trackResources) { + if (!$classReflector) { + $this->addResource($resource ?? new ClassExistenceResource($class, \false)); + } elseif (!$classReflector->isInternal()) { + $path = $classReflector->getFileName(); + if (!$this->inVendors($path)) { + $this->addResource(new ReflectionClassResource($classReflector, $this->vendors)); + } + } + $this->classReflectors[$class] = $classReflector; + } + return $classReflector ?: null; + } + /** + * Checks whether the requested file or directory exists and registers the result for resource tracking. + * + * @param string $path The file or directory path for which to check the existence + * @param bool|string $trackContents Whether to track contents of the given resource. If a string is passed, + * it will be used as pattern for tracking contents of the requested directory + * + * @final + */ + public function fileExists(string $path, $trackContents = \true) : bool + { + $exists = \file_exists($path); + if (!$this->trackResources || $this->inVendors($path)) { + return $exists; + } + if (!$exists) { + $this->addResource(new FileExistenceResource($path)); + return $exists; + } + if (\is_dir($path)) { + if ($trackContents) { + $this->addResource(new DirectoryResource($path, \is_string($trackContents) ? $trackContents : null)); + } else { + $this->addResource(new GlobResource($path, '/*', \false)); + } + } elseif ($trackContents) { + $this->addResource(new FileResource($path)); + } + return $exists; + } + /** + * Loads the configuration for an extension. + * + * @param string $extension The extension alias or namespace + * @param array|null $values An array of values that customizes the extension + * + * @return $this + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + * @throws \LogicException if the extension is not registered + */ + public function loadFromExtension(string $extension, array $values = null) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Cannot load from an extension on a compiled container.'); + } + $namespace = $this->getExtension($extension)->getAlias(); + $this->extensionConfigs[$namespace][] = $values ?? []; + return $this; + } + /** + * Adds a compiler pass. + * + * @param string $type The type of compiler pass + * @param int $priority Used to sort the passes + * + * @return $this + */ + public function addCompilerPass(CompilerPassInterface $pass, string $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, int $priority = 0) + { + $this->getCompiler()->addPass($pass, $type, $priority); + $this->addObjectResource($pass); + return $this; + } + /** + * Returns the compiler pass config which can then be modified. + */ + public function getCompilerPassConfig() : PassConfig + { + return $this->getCompiler()->getPassConfig(); + } + /** + * Returns the compiler. + */ + public function getCompiler() : Compiler + { + return $this->compiler = $this->compiler ?? new Compiler(); + } + /** + * Sets a service. + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function set(string $id, ?object $service) + { + if ($this->isCompiled() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) { + // setting a synthetic service on a compiled container is alright + throw new BadMethodCallException(\sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a compiled container is not allowed.', $id)); + } + unset($this->definitions[$id], $this->aliasDefinitions[$id], $this->removedIds[$id]); + parent::set($id, $service); + } + /** + * Removes a service definition. + */ + public function removeDefinition(string $id) + { + if (isset($this->definitions[$id])) { + unset($this->definitions[$id]); + $this->removedIds[$id] = \true; + } + } + public function has(string $id) : bool + { + return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id); + } + /** + * @throws InvalidArgumentException when no definitions are available + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * @throws \Exception + * + * @see Reference + */ + public function get(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) : ?object + { + if ($this->isCompiled() && isset($this->removedIds[$id])) { + return ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $invalidBehavior ? parent::get($id) : null; + } + return $this->doGet($id, $invalidBehavior); + } + /** + * @return mixed + */ + private function doGet(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, array &$inlineServices = null, bool $isConstructorArgument = \false) + { + if (isset($inlineServices[$id])) { + return $inlineServices[$id]; + } + if (null === $inlineServices) { + $isConstructorArgument = \true; + $inlineServices = []; + } + try { + if (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) { + return $this->privates[$id] ?? parent::get($id, $invalidBehavior); + } + if (null !== ($service = $this->privates[$id] ?? parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE))) { + return $service; + } + } catch (ServiceCircularReferenceException $e) { + if ($isConstructorArgument) { + throw $e; + } + } + if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) { + $alias = $this->aliasDefinitions[$id]; + if ($alias->isDeprecated()) { + $deprecation = $alias->getDeprecation($id); + trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']); + } + return $this->doGet((string) $alias, $invalidBehavior, $inlineServices, $isConstructorArgument); + } + try { + $definition = $this->getDefinition($id); + } catch (ServiceNotFoundException $e) { + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $invalidBehavior) { + return null; + } + throw $e; + } + if ($definition->hasErrors() && ($e = $definition->getErrors())) { + throw new RuntimeException(\reset($e)); + } + if ($isConstructorArgument) { + $this->loading[$id] = \true; + } + try { + return $this->createService($definition, $inlineServices, $isConstructorArgument, $id); + } finally { + if ($isConstructorArgument) { + unset($this->loading[$id]); + } + } + } + /** + * Merges a ContainerBuilder with the current ContainerBuilder configuration. + * + * Service definitions overrides the current defined ones. + * + * But for parameters, they are overridden by the current ones. It allows + * the parameters passed to the container constructor to have precedence + * over the loaded ones. + * + * $container = new ContainerBuilder(new ParameterBag(['foo' => 'bar'])); + * $loader = new LoaderXXX($container); + * $loader->load('resource_name'); + * $container->register('foo', 'stdClass'); + * + * In the above example, even if the loaded resource defines a foo + * parameter, the value will still be 'bar' as defined in the ContainerBuilder + * constructor. + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function merge(self $container) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Cannot merge on a compiled container.'); + } + $this->addDefinitions($container->getDefinitions()); + $this->addAliases($container->getAliases()); + $this->getParameterBag()->add($container->getParameterBag()->all()); + if ($this->trackResources) { + foreach ($container->getResources() as $resource) { + $this->addResource($resource); + } + } + foreach ($this->extensions as $name => $extension) { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + $this->extensionConfigs[$name] = \array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name)); + } + if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) { + $envPlaceholders = $container->getParameterBag()->getEnvPlaceholders(); + $this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag()); + } else { + $envPlaceholders = []; + } + foreach ($container->envCounters as $env => $count) { + if (!$count && !isset($envPlaceholders[$env])) { + continue; + } + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = $count; + } else { + $this->envCounters[$env] += $count; + } + } + foreach ($container->getAutoconfiguredInstanceof() as $interface => $childDefinition) { + if (isset($this->autoconfiguredInstanceof[$interface])) { + throw new InvalidArgumentException(\sprintf('"%s" has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.', $interface)); + } + $this->autoconfiguredInstanceof[$interface] = $childDefinition; + } + foreach ($container->getAutoconfiguredAttributes() as $attribute => $configurator) { + if (isset($this->autoconfiguredAttributes[$attribute])) { + throw new InvalidArgumentException(\sprintf('"%s" has already been autoconfigured and merge() does not support merging autoconfiguration for the same attribute.', $attribute)); + } + $this->autoconfiguredAttributes[$attribute] = $configurator; + } + } + /** + * Returns the configuration array for the given extension. + * + * @return array> + */ + public function getExtensionConfig(string $name) : array + { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + return $this->extensionConfigs[$name]; + } + /** + * Prepends a config array to the configs of the given extension. + * + * @param array $config + */ + public function prependExtensionConfig(string $name, array $config) + { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + \array_unshift($this->extensionConfigs[$name], $config); + } + /** + * Compiles the container. + * + * This method passes the container to compiler + * passes whose job is to manipulate and optimize + * the container. + * + * The main compiler passes roughly do four things: + * + * * The extension configurations are merged; + * * Parameter values are resolved; + * * The parameter bag is frozen; + * * Extension loading is disabled. + * + * @param bool $resolveEnvPlaceholders Whether %env()% parameters should be resolved using the current + * env vars or be replaced by uniquely identifiable placeholders. + * Set to "true" when you want to use the current ContainerBuilder + * directly, keep to "false" when the container is dumped instead. + */ + public function compile(bool $resolveEnvPlaceholders = \false) + { + $compiler = $this->getCompiler(); + if ($this->trackResources) { + foreach ($compiler->getPassConfig()->getPasses() as $pass) { + $this->addObjectResource($pass); + } + } + $bag = $this->getParameterBag(); + if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) { + $compiler->addPass(new ResolveEnvPlaceholdersPass(), PassConfig::TYPE_AFTER_REMOVING, -1000); + } + $compiler->compile($this); + foreach ($this->definitions as $id => $definition) { + if ($this->trackResources && $definition->isLazy()) { + $this->getReflectionClass($definition->getClass()); + } + } + $this->extensionConfigs = []; + if ($bag instanceof EnvPlaceholderParameterBag) { + if ($resolveEnvPlaceholders) { + $this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), \true)); + } + $this->envPlaceholders = $bag->getEnvPlaceholders(); + } + parent::compile(); + foreach ($this->definitions + $this->aliasDefinitions as $id => $definition) { + if (!$definition->isPublic() || $definition->isPrivate()) { + $this->removedIds[$id] = \true; + } + } + } + /** + * {@inheritdoc} + */ + public function getServiceIds() : array + { + return \array_map('strval', \array_unique(\array_merge(\array_keys($this->getDefinitions()), \array_keys($this->aliasDefinitions), parent::getServiceIds()))); + } + /** + * Gets removed service or alias ids. + * + * @return array + */ + public function getRemovedIds() : array + { + return $this->removedIds; + } + /** + * Adds the service aliases. + * + * @param array $aliases + */ + public function addAliases(array $aliases) + { + foreach ($aliases as $alias => $id) { + $this->setAlias($alias, $id); + } + } + /** + * Sets the service aliases. + * + * @param array $aliases + */ + public function setAliases(array $aliases) + { + $this->aliasDefinitions = []; + $this->addAliases($aliases); + } + /** + * Sets an alias for an existing service. + * + * @throws InvalidArgumentException if the id is not a string or an Alias + * @throws InvalidArgumentException if the alias is for itself + * @param string|\Symfony\Component\DependencyInjection\Alias $id + */ + public function setAlias(string $alias, $id) : Alias + { + if ('' === $alias || '\\' === $alias[-1] || \strlen($alias) !== \strcspn($alias, "\x00\r\n'")) { + throw new InvalidArgumentException(\sprintf('Invalid alias id: "%s".', $alias)); + } + if (\is_string($id)) { + $id = new Alias($id); + } + if ($alias === (string) $id) { + throw new InvalidArgumentException(\sprintf('An alias cannot reference itself, got a circular reference on "%s".', $alias)); + } + unset($this->definitions[$alias], $this->removedIds[$alias]); + return $this->aliasDefinitions[$alias] = $id; + } + public function removeAlias(string $alias) + { + if (isset($this->aliasDefinitions[$alias])) { + unset($this->aliasDefinitions[$alias]); + $this->removedIds[$alias] = \true; + } + } + public function hasAlias(string $id) : bool + { + return isset($this->aliasDefinitions[$id]); + } + /** + * @return array + */ + public function getAliases() : array + { + return $this->aliasDefinitions; + } + /** + * @throws InvalidArgumentException if the alias does not exist + */ + public function getAlias(string $id) : Alias + { + if (!isset($this->aliasDefinitions[$id])) { + throw new InvalidArgumentException(\sprintf('The service alias "%s" does not exist.', $id)); + } + return $this->aliasDefinitions[$id]; + } + /** + * Registers a service definition. + * + * This methods allows for simple registration of service definition + * with a fluid interface. + */ + public function register(string $id, string $class = null) : Definition + { + return $this->setDefinition($id, new Definition($class)); + } + /** + * Registers an autowired service definition. + * + * This method implements a shortcut for using setDefinition() with + * an autowired definition. + */ + public function autowire(string $id, string $class = null) : Definition + { + return $this->setDefinition($id, (new Definition($class))->setAutowired(\true)); + } + /** + * Adds the service definitions. + * + * @param array $definitions + */ + public function addDefinitions(array $definitions) + { + foreach ($definitions as $id => $definition) { + $this->setDefinition($id, $definition); + } + } + /** + * Sets the service definitions. + * + * @param array $definitions + */ + public function setDefinitions(array $definitions) + { + $this->definitions = []; + $this->addDefinitions($definitions); + } + /** + * Gets all service definitions. + * + * @return array + */ + public function getDefinitions() : array + { + return $this->definitions; + } + /** + * Sets a service definition. + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function setDefinition(string $id, Definition $definition) : Definition + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Adding definition to a compiled container is not allowed.'); + } + if ('' === $id || '\\' === $id[-1] || \strlen($id) !== \strcspn($id, "\x00\r\n'")) { + throw new InvalidArgumentException(\sprintf('Invalid service id: "%s".', $id)); + } + unset($this->aliasDefinitions[$id], $this->removedIds[$id]); + return $this->definitions[$id] = $definition; + } + /** + * Returns true if a service definition exists under the given identifier. + */ + public function hasDefinition(string $id) : bool + { + return isset($this->definitions[$id]); + } + /** + * Gets a service definition. + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public function getDefinition(string $id) : Definition + { + if (!isset($this->definitions[$id])) { + throw new ServiceNotFoundException($id); + } + return $this->definitions[$id]; + } + /** + * Gets a service definition by id or alias. + * + * The method "unaliases" recursively to return a Definition instance. + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public function findDefinition(string $id) : Definition + { + $seen = []; + while (isset($this->aliasDefinitions[$id])) { + $id = (string) $this->aliasDefinitions[$id]; + if (isset($seen[$id])) { + $seen = \array_values($seen); + $seen = \array_slice($seen, \array_search($id, $seen)); + $seen[] = $id; + throw new ServiceCircularReferenceException($id, $seen); + } + $seen[$id] = $id; + } + return $this->getDefinition($id); + } + /** + * Creates a service for a service definition. + * + * @throws RuntimeException When the factory definition is incomplete + * @throws RuntimeException When the service is a synthetic service + * @throws InvalidArgumentException When configure callable is not callable + * @return mixed + */ + private function createService(Definition $definition, array &$inlineServices, bool $isConstructorArgument = \false, string $id = null, bool $tryProxy = \true) + { + if (null === $id && isset($inlineServices[$h = \spl_object_hash($definition)])) { + return $inlineServices[$h]; + } + if ($definition instanceof ChildDefinition) { + throw new RuntimeException(\sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id)); + } + if ($definition->isSynthetic()) { + throw new RuntimeException(\sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id)); + } + if ($definition->isDeprecated()) { + $deprecation = $definition->getDeprecation($id); + trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']); + } + if ($tryProxy && $definition->isLazy() && !($tryProxy = !($proxy = $this->proxyInstantiator) || $proxy instanceof RealServiceInstantiator)) { + $proxy = $proxy->instantiateProxy($this, $definition, $id, function () use($definition, &$inlineServices, $id) { + return $this->createService($definition, $inlineServices, \true, $id, \false); + }); + $this->shareService($definition, $proxy, $id, $inlineServices); + return $proxy; + } + $parameterBag = $this->getParameterBag(); + if (null !== $definition->getFile()) { + require_once $parameterBag->resolveValue($definition->getFile()); + } + $arguments = $definition->getArguments(); + if (null !== ($factory = $definition->getFactory())) { + if (\is_array($factory)) { + $factory = [$this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlineServices, $isConstructorArgument), $factory[1]]; + } elseif (!\is_string($factory)) { + throw new RuntimeException(\sprintf('Cannot create service "%s" because of invalid factory.', $id)); + } elseif (\strncmp($factory, '@=', \strlen('@=')) === 0) { + $factory = function (ServiceLocator $arguments) use($factory) { + return $this->getExpressionLanguage()->evaluate(\substr($factory, 2), ['container' => $this, 'args' => $arguments]); + }; + $arguments = [new ServiceLocatorArgument($arguments)]; + } + } + $arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($arguments)), $inlineServices, $isConstructorArgument); + if (null !== $id && $definition->isShared() && (isset($this->services[$id]) || isset($this->privates[$id])) && ($tryProxy || !$definition->isLazy())) { + return $this->services[$id] ?? $this->privates[$id]; + } + $arrayIsListFunction = function (array $array) : bool { + if (\function_exists('array_is_list')) { + return \array_is_list($array); + } + if ($array === []) { + return \true; + } + $current_key = 0; + foreach ($array as $key => $noop) { + if ($key !== $current_key) { + return \false; + } + ++$current_key; + } + return \true; + }; + if (!$arrayIsListFunction($arguments)) { + $arguments = \array_combine(\array_map(function ($k) { + return \preg_replace('/^.*\\$/', '', $k); + }, \array_keys($arguments)), $arguments); + } + if (null !== $factory) { + $service = $factory(...$arguments); + if (!$definition->isDeprecated() && \is_array($factory) && \is_string($factory[0])) { + $r = new \ReflectionClass($factory[0]); + if (0 < \strpos($r->getDocComment(), "\n * @deprecated ")) { + trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name); + } + } + } else { + $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass())); + $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments); + if (!$definition->isDeprecated() && 0 < \strpos($r->getDocComment(), "\n * @deprecated ")) { + trigger_deprecation('', '', 'The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name); + } + } + $lastWitherIndex = null; + foreach ($definition->getMethodCalls() as $k => $call) { + if ($call[2] ?? \false) { + $lastWitherIndex = $k; + } + } + if (null === $lastWitherIndex && ($tryProxy || !$definition->isLazy())) { + // share only if proxying failed, or if not a proxy, and if no withers are found + $this->shareService($definition, $service, $id, $inlineServices); + } + $properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlineServices); + foreach ($properties as $name => $value) { + $service->{$name} = $value; + } + foreach ($definition->getMethodCalls() as $k => $call) { + $service = $this->callMethod($service, $call, $inlineServices); + if ($lastWitherIndex === $k && ($tryProxy || !$definition->isLazy())) { + // share only if proxying failed, or if not a proxy, and this is the last wither + $this->shareService($definition, $service, $id, $inlineServices); + } + } + if ($callable = $definition->getConfigurator()) { + if (\is_array($callable)) { + $callable[0] = $parameterBag->resolveValue($callable[0]); + if ($callable[0] instanceof Reference) { + $callable[0] = $this->doGet((string) $callable[0], $callable[0]->getInvalidBehavior(), $inlineServices); + } elseif ($callable[0] instanceof Definition) { + $callable[0] = $this->createService($callable[0], $inlineServices); + } + } + if (!\is_callable($callable)) { + throw new InvalidArgumentException(\sprintf('The configure callable for class "%s" is not a callable.', \get_debug_type($service))); + } + $callable($service); + } + return $service; + } + /** + * Replaces service references by the real service instance and evaluates expressions. + * + * @return mixed The same value with all service references replaced by + * the real service instances and all expressions evaluated + * @param mixed $value + */ + public function resolveServices($value) + { + return $this->doResolveServices($value); + } + /** + * @param mixed $value + * @return mixed + */ + private function doResolveServices($value, array &$inlineServices = [], bool $isConstructorArgument = \false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = $this->doResolveServices($v, $inlineServices, $isConstructorArgument); + } + } elseif ($value instanceof ServiceClosureArgument) { + $reference = $value->getValues()[0]; + $value = function () use($reference) { + return $this->resolveServices($reference); + }; + } elseif ($value instanceof IteratorArgument) { + $value = new RewindableGenerator(function () use($value, &$inlineServices) { + foreach ($value->getValues() as $k => $v) { + foreach (self::getServiceConditionals($v) as $s) { + if (!$this->has($s)) { + continue 2; + } + } + foreach (self::getInitializedConditionals($v) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) { + continue 2; + } + } + (yield $k => $this->doResolveServices($v, $inlineServices)); + } + }, function () use($value) : int { + $count = 0; + foreach ($value->getValues() as $v) { + foreach (self::getServiceConditionals($v) as $s) { + if (!$this->has($s)) { + continue 2; + } + } + foreach (self::getInitializedConditionals($v) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) { + continue 2; + } + } + ++$count; + } + return $count; + }); + } elseif ($value instanceof ServiceLocatorArgument) { + $refs = $types = []; + foreach ($value->getValues() as $k => $v) { + $refs[$k] = [$v, null]; + $types[$k] = $v instanceof TypedReference ? $v->getType() : '?'; + } + $value = new ServiceLocator(\Closure::fromCallable([$this, 'resolveServices']), $refs, $types); + } elseif ($value instanceof Reference) { + $value = $this->doGet((string) $value, $value->getInvalidBehavior(), $inlineServices, $isConstructorArgument); + } elseif ($value instanceof Definition) { + $value = $this->createService($value, $inlineServices, $isConstructorArgument); + } elseif ($value instanceof Parameter) { + $value = $this->getParameter((string) $value); + } elseif ($value instanceof Expression) { + $value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this]); + } elseif ($value instanceof AbstractArgument) { + throw new RuntimeException($value->getTextWithContext()); + } + return $value; + } + /** + * Returns service ids for a given tag. + * + * Example: + * + * $container->register('foo')->addTag('my.tag', ['hello' => 'world']); + * + * $serviceIds = $container->findTaggedServiceIds('my.tag'); + * foreach ($serviceIds as $serviceId => $tags) { + * foreach ($tags as $tag) { + * echo $tag['hello']; + * } + * } + * + * @return array An array of tags with the tagged service as key, holding a list of attribute arrays + */ + public function findTaggedServiceIds(string $name, bool $throwOnAbstract = \false) : array + { + $this->usedTags[] = $name; + $tags = []; + foreach ($this->getDefinitions() as $id => $definition) { + if ($definition->hasTag($name)) { + if ($throwOnAbstract && $definition->isAbstract()) { + throw new InvalidArgumentException(\sprintf('The service "%s" tagged "%s" must not be abstract.', $id, $name)); + } + $tags[$id] = $definition->getTag($name); + } + } + return $tags; + } + /** + * Returns all tags the defined services use. + * + * @return string[] + */ + public function findTags() : array + { + $tags = []; + foreach ($this->getDefinitions() as $id => $definition) { + $tags[] = \array_keys($definition->getTags()); + } + return \array_unique(\array_merge([], ...$tags)); + } + /** + * Returns all tags not queried by findTaggedServiceIds. + * + * @return string[] + */ + public function findUnusedTags() : array + { + return \array_values(\array_diff($this->findTags(), $this->usedTags)); + } + public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) + { + $this->expressionLanguageProviders[] = $provider; + } + /** + * @return ExpressionFunctionProviderInterface[] + */ + public function getExpressionLanguageProviders() : array + { + return $this->expressionLanguageProviders; + } + /** + * Returns a ChildDefinition that will be used for autoconfiguring the interface/class. + */ + public function registerForAutoconfiguration(string $interface) : ChildDefinition + { + if (!isset($this->autoconfiguredInstanceof[$interface])) { + $this->autoconfiguredInstanceof[$interface] = new ChildDefinition(''); + } + return $this->autoconfiguredInstanceof[$interface]; + } + /** + * Registers an attribute that will be used for autoconfiguring annotated classes. + * + * The third argument passed to the callable is the reflector of the + * class/method/property/parameter that the attribute targets. Using one or many of + * \ReflectionClass|\ReflectionMethod|\ReflectionProperty|\ReflectionParameter as a type-hint + * for this argument allows filtering which attributes should be passed to the callable. + * + * @template T + * + * @param class-string $attributeClass + * @param callable(ChildDefinition, T, \Reflector): void $configurator + */ + public function registerAttributeForAutoconfiguration(string $attributeClass, callable $configurator) : void + { + $this->autoconfiguredAttributes[$attributeClass] = $configurator; + } + /** + * Registers an autowiring alias that only binds to a specific argument name. + * + * The argument name is derived from $name if provided (from $id otherwise) + * using camel case: "foo.bar" or "foo_bar" creates an alias bound to + * "$fooBar"-named arguments with $type as type-hint. Such arguments will + * receive the service $id when autowiring is used. + */ + public function registerAliasForArgument(string $id, string $type, string $name = null) : Alias + { + $name = (new Target($name ?? $id))->name; + if (!\preg_match('/^[a-zA-Z_\\x7f-\\xff]/', $name)) { + throw new InvalidArgumentException(\sprintf('Invalid argument name "%s" for service "%s": the first character must be a letter.', $name, $id)); + } + return $this->setAlias($type . ' $' . $name, $id); + } + /** + * Returns an array of ChildDefinition[] keyed by interface. + * + * @return array + */ + public function getAutoconfiguredInstanceof() : array + { + return $this->autoconfiguredInstanceof; + } + /** + * @return array + */ + public function getAutoconfiguredAttributes() : array + { + return $this->autoconfiguredAttributes; + } + /** + * Resolves env parameter placeholders in a string or an array. + * + * @param string|bool $format A sprintf() format returning the replacement for each env var name or + null to resolve back to the original "%env(VAR)%" format or + true to resolve to the actual values of the referenced env vars + * @param array &$usedEnvs Env vars found while resolving are added to this array + * + * @return mixed The value with env parameters resolved if a string or an array is passed + * @param mixed $value + */ + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) + { + if (null === $format) { + $format = '%%env(%s)%%'; + } + $bag = $this->getParameterBag(); + if (\true === $format) { + $value = $bag->resolveValue($value); + } + if ($value instanceof Definition) { + $value = (array) $value; + } + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[\is_string($k) ? $this->resolveEnvPlaceholders($k, $format, $usedEnvs) : $k] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs); + } + return $result; + } + if (!\is_string($value) || 38 > \strlen($value) || !\preg_match('/env[_(]/i', $value)) { + return $value; + } + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + $completed = \false; + foreach ($envPlaceholders as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (\false !== \stripos($value, $placeholder)) { + if (\true === $format) { + $resolved = $bag->escapeValue($this->getEnv($env)); + } else { + $resolved = \sprintf($format, $env); + } + if ($placeholder === $value) { + $value = $resolved; + $completed = \true; + } else { + if (!\is_string($resolved) && !\is_numeric($resolved)) { + throw new RuntimeException(\sprintf('A string value must be composed of strings and/or numbers, but found parameter "env(%s)" of type "%s" inside string value "%s".', $env, \get_debug_type($resolved), $this->resolveEnvPlaceholders($value))); + } + $value = \str_ireplace($placeholder, $resolved, $value); + } + $usedEnvs[$env] = $env; + $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1; + if ($completed) { + break 2; + } + } + } + } + return $value; + } + /** + * Get statistics about env usage. + * + * @return int[] The number of time each env vars has been resolved + */ + public function getEnvCounters() : array + { + $bag = $this->getParameterBag(); + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + foreach ($envPlaceholders as $env => $placeholders) { + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = 0; + } + } + return $this->envCounters; + } + /** + * @final + */ + public function log(CompilerPassInterface $pass, string $message) + { + $this->getCompiler()->log($pass, $this->resolveEnvPlaceholders($message)); + } + /** + * Checks whether a class is available and will remain available in the "no-dev" mode of Composer. + * + * When parent packages are provided and if any of them is in dev-only mode, + * the class will be considered available even if it is also in dev-only mode. + * + * @throws \LogicException If dependencies have been installed with Composer 1 + */ + public static final function willBeAvailable(string $package, string $class, array $parentPackages) : bool + { + if (!\class_exists(InstalledVersions::class)) { + throw new \LogicException(\sprintf('Calling "%s" when dependencies have been installed with Composer 1 is not supported. Consider upgrading to Composer 2.', __METHOD__)); + } + if (!\class_exists($class) && !\interface_exists($class, \false) && !\trait_exists($class, \false)) { + return \false; + } + if (!InstalledVersions::isInstalled($package) || InstalledVersions::isInstalled($package, \false)) { + return \true; + } + // the package is installed but in dev-mode only, check if this applies to one of the parent packages too + $rootPackage = InstalledVersions::getRootPackage()['name'] ?? ''; + if ('symfony/symfony' === $rootPackage) { + return \true; + } + foreach ($parentPackages as $parentPackage) { + if ($rootPackage === $parentPackage || InstalledVersions::isInstalled($parentPackage) && !InstalledVersions::isInstalled($parentPackage, \false)) { + return \true; + } + } + return \false; + } + /** + * Gets removed binding ids. + * + * @return array + * + * @internal + */ + public function getRemovedBindingIds() : array + { + return $this->removedBindingIds; + } + /** + * Removes bindings for a service. + * + * @internal + */ + public function removeBindings(string $id) + { + if ($this->hasDefinition($id)) { + foreach ($this->getDefinition($id)->getBindings() as $key => $binding) { + [, $bindingId] = $binding->getValues(); + $this->removedBindingIds[(int) $bindingId] = \true; + } + } + } + /** + * @return string[] + * + * @internal + * @param mixed $value + */ + public static function getServiceConditionals($value) : array + { + $services = []; + if (\is_array($value)) { + foreach ($value as $v) { + $services = \array_unique(\array_merge($services, self::getServiceConditionals($v))); + } + } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) { + $services[] = (string) $value; + } + return $services; + } + /** + * @return string[] + * + * @internal + * @param mixed $value + */ + public static function getInitializedConditionals($value) : array + { + $services = []; + if (\is_array($value)) { + foreach ($value as $v) { + $services = \array_unique(\array_merge($services, self::getInitializedConditionals($v))); + } + } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()) { + $services[] = (string) $value; + } + return $services; + } + /** + * Computes a reasonably unique hash of a serializable value. + * @param mixed $value + */ + public static function hash($value) : string + { + $hash = \substr(\base64_encode(\hash('sha256', \serialize($value), \true)), 0, 7); + return \str_replace(['/', '+'], ['.', '_'], $hash); + } + /** + * {@inheritdoc} + * @return mixed + */ + protected function getEnv(string $name) + { + $value = parent::getEnv($name); + $bag = $this->getParameterBag(); + if (!\is_string($value) || !$bag instanceof EnvPlaceholderParameterBag) { + return $value; + } + $envPlaceholders = $bag->getEnvPlaceholders(); + if (isset($envPlaceholders[$name][$value])) { + $bag = new ParameterBag($bag->all()); + return $bag->unescapeValue($bag->get("env({$name})")); + } + foreach ($envPlaceholders as $env => $placeholders) { + if (isset($placeholders[$value])) { + return $this->getEnv($env); + } + } + $this->resolving["env({$name})"] = \true; + try { + return $bag->unescapeValue($this->resolveEnvPlaceholders($bag->escapeValue($value), \true)); + } finally { + unset($this->resolving["env({$name})"]); + } + } + /** + * @return mixed + */ + private function callMethod(object $service, array $call, array &$inlineServices) + { + foreach (self::getServiceConditionals($call[1]) as $s) { + if (!$this->has($s)) { + return $service; + } + } + foreach (self::getInitializedConditionals($call[1]) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) { + return $service; + } + } + $result = $service->{$call[0]}(...$this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlineServices)); + return empty($call[2]) ? $service : $result; + } + /** + * @param mixed $service + */ + private function shareService(Definition $definition, $service, ?string $id, array &$inlineServices) + { + $inlineServices[$id ?? \spl_object_hash($definition)] = $service; + if (null !== $id && $definition->isShared()) { + if ($definition->isPrivate() && $this->isCompiled()) { + $this->privates[$id] = $service; + } else { + $this->services[$id] = $service; + } + unset($this->loading[$id]); + } + } + private function getExpressionLanguage() : ExpressionLanguage + { + if (!isset($this->expressionLanguage)) { + if (!\class_exists(Expression::class)) { + throw new LogicException('Expressions cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); + } + $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders, null, \Closure::fromCallable([$this, 'getEnv'])); + } + return $this->expressionLanguage; + } + private function inVendors(string $path) : bool + { + $this->vendors = $this->vendors ?? (new ComposerResource())->getVendors(); + $path = \realpath($path) ?: $path; + foreach ($this->vendors as $vendor) { + if (\strncmp($path, $vendor, \strlen($vendor)) === 0 && \false !== \strpbrk(\substr($path, \strlen($vendor), 1), '/' . \DIRECTORY_SEPARATOR)) { + $this->addResource(new FileResource($vendor . '/composer/installed.json')); + return \true; + } + } + return \false; + } +} diff --git a/vendor/symfony/dependency-injection/ContainerInterface.php b/vendor/symfony/dependency-injection/ContainerInterface.php new file mode 100644 index 0000000000..e9c702d0b1 --- /dev/null +++ b/vendor/symfony/dependency-injection/ContainerInterface.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface as PsrContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +/** + * ContainerInterface is the interface implemented by service container classes. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +interface ContainerInterface extends PsrContainerInterface +{ + public const RUNTIME_EXCEPTION_ON_INVALID_REFERENCE = 0; + public const EXCEPTION_ON_INVALID_REFERENCE = 1; + public const NULL_ON_INVALID_REFERENCE = 2; + public const IGNORE_ON_INVALID_REFERENCE = 3; + public const IGNORE_ON_UNINITIALIZED_REFERENCE = 4; + public function set(string $id, ?object $service); + /** + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * + * @see Reference + */ + public function get(string $id, int $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) : ?object; + public function has(string $id) : bool; + /** + * Check for whether or not a service has been initialized. + */ + public function initialized(string $id) : bool; + /** + * @return array|bool|string|int|float|\UnitEnum|null + * + * @throws InvalidArgumentException if the parameter is not defined + */ + public function getParameter(string $name); + public function hasParameter(string $name) : bool; + /** + * @param mixed[]|bool|string|int|float|\UnitEnum|null $value + */ + public function setParameter(string $name, $value); +} diff --git a/vendor/symfony/dependency-injection/Definition.php b/vendor/symfony/dependency-injection/Definition.php new file mode 100644 index 0000000000..6a4eea6a98 --- /dev/null +++ b/vendor/symfony/dependency-injection/Definition.php @@ -0,0 +1,762 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\BoundArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; +/** + * Definition represents a service definition. + * + * @author Fabien Potencier + */ +class Definition +{ + private const DEFAULT_DEPRECATION_TEMPLATE = 'The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.'; + /** + * @var string|null + */ + private $class; + /** + * @var string|null + */ + private $file; + /** + * @var string|mixed[]|null + */ + private $factory = null; + /** + * @var bool + */ + private $shared = \true; + /** + * @var mixed[] + */ + private $deprecation = []; + /** + * @var mixed[] + */ + private $properties = []; + /** + * @var mixed[] + */ + private $calls = []; + /** + * @var mixed[] + */ + private $instanceof = []; + /** + * @var bool + */ + private $autoconfigured = \false; + /** + * @var string|mixed[]|null + */ + private $configurator = null; + /** + * @var mixed[] + */ + private $tags = []; + /** + * @var bool + */ + private $public = \false; + /** + * @var bool + */ + private $synthetic = \false; + /** + * @var bool + */ + private $abstract = \false; + /** + * @var bool + */ + private $lazy = \false; + /** + * @var mixed[]|null + */ + private $decoratedService; + /** + * @var bool + */ + private $autowired = \false; + /** + * @var mixed[] + */ + private $changes = []; + /** + * @var mixed[] + */ + private $bindings = []; + /** + * @var mixed[] + */ + private $errors = []; + protected $arguments = []; + /** + * @internal + * + * Used to store the name of the inner id when using service decoration together with autowiring + * @var string|null + */ + public $innerServiceId; + /** + * @internal + * + * Used to store the behavior to follow when using service decoration and the decorated service is invalid + * @var int|null + */ + public $decorationOnInvalid; + public function __construct(string $class = null, array $arguments = []) + { + if (null !== $class) { + $this->setClass($class); + } + $this->arguments = $arguments; + } + /** + * Returns all changes tracked for the Definition object. + */ + public function getChanges() : array + { + return $this->changes; + } + /** + * Sets the tracked changes for the Definition object. + * + * @param array $changes An array of changes for this Definition + * + * @return $this + */ + public function setChanges(array $changes) + { + $this->changes = $changes; + return $this; + } + /** + * Sets a factory. + * + * @param string|array|Reference|null $factory A PHP function, reference or an array containing a class/Reference and a method to call + * + * @return $this + */ + public function setFactory($factory) + { + $this->changes['factory'] = \true; + if (\is_string($factory) && \strpos($factory, '::') !== \false) { + $factory = \explode('::', $factory, 2); + } elseif ($factory instanceof Reference) { + $factory = [$factory, '__invoke']; + } + $this->factory = $factory; + return $this; + } + /** + * Gets the factory. + * + * @return string|array|null The PHP function or an array containing a class/Reference and a method to call + */ + public function getFactory() + { + return $this->factory; + } + /** + * Sets the service that this service is decorating. + * + * @param string|null $id The decorated service id, use null to remove decoration + * @param string|null $renamedId The new decorated service id + * + * @return $this + * + * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals + */ + public function setDecoratedService(?string $id, string $renamedId = null, int $priority = 0, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + if ($renamedId && $id === $renamedId) { + throw new InvalidArgumentException(\sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id)); + } + $this->changes['decorated_service'] = \true; + if (null === $id) { + $this->decoratedService = null; + } else { + $this->decoratedService = [$id, $renamedId, $priority]; + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { + $this->decoratedService[] = $invalidBehavior; + } + } + return $this; + } + /** + * Gets the service that this service is decorating. + * + * @return array|null An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated + */ + public function getDecoratedService() : ?array + { + return $this->decoratedService; + } + /** + * Sets the service class. + * + * @return $this + */ + public function setClass(?string $class) + { + $this->changes['class'] = \true; + $this->class = $class; + return $this; + } + /** + * Gets the service class. + */ + public function getClass() : ?string + { + return $this->class; + } + /** + * Sets the arguments to pass to the service constructor/factory method. + * + * @return $this + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + return $this; + } + /** + * Sets the properties to define when creating the service. + * + * @return $this + */ + public function setProperties(array $properties) + { + $this->properties = $properties; + return $this; + } + /** + * Gets the properties to define when creating the service. + */ + public function getProperties() : array + { + return $this->properties; + } + /** + * Sets a specific property. + * + * @return $this + * @param mixed $value + */ + public function setProperty(string $name, $value) + { + $this->properties[$name] = $value; + return $this; + } + /** + * Adds an argument to pass to the service constructor/factory method. + * + * @return $this + * @param mixed $argument + */ + public function addArgument($argument) + { + $this->arguments[] = $argument; + return $this; + } + /** + * Replaces a specific argument. + * + * @return $this + * + * @throws OutOfBoundsException When the replaced argument does not exist + * @param int|string $index + * @param mixed $argument + */ + public function replaceArgument($index, $argument) + { + if (0 === \count($this->arguments)) { + throw new OutOfBoundsException(\sprintf('Cannot replace arguments for class "%s" if none have been configured yet.', $this->class)); + } + if (\is_int($index) && ($index < 0 || $index > \count($this->arguments) - 1)) { + throw new OutOfBoundsException(\sprintf('The index "%d" is not in the range [0, %d] of the arguments of class "%s".', $index, \count($this->arguments) - 1, $this->class)); + } + if (!\array_key_exists($index, $this->arguments)) { + throw new OutOfBoundsException(\sprintf('The argument "%s" doesn\'t exist in class "%s".', $index, $this->class)); + } + $this->arguments[$index] = $argument; + return $this; + } + /** + * Sets a specific argument. + * + * @return $this + * @param int|string $key + * @param mixed $value + */ + public function setArgument($key, $value) + { + $this->arguments[$key] = $value; + return $this; + } + /** + * Gets the arguments to pass to the service constructor/factory method. + */ + public function getArguments() : array + { + return $this->arguments; + } + /** + * Gets an argument to pass to the service constructor/factory method. + * + * @throws OutOfBoundsException When the argument does not exist + * @param int|string $index + * @return mixed + */ + public function getArgument($index) + { + if (!\array_key_exists($index, $this->arguments)) { + throw new OutOfBoundsException(\sprintf('The argument "%s" doesn\'t exist in class "%s".', $index, $this->class)); + } + return $this->arguments[$index]; + } + /** + * Sets the methods to call after service initialization. + * + * @return $this + */ + public function setMethodCalls(array $calls = []) + { + $this->calls = []; + foreach ($calls as $call) { + $this->addMethodCall($call[0], $call[1], $call[2] ?? \false); + } + return $this; + } + /** + * Adds a method to call after service initialization. + * + * @param string $method The method name to call + * @param array $arguments An array of arguments to pass to the method call + * @param bool $returnsClone Whether the call returns the service instance or not + * + * @return $this + * + * @throws InvalidArgumentException on empty $method param + */ + public function addMethodCall(string $method, array $arguments = [], bool $returnsClone = \false) + { + if (empty($method)) { + throw new InvalidArgumentException('Method name cannot be empty.'); + } + $this->calls[] = $returnsClone ? [$method, $arguments, \true] : [$method, $arguments]; + return $this; + } + /** + * Removes a method to call after service initialization. + * + * @return $this + */ + public function removeMethodCall(string $method) + { + foreach ($this->calls as $i => $call) { + if ($call[0] === $method) { + unset($this->calls[$i]); + } + } + return $this; + } + /** + * Check if the current definition has a given method to call after service initialization. + */ + public function hasMethodCall(string $method) : bool + { + foreach ($this->calls as $call) { + if ($call[0] === $method) { + return \true; + } + } + return \false; + } + /** + * Gets the methods to call after service initialization. + */ + public function getMethodCalls() : array + { + return $this->calls; + } + /** + * Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. + * + * @param ChildDefinition[] $instanceof + * + * @return $this + */ + public function setInstanceofConditionals(array $instanceof) + { + $this->instanceof = $instanceof; + return $this; + } + /** + * Gets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. + * + * @return ChildDefinition[] + */ + public function getInstanceofConditionals() : array + { + return $this->instanceof; + } + /** + * Sets whether or not instanceof conditionals should be prepended with a global set. + * + * @return $this + */ + public function setAutoconfigured(bool $autoconfigured) + { + $this->changes['autoconfigured'] = \true; + $this->autoconfigured = $autoconfigured; + return $this; + } + public function isAutoconfigured() : bool + { + return $this->autoconfigured; + } + /** + * Sets tags for this definition. + * + * @return $this + */ + public function setTags(array $tags) + { + $this->tags = $tags; + return $this; + } + /** + * Returns all tags. + */ + public function getTags() : array + { + return $this->tags; + } + /** + * Gets a tag by name. + */ + public function getTag(string $name) : array + { + return $this->tags[$name] ?? []; + } + /** + * Adds a tag for this definition. + * + * @return $this + */ + public function addTag(string $name, array $attributes = []) + { + $this->tags[$name][] = $attributes; + return $this; + } + /** + * Whether this definition has a tag with the given name. + */ + public function hasTag(string $name) : bool + { + return isset($this->tags[$name]); + } + /** + * Clears all tags for a given name. + * + * @return $this + */ + public function clearTag(string $name) + { + unset($this->tags[$name]); + return $this; + } + /** + * Clears the tags for this definition. + * + * @return $this + */ + public function clearTags() + { + $this->tags = []; + return $this; + } + /** + * Sets a file to require before creating the service. + * + * @return $this + */ + public function setFile(?string $file) + { + $this->changes['file'] = \true; + $this->file = $file; + return $this; + } + /** + * Gets the file to require before creating the service. + */ + public function getFile() : ?string + { + return $this->file; + } + /** + * Sets if the service must be shared or not. + * + * @return $this + */ + public function setShared(bool $shared) + { + $this->changes['shared'] = \true; + $this->shared = $shared; + return $this; + } + /** + * Whether this service is shared. + */ + public function isShared() : bool + { + return $this->shared; + } + /** + * Sets the visibility of this service. + * + * @return $this + */ + public function setPublic(bool $boolean) + { + $this->changes['public'] = \true; + $this->public = $boolean; + return $this; + } + /** + * Whether this service is public facing. + */ + public function isPublic() : bool + { + return $this->public; + } + /** + * Whether this service is private. + */ + public function isPrivate() : bool + { + return !$this->public; + } + /** + * Sets the lazy flag of this service. + * + * @return $this + */ + public function setLazy(bool $lazy) + { + $this->changes['lazy'] = \true; + $this->lazy = $lazy; + return $this; + } + /** + * Whether this service is lazy. + */ + public function isLazy() : bool + { + return $this->lazy; + } + /** + * Sets whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @return $this + */ + public function setSynthetic(bool $boolean) + { + $this->synthetic = $boolean; + if (!isset($this->changes['public'])) { + $this->setPublic(\true); + } + return $this; + } + /** + * Whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + */ + public function isSynthetic() : bool + { + return $this->synthetic; + } + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @return $this + */ + public function setAbstract(bool $boolean) + { + $this->abstract = $boolean; + return $this; + } + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + */ + public function isAbstract() : bool + { + return $this->abstract; + } + /** + * Whether this definition is deprecated, that means it should not be called + * anymore. + * + * @param string $package The name of the composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message The deprecation message to use + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + public function setDeprecated(string $package, string $version, string $message) + { + if ('' !== $message) { + if (\preg_match('#[\\r\\n]|\\*/#', $message)) { + throw new InvalidArgumentException('Invalid characters found in deprecation template.'); + } + if (\strpos($message, '%service_id%') === \false) { + throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.'); + } + } + $this->changes['deprecated'] = \true; + $this->deprecation = ['package' => $package, 'version' => $version, 'message' => $message ?: self::DEFAULT_DEPRECATION_TEMPLATE]; + return $this; + } + /** + * Whether this definition is deprecated, that means it should not be called + * anymore. + */ + public function isDeprecated() : bool + { + return (bool) $this->deprecation; + } + /** + * @param string $id Service id relying on this definition + */ + public function getDeprecation(string $id) : array + { + return ['package' => $this->deprecation['package'], 'version' => $this->deprecation['version'], 'message' => \str_replace('%service_id%', $id, $this->deprecation['message'])]; + } + /** + * Sets a configurator to call after the service is fully initialized. + * + * @param string|array|Reference|null $configurator A PHP function, reference or an array containing a class/Reference and a method to call + * + * @return $this + */ + public function setConfigurator($configurator) + { + $this->changes['configurator'] = \true; + if (\is_string($configurator) && \strpos($configurator, '::') !== \false) { + $configurator = \explode('::', $configurator, 2); + } elseif ($configurator instanceof Reference) { + $configurator = [$configurator, '__invoke']; + } + $this->configurator = $configurator; + return $this; + } + /** + * Gets the configurator to call after the service is fully initialized. + * @return string|mixed[]|null + */ + public function getConfigurator() + { + return $this->configurator; + } + /** + * Is the definition autowired? + */ + public function isAutowired() : bool + { + return $this->autowired; + } + /** + * Enables/disables autowiring. + * + * @return $this + */ + public function setAutowired(bool $autowired) + { + $this->changes['autowired'] = \true; + $this->autowired = $autowired; + return $this; + } + /** + * Gets bindings. + * + * @return BoundArgument[] + */ + public function getBindings() : array + { + return $this->bindings; + } + /** + * Sets bindings. + * + * Bindings map $named or FQCN arguments to values that should be + * injected in the matching parameters (of the constructor, of methods + * called and of controller actions). + * + * @return $this + */ + public function setBindings(array $bindings) + { + foreach ($bindings as $key => $binding) { + if (0 < \strpos($key, '$') && $key !== ($k = \preg_replace('/[ \\t]*\\$/', ' $', $key))) { + unset($bindings[$key]); + $bindings[$key = $k] = $binding; + } + if (!$binding instanceof BoundArgument) { + $bindings[$key] = new BoundArgument($binding); + } + } + $this->bindings = $bindings; + return $this; + } + /** + * Add an error that occurred when building this Definition. + * + * @return $this + * @param string|\Closure|\Symfony\Component\DependencyInjection\Definition $error + */ + public function addError($error) + { + if ($error instanceof self) { + $this->errors = \array_merge($this->errors, $error->errors); + } else { + $this->errors[] = $error; + } + return $this; + } + /** + * Returns any errors that occurred while building this Definition. + */ + public function getErrors() : array + { + foreach ($this->errors as $i => $error) { + if ($error instanceof \Closure) { + $this->errors[$i] = (string) $error(); + } elseif (!\is_string($error)) { + $this->errors[$i] = (string) $error; + } + } + return $this->errors; + } + public function hasErrors() : bool + { + return (bool) $this->errors; + } +} diff --git a/vendor/symfony/dependency-injection/Dumper/Dumper.php b/vendor/symfony/dependency-injection/Dumper/Dumper.php new file mode 100644 index 0000000000..f6dcf839dd --- /dev/null +++ b/vendor/symfony/dependency-injection/Dumper/Dumper.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Dumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * Dumper is the abstract class for all built-in dumpers. + * + * @author Fabien Potencier + */ +abstract class Dumper implements DumperInterface +{ + protected $container; + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } +} diff --git a/vendor/symfony/dependency-injection/Dumper/DumperInterface.php b/vendor/symfony/dependency-injection/Dumper/DumperInterface.php new file mode 100644 index 0000000000..dd1c75be62 --- /dev/null +++ b/vendor/symfony/dependency-injection/Dumper/DumperInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Dumper; + +/** + * DumperInterface is the interface implemented by service container dumper classes. + * + * @author Fabien Potencier + */ +interface DumperInterface +{ + /** + * Dumps the service container. + * @return string|mixed[] + */ + public function dump(array $options = []); +} diff --git a/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php b/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php new file mode 100644 index 0000000000..57dd890810 --- /dev/null +++ b/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php @@ -0,0 +1,202 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Dumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Parameter; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +/** + * GraphvizDumper dumps a service container as a graphviz file. + * + * You can convert the generated dot file with the dot utility (http://www.graphviz.org/): + * + * dot -Tpng container.dot > foo.png + * + * @author Fabien Potencier + */ +class GraphvizDumper extends Dumper +{ + /** + * @var mixed[] + */ + private $nodes; + /** + * @var mixed[] + */ + private $edges; + // All values should be strings + /** + * @var mixed[] + */ + private $options = ['graph' => ['ratio' => 'compress'], 'node' => ['fontsize' => '11', 'fontname' => 'Arial', 'shape' => 'record'], 'edge' => ['fontsize' => '9', 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => '0.5'], 'node.instance' => ['fillcolor' => '#9999ff', 'style' => 'filled'], 'node.definition' => ['fillcolor' => '#eeeeee'], 'node.missing' => ['fillcolor' => '#ff9999', 'style' => 'filled']]; + /** + * Dumps the service container as a graphviz graph. + * + * Available options: + * + * * graph: The default options for the whole graph + * * node: The default options for nodes + * * edge: The default options for edges + * * node.instance: The default options for services that are defined directly by object instances + * * node.definition: The default options for services that are defined via service definition instances + * * node.missing: The default options for missing services + */ + public function dump(array $options = []) : string + { + foreach (['graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing'] as $key) { + if (isset($options[$key])) { + $this->options[$key] = \array_merge($this->options[$key], $options[$key]); + } + } + $this->nodes = $this->findNodes(); + $this->edges = []; + foreach ($this->container->getDefinitions() as $id => $definition) { + $this->edges[$id] = \array_merge($this->findEdges($id, $definition->getArguments(), \true, ''), $this->findEdges($id, $definition->getProperties(), \false, '')); + foreach ($definition->getMethodCalls() as $call) { + $this->edges[$id] = \array_merge($this->edges[$id], $this->findEdges($id, $call[1], \false, $call[0] . '()')); + } + } + return $this->container->resolveEnvPlaceholders($this->startDot() . $this->addNodes() . $this->addEdges() . $this->endDot(), '__ENV_%s__'); + } + private function addNodes() : string + { + $code = ''; + foreach ($this->nodes as $id => $node) { + $aliases = $this->getAliases($id); + $code .= \sprintf(" node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id . ($aliases ? ' (' . \implode(', ', $aliases) . ')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes'])); + } + return $code; + } + private function addEdges() : string + { + $code = ''; + foreach ($this->edges as $id => $edges) { + foreach ($edges as $edge) { + $code .= \sprintf(" node_%s -> node_%s [label=\"%s\" style=\"%s\"%s];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed', $edge['lazy'] ? ' color="#9999ff"' : ''); + } + } + return $code; + } + /** + * Finds all edges belonging to a specific service id. + */ + private function findEdges(string $id, array $arguments, bool $required, string $name, bool $lazy = \false) : array + { + $edges = []; + foreach ($arguments as $argument) { + if ($argument instanceof Parameter) { + $argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null; + } elseif (\is_string($argument) && \preg_match('/^%([^%]+)%$/', $argument, $match)) { + $argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null; + } + if ($argument instanceof Reference) { + $lazyEdge = $lazy; + if (!$this->container->has((string) $argument)) { + $this->nodes[(string) $argument] = ['name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']]; + } elseif ('service_container' !== (string) $argument) { + $lazyEdge = $lazy || $this->container->getDefinition((string) $argument)->isLazy(); + } + $edges[] = [['name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge]]; + } elseif ($argument instanceof ArgumentInterface) { + $edges[] = $this->findEdges($id, $argument->getValues(), $required, $name, \true); + } elseif ($argument instanceof Definition) { + $edges[] = $this->findEdges($id, $argument->getArguments(), $required, ''); + $edges[] = $this->findEdges($id, $argument->getProperties(), \false, ''); + foreach ($argument->getMethodCalls() as $call) { + $edges[] = $this->findEdges($id, $call[1], \false, $call[0] . '()'); + } + } elseif (\is_array($argument)) { + $edges[] = $this->findEdges($id, $argument, $required, $name, $lazy); + } + } + return \array_merge([], ...$edges); + } + private function findNodes() : array + { + $nodes = []; + $container = $this->cloneContainer(); + foreach ($container->getDefinitions() as $id => $definition) { + $class = $definition->getClass(); + if (\strncmp($class, '\\', \strlen('\\')) === 0) { + $class = \substr($class, 1); + } + try { + $class = $this->container->getParameterBag()->resolveValue($class); + } catch (ParameterNotFoundException $exception) { + } + $nodes[$id] = ['class' => \str_replace('\\', '\\\\', $class), 'attributes' => \array_merge($this->options['node.definition'], ['style' => $definition->isShared() ? 'filled' : 'dotted'])]; + $container->setDefinition($id, new Definition('stdClass')); + } + foreach ($container->getServiceIds() as $id) { + if (\array_key_exists($id, $container->getAliases())) { + continue; + } + if (!$container->hasDefinition($id)) { + $nodes[$id] = ['class' => \str_replace('\\', '\\\\', \get_class($container->get($id))), 'attributes' => $this->options['node.instance']]; + } + } + return $nodes; + } + private function cloneContainer() : ContainerBuilder + { + $parameterBag = new ParameterBag($this->container->getParameterBag()->all()); + $container = new ContainerBuilder($parameterBag); + $container->setDefinitions($this->container->getDefinitions()); + $container->setAliases($this->container->getAliases()); + $container->setResources($this->container->getResources()); + foreach ($this->container->getExtensions() as $extension) { + $container->registerExtension($extension); + } + return $container; + } + private function startDot() : string + { + return \sprintf("digraph sc {\n %s\n node [%s];\n edge [%s];\n\n", $this->addOptions($this->options['graph']), $this->addOptions($this->options['node']), $this->addOptions($this->options['edge'])); + } + private function endDot() : string + { + return "}\n"; + } + private function addAttributes(array $attributes) : string + { + $code = []; + foreach ($attributes as $k => $v) { + $code[] = \sprintf('%s="%s"', $k, $v); + } + return $code ? ', ' . \implode(', ', $code) : ''; + } + private function addOptions(array $options) : string + { + $code = []; + foreach ($options as $k => $v) { + $code[] = \sprintf('%s="%s"', $k, $v); + } + return \implode(' ', $code); + } + private function dotize(string $id) : string + { + return \preg_replace('/\\W/i', '_', $id); + } + private function getAliases(string $id) : array + { + $aliases = []; + foreach ($this->container->getAliases() as $alias => $origin) { + if ($id == $origin) { + $aliases[] = $alias; + } + } + return $aliases; + } +} diff --git a/vendor/symfony/dependency-injection/Dumper/PhpDumper.php b/vendor/symfony/dependency-injection/Dumper/PhpDumper.php new file mode 100644 index 0000000000..6a59e9b7c7 --- /dev/null +++ b/vendor/symfony/dependency-injection/Dumper/PhpDumper.php @@ -0,0 +1,1995 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Dumper; + +use MonorepoBuilderPrefix202310\Composer\Autoload\ClassLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraphNode; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Container; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\EnvParameterException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ExpressionLanguage; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\FileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Parameter; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\TypedReference; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Variable; +use MonorepoBuilderPrefix202310\Symfony\Component\ErrorHandler\DebugClassLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +use MonorepoBuilderPrefix202310\Symfony\Component\HttpKernel\Kernel; +/** + * PhpDumper dumps a service container as a PHP class. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class PhpDumper extends Dumper +{ + /** + * Characters that might appear in the generated variable name as first character. + */ + public const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz'; + /** + * Characters that might appear in the generated variable name as any but the first character. + */ + public const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; + /** @var \SplObjectStorage|null */ + private $definitionVariables; + /** + * @var mixed[]|null + */ + private $referenceVariables; + /** + * @var int + */ + private $variableCount; + /** + * @var \SplObjectStorage|null + */ + private $inlinedDefinitions; + /** + * @var mixed[]|null + */ + private $serviceCalls; + /** + * @var mixed[] + */ + private $reservedVariables = ['instance', 'class', 'this', 'container']; + /** + * @var \Symfony\Component\DependencyInjection\ExpressionLanguage + */ + private $expressionLanguage; + /** + * @var string|null + */ + private $targetDirRegex; + /** + * @var int + */ + private $targetDirMaxMatches; + /** + * @var string + */ + private $docStar; + /** + * @var mixed[] + */ + private $serviceIdToMethodNameMap; + /** + * @var mixed[] + */ + private $usedMethodNames; + /** + * @var string + */ + private $namespace; + /** + * @var bool + */ + private $asFiles; + /** + * @var string + */ + private $hotPathTag; + /** + * @var mixed[] + */ + private $preloadTags; + /** + * @var bool + */ + private $inlineFactories; + /** + * @var bool + */ + private $inlineRequires; + /** + * @var mixed[] + */ + private $inlinedRequires = []; + /** + * @var mixed[] + */ + private $circularReferences = []; + /** + * @var mixed[] + */ + private $singleUsePrivateIds = []; + /** + * @var mixed[] + */ + private $preload = []; + /** + * @var bool + */ + private $addGetService = \false; + /** + * @var mixed[] + */ + private $locatedIds = []; + /** + * @var string + */ + private $serviceLocatorTag; + /** + * @var mixed[] + */ + private $exportedVariables = []; + /** + * @var string + */ + private $baseClass; + /** + * @var \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface + */ + private $proxyDumper; + /** + * @var bool + */ + private $hasProxyDumper = \false; + /** + * {@inheritdoc} + */ + public function __construct(ContainerBuilder $container) + { + if (!$container->isCompiled()) { + throw new LogicException('Cannot dump an uncompiled container.'); + } + parent::__construct($container); + } + /** + * Sets the dumper to be used when dumping proxies in the generated container. + */ + public function setProxyDumper(DumperInterface $proxyDumper) + { + $this->proxyDumper = $proxyDumper; + $this->hasProxyDumper = !$proxyDumper instanceof NullDumper; + } + /** + * Dumps the service container as a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * * namespace: The class namespace + * * as_files: To split the container in several files + * + * @return string|array A PHP class representing the service container or an array of PHP files if the "as_files" option is set + * + * @throws EnvParameterException When an env var exists but has not been dumped + */ + public function dump(array $options = []) + { + $this->locatedIds = []; + $this->targetDirRegex = null; + $this->inlinedRequires = []; + $this->exportedVariables = []; + $options = \array_merge(['class' => 'ProjectServiceContainer', 'base_class' => 'Container', 'namespace' => '', 'as_files' => \false, 'debug' => \true, 'hot_path_tag' => 'container.hot_path', 'preload_tags' => ['container.preload', 'container.no_preload'], 'inline_factories_parameter' => 'container.dumper.inline_factories', 'inline_class_loader_parameter' => 'container.dumper.inline_class_loader', 'preload_classes' => [], 'service_locator_tag' => 'container.service_locator', 'build_time' => \time()], $options); + $this->addGetService = \false; + $this->namespace = $options['namespace']; + $this->asFiles = $options['as_files']; + $this->hotPathTag = $options['hot_path_tag']; + $this->preloadTags = $options['preload_tags']; + $this->inlineFactories = $this->asFiles && $options['inline_factories_parameter'] && $this->container->hasParameter($options['inline_factories_parameter']) && $this->container->getParameter($options['inline_factories_parameter']); + $this->inlineRequires = $options['inline_class_loader_parameter'] && ($this->container->hasParameter($options['inline_class_loader_parameter']) ? $this->container->getParameter($options['inline_class_loader_parameter']) : $options['debug']); + $this->serviceLocatorTag = $options['service_locator_tag']; + if (\strncmp($baseClass = $options['base_class'], '\\', \strlen('\\')) !== 0 && 'Container' !== $baseClass) { + $baseClass = \sprintf('%s\\%s', $options['namespace'] ? '\\' . $options['namespace'] : '', $baseClass); + $this->baseClass = $baseClass; + } elseif ('Container' === $baseClass) { + $this->baseClass = Container::class; + } else { + $this->baseClass = $baseClass; + } + $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass); + if (!$this->hasProxyDumper) { + (new AnalyzeServiceReferencesPass(\true, \false))->process($this->container); + try { + (new CheckCircularReferencesPass())->process($this->container); + } catch (ServiceCircularReferenceException $e) { + $path = $e->getPath(); + \end($path); + $path[\key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge'; + throw new ServiceCircularReferenceException($e->getServiceId(), $path); + } + } + $this->analyzeReferences(); + $this->docStar = $options['debug'] ? '*' : ''; + if (!empty($options['file']) && \is_dir($dir = \dirname($options['file']))) { + // Build a regexp where the first root dirs are mandatory, + // but every other sub-dir is optional up to the full path in $dir + // Mandate at least 1 root dir and not more than 5 optional dirs. + $dir = \explode(\DIRECTORY_SEPARATOR, \realpath($dir)); + $i = \count($dir); + if (2 + (int) ('\\' === \DIRECTORY_SEPARATOR) <= $i) { + $regex = ''; + $lastOptionalDir = $i > 8 ? $i - 5 : 2 + (int) ('\\' === \DIRECTORY_SEPARATOR); + $this->targetDirMaxMatches = $i - $lastOptionalDir; + while (--$i >= $lastOptionalDir) { + $regex = \sprintf('(%s%s)?', \preg_quote(\DIRECTORY_SEPARATOR . $dir[$i], '#'), $regex); + } + do { + $regex = \preg_quote(\DIRECTORY_SEPARATOR . $dir[$i], '#') . $regex; + } while (0 < --$i); + $this->targetDirRegex = '#(^|file://|[:;, \\|\\r\\n])' . \preg_quote($dir[0], '#') . $regex . '#'; + } + } + $proxyClasses = $this->inlineFactories ? $this->generateProxyClasses() : null; + if ($options['preload_classes']) { + $this->preload = \array_combine($options['preload_classes'], $options['preload_classes']); + } + $code = $this->startClass($options['class'], $baseClass, $this->inlineFactories && $proxyClasses) . $this->addServices($services) . $this->addDeprecatedAliases() . $this->addDefaultParametersMethod(); + $proxyClasses = $proxyClasses ?? $this->generateProxyClasses(); + if ($this->addGetService) { + $code = \preg_replace("/(\r?\n\r?\n public function __construct.+?\\{\r?\n)/s", "\n protected \\Closure \$getService;\$1 \$this->getService = \$this->getService(...);\n", $code, 1); + } + if ($this->asFiles) { + $fileTemplate = <<docStar} + * @internal This class has been auto-generated by the Symfony Dependency Injection Component. + */ +class %s extends {$options['class']} +{%s} + +EOF; + $files = []; + $preloadedFiles = []; + $ids = $this->container->getRemovedIds(); + foreach ($this->container->getDefinitions() as $id => $definition) { + if (!$definition->isPublic()) { + $ids[$id] = \true; + } + } + if ($ids = \array_keys($ids)) { + \sort($ids); + $c = "doExport($id) . " => true,\n"; + } + $files['removed-ids.php'] = $c . "];\n"; + } + if (!$this->inlineFactories) { + foreach ($this->generateServiceFiles($services) as $file => [$c, $preload]) { + $files[$file] = \sprintf($fileTemplate, \substr($file, 0, -4), $c); + if ($preload) { + $preloadedFiles[$file] = $file; + } + } + foreach ($proxyClasses as $file => $c) { + $files[$file] = "endClass(); + if ($this->inlineFactories && $proxyClasses) { + $files['proxy-classes.php'] = " $c) { + $code["Container{$hash}/{$file}"] = \substr_replace($c, "namespace ? "\nnamespace {$this->namespace};\n" : ''; + $time = $options['build_time']; + $id = \hash('crc32', $hash . $time); + $this->asFiles = \false; + if ($this->preload && null !== ($autoloadFile = $this->getAutoloadFile())) { + $autoloadFile = \trim($this->export($autoloadFile), '()\\'); + $preloadedFiles = \array_reverse($preloadedFiles); + if ('' !== ($preloadedFiles = \implode("';\nrequire __DIR__.'/", $preloadedFiles))) { + $preloadedFiles = "require __DIR__.'/{$preloadedFiles}';\n"; + } + $code[$options['class'] . '.preload.php'] = <<= 7.4 when preloading is desired + +use MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Dumper\\Preloader; + +if (in_array(PHP_SAPI, ['cli', 'phpdbg'], true)) { + return; +} + +require {$autoloadFile}; +(require __DIR__.'/{$options['class']}.php')->set(\\Container{$hash}\\{$options['class']}::class, null); +{$preloadedFiles} +\$classes = []; + +EOF; + foreach ($this->preload as $class) { + if (!$class || \strpos($class, '$') !== \false || \in_array($class, ['int', 'float', 'string', 'bool', 'resource', 'object', 'array', 'null', 'callable', 'iterable', 'mixed', 'void'], \true)) { + continue; + } + if (!(\class_exists($class, \false) || \interface_exists($class, \false) || \trait_exists($class, \false)) || (new \ReflectionClass($class))->isUserDefined()) { + $code[$options['class'] . '.preload.php'] .= \sprintf("\$classes[] = '%s';\n", $class); + } + } + $code[$options['class'] . '.preload.php'] .= <<<'EOF' + +$preloaded = Preloader::preload($classes); + +EOF; + } + $code[$options['class'] . '.php'] = << '{$hash}', + 'container.build_id' => '{$id}', + 'container.build_time' => {$time}, +], __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}'); + +EOF; + } else { + $code .= $this->endClass(); + foreach ($proxyClasses as $c) { + $code .= $c; + } + } + $this->targetDirRegex = null; + $this->inlinedRequires = []; + $this->circularReferences = []; + $this->locatedIds = []; + $this->exportedVariables = []; + $this->preload = []; + $unusedEnvs = []; + foreach ($this->container->getEnvCounters() as $env => $use) { + if (!$use) { + $unusedEnvs[] = $env; + } + } + if ($unusedEnvs) { + throw new EnvParameterException($unusedEnvs, null, 'Environment variables "%s" are never used. Please, check your container\'s configuration.'); + } + return $code; + } + /** + * Retrieves the currently set proxy dumper or instantiates one. + */ + private function getProxyDumper() : DumperInterface + { + return $this->proxyDumper = $this->proxyDumper ?? new NullDumper(); + } + private function analyzeReferences() + { + (new AnalyzeServiceReferencesPass(\false, $this->hasProxyDumper))->process($this->container); + $checkedNodes = []; + $this->circularReferences = []; + $this->singleUsePrivateIds = []; + foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { + if (!$node->getValue() instanceof Definition) { + continue; + } + if ($this->isSingleUsePrivateNode($node)) { + $this->singleUsePrivateIds[$id] = $id; + } + $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes); + } + $this->container->getCompiler()->getServiceReferenceGraph()->clear(); + $this->singleUsePrivateIds = \array_diff_key($this->singleUsePrivateIds, $this->circularReferences); + } + private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$loops = [], array $path = [], bool $byConstructor = \true) : void + { + $path[$sourceId] = $byConstructor; + $checkedNodes[$sourceId] = \true; + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $id = $node->getId(); + if ($sourceId === $id || !$node->getValue() instanceof Definition || $edge->isWeak()) { + continue; + } + if (isset($path[$id])) { + $loop = null; + $loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy(); + $pathInLoop = [$id, []]; + foreach ($path as $k => $pathByConstructor) { + if (null !== $loop) { + $loop[] = $k; + $pathInLoop[1][$k] = $pathByConstructor; + $loops[$k][] =& $pathInLoop; + $loopByConstructor = $loopByConstructor && $pathByConstructor; + } elseif ($k === $id) { + $loop = []; + } + } + $this->addCircularReferences($id, $loop, $loopByConstructor); + } elseif (!isset($checkedNodes[$id])) { + $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $loops, $path, $edge->isReferencedByConstructor() && !$edge->isLazy()); + } elseif (isset($loops[$id])) { + // we already had detected loops for this edge + // let's check if we have a common ancestor in one of the detected loops + foreach ($loops[$id] as [$first, $loopPath]) { + if (!isset($path[$first])) { + continue; + } + // We have a common ancestor, let's fill the current path + $fillPath = null; + foreach ($loopPath as $k => $pathByConstructor) { + if (null !== $fillPath) { + $fillPath[$k] = $pathByConstructor; + } elseif ($k === $id) { + $fillPath = $path; + $fillPath[$k] = $pathByConstructor; + } + } + // we can now build the loop + $loop = null; + $loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy(); + foreach ($fillPath as $k => $pathByConstructor) { + if (null !== $loop) { + $loop[] = $k; + $loopByConstructor = $loopByConstructor && $pathByConstructor; + } elseif ($k === $first) { + $loop = []; + } + } + $this->addCircularReferences($first, $loop, $loopByConstructor); + break; + } + } + } + unset($path[$sourceId]); + } + private function addCircularReferences(string $sourceId, array $currentPath, bool $byConstructor) + { + $currentId = $sourceId; + $currentPath = \array_reverse($currentPath); + $currentPath[] = $currentId; + foreach ($currentPath as $parentId) { + if (empty($this->circularReferences[$parentId][$currentId])) { + $this->circularReferences[$parentId][$currentId] = $byConstructor; + } + $currentId = $parentId; + } + } + private function collectLineage(string $class, array &$lineage) + { + if (isset($lineage[$class])) { + return; + } + if (!($r = $this->container->getReflectionClass($class, \false))) { + return; + } + if (\is_a($class, $this->baseClass, \true)) { + return; + } + $file = $r->getFileName(); + if (\substr_compare($file, ') : eval()\'d code', -\strlen(') : eval()\'d code')) === 0) { + $file = \substr($file, 0, \strrpos($file, '(', -17)); + } + if (!$file || $this->doExport($file) === ($exportedFile = $this->export($file))) { + return; + } + $lineage[$class] = \substr($exportedFile, 1, -1); + if ($parent = $r->getParentClass()) { + $this->collectLineage($parent->name, $lineage); + } + foreach ($r->getInterfaces() as $parent) { + $this->collectLineage($parent->name, $lineage); + } + foreach ($r->getTraits() as $parent) { + $this->collectLineage($parent->name, $lineage); + } + unset($lineage[$class]); + $lineage[$class] = \substr($exportedFile, 1, -1); + } + private function generateProxyClasses() : array + { + $proxyClasses = []; + $alreadyGenerated = []; + $definitions = $this->container->getDefinitions(); + $strip = '' === $this->docStar && \method_exists(Kernel::class, 'stripComments'); + $proxyDumper = $this->getProxyDumper(); + \ksort($definitions); + foreach ($definitions as $definition) { + if (!$proxyDumper->isProxyCandidate($definition)) { + continue; + } + if (isset($alreadyGenerated[$class = $definition->getClass()])) { + continue; + } + $alreadyGenerated[$class] = \true; + // register class' reflector for resource tracking + $this->container->getReflectionClass($class); + if ("\n" === ($proxyCode = "\n" . $proxyDumper->getProxyCode($definition))) { + continue; + } + if ($this->inlineRequires) { + $lineage = []; + $this->collectLineage($class, $lineage); + $code = ''; + foreach (\array_diff_key(\array_flip($lineage), $this->inlinedRequires) as $file => $class) { + if ($this->inlineFactories) { + $this->inlinedRequires[$file] = \true; + } + $code .= \sprintf("include_once %s;\n", $file); + } + $proxyCode = $code . $proxyCode; + } + if ($strip) { + $proxyCode = "inlineRequires ? \substr($proxyCode, \strlen($code)) : $proxyCode, 3)[1]; + if ($this->asFiles || $this->namespace) { + $proxyCode .= "\nif (!\\class_exists('{$proxyClass}', false)) {\n \\class_alias(__NAMESPACE__.'\\\\{$proxyClass}', '{$proxyClass}', false);\n}\n"; + } + $proxyClasses[$proxyClass . '.php'] = $proxyCode; + } + return $proxyClasses; + } + private function addServiceInclude(string $cId, Definition $definition) : string + { + $code = ''; + if ($this->inlineRequires && (!$this->isHotPath($definition) || $this->getProxyDumper()->isProxyCandidate($definition))) { + $lineage = []; + foreach ($this->inlinedDefinitions as $def) { + if (!$def->isDeprecated()) { + foreach ($this->getClasses($def, $cId) as $class) { + $this->collectLineage($class, $lineage); + } + } + } + foreach ($this->serviceCalls as $id => [$callCount, $behavior]) { + if ('service_container' !== $id && $id !== $cId && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior && $this->container->has($id) && $this->isTrivialInstance($def = $this->container->findDefinition($id))) { + foreach ($this->getClasses($def, $cId) as $class) { + $this->collectLineage($class, $lineage); + } + } + } + foreach (\array_diff_key(\array_flip($lineage), $this->inlinedRequires) as $file => $class) { + $code .= \sprintf(" include_once %s;\n", $file); + } + } + foreach ($this->inlinedDefinitions as $def) { + if ($file = $def->getFile()) { + $file = $this->dumpValue($file); + $file = '(' === $file[0] ? \substr($file, 1, -1) : $file; + $code .= \sprintf(" include_once %s;\n", $file); + } + } + if ('' !== $code) { + $code .= "\n"; + } + return $code; + } + /** + * @throws InvalidArgumentException + * @throws RuntimeException + */ + private function addServiceInstance(string $id, Definition $definition, bool $isSimpleInstance) : string + { + $class = $this->dumpValue($definition->getClass()); + if (\strncmp($class, "'", \strlen("'")) === 0 && \strpos($class, '$') === \false && !\preg_match('/^\'(?:\\\\{2})?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?:\\\\{2}[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)*\'$/', $class)) { + throw new InvalidArgumentException(\sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); + } + $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition); + $instantiation = ''; + $lastWitherIndex = null; + foreach ($definition->getMethodCalls() as $k => $call) { + if ($call[2] ?? \false) { + $lastWitherIndex = $k; + } + } + if (!$isProxyCandidate && $definition->isShared() && !isset($this->singleUsePrivateIds[$id]) && null === $lastWitherIndex) { + $instantiation = \sprintf('$this->%s[%s] = %s', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $this->doExport($id), $isSimpleInstance ? '' : '$instance'); + } elseif (!$isSimpleInstance) { + $instantiation = '$instance'; + } + $return = ''; + if ($isSimpleInstance) { + $return = 'return '; + } else { + $instantiation .= ' = '; + } + return $this->addNewInstance($definition, ' ' . $return . $instantiation, $id); + } + private function isTrivialInstance(Definition $definition) : bool + { + if ($definition->hasErrors()) { + return \true; + } + if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) { + return \false; + } + if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < \count($definition->getArguments())) { + return \false; + } + foreach ($definition->getArguments() as $arg) { + if (!$arg || $arg instanceof Parameter) { + continue; + } + if (\is_array($arg) && 3 >= \count($arg)) { + foreach ($arg as $k => $v) { + if ($this->dumpValue($k) !== $this->dumpValue($k, \false)) { + return \false; + } + if (!$v || $v instanceof Parameter) { + continue; + } + if ($v instanceof Reference && $this->container->has($id = (string) $v) && $this->container->findDefinition($id)->isSynthetic()) { + continue; + } + if (!\is_scalar($v) || $this->dumpValue($v) !== $this->dumpValue($v, \false)) { + return \false; + } + } + } elseif ($arg instanceof Reference && $this->container->has($id = (string) $arg) && $this->container->findDefinition($id)->isSynthetic()) { + continue; + } elseif (!\is_scalar($arg) || $this->dumpValue($arg) !== $this->dumpValue($arg, \false)) { + return \false; + } + } + return \true; + } + private function addServiceMethodCalls(Definition $definition, string $variableName, ?string $sharedNonLazyId) : string + { + $lastWitherIndex = null; + foreach ($definition->getMethodCalls() as $k => $call) { + if ($call[2] ?? \false) { + $lastWitherIndex = $k; + } + } + $calls = ''; + foreach ($definition->getMethodCalls() as $k => $call) { + $arguments = []; + foreach ($call[1] as $i => $value) { + $arguments[] = (\is_string($i) ? $i . ': ' : '') . $this->dumpValue($value); + } + $witherAssignation = ''; + if ($call[2] ?? \false) { + if (null !== $sharedNonLazyId && $lastWitherIndex === $k && 'instance' === $variableName) { + $witherAssignation = \sprintf('$this->%s[\'%s\'] = ', $definition->isPublic() ? 'services' : 'privates', $sharedNonLazyId); + } + $witherAssignation .= \sprintf('$%s = ', $variableName); + } + $calls .= $this->wrapServiceConditionals($call[1], \sprintf(" %s\$%s->%s(%s);\n", $witherAssignation, $variableName, $call[0], \implode(', ', $arguments))); + } + return $calls; + } + private function addServiceProperties(Definition $definition, string $variableName = 'instance') : string + { + $code = ''; + foreach ($definition->getProperties() as $name => $value) { + $code .= \sprintf(" \$%s->%s = %s;\n", $variableName, $name, $this->dumpValue($value)); + } + return $code; + } + private function addServiceConfigurator(Definition $definition, string $variableName = 'instance') : string + { + if (!($callable = $definition->getConfigurator())) { + return ''; + } + if (\is_array($callable)) { + if ($callable[0] instanceof Reference || $callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0])) { + return \sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + $class = $this->dumpValue($callable[0]); + // If the class is a string we can optimize away + if (\strncmp($class, "'", \strlen("'")) === 0 && \strpos($class, '$') === \false) { + return \sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName); + } + if (\strncmp($class, 'new ', \strlen('new ')) === 0) { + return \sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + return \sprintf(" [%s, '%s'](\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + return \sprintf(" %s(\$%s);\n", $callable, $variableName); + } + private function addService(string $id, Definition $definition) : array + { + $this->definitionVariables = new \SplObjectStorage(); + $this->referenceVariables = []; + $this->variableCount = 0; + $this->referenceVariables[$id] = new Variable('instance'); + $return = []; + if ($class = $definition->getClass()) { + $class = $class instanceof Parameter ? '%' . $class . '%' : $this->container->resolveEnvPlaceholders($class); + $return[] = \sprintf(\strncmp($class, '%', \strlen('%')) === 0 ? '@return object A %1$s instance' : '@return \\%s', \ltrim($class, '\\')); + } elseif ($definition->getFactory()) { + $factory = $definition->getFactory(); + if (\is_string($factory) && \strncmp($factory, '@=', \strlen('@=')) !== 0) { + $return[] = \sprintf('@return object An instance returned by %s()', $factory); + } elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) { + $class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0]; + $class = $class instanceof Parameter ? '%' . $class . '%' : $this->container->resolveEnvPlaceholders($class); + $return[] = \sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]); + } + } + if ($definition->isDeprecated()) { + if ($return && \strncmp($return[\count($return) - 1], '@return', \strlen('@return')) === 0) { + $return[] = ''; + } + $deprecation = $definition->getDeprecation($id); + $return[] = \sprintf('@deprecated %s', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '') . $deprecation['message']); + } + $return = \str_replace("\n * \n", "\n *\n", \implode("\n * ", $return)); + $return = $this->container->resolveEnvPlaceholders($return); + $shared = $definition->isShared() ? ' shared' : ''; + $public = $definition->isPublic() ? 'public' : 'private'; + $autowired = $definition->isAutowired() ? ' autowired' : ''; + $asFile = $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition); + $methodName = $this->generateMethodName($id); + if ($asFile || $definition->isLazy()) { + $lazyInitialization = '$lazyLoad = true'; + } else { + $lazyInitialization = ''; + } + $code = <<docStar} + * Gets the {$public} '{$id}'{$shared}{$autowired} service. + * + * {$return} +EOF; + $code = \str_replace('*/', ' ', $code) . <<hasErrors() && ($e = $definition->getErrors())) { + $code .= \sprintf(" throw new RuntimeException(%s);\n", $this->export(\reset($e))); + } else { + $this->serviceCalls = []; + $this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls); + if ($definition->isDeprecated()) { + $deprecation = $definition->getDeprecation($id); + $code .= \sprintf(" trigger_deprecation(%s, %s, %s);\n\n", $this->export($deprecation['package']), $this->export($deprecation['version']), $this->export($deprecation['message'])); + } elseif ($definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1])) { + foreach ($this->inlinedDefinitions as $def) { + foreach ($this->getClasses($def, $id) as $class) { + $this->preload[$class] = $class; + } + } + } + if (!$definition->isShared()) { + $factory = \sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id)); + } + if ($isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition)) { + if (!$definition->isShared()) { + $code .= \sprintf(' %s = %1$s ?? ', $factory); + if ($asFile) { + $code .= "function () {\n"; + $code .= " return self::do(\$container);\n"; + $code .= " };\n\n"; + } else { + $code .= \sprintf("\$this->%s(...);\n\n", $methodName); + } + } + $factoryCode = $asFile ? 'self::do($container, false)' : \sprintf('$this->%s(false)', $methodName); + $factoryCode = $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $factoryCode); + $code .= $asFile ? \preg_replace('/function \\(([^)]*+)\\)( {|:)/', 'function (\\1) use ($container)\\2', $factoryCode) : $factoryCode; + } + $c = $this->addServiceInclude($id, $definition); + if ('' !== $c && $isProxyCandidate && !$definition->isShared()) { + $c = \implode("\n", \array_map(function ($line) { + return $line ? ' ' . $line : $line; + }, \explode("\n", $c))); + $code .= " static \$include = true;\n\n"; + $code .= " if (\$include) {\n"; + $code .= $c; + $code .= " \$include = false;\n"; + $code .= " }\n\n"; + } else { + $code .= $c; + } + $c = $this->addInlineService($id, $definition); + if (!$isProxyCandidate && !$definition->isShared()) { + $c = \implode("\n", \array_map(function ($line) { + return $line ? ' ' . $line : $line; + }, \explode("\n", $c))); + $lazyloadInitialization = $definition->isLazy() ? '$lazyLoad = true' : ''; + $c = \sprintf(" %s = function (%s) {\n%s };\n\n return %1\$s();\n", $factory, $lazyloadInitialization, $c); + } + $code .= $c; + } + if ($asFile) { + $code = \str_replace('$this', '$container', $code); + $code = \preg_replace('/function \\(([^)]*+)\\)( {|:)/', 'function (\\1) use ($container)\\2', $code); + } + $code .= " }\n"; + $this->definitionVariables = $this->inlinedDefinitions = null; + $this->referenceVariables = $this->serviceCalls = null; + return [$file, $code]; + } + private function addInlineVariables(string $id, Definition $definition, array $arguments, bool $forConstructor) : string + { + $code = ''; + foreach ($arguments as $argument) { + if (\is_array($argument)) { + $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor); + } elseif ($argument instanceof Reference) { + $code .= $this->addInlineReference($id, $definition, $argument, $forConstructor); + } elseif ($argument instanceof Definition) { + $code .= $this->addInlineService($id, $definition, $argument, $forConstructor); + } + } + return $code; + } + private function addInlineReference(string $id, Definition $definition, string $targetId, bool $forConstructor) : string + { + while ($this->container->hasAlias($targetId)) { + $targetId = (string) $this->container->getAlias($targetId); + } + [$callCount, $behavior] = $this->serviceCalls[$targetId]; + if ($id === $targetId) { + return $this->addInlineService($id, $definition, $definition); + } + if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { + return ''; + } + if ($this->container->hasDefinition($targetId) && ($def = $this->container->getDefinition($targetId)) && !$def->isShared()) { + return ''; + } + $hasSelfRef = isset($this->circularReferences[$id][$targetId]) && !isset($this->definitionVariables[$definition]) && !($this->hasProxyDumper && $definition->isLazy()); + if ($hasSelfRef && !$forConstructor && !($forConstructor = !$this->circularReferences[$id][$targetId])) { + $code = $this->addInlineService($id, $definition, $definition); + } else { + $code = ''; + } + if (isset($this->referenceVariables[$targetId]) || 2 > $callCount && (!$hasSelfRef || !$forConstructor)) { + return $code; + } + $name = $this->getNextVariableName(); + $this->referenceVariables[$targetId] = new Variable($name); + $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null; + $code .= \sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference)); + if (!$hasSelfRef || !$forConstructor) { + return $code; + } + $code .= \sprintf(<<<'EOTXT' + + if (isset($this->%s[%s])) { + return $this->%1$s[%2$s]; + } + +EOTXT +, $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $this->doExport($id)); + return $code; + } + private function addInlineService(string $id, Definition $definition, Definition $inlineDef = null, bool $forConstructor = \true) : string + { + $code = ''; + if ($isSimpleInstance = $isRootInstance = null === $inlineDef) { + foreach ($this->serviceCalls as $targetId => [$callCount, $behavior, $byConstructor]) { + if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId] && !($this->hasProxyDumper && $definition->isLazy())) { + $code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor); + } + } + } + if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) { + return $code; + } + $arguments = [$inlineDef->getArguments(), $inlineDef->getFactory()]; + $code .= $this->addInlineVariables($id, $definition, $arguments, $forConstructor); + if ($arguments = \array_filter([$inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()])) { + $isSimpleInstance = \false; + } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) { + return $code; + } + if (isset($this->definitionVariables[$inlineDef])) { + $isSimpleInstance = \false; + } else { + $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName(); + $this->definitionVariables[$inlineDef] = new Variable($name); + $code .= '' !== $code ? "\n" : ''; + if ('instance' === $name) { + $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance); + } else { + $code .= $this->addNewInstance($inlineDef, ' $' . $name . ' = ', $id); + } + if ('' !== ($inline = $this->addInlineVariables($id, $definition, $arguments, \false))) { + $code .= "\n" . $inline . "\n"; + } elseif ($arguments && 'instance' === $name) { + $code .= "\n"; + } + $code .= $this->addServiceProperties($inlineDef, $name); + $code .= $this->addServiceMethodCalls($inlineDef, $name, !$this->getProxyDumper()->isProxyCandidate($inlineDef) && $inlineDef->isShared() && !isset($this->singleUsePrivateIds[$id]) ? $id : null); + $code .= $this->addServiceConfigurator($inlineDef, $name); + } + if ($isRootInstance && !$isSimpleInstance) { + $code .= "\n return \$instance;\n"; + } + return $code; + } + private function addServices(array &$services = null) : string + { + $publicServices = $privateServices = ''; + $definitions = $this->container->getDefinitions(); + \ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic()) { + $services[$id] = $this->addService($id, $definition); + } elseif ($definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1])) { + $services[$id] = null; + foreach ($this->getClasses($definition, $id) as $class) { + $this->preload[$class] = $class; + } + } + } + foreach ($definitions as $id => $definition) { + if (!([$file, $code] = $services[$id]) || null !== $file) { + continue; + } + if ($definition->isPublic()) { + $publicServices .= $code; + } elseif (!$this->isTrivialInstance($definition) || isset($this->locatedIds[$id])) { + $privateServices .= $code; + } + } + return $publicServices . $privateServices; + } + private function generateServiceFiles(array $services) : iterable + { + $definitions = $this->container->getDefinitions(); + \ksort($definitions); + foreach ($definitions as $id => $definition) { + if (([$file, $code] = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) { + (yield $file => [$code, $definition->hasTag($this->hotPathTag) || !$definition->hasTag($this->preloadTags[1]) && !$definition->isDeprecated() && !$definition->hasErrors()]); + } + } + } + private function addNewInstance(Definition $definition, string $return = '', string $id = null) : string + { + $tail = $return ? ";\n" : ''; + if (BaseServiceLocator::class === $definition->getClass() && $definition->hasTag($this->serviceLocatorTag)) { + $arguments = []; + foreach ($definition->getArgument(0) as $k => $argument) { + $arguments[$k] = $argument->getValues()[0]; + } + return $return . $this->dumpValue(new ServiceLocatorArgument($arguments)) . $tail; + } + $arguments = []; + foreach ($definition->getArguments() as $i => $value) { + $arguments[] = (\is_string($i) ? $i . ': ' : '') . $this->dumpValue($value); + } + if (null !== $definition->getFactory()) { + $callable = $definition->getFactory(); + if (['Closure', 'fromCallable'] === $callable && [0] === \array_keys($definition->getArguments())) { + $callable = $definition->getArgument(0); + $arguments = ['...']; + if ($callable instanceof Reference || $callable instanceof Definition) { + $callable = [$callable, '__invoke']; + } + } + if (\is_array($callable)) { + if (!\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $callable[1])) { + throw new RuntimeException(\sprintf('Cannot dump definition because of invalid factory method (%s).', $callable[1] ?: 'n/a')); + } + if ($callable[0] instanceof Reference || $callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0])) { + return $return . \sprintf('%s->%s(%s)', $this->dumpValue($callable[0]), $callable[1], $arguments ? \implode(', ', $arguments) : '') . $tail; + } + $class = $this->dumpValue($callable[0]); + // If the class is a string we can optimize away + if (\strncmp($class, "'", \strlen("'")) === 0 && \strpos($class, '$') === \false) { + if ("''" === $class) { + throw new RuntimeException(\sprintf('Cannot dump definition: "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id ? 'The "' . $id . '"' : 'inline')); + } + return $return . \sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $callable[1], $arguments ? \implode(', ', $arguments) : '') . $tail; + } + if (\strncmp($class, 'new ', \strlen('new ')) === 0) { + return $return . \sprintf('(%s)->%s(%s)', $class, $callable[1], $arguments ? \implode(', ', $arguments) : '') . $tail; + } + return $return . \sprintf("[%s, '%s'](%s)", $class, $callable[1], $arguments ? \implode(', ', $arguments) : '') . $tail; + } + if (\is_string($callable) && \strncmp($callable, '@=', \strlen('@=')) === 0) { + return $return . \sprintf('(($args = %s) ? (%s) : null)', $this->dumpValue(new ServiceLocatorArgument($definition->getArguments())), $this->getExpressionLanguage()->compile(\substr($callable, 2), ['this' => 'container', 'args' => 'args'])) . $tail; + } + return $return . \sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? \implode(', ', $arguments) : '') . $tail; + } + if (null === ($class = $definition->getClass())) { + throw new RuntimeException('Cannot dump definitions which have no class nor factory.'); + } + return $return . \sprintf('new %s(%s)', $this->dumpLiteralClass($this->dumpValue($class)), \implode(', ', $arguments)) . $tail; + } + private function startClass(string $class, string $baseClass, bool $hasProxyClasses) : string + { + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + $code = <<docStar} + * @internal This class has been auto-generated by the Symfony Dependency Injection Component. + */ +class {$class} extends {$baseClass} +{ + protected \$parameters = []; + + public function __construct() + { + +EOF; + if ($this->asFiles) { + $code = \str_replace('$parameters = []', "\$containerDir;\n protected \$parameters = [];\n private \$buildParameters", $code); + $code = \str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code); + $code .= " \$this->buildParameters = \$buildParameters;\n"; + $code .= " \$this->containerDir = \$containerDir;\n"; + if (null !== $this->targetDirRegex) { + $code = \str_replace('$parameters = []', "\$targetDir;\n protected \$parameters = []", $code); + $code .= ' $this->targetDir = \\dirname($containerDir);' . "\n"; + } + } + if (Container::class !== $this->baseClass) { + $r = $this->container->getReflectionClass($this->baseClass, \false); + if (null !== $r && null !== ($constructor = $r->getConstructor()) && 0 === $constructor->getNumberOfRequiredParameters() && Container::class !== $constructor->getDeclaringClass()->name) { + $code .= " parent::__construct();\n"; + $code .= " \$this->parameterBag = null;\n\n"; + } + } + if ($this->container->getParameterBag()->all()) { + $code .= " \$this->parameters = \$this->getDefaultParameters();\n\n"; + } + $code .= " \$this->services = \$this->privates = [];\n"; + $code .= $this->addSyntheticIds(); + $code .= $this->addMethodMap(); + $code .= $this->asFiles && !$this->inlineFactories ? $this->addFileMap() : ''; + $code .= $this->addAliases(); + $code .= $this->addInlineRequires($hasProxyClasses); + $code .= <<addRemovedIds(); + if ($this->asFiles && !$this->inlineFactories) { + $code .= <<<'EOF' + + protected function load($file, $lazyLoad = true) + { + if (class_exists($class = __NAMESPACE__.'\\'.$file, false)) { + return $class::do($this, $lazyLoad); + } + + if ('.' === $file[-4]) { + $class = substr($class, 0, -4); + } else { + $file .= '.php'; + } + + $service = require $this->containerDir.\DIRECTORY_SEPARATOR.$file; + + return class_exists($class, false) ? $class::do($this, $lazyLoad) : $service; + } + +EOF; + } + $proxyDumper = $this->getProxyDumper(); + foreach ($this->container->getDefinitions() as $definition) { + if (!$proxyDumper->isProxyCandidate($definition)) { + continue; + } + if ($this->asFiles && !$this->inlineFactories) { + $proxyLoader = "class_exists(\$class, false) || require __DIR__.'/'.\$class.'.php';\n\n "; + } else { + $proxyLoader = ''; + } + $code .= <<container->getDefinitions(); + \ksort($definitions); + foreach ($definitions as $id => $definition) { + if ($definition->isSynthetic() && 'service_container' !== $id) { + $code .= ' ' . $this->doExport($id) . " => true,\n"; + } + } + return $code ? " \$this->syntheticIds = [\n{$code} ];\n" : ''; + } + private function addRemovedIds() : string + { + $ids = $this->container->getRemovedIds(); + foreach ($this->container->getDefinitions() as $id => $definition) { + if (!$definition->isPublic()) { + $ids[$id] = \true; + } + } + if (!$ids) { + return ''; + } + if ($this->asFiles) { + $code = "require \$this->containerDir.\\DIRECTORY_SEPARATOR.'removed-ids.php'"; + } else { + $code = ''; + $ids = \array_keys($ids); + \sort($ids); + foreach ($ids as $id) { + if (\preg_match(FileLoader::ANONYMOUS_ID_REGEXP, $id)) { + continue; + } + $code .= ' ' . $this->doExport($id) . " => true,\n"; + } + $code = "[\n{$code} ]"; + } + return <<container->getDefinitions(); + \ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic() && $definition->isPublic() && (!$this->asFiles || $this->inlineFactories || $this->isHotPath($definition))) { + $code .= ' ' . $this->doExport($id) . ' => ' . $this->doExport($this->generateMethodName($id)) . ",\n"; + } + } + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + if (!$id->isDeprecated()) { + continue; + } + $code .= ' ' . $this->doExport($alias) . ' => ' . $this->doExport($this->generateMethodName($alias)) . ",\n"; + } + return $code ? " \$this->methodMap = [\n{$code} ];\n" : ''; + } + private function addFileMap() : string + { + $code = ''; + $definitions = $this->container->getDefinitions(); + \ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic() && $definition->isPublic() && !$this->isHotPath($definition)) { + $code .= \sprintf(" %s => '%s',\n", $this->doExport($id), $this->generateMethodName($id)); + } + } + return $code ? " \$this->fileMap = [\n{$code} ];\n" : ''; + } + private function addAliases() : string + { + if (!($aliases = $this->container->getAliases())) { + return "\n \$this->aliases = [];\n"; + } + $code = " \$this->aliases = [\n"; + \ksort($aliases); + foreach ($aliases as $alias => $id) { + if ($id->isDeprecated()) { + continue; + } + $id = (string) $id; + while (isset($aliases[$id])) { + $id = (string) $aliases[$id]; + } + $code .= ' ' . $this->doExport($alias) . ' => ' . $this->doExport($id) . ",\n"; + } + return $code . " ];\n"; + } + private function addDeprecatedAliases() : string + { + $code = ''; + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $definition) { + if (!$definition->isDeprecated()) { + continue; + } + $public = $definition->isPublic() ? 'public' : 'private'; + $id = (string) $definition; + $methodNameAlias = $this->generateMethodName($alias); + $idExported = $this->export($id); + $deprecation = $definition->getDeprecation($alias); + $packageExported = $this->export($deprecation['package']); + $versionExported = $this->export($deprecation['version']); + $messageExported = $this->export($deprecation['message']); + $code .= <<docStar} + * Gets the {$public} '{$alias}' alias. + * + * @return object The "{$id}" service. + */ + protected function {$methodNameAlias}() + { + trigger_deprecation({$packageExported}, {$versionExported}, {$messageExported}); + + return \$this->get({$idExported}); + } + +EOF; + } + return $code; + } + private function addInlineRequires(bool $hasProxyClasses) : string + { + $lineage = []; + $hotPathServices = $this->hotPathTag && $this->inlineRequires ? $this->container->findTaggedServiceIds($this->hotPathTag) : []; + foreach ($hotPathServices as $id => $tags) { + $definition = $this->container->getDefinition($id); + if ($this->getProxyDumper()->isProxyCandidate($definition)) { + continue; + } + $inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]); + foreach ($inlinedDefinitions as $def) { + foreach ($this->getClasses($def, $id) as $class) { + $this->collectLineage($class, $lineage); + } + } + } + $code = ''; + foreach ($lineage as $file) { + if (!isset($this->inlinedRequires[$file])) { + $this->inlinedRequires[$file] = \true; + $code .= \sprintf("\n include_once %s;", $file); + } + } + if ($hasProxyClasses) { + $code .= "\n include_once __DIR__.'/proxy-classes.php';"; + } + return $code ? \sprintf("\n \$this->privates['service_container'] = function () {%s\n };\n", $code) : ''; + } + private function addDefaultParametersMethod() : string + { + if (!$this->container->getParameterBag()->all()) { + return ''; + } + $php = []; + $dynamicPhp = []; + foreach ($this->container->getParameterBag()->all() as $key => $value) { + if ($key !== ($resolvedKey = $this->container->resolveEnvPlaceholders($key))) { + throw new InvalidArgumentException(\sprintf('Parameter name cannot use env parameters: "%s".', $resolvedKey)); + } + $hasEnum = \false; + $export = $this->exportParameters([$value], '', 12, $hasEnum); + $export = \explode('0 => ', \substr(\rtrim($export, " ]\n"), 2, -1), 2); + if ($hasEnum || \preg_match("/\\\$this->(?:getEnv\\('(?:[-.\\w]*+:)*+\\w++'\\)|targetDir\\.'')/", $export[1])) { + $dynamicPhp[$key] = \sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); + } else { + $php[] = \sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); + } + } + $parameters = \sprintf("[\n%s\n%s]", \implode("\n", $php), \str_repeat(' ', 8)); + $code = <<<'EOF' + + public function getParameter(string $name): array|bool|string|int|float|\UnitEnum|null + { + if (isset($this->buildParameters[$name])) { + return $this->buildParameters[$name]; + } + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || \array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter(string $name): bool + { + if (isset($this->buildParameters[$name])) { + return true; + } + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || \array_key_exists($name, $this->parameters); + } + + public function setParameter(string $name, $value): void + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag(): ParameterBagInterface + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + foreach ($this->buildParameters as $name => $value) { + $parameters[$name] = $value; + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + +EOF; + if (!$this->asFiles) { + $code = \preg_replace('/^.*buildParameters.*\\n.*\\n.*\\n\\n?/m', '', $code); + } + if ($dynamicPhp) { + $loadedDynamicParameters = $this->exportParameters(\array_combine(\array_keys($dynamicPhp), \array_fill(0, \count($dynamicPhp), \false)), '', 8); + $getDynamicParameter = <<<'EOF' + $value = match ($name) { +%s + default => throw new InvalidArgumentException(sprintf('The dynamic parameter "%%s" must be defined.', $name)), + }; + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; +EOF; + $getDynamicParameter = \sprintf($getDynamicParameter, \implode("\n", $dynamicPhp)); + } else { + $loadedDynamicParameters = '[]'; + $getDynamicParameter = \str_repeat(' ', 8) . 'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));'; + } + $code .= << $value) { + if (\is_array($value)) { + $value = $this->exportParameters($value, $path . '/' . $key, $indent + 4, $hasEnum); + } elseif ($value instanceof ArgumentInterface) { + throw new InvalidArgumentException(\sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', \get_debug_type($value), $path . '/' . $key)); + } elseif ($value instanceof Variable) { + throw new InvalidArgumentException(\sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path . '/' . $key)); + } elseif ($value instanceof Definition) { + throw new InvalidArgumentException(\sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path . '/' . $key)); + } elseif ($value instanceof Reference) { + throw new InvalidArgumentException(\sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path . '/' . $key)); + } elseif ($value instanceof Expression) { + throw new InvalidArgumentException(\sprintf('You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".', $value, $path . '/' . $key)); + } elseif ($value instanceof \UnitEnum) { + $hasEnum = \true; + $value = \sprintf('\\%s::%s', \get_class($value), $value->name); + } else { + $value = $this->export($value); + } + $php[] = \sprintf('%s%s => %s,', \str_repeat(' ', $indent), $this->export($key), $value); + } + return \sprintf("[\n%s\n%s]", \implode("\n", $php), \str_repeat(' ', $indent - 4)); + } + private function endClass() : string + { + return <<<'EOF' +} + +EOF; + } + /** + * @param mixed $value + */ + private function wrapServiceConditionals($value, string $code) : string + { + if (!($condition = $this->getServiceConditionals($value))) { + return $code; + } + // re-indent the wrapped code + $code = \implode("\n", \array_map(function ($line) { + return $line ? ' ' . $line : $line; + }, \explode("\n", $code))); + return \sprintf(" if (%s) {\n%s }\n", $condition, $code); + } + /** + * @param mixed $value + */ + private function getServiceConditionals($value) : string + { + $conditions = []; + foreach (ContainerBuilder::getInitializedConditionals($value) as $service) { + if (!$this->container->hasDefinition($service)) { + return 'false'; + } + $conditions[] = \sprintf('isset($this->%s[%s])', $this->container->getDefinition($service)->isPublic() ? 'services' : 'privates', $this->doExport($service)); + } + foreach (ContainerBuilder::getServiceConditionals($value) as $service) { + if ($this->container->hasDefinition($service) && !$this->container->getDefinition($service)->isPublic()) { + continue; + } + $conditions[] = \sprintf('$this->has(%s)', $this->doExport($service)); + } + if (!$conditions) { + return ''; + } + return \implode(' && ', $conditions); + } + private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = [], bool $byConstructor = null) : \SplObjectStorage + { + if (null === $definitions) { + $definitions = new \SplObjectStorage(); + } + foreach ($arguments as $argument) { + if (\is_array($argument)) { + $this->getDefinitionsFromArguments($argument, $definitions, $calls, $byConstructor); + } elseif ($argument instanceof Reference) { + $id = (string) $argument; + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + if (!isset($calls[$id])) { + $calls[$id] = [0, $argument->getInvalidBehavior(), $byConstructor]; + } else { + $calls[$id][1] = \min($calls[$id][1], $argument->getInvalidBehavior()); + } + ++$calls[$id][0]; + } elseif (!$argument instanceof Definition) { + // no-op + } elseif (isset($definitions[$argument])) { + $definitions[$argument] = 1 + $definitions[$argument]; + } else { + $definitions[$argument] = 1; + $arguments = [$argument->getArguments(), $argument->getFactory()]; + $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null === $byConstructor || $byConstructor); + $arguments = [$argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()]; + $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null !== $byConstructor && $byConstructor); + } + } + return $definitions; + } + /** + * @throws RuntimeException + * @param mixed $value + */ + private function dumpValue($value, bool $interpolate = \true) : string + { + if (\is_array($value)) { + if ($value && $interpolate && \false !== ($param = \array_search($value, $this->container->getParameterBag()->all(), \true))) { + return $this->dumpValue("%{$param}%"); + } + $code = []; + foreach ($value as $k => $v) { + $code[] = \sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); + } + return \sprintf('[%s]', \implode(', ', $code)); + } elseif ($value instanceof ArgumentInterface) { + $scope = [$this->definitionVariables, $this->referenceVariables]; + $this->definitionVariables = $this->referenceVariables = null; + try { + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + $code = $this->dumpValue($value, $interpolate); + $returnedType = ''; + if ($value instanceof TypedReference) { + $returnedType = \sprintf(': %s\\%s', ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $value->getInvalidBehavior() ? '' : '?', \str_replace(['|', '&'], ['|\\', '&\\'], $value->getType())); + } + $code = \sprintf('return %s;', $code); + $attribute = ''; + if ($value instanceof Reference) { + $attribute = 'name: ' . $this->dumpValue((string) $value, $interpolate); + if ($this->container->hasDefinition($value) && ($class = $this->container->findDefinition($value)->getClass()) && $class !== (string) $value) { + $attribute .= ', class: ' . $this->dumpValue($class, $interpolate); + } + $attribute = \sprintf('#[\\Closure(%s)] ', $attribute); + } + return \sprintf("%sfunction ()%s {\n %s\n }", $attribute, $returnedType, $code); + } + if ($value instanceof IteratorArgument) { + $operands = [0]; + $code = []; + $code[] = 'new RewindableGenerator(function () {'; + if (!($values = $value->getValues())) { + $code[] = ' return new \\EmptyIterator();'; + } else { + $countCode = []; + $countCode[] = 'function () {'; + foreach ($values as $k => $v) { + ($c = $this->getServiceConditionals($v)) ? $operands[] = "(int) ({$c})" : ++$operands[0]; + $v = $this->wrapServiceConditionals($v, \sprintf(" yield %s => %s;\n", $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate))); + foreach (\explode("\n", $v) as $v) { + if ($v) { + $code[] = ' ' . $v; + } + } + } + $countCode[] = \sprintf(' return %s;', \implode(' + ', $operands)); + $countCode[] = ' }'; + } + $code[] = \sprintf(' }, %s)', \count($operands) > 1 ? \implode("\n", $countCode) : $operands[0]); + return \implode("\n", $code); + } + if ($value instanceof ServiceLocatorArgument) { + $serviceMap = ''; + $serviceTypes = ''; + foreach ($value->getValues() as $k => $v) { + if (!$v instanceof Reference) { + $serviceMap .= \sprintf("\n %s => [%s],", $this->export($k), $this->dumpValue($v)); + $serviceTypes .= \sprintf("\n %s => '?',", $this->export($k)); + continue; + } + $id = (string) $v; + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + $definition = $this->container->getDefinition($id); + $load = !($definition->hasErrors() && ($e = $definition->getErrors())) ? $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) : \reset($e); + $serviceMap .= \sprintf("\n %s => [%s, %s, %s, %s],", $this->export($k), $this->export($definition->isShared() ? $definition->isPublic() ? 'services' : 'privates' : \false), $this->doExport($id), $this->export(ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $v->getInvalidBehavior() && !\is_string($load) ? $this->generateMethodName($id) : null), $this->export($load)); + $serviceTypes .= \sprintf("\n %s => %s,", $this->export($k), $this->export($v instanceof TypedReference ? $v->getType() : '?')); + $this->locatedIds[$id] = \true; + } + $this->addGetService = \true; + return \sprintf('new \\%s($this->getService, [%s%s], [%s%s])', ServiceLocator::class, $serviceMap, $serviceMap ? "\n " : '', $serviceTypes, $serviceTypes ? "\n " : ''); + } + } finally { + [$this->definitionVariables, $this->referenceVariables] = $scope; + } + } elseif ($value instanceof Definition) { + if ($value->hasErrors() && ($e = $value->getErrors())) { + return \sprintf('throw new RuntimeException(%s)', $this->export(\reset($e))); + } + if (($nullsafeVariable1 = $this->definitionVariables) ? $nullsafeVariable1->contains($value) : null) { + return $this->dumpValue($this->definitionVariables[$value], $interpolate); + } + if ($value->getMethodCalls()) { + throw new RuntimeException('Cannot dump definitions which have method calls.'); + } + if ($value->getProperties()) { + throw new RuntimeException('Cannot dump definitions which have properties.'); + } + if (null !== $value->getConfigurator()) { + throw new RuntimeException('Cannot dump definitions which have a configurator.'); + } + return $this->addNewInstance($value); + } elseif ($value instanceof Variable) { + return '$' . $value; + } elseif ($value instanceof Reference) { + $id = (string) $value; + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + if (null !== $this->referenceVariables && isset($this->referenceVariables[$id])) { + return $this->dumpValue($this->referenceVariables[$id], $interpolate); + } + return $this->getServiceCall($id, $value); + } elseif ($value instanceof Expression) { + return $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']); + } elseif ($value instanceof Parameter) { + return $this->dumpParameter($value); + } elseif (\true === $interpolate && \is_string($value)) { + if (\preg_match('/^%([^%]+)%$/', $value, $match)) { + // we do this to deal with non string values (Boolean, integer, ...) + // the preg_replace_callback converts them to strings + return $this->dumpParameter($match[1]); + } else { + $replaceParameters = function ($match) { + return "'." . $this->dumpParameter($match[2]) . ".'"; + }; + $code = \str_replace('%%', '%', \preg_replace_callback('/(?export($value))); + return $code; + } + } elseif ($value instanceof \UnitEnum) { + return \sprintf('\\%s::%s', \get_class($value), $value->name); + } elseif ($value instanceof AbstractArgument) { + throw new RuntimeException($value->getTextWithContext()); + } elseif (\is_object($value) || \is_resource($value)) { + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + } + return $this->export($value); + } + /** + * Dumps a string to a literal (aka PHP Code) class value. + * + * @throws RuntimeException + */ + private function dumpLiteralClass(string $class) : string + { + if (\strpos($class, '$') !== \false) { + return \sprintf('${($_ = %s) && false ?: "_"}', $class); + } + if (\strncmp($class, "'", \strlen("'")) !== 0 || !\preg_match('/^\'(?:\\\\{2})?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?:\\\\{2}[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)*\'$/', $class)) { + throw new RuntimeException(\sprintf('Cannot dump definition because of invalid class name (%s).', $class ?: 'n/a')); + } + $class = \substr(\str_replace('\\\\', '\\', $class), 1, -1); + return \strncmp($class, '\\', \strlen('\\')) === 0 ? $class : '\\' . $class; + } + private function dumpParameter(string $name) : string + { + if ($this->container->hasParameter($name)) { + $value = $this->container->getParameter($name); + $dumpedValue = $this->dumpValue($value, \false); + if (!$value || !\is_array($value)) { + return $dumpedValue; + } + if (!\preg_match("/\\\$this->(?:getEnv\\('(?:[-.\\w]*+:)*+\\w++'\\)|targetDir\\.'')/", $dumpedValue)) { + return \sprintf('$this->parameters[%s]', $this->doExport($name)); + } + } + return \sprintf('$this->getParameter(%s)', $this->doExport($name)); + } + private function getServiceCall(string $id, Reference $reference = null) : string + { + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + if ('service_container' === $id) { + return '$this'; + } + if ($this->container->hasDefinition($id) && ($definition = $this->container->getDefinition($id))) { + if ($definition->isSynthetic()) { + $code = \sprintf('$this->get(%s%s)', $this->doExport($id), null !== $reference ? ', ' . $reference->getInvalidBehavior() : ''); + } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + $code = 'null'; + if (!$definition->isShared()) { + return $code; + } + } elseif ($this->isTrivialInstance($definition)) { + if ($definition->hasErrors() && ($e = $definition->getErrors())) { + return \sprintf('throw new RuntimeException(%s)', $this->export(\reset($e))); + } + $code = $this->addNewInstance($definition, '', $id); + if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) { + $code = \sprintf('$this->%s[%s] = %s', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code); + } + $code = "({$code})"; + } else { + $code = $this->asFiles && !$this->inlineFactories && !$this->isHotPath($definition) ? "\$this->load('%s')" : '$this->%s()'; + $code = \sprintf($code, $this->generateMethodName($id)); + if (!$definition->isShared()) { + $factory = \sprintf('$this->factories%s[%s]', $definition->isPublic() ? '' : "['service_container']", $this->doExport($id)); + $code = \sprintf('(isset(%s) ? %1$s() : %s)', $factory, $code); + } + } + if ($definition->isShared() && !isset($this->singleUsePrivateIds[$id])) { + $code = \sprintf('($this->%s[%s] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $this->doExport($id), $code); + } + return $code; + } + if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + return 'null'; + } + if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE < $reference->getInvalidBehavior()) { + $code = \sprintf('$this->get(%s, ContainerInterface::NULL_ON_INVALID_REFERENCE)', $this->doExport($id)); + } else { + $code = \sprintf('$this->get(%s)', $this->doExport($id)); + } + return \sprintf('($this->services[%s] ?? %s)', $this->doExport($id), $code); + } + /** + * Initializes the method names map to avoid conflicts with the Container methods. + */ + private function initializeMethodNamesMap(string $class) + { + $this->serviceIdToMethodNameMap = []; + $this->usedMethodNames = []; + if ($reflectionClass = $this->container->getReflectionClass($class)) { + foreach ($reflectionClass->getMethods() as $method) { + $this->usedMethodNames[\strtolower($method->getName())] = \true; + } + } + } + /** + * @throws InvalidArgumentException + */ + private function generateMethodName(string $id) : string + { + if (isset($this->serviceIdToMethodNameMap[$id])) { + return $this->serviceIdToMethodNameMap[$id]; + } + $i = \strrpos($id, '\\'); + $name = Container::camelize(\false !== $i && isset($id[1 + $i]) ? \substr($id, 1 + $i) : $id); + $name = \preg_replace('/[^a-zA-Z0-9_\\x7f-\\xff]/', '', $name); + $methodName = 'get' . $name . 'Service'; + $suffix = 1; + while (isset($this->usedMethodNames[\strtolower($methodName)])) { + ++$suffix; + $methodName = 'get' . $name . $suffix . 'Service'; + } + $this->serviceIdToMethodNameMap[$id] = $methodName; + $this->usedMethodNames[\strtolower($methodName)] = \true; + return $methodName; + } + private function getNextVariableName() : string + { + $firstChars = self::FIRST_CHARS; + $firstCharsLength = \strlen($firstChars); + $nonFirstChars = self::NON_FIRST_CHARS; + $nonFirstCharsLength = \strlen($nonFirstChars); + while (\true) { + $name = ''; + $i = $this->variableCount; + if ('' === $name) { + $name .= $firstChars[$i % $firstCharsLength]; + $i = (int) ($i / $firstCharsLength); + } + while ($i > 0) { + --$i; + $name .= $nonFirstChars[$i % $nonFirstCharsLength]; + $i = (int) ($i / $nonFirstCharsLength); + } + ++$this->variableCount; + // check that the name is not reserved + if (\in_array($name, $this->reservedVariables, \true)) { + continue; + } + return $name; + } + } + private function getExpressionLanguage() : ExpressionLanguage + { + if (!isset($this->expressionLanguage)) { + if (!\class_exists(\MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\ExpressionLanguage::class)) { + throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); + } + $providers = $this->container->getExpressionLanguageProviders(); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) { + $id = '""' === \substr_replace($arg, '', 1, -1) ? \stripcslashes(\substr($arg, 1, -1)) : null; + if (null !== $id && ($this->container->hasAlias($id) || $this->container->hasDefinition($id))) { + return $this->getServiceCall($id); + } + return \sprintf('$this->get(%s)', $arg); + }); + if ($this->container->isTrackingResources()) { + foreach ($providers as $provider) { + $this->container->addObjectResource($provider); + } + } + } + return $this->expressionLanguage; + } + private function isHotPath(Definition $definition) : bool + { + return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated(); + } + private function isSingleUsePrivateNode(ServiceReferenceGraphNode $node) : bool + { + if ($node->getValue()->isPublic()) { + return \false; + } + $ids = []; + foreach ($node->getInEdges() as $edge) { + if (!($value = $edge->getSourceNode()->getValue())) { + continue; + } + if ($edge->isLazy() || !$value instanceof Definition || !$value->isShared()) { + return \false; + } + $ids[$edge->getSourceNode()->getId()] = \true; + } + return 1 === \count($ids); + } + /** + * @param mixed $value + * @return mixed + */ + private function export($value) + { + if (null !== $this->targetDirRegex && \is_string($value) && \preg_match($this->targetDirRegex, $value, $matches, \PREG_OFFSET_CAPTURE)) { + $suffix = $matches[0][1] + \strlen($matches[0][0]); + $matches[0][1] += \strlen($matches[1][0]); + $prefix = $matches[0][1] ? $this->doExport(\substr($value, 0, $matches[0][1]), \true) . '.' : ''; + if ('\\' === \DIRECTORY_SEPARATOR && isset($value[$suffix])) { + $cookie = '\\' . \random_int(100000, \PHP_INT_MAX); + $suffix = '.' . $this->doExport(\str_replace('\\', $cookie, \substr($value, $suffix)), \true); + $suffix = \str_replace('\\' . $cookie, "'.\\DIRECTORY_SEPARATOR.'", $suffix); + } else { + $suffix = isset($value[$suffix]) ? '.' . $this->doExport(\substr($value, $suffix), \true) : ''; + } + $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__'; + $offset = 2 + $this->targetDirMaxMatches - \count($matches); + if (0 < $offset) { + $dirname = \sprintf('\\dirname(__DIR__, %d)', $offset + (int) $this->asFiles); + } elseif ($this->asFiles) { + $dirname = "\$this->targetDir.''"; + // empty string concatenation on purpose + } + if ($prefix || $suffix) { + return \sprintf('(%s%s%s)', $prefix, $dirname, $suffix); + } + return $dirname; + } + return $this->doExport($value, \true); + } + /** + * @param mixed $value + * @return mixed + */ + private function doExport($value, bool $resolveEnv = \false) + { + $shouldCacheValue = $resolveEnv && \is_string($value); + if ($shouldCacheValue && isset($this->exportedVariables[$value])) { + return $this->exportedVariables[$value]; + } + if (\is_string($value) && \strpos($value, "\n") !== \false) { + $cleanParts = \explode("\n", $value); + $cleanParts = \array_map(function ($part) { + return \var_export($part, \true); + }, $cleanParts); + $export = \implode('."\\n".', $cleanParts); + } else { + $export = \var_export($value, \true); + } + if ($this->asFiles) { + if (\strpos($export, '$this') !== \false) { + $export = \str_replace('$this', "\$'.'this", $export); + } + if (\strpos($export, 'function () {') !== \false) { + $export = \str_replace('function () {', "function ('.') {", $export); + } + } + if ($resolveEnv && "'" === $export[0] && $export !== ($resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'"))) { + $export = $resolvedExport; + if (\substr_compare($export, ".''", -\strlen(".''")) === 0) { + $export = \substr($export, 0, -3); + if ("'" === $export[1]) { + $export = \substr_replace($export, '', 18, 7); + } + } + if ("'" === $export[1]) { + $export = \substr($export, 3); + } + } + if ($shouldCacheValue) { + $this->exportedVariables[$value] = $export; + } + return $export; + } + private function getAutoloadFile() : ?string + { + $file = null; + foreach (\spl_autoload_functions() as $autoloader) { + if (!\is_array($autoloader)) { + continue; + } + if ($autoloader[0] instanceof DebugClassLoader || $autoloader[0] instanceof LegacyDebugClassLoader) { + $autoloader = $autoloader[0]->getClassLoader(); + } + if (!\is_array($autoloader) || !$autoloader[0] instanceof ClassLoader || !$autoloader[0]->findFile(__CLASS__)) { + continue; + } + foreach (\get_declared_classes() as $class) { + if (\strncmp($class, 'ComposerAutoloaderInit', \strlen('ComposerAutoloaderInit')) === 0 && $class::getLoader() === $autoloader[0]) { + $file = \dirname((new \ReflectionClass($class))->getFileName(), 2) . '/autoload.php'; + if (null !== $this->targetDirRegex && \preg_match($this->targetDirRegex . 'A', $file)) { + return $file; + } + } + } + } + return $file; + } + private function getClasses(Definition $definition, string $id) : array + { + $classes = []; + while ($definition instanceof Definition) { + foreach ($definition->getTag($this->preloadTags[0]) as $tag) { + if (!isset($tag['class'])) { + throw new InvalidArgumentException(\sprintf('Missing attribute "class" on tag "%s" for service "%s".', $this->preloadTags[0], $id)); + } + $classes[] = \trim($tag['class'], '\\'); + } + if ($class = $definition->getClass()) { + $classes[] = \trim($class, '\\'); + } + $factory = $definition->getFactory(); + if (!\is_array($factory)) { + $factory = [$factory]; + } + if (\is_string($factory[0])) { + if (\false !== ($i = \strrpos($factory[0], '::'))) { + $factory[0] = \substr($factory[0], 0, $i); + } + $classes[] = \trim($factory[0], '\\'); + } + $definition = $factory[0]; + } + return $classes; + } +} diff --git a/vendor/symfony/dependency-injection/Dumper/Preloader.php b/vendor/symfony/dependency-injection/Dumper/Preloader.php new file mode 100644 index 0000000000..4010ff4a59 --- /dev/null +++ b/vendor/symfony/dependency-injection/Dumper/Preloader.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Dumper; + +/** + * @author Nicolas Grekas + */ +final class Preloader +{ + public static function append(string $file, array $list) : void + { + if (!\file_exists($file)) { + throw new \LogicException(\sprintf('File "%s" does not exist.', $file)); + } + $cacheDir = \dirname($file); + $classes = []; + foreach ($list as $item) { + if (\strncmp($item, $cacheDir, \strlen($cacheDir)) === 0) { + \file_put_contents($file, \sprintf("require_once __DIR__.%s;\n", \var_export(\strtr(\substr($item, \strlen($cacheDir)), \DIRECTORY_SEPARATOR, '/'), \true)), \FILE_APPEND); + continue; + } + $classes[] = \sprintf("\$classes[] = %s;\n", \var_export($item, \true)); + } + \file_put_contents($file, \sprintf("\n\$classes = [];\n%s\$preloaded = Preloader::preload(\$classes, \$preloaded);\n", \implode('', $classes)), \FILE_APPEND); + } + public static function preload(array $classes, array $preloaded = []) : array + { + \set_error_handler(function ($t, $m, $f, $l) { + if (\error_reporting() & $t) { + if (__FILE__ !== $f) { + throw new \ErrorException($m, 0, $t, $f, $l); + } + throw new \ReflectionException($m); + } + }); + $prev = []; + try { + while ($prev !== $classes) { + $prev = $classes; + foreach ($classes as $c) { + if (!isset($preloaded[$c])) { + self::doPreload($c, $preloaded); + } + } + $classes = \array_merge(\get_declared_classes(), \get_declared_interfaces(), \get_declared_traits()); + } + } finally { + \restore_error_handler(); + } + return $preloaded; + } + private static function doPreload(string $class, array &$preloaded) : void + { + if (isset($preloaded[$class]) || \in_array($class, ['self', 'static', 'parent'], \true)) { + return; + } + $preloaded[$class] = \true; + try { + if (!\class_exists($class) && !\interface_exists($class, \false) && !\trait_exists($class, \false)) { + return; + } + $r = new \ReflectionClass($class); + if ($r->isInternal()) { + return; + } + $r->getConstants(); + $r->getDefaultProperties(); + foreach ($r->getProperties(\ReflectionProperty::IS_PUBLIC) as $p) { + self::preloadType(\method_exists($p, 'getType') ? $p->getType() : null, $preloaded); + } + foreach ($r->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) { + foreach ($m->getParameters() as $p) { + if ($p->isDefaultValueAvailable() && $p->isDefaultValueConstant()) { + $c = $p->getDefaultValueConstantName(); + if ($i = \strpos($c, '::')) { + self::doPreload(\substr($c, 0, $i), $preloaded); + } + } + self::preloadType($p->getType(), $preloaded); + } + self::preloadType($m->getReturnType(), $preloaded); + } + } catch (\Throwable $exception) { + // ignore missing classes + } + } + private static function preloadType(?\ReflectionType $t, array &$preloaded) : void + { + if (!$t) { + return; + } + foreach ($t instanceof \ReflectionUnionType || $t instanceof \ReflectionIntersectionType ? $t->getTypes() : [$t] as $t) { + if (!$t->isBuiltin()) { + self::doPreload($t instanceof \ReflectionNamedType ? $t->getName() : $t, $preloaded); + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Dumper/XmlDumper.php b/vendor/symfony/dependency-injection/Dumper/XmlDumper.php new file mode 100644 index 0000000000..8aed5c1b46 --- /dev/null +++ b/vendor/symfony/dependency-injection/Dumper/XmlDumper.php @@ -0,0 +1,366 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Dumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Parameter; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * XmlDumper dumps a service container as an XML string. + * + * @author Fabien Potencier + * @author Martin Hasoň + */ +class XmlDumper extends Dumper +{ + /** + * @var \DOMDocument + */ + private $document; + /** + * Dumps the service container as an XML string. + */ + public function dump(array $options = []) : string + { + $this->document = new \DOMDocument('1.0', 'utf-8'); + $this->document->formatOutput = \true; + $container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container'); + $container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd'); + $this->addParameters($container); + $this->addServices($container); + $this->document->appendChild($container); + $xml = $this->document->saveXML(); + unset($this->document); + return $this->container->resolveEnvPlaceholders($xml); + } + private function addParameters(\DOMElement $parent) + { + $data = $this->container->getParameterBag()->all(); + if (!$data) { + return; + } + if ($this->container->isCompiled()) { + $data = $this->escape($data); + } + $parameters = $this->document->createElement('parameters'); + $parent->appendChild($parameters); + $this->convertParameters($data, 'parameter', $parameters); + } + private function addMethodCalls(array $methodcalls, \DOMElement $parent) + { + foreach ($methodcalls as $methodcall) { + $call = $this->document->createElement('call'); + $call->setAttribute('method', $methodcall[0]); + if (\count($methodcall[1])) { + $this->convertParameters($methodcall[1], 'argument', $call); + } + if ($methodcall[2] ?? \false) { + $call->setAttribute('returns-clone', 'true'); + } + $parent->appendChild($call); + } + } + private function addService(Definition $definition, ?string $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + if (null !== $id) { + $service->setAttribute('id', $id); + } + if ($class = $definition->getClass()) { + if (\strncmp($class, '\\', \strlen('\\')) === 0) { + $class = \substr($class, 1); + } + $service->setAttribute('class', $class); + } + if (!$definition->isShared()) { + $service->setAttribute('shared', 'false'); + } + if ($definition->isPublic()) { + $service->setAttribute('public', 'true'); + } + if ($definition->isSynthetic()) { + $service->setAttribute('synthetic', 'true'); + } + if ($definition->isLazy()) { + $service->setAttribute('lazy', 'true'); + } + if (null !== ($decoratedService = $definition->getDecoratedService())) { + [$decorated, $renamedId, $priority] = $decoratedService; + $service->setAttribute('decorates', $decorated); + $decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if (\in_array($decorationOnInvalid, [ContainerInterface::IGNORE_ON_INVALID_REFERENCE, ContainerInterface::NULL_ON_INVALID_REFERENCE], \true)) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE === $decorationOnInvalid ? 'null' : 'ignore'; + $service->setAttribute('decoration-on-invalid', $invalidBehavior); + } + if (null !== $renamedId) { + $service->setAttribute('decoration-inner-name', $renamedId); + } + if (0 !== $priority) { + $service->setAttribute('decoration-priority', $priority); + } + } + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $tag = $this->document->createElement('tag'); + if (!\array_key_exists('name', $attributes)) { + $tag->setAttribute('name', $name); + } else { + $tag->appendChild($this->document->createTextNode($name)); + } + foreach ($attributes as $key => $value) { + $tag->setAttribute($key, $value ?? ''); + } + $service->appendChild($tag); + } + } + if ($definition->getFile()) { + $file = $this->document->createElement('file'); + $file->appendChild($this->document->createTextNode($definition->getFile())); + $service->appendChild($file); + } + if ($parameters = $definition->getArguments()) { + $this->convertParameters($parameters, 'argument', $service); + } + if ($parameters = $definition->getProperties()) { + $this->convertParameters($parameters, 'property', $service, 'name'); + } + $this->addMethodCalls($definition->getMethodCalls(), $service); + if ($callable = $definition->getFactory()) { + $factory = $this->document->createElement('factory'); + if (\is_array($callable) && $callable[0] instanceof Definition) { + $this->addService($callable[0], null, $factory); + $factory->setAttribute('method', $callable[1]); + } elseif (\is_array($callable)) { + if (null !== $callable[0]) { + $factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]); + } + $factory->setAttribute('method', $callable[1]); + } else { + $factory->setAttribute('function', $callable); + } + $service->appendChild($factory); + } + if ($definition->isDeprecated()) { + $deprecation = $definition->getDeprecation('%service_id%'); + $deprecated = $this->document->createElement('deprecated'); + $deprecated->appendChild($this->document->createTextNode($definition->getDeprecation('%service_id%')['message'])); + $deprecated->setAttribute('package', $deprecation['package']); + $deprecated->setAttribute('version', $deprecation['version']); + $service->appendChild($deprecated); + } + if ($definition->isAutowired()) { + $service->setAttribute('autowire', 'true'); + } + if ($definition->isAutoconfigured()) { + $service->setAttribute('autoconfigure', 'true'); + } + if ($definition->isAbstract()) { + $service->setAttribute('abstract', 'true'); + } + if ($callable = $definition->getConfigurator()) { + $configurator = $this->document->createElement('configurator'); + if (\is_array($callable) && $callable[0] instanceof Definition) { + $this->addService($callable[0], null, $configurator); + $configurator->setAttribute('method', $callable[1]); + } elseif (\is_array($callable)) { + $configurator->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]); + $configurator->setAttribute('method', $callable[1]); + } else { + $configurator->setAttribute('function', $callable); + } + $service->appendChild($configurator); + } + $parent->appendChild($service); + } + private function addServiceAlias(string $alias, Alias $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + $service->setAttribute('id', $alias); + $service->setAttribute('alias', $id); + if ($id->isPublic()) { + $service->setAttribute('public', 'true'); + } + if ($id->isDeprecated()) { + $deprecation = $id->getDeprecation('%alias_id%'); + $deprecated = $this->document->createElement('deprecated'); + $deprecated->appendChild($this->document->createTextNode($deprecation['message'])); + $deprecated->setAttribute('package', $deprecation['package']); + $deprecated->setAttribute('version', $deprecation['version']); + $service->appendChild($deprecated); + } + $parent->appendChild($service); + } + private function addServices(\DOMElement $parent) + { + $definitions = $this->container->getDefinitions(); + if (!$definitions) { + return; + } + $services = $this->document->createElement('services'); + foreach ($definitions as $id => $definition) { + $this->addService($definition, $id, $services); + } + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + while (isset($aliases[(string) $id])) { + $id = $aliases[(string) $id]; + } + $this->addServiceAlias($alias, $id, $services); + } + $parent->appendChild($services); + } + private function convertParameters(array $parameters, string $type, \DOMElement $parent, string $keyAttribute = 'key') + { + $arrayIsListFunction = function (array $array) : bool { + if (\function_exists('array_is_list')) { + return \array_is_list($array); + } + if ($array === []) { + return \true; + } + $current_key = 0; + foreach ($array as $key => $noop) { + if ($key !== $current_key) { + return \false; + } + ++$current_key; + } + return \true; + }; + $withKeys = !$arrayIsListFunction($parameters); + foreach ($parameters as $key => $value) { + $element = $this->document->createElement($type); + if ($withKeys) { + $element->setAttribute($keyAttribute, $key); + } + if (\is_array($tag = $value)) { + $element->setAttribute('type', 'collection'); + $this->convertParameters($value, $type, $element, 'key'); + } elseif ($value instanceof TaggedIteratorArgument || $value instanceof ServiceLocatorArgument && ($tag = $value->getTaggedIteratorArgument())) { + $element->setAttribute('type', $value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator'); + $element->setAttribute('tag', $tag->getTag()); + if (null !== $tag->getIndexAttribute()) { + $element->setAttribute('index-by', $tag->getIndexAttribute()); + if (null !== $tag->getDefaultIndexMethod()) { + $element->setAttribute('default-index-method', $tag->getDefaultIndexMethod()); + } + if (null !== $tag->getDefaultPriorityMethod()) { + $element->setAttribute('default-priority-method', $tag->getDefaultPriorityMethod()); + } + } + } elseif ($value instanceof IteratorArgument) { + $element->setAttribute('type', 'iterator'); + $this->convertParameters($value->getValues(), $type, $element, 'key'); + } elseif ($value instanceof ServiceLocatorArgument) { + $element->setAttribute('type', 'service_locator'); + $this->convertParameters($value->getValues(), $type, $element, 'key'); + } elseif ($value instanceof ServiceClosureArgument && !$value->getValues()[0] instanceof Reference) { + $element->setAttribute('type', 'service_closure'); + $this->convertParameters($value->getValues(), $type, $element, 'key'); + } elseif ($value instanceof Reference || $value instanceof ServiceClosureArgument) { + $element->setAttribute('type', 'service'); + if ($value instanceof ServiceClosureArgument) { + $element->setAttribute('type', 'service_closure'); + $value = $value->getValues()[0]; + } + $element->setAttribute('id', (string) $value); + $behavior = $value->getInvalidBehavior(); + if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'null'); + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'ignore'); + } elseif (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'ignore_uninitialized'); + } + } elseif ($value instanceof Definition) { + $element->setAttribute('type', 'service'); + $this->addService($value, null, $element); + } elseif ($value instanceof Expression) { + $element->setAttribute('type', 'expression'); + $text = $this->document->createTextNode(self::phpToXml((string) $value)); + $element->appendChild($text); + } elseif (\is_string($value) && !\preg_match('/^[^\\x00-\\x08\\x0B\\x0E-\\x1A\\x1C-\\x1F\\x7F]*+$/u', $value)) { + $element->setAttribute('type', 'binary'); + $text = $this->document->createTextNode(self::phpToXml(\base64_encode($value))); + $element->appendChild($text); + } elseif ($value instanceof \UnitEnum) { + $element->setAttribute('type', 'constant'); + $element->appendChild($this->document->createTextNode(self::phpToXml($value))); + } elseif ($value instanceof AbstractArgument) { + $element->setAttribute('type', 'abstract'); + $text = $this->document->createTextNode(self::phpToXml($value->getText())); + $element->appendChild($text); + } else { + if (\in_array($value, ['null', 'true', 'false'], \true)) { + $element->setAttribute('type', 'string'); + } + if (\is_string($value) && (\is_numeric($value) || \preg_match('/^0b[01]*$/', $value) || \preg_match('/^0x[0-9a-f]++$/i', $value))) { + $element->setAttribute('type', 'string'); + } + $text = $this->document->createTextNode(self::phpToXml($value)); + $element->appendChild($text); + } + $parent->appendChild($element); + } + } + /** + * Escapes arguments. + */ + private function escape(array $arguments) : array + { + $args = []; + foreach ($arguments as $k => $v) { + if (\is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (\is_string($v)) { + $args[$k] = \str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + return $args; + } + /** + * Converts php types to xml types. + * + * @throws RuntimeException When trying to dump object or resource + * @param mixed $value + */ + public static function phpToXml($value) : string + { + switch (\true) { + case null === $value: + return 'null'; + case \true === $value: + return 'true'; + case \false === $value: + return 'false'; + case $value instanceof Parameter: + return '%' . $value . '%'; + case $value instanceof \UnitEnum: + return \sprintf('%s::%s', \get_class($value), $value->name); + case \is_object($value) || \is_resource($value): + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + default: + return (string) $value; + } + } +} diff --git a/vendor/symfony/dependency-injection/Dumper/YamlDumper.php b/vendor/symfony/dependency-injection/Dumper/YamlDumper.php new file mode 100644 index 0000000000..938ff22f54 --- /dev/null +++ b/vendor/symfony/dependency-injection/Dumper/YamlDumper.php @@ -0,0 +1,313 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Dumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Parameter; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Dumper as YmlDumper; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Parser; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Tag\TaggedValue; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Yaml; +/** + * YamlDumper dumps a service container as a YAML string. + * + * @author Fabien Potencier + */ +class YamlDumper extends Dumper +{ + /** + * @var YmlDumper + */ + private $dumper; + /** + * Dumps the service container as an YAML string. + */ + public function dump(array $options = []) : string + { + if (!\class_exists(YmlDumper::class)) { + throw new LogicException('Unable to dump the container as the Symfony Yaml Component is not installed.'); + } + $this->dumper = $this->dumper ?? new YmlDumper(); + return $this->container->resolveEnvPlaceholders($this->addParameters() . "\n" . $this->addServices()); + } + private function addService(string $id, Definition $definition) : string + { + $code = " {$id}:\n"; + if ($class = $definition->getClass()) { + if (\strncmp($class, '\\', \strlen('\\')) === 0) { + $class = \substr($class, 1); + } + $code .= \sprintf(" class: %s\n", $this->dumper->dump($class)); + } + if (!$definition->isPrivate()) { + $code .= \sprintf(" public: %s\n", $definition->isPublic() ? 'true' : 'false'); + } + $tagsCode = ''; + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $att = []; + foreach ($attributes as $key => $value) { + $att[] = \sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value)); + } + $att = $att ? ': { ' . \implode(', ', $att) . ' }' : ''; + $tagsCode .= \sprintf(" - %s%s\n", $this->dumper->dump($name), $att); + } + } + if ($tagsCode) { + $code .= " tags:\n" . $tagsCode; + } + if ($definition->getFile()) { + $code .= \sprintf(" file: %s\n", $this->dumper->dump($definition->getFile())); + } + if ($definition->isSynthetic()) { + $code .= " synthetic: true\n"; + } + if ($definition->isDeprecated()) { + $code .= " deprecated:\n"; + foreach ($definition->getDeprecation('%service_id%') as $key => $value) { + if ('' !== $value) { + $code .= \sprintf(" %s: %s\n", $key, $this->dumper->dump($value)); + } + } + } + if ($definition->isAutowired()) { + $code .= " autowire: true\n"; + } + if ($definition->isAutoconfigured()) { + $code .= " autoconfigure: true\n"; + } + if ($definition->isAbstract()) { + $code .= " abstract: true\n"; + } + if ($definition->isLazy()) { + $code .= " lazy: true\n"; + } + if ($definition->getArguments()) { + $code .= \sprintf(" arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0)); + } + if ($definition->getProperties()) { + $code .= \sprintf(" properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0)); + } + if ($definition->getMethodCalls()) { + $code .= \sprintf(" calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12)); + } + if (!$definition->isShared()) { + $code .= " shared: false\n"; + } + if (null !== ($decoratedService = $definition->getDecoratedService())) { + [$decorated, $renamedId, $priority] = $decoratedService; + $code .= \sprintf(" decorates: %s\n", $decorated); + if (null !== $renamedId) { + $code .= \sprintf(" decoration_inner_name: %s\n", $renamedId); + } + if (0 !== $priority) { + $code .= \sprintf(" decoration_priority: %s\n", $priority); + } + $decorationOnInvalid = $decoratedService[3] ?? ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if (\in_array($decorationOnInvalid, [ContainerInterface::IGNORE_ON_INVALID_REFERENCE, ContainerInterface::NULL_ON_INVALID_REFERENCE])) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE === $decorationOnInvalid ? 'null' : 'ignore'; + $code .= \sprintf(" decoration_on_invalid: %s\n", $invalidBehavior); + } + } + if ($callable = $definition->getFactory()) { + $code .= \sprintf(" factory: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0)); + } + if ($callable = $definition->getConfigurator()) { + $code .= \sprintf(" configurator: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0)); + } + return $code; + } + private function addServiceAlias(string $alias, Alias $id) : string + { + $deprecated = ''; + if ($id->isDeprecated()) { + $deprecated = " deprecated:\n"; + foreach ($id->getDeprecation('%alias_id%') as $key => $value) { + if ('' !== $value) { + $deprecated .= \sprintf(" %s: %s\n", $key, $value); + } + } + } + if (!$id->isDeprecated() && $id->isPrivate()) { + return \sprintf(" %s: '@%s'\n", $alias, $id); + } + if ($id->isPublic()) { + $deprecated = " public: true\n" . $deprecated; + } + return \sprintf(" %s:\n alias: %s\n%s", $alias, $id, $deprecated); + } + private function addServices() : string + { + if (!$this->container->getDefinitions()) { + return ''; + } + $code = "services:\n"; + foreach ($this->container->getDefinitions() as $id => $definition) { + $code .= $this->addService($id, $definition); + } + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + while (isset($aliases[(string) $id])) { + $id = $aliases[(string) $id]; + } + $code .= $this->addServiceAlias($alias, $id); + } + return $code; + } + private function addParameters() : string + { + if (!$this->container->getParameterBag()->all()) { + return ''; + } + $parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isCompiled()); + return $this->dumper->dump(['parameters' => $parameters], 2); + } + /** + * Dumps callable to YAML format. + * @param mixed $callable + * @return mixed + */ + private function dumpCallable($callable) + { + if (\is_array($callable)) { + if ($callable[0] instanceof Reference) { + $callable = [$this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]]; + } else { + $callable = [$callable[0], $callable[1]]; + } + } + return $callable; + } + /** + * Dumps the value to YAML format. + * + * @throws RuntimeException When trying to dump object or resource + * @param mixed $value + * @return mixed + */ + private function dumpValue($value) + { + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + return new TaggedValue('service_closure', $this->dumpValue($value)); + } + if ($value instanceof ArgumentInterface) { + $tag = $value; + if ($value instanceof TaggedIteratorArgument || $value instanceof ServiceLocatorArgument && ($tag = $value->getTaggedIteratorArgument())) { + if (null === $tag->getIndexAttribute()) { + $content = $tag->getTag(); + } else { + $content = ['tag' => $tag->getTag(), 'index_by' => $tag->getIndexAttribute()]; + if (null !== $tag->getDefaultIndexMethod()) { + $content['default_index_method'] = $tag->getDefaultIndexMethod(); + } + if (null !== $tag->getDefaultPriorityMethod()) { + $content['default_priority_method'] = $tag->getDefaultPriorityMethod(); + } + } + return new TaggedValue($value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator', $content); + } + if ($value instanceof IteratorArgument) { + $tag = 'iterator'; + } elseif ($value instanceof ServiceLocatorArgument) { + $tag = 'service_locator'; + } else { + throw new RuntimeException(\sprintf('Unspecified Yaml tag for type "%s".', \get_debug_type($value))); + } + return new TaggedValue($tag, $this->dumpValue($value->getValues())); + } + if (\is_array($value)) { + $code = []; + foreach ($value as $k => $v) { + $code[$k] = $this->dumpValue($v); + } + return $code; + } elseif ($value instanceof Reference) { + return $this->getServiceCall((string) $value, $value); + } elseif ($value instanceof Parameter) { + return $this->getParameterCall((string) $value); + } elseif ($value instanceof Expression) { + return $this->getExpressionCall((string) $value); + } elseif ($value instanceof Definition) { + return new TaggedValue('service', (new Parser())->parse("_:\n" . $this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']); + } elseif ($value instanceof \UnitEnum) { + return new TaggedValue('php/const', \sprintf('%s::%s', \get_class($value), $value->name)); + } elseif ($value instanceof AbstractArgument) { + return new TaggedValue('abstract', $value->getText()); + } elseif (\is_object($value) || \is_resource($value)) { + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + } + return $value; + } + private function getServiceCall(string $id, Reference $reference = null) : string + { + if (null !== $reference) { + switch ($reference->getInvalidBehavior()) { + case ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE: + break; + case ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE: + break; + case ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE: + return \sprintf('@!%s', $id); + default: + return \sprintf('@?%s', $id); + } + } + return \sprintf('@%s', $id); + } + private function getParameterCall(string $id) : string + { + return \sprintf('%%%s%%', $id); + } + private function getExpressionCall(string $expression) : string + { + return \sprintf('@=%s', $expression); + } + private function prepareParameters(array $parameters, bool $escape = \true) : array + { + $filtered = []; + foreach ($parameters as $key => $value) { + if (\is_array($value)) { + $value = $this->prepareParameters($value, $escape); + } elseif ($value instanceof Reference || \is_string($value) && \strncmp($value, '@', \strlen('@')) === 0) { + $value = '@' . $value; + } + $filtered[$key] = $value; + } + return $escape ? $this->escape($filtered) : $filtered; + } + private function escape(array $arguments) : array + { + $args = []; + foreach ($arguments as $k => $v) { + if (\is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (\is_string($v)) { + $args[$k] = \str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + return $args; + } +} diff --git a/vendor/symfony/dependency-injection/EnvVarLoaderInterface.php b/vendor/symfony/dependency-injection/EnvVarLoaderInterface.php new file mode 100644 index 0000000000..f7d51235e3 --- /dev/null +++ b/vendor/symfony/dependency-injection/EnvVarLoaderInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * EnvVarLoaderInterface objects return key/value pairs that are added to the list of available env vars. + * + * @author Nicolas Grekas + */ +interface EnvVarLoaderInterface +{ + /** + * @return string[] Key/value pairs that can be accessed using the regular "%env()%" syntax + */ + public function loadEnvVars() : array; +} diff --git a/vendor/symfony/dependency-injection/EnvVarProcessor.php b/vendor/symfony/dependency-injection/EnvVarProcessor.php new file mode 100644 index 0000000000..58d6db9a1b --- /dev/null +++ b/vendor/symfony/dependency-injection/EnvVarProcessor.php @@ -0,0 +1,237 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * @author Nicolas Grekas + */ +class EnvVarProcessor implements EnvVarProcessorInterface +{ + /** + * @var \Symfony\Component\DependencyInjection\ContainerInterface + */ + private $container; + /** + * @var \Traversable + */ + private $loaders; + /** + * @var mixed[] + */ + private $loadedVars = []; + /** + * @param EnvVarLoaderInterface[] $loaders + */ + public function __construct(ContainerInterface $container, \Traversable $loaders = null) + { + $this->container = $container; + $this->loaders = $loaders ?? new \ArrayIterator(); + } + /** + * {@inheritdoc} + */ + public static function getProvidedTypes() : array + { + return ['base64' => 'string', 'bool' => 'bool', 'not' => 'bool', 'const' => 'bool|int|float|string|array', 'csv' => 'array', 'file' => 'string', 'float' => 'float', 'int' => 'int', 'json' => 'array', 'key' => 'bool|int|float|string|array', 'url' => 'array', 'query_string' => 'array', 'resolve' => 'string', 'default' => 'bool|int|float|string|array', 'string' => 'string', 'trim' => 'string', 'require' => 'bool|int|float|string|array']; + } + /** + * {@inheritdoc} + * @return mixed + */ + public function getEnv(string $prefix, string $name, \Closure $getEnv) + { + $i = \strpos($name, ':'); + if ('key' === $prefix) { + if (\false === $i) { + throw new RuntimeException(\sprintf('Invalid env "key:%s": a key specifier should be provided.', $name)); + } + $next = \substr($name, $i + 1); + $key = \substr($name, 0, $i); + $array = $getEnv($next); + if (!\is_array($array)) { + throw new RuntimeException(\sprintf('Resolved value of "%s" did not result in an array value.', $next)); + } + if (!isset($array[$key]) && !\array_key_exists($key, $array)) { + throw new EnvNotFoundException(\sprintf('Key "%s" not found in %s (resolved from "%s").', $key, \json_encode($array), $next)); + } + return $array[$key]; + } + if ('default' === $prefix) { + if (\false === $i) { + throw new RuntimeException(\sprintf('Invalid env "default:%s": a fallback parameter should be provided.', $name)); + } + $next = \substr($name, $i + 1); + $default = \substr($name, 0, $i); + if ('' !== $default && !$this->container->hasParameter($default)) { + throw new RuntimeException(\sprintf('Invalid env fallback in "default:%s": parameter "%s" not found.', $name, $default)); + } + try { + $env = $getEnv($next); + if ('' !== $env && null !== $env) { + return $env; + } + } catch (EnvNotFoundException $exception) { + // no-op + } + return '' === $default ? null : $this->container->getParameter($default); + } + if ('file' === $prefix || 'require' === $prefix) { + if (!\is_scalar($file = $getEnv($name))) { + throw new RuntimeException(\sprintf('Invalid file name: env var "%s" is non-scalar.', $name)); + } + if (!\is_file($file)) { + throw new EnvNotFoundException(\sprintf('File "%s" not found (resolved from "%s").', $file, $name)); + } + if ('file' === $prefix) { + return \file_get_contents($file); + } else { + return require $file; + } + } + if (\false !== $i || 'string' !== $prefix) { + $env = $getEnv($name); + } elseif (isset($_ENV[$name])) { + $env = $_ENV[$name]; + } elseif (isset($_SERVER[$name]) && \strncmp($name, 'HTTP_', \strlen('HTTP_')) !== 0) { + $env = $_SERVER[$name]; + } elseif (\false === ($env = \getenv($name)) || null === $env) { + // null is a possible value because of thread safety issues + foreach ($this->loadedVars as $vars) { + if (\false !== ($env = $vars[$name] ?? \false)) { + break; + } + } + if (\false === $env || null === $env) { + $loaders = $this->loaders; + $this->loaders = new \ArrayIterator(); + try { + $i = 0; + $ended = \true; + $count = $loaders instanceof \Countable ? $loaders->count() : 0; + foreach ($loaders as $loader) { + if (\count($this->loadedVars) > $i++) { + continue; + } + $this->loadedVars[] = $vars = $loader->loadEnvVars(); + if (\false !== ($env = $vars[$name] ?? \false)) { + $ended = \false; + break; + } + } + if ($ended || $count === $i) { + $loaders = $this->loaders; + } + } catch (ParameterCircularReferenceException $exception) { + // skip loaders that need an env var that is not defined + } finally { + $this->loaders = $loaders; + } + } + if (\false === $env || null === $env) { + if (!$this->container->hasParameter("env({$name})")) { + throw new EnvNotFoundException(\sprintf('Environment variable not found: "%s".', $name)); + } + $env = $this->container->getParameter("env({$name})"); + } + } + if (null === $env) { + if (!isset($this->getProvidedTypes()[$prefix])) { + throw new RuntimeException(\sprintf('Unsupported env var prefix "%s".', $prefix)); + } + return null; + } + if (!\is_scalar($env)) { + throw new RuntimeException(\sprintf('Non-scalar env var "%s" cannot be cast to "%s".', $name, $prefix)); + } + if ('string' === $prefix) { + return (string) $env; + } + if (\in_array($prefix, ['bool', 'not'], \true)) { + $env = (bool) ((\filter_var($env, \FILTER_VALIDATE_BOOLEAN) ?: \filter_var($env, \FILTER_VALIDATE_INT)) ?: \filter_var($env, \FILTER_VALIDATE_FLOAT)); + return 'not' === $prefix ? !$env : $env; + } + if ('int' === $prefix) { + if (\false === ($env = \filter_var($env, \FILTER_VALIDATE_INT) ?: \filter_var($env, \FILTER_VALIDATE_FLOAT))) { + throw new RuntimeException(\sprintf('Non-numeric env var "%s" cannot be cast to int.', $name)); + } + return (int) $env; + } + if ('float' === $prefix) { + if (\false === ($env = \filter_var($env, \FILTER_VALIDATE_FLOAT))) { + throw new RuntimeException(\sprintf('Non-numeric env var "%s" cannot be cast to float.', $name)); + } + return (float) $env; + } + if ('const' === $prefix) { + if (!\defined($env)) { + throw new RuntimeException(\sprintf('Env var "%s" maps to undefined constant "%s".', $name, $env)); + } + return \constant($env); + } + if ('base64' === $prefix) { + return \base64_decode(\strtr($env, '-_', '+/')); + } + if ('json' === $prefix) { + $env = \json_decode($env, \true); + if (\JSON_ERROR_NONE !== \json_last_error()) { + throw new RuntimeException(\sprintf('Invalid JSON in env var "%s": ', $name) . \json_last_error_msg()); + } + if (null !== $env && !\is_array($env)) { + throw new RuntimeException(\sprintf('Invalid JSON env var "%s": array or null expected, "%s" given.', $name, \get_debug_type($env))); + } + return $env; + } + if ('url' === $prefix) { + $parsedEnv = \parse_url($env); + if (\false === $parsedEnv) { + throw new RuntimeException(\sprintf('Invalid URL in env var "%s".', $name)); + } + if (!isset($parsedEnv['scheme'], $parsedEnv['host'])) { + throw new RuntimeException(\sprintf('Invalid URL env var "%s": schema and host expected, "%s" given.', $name, $env)); + } + $parsedEnv += ['port' => null, 'user' => null, 'pass' => null, 'path' => null, 'query' => null, 'fragment' => null]; + // remove the '/' separator + $parsedEnv['path'] = '/' === ($parsedEnv['path'] ?? '/') ? '' : \substr($parsedEnv['path'], 1); + return $parsedEnv; + } + if ('query_string' === $prefix) { + $queryString = \parse_url($env, \PHP_URL_QUERY) ?: $env; + \parse_str($queryString, $result); + return $result; + } + if ('resolve' === $prefix) { + return \preg_replace_callback('/%%|%([^%\\s]+)%/', function ($match) use($name, $getEnv) { + if (!isset($match[1])) { + return '%'; + } + if (\strncmp($match[1], 'env(', \strlen('env(')) === 0 && \substr_compare($match[1], ')', -\strlen(')')) === 0 && 'env()' !== $match[1]) { + $value = $getEnv(\substr($match[1], 4, -1)); + } else { + $value = $this->container->getParameter($match[1]); + } + if (!\is_scalar($value)) { + throw new RuntimeException(\sprintf('Parameter "%s" found when resolving env var "%s" must be scalar, "%s" given.', $match[1], $name, \get_debug_type($value))); + } + return $value; + }, $env); + } + if ('csv' === $prefix) { + return \str_getcsv($env, ',', '"', ''); + } + if ('trim' === $prefix) { + return \trim($env); + } + throw new RuntimeException(\sprintf('Unsupported env var prefix "%s" for env name "%s".', $prefix, $name)); + } +} diff --git a/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php b/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php new file mode 100644 index 0000000000..8de3c4c3cd --- /dev/null +++ b/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * The EnvVarProcessorInterface is implemented by objects that manage environment-like variables. + * + * @author Nicolas Grekas + */ +interface EnvVarProcessorInterface +{ + /** + * Returns the value of the given variable as managed by the current instance. + * + * @param string $prefix The namespace of the variable + * @param string $name The name of the variable within the namespace + * @param \Closure $getEnv A closure that allows fetching more env vars + * + * @throws RuntimeException on error + * @return mixed + */ + public function getEnv(string $prefix, string $name, \Closure $getEnv); + /** + * @return string[] The PHP-types managed by getEnv(), keyed by prefixes + */ + public static function getProvidedTypes() : array; +} diff --git a/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php b/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php new file mode 100644 index 0000000000..59317e374a --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * Thrown when a definition cannot be autowired. + */ +class AutowiringFailedException extends RuntimeException +{ + /** + * @var string + */ + private $serviceId; + /** + * @var \Closure|null + */ + private $messageCallback; + /** + * @param string|\Closure $message + */ + public function __construct(string $serviceId, $message = '', int $code = 0, \Throwable $previous = null) + { + $this->serviceId = $serviceId; + if ($message instanceof \Closure && (\function_exists('xdebug_is_enabled') ? \xdebug_is_enabled() : \function_exists('xdebug_info'))) { + $message = $message(); + } + if (!$message instanceof \Closure) { + parent::__construct($message, $code, $previous); + return; + } + $this->messageCallback = $message; + parent::__construct('', $code, $previous); + $this->message = new class($this->message, $this->messageCallback) + { + /** + * @var string|$this + */ + private $message; + /** + * @var \Closure|null + */ + private $messageCallback; + public function __construct(&$message, &$messageCallback) + { + $this->message =& $message; + $this->messageCallback =& $messageCallback; + } + public function __toString() : string + { + $messageCallback = $this->messageCallback; + $this->messageCallback = null; + try { + return $this->message = $messageCallback(); + } catch (\Throwable $e) { + return $this->message = $e->getMessage(); + } + } + }; + } + public function getMessageCallback() : ?\Closure + { + return $this->messageCallback; + } + public function getServiceId() + { + return $this->serviceId; + } +} diff --git a/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php b/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php new file mode 100644 index 0000000000..5c802ddb10 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * Base BadMethodCallException for Dependency Injection component. + */ +class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php b/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php new file mode 100644 index 0000000000..b34b068e7c --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when an environment variable is not found. + * + * @author Nicolas Grekas + */ +class EnvNotFoundException extends InvalidArgumentException +{ +} diff --git a/vendor/symfony/dependency-injection/Exception/EnvParameterException.php b/vendor/symfony/dependency-injection/Exception/EnvParameterException.php new file mode 100644 index 0000000000..f3f9583f25 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/EnvParameterException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * This exception wraps exceptions whose messages contain a reference to an env parameter. + * + * @author Nicolas Grekas + */ +class EnvParameterException extends InvalidArgumentException +{ + public function __construct(array $envs, \Throwable $previous = null, string $message = 'Incompatible use of dynamic environment variables "%s" found in parameters.') + { + parent::__construct(\sprintf($message, \implode('", "', $envs)), 0, $previous); + } +} diff --git a/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php b/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php new file mode 100644 index 0000000000..ed6d55b950 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerExceptionInterface; +/** + * Base ExceptionInterface for Dependency Injection component. + * + * @author Fabien Potencier + * @author Bulat Shakirzyanov + */ +interface ExceptionInterface extends ContainerExceptionInterface +{ +} diff --git a/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php b/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000..fc24ce3516 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * Base InvalidArgumentException for Dependency Injection component. + * + * @author Bulat Shakirzyanov + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/dependency-injection/Exception/InvalidParameterTypeException.php b/vendor/symfony/dependency-injection/Exception/InvalidParameterTypeException.php new file mode 100644 index 0000000000..b023eeadf7 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/InvalidParameterTypeException.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * Thrown when trying to inject a parameter into a constructor/method with an incompatible type. + * + * @author Nicolas Grekas + * @author Julien Maulny + */ +class InvalidParameterTypeException extends InvalidArgumentException +{ + public function __construct(string $serviceId, string $type, \ReflectionParameter $parameter) + { + $acceptedType = $parameter->getType(); + $acceptedType = $acceptedType instanceof \ReflectionNamedType ? $acceptedType->getName() : (string) $acceptedType; + $this->code = $type; + $function = $parameter->getDeclaringFunction(); + $functionName = $function instanceof \ReflectionMethod ? \sprintf('%s::%s', $function->getDeclaringClass()->getName(), $function->getName()) : $function->getName(); + parent::__construct(\sprintf('Invalid definition for service "%s": argument %d of "%s()" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $functionName, $acceptedType, $type)); + } +} diff --git a/vendor/symfony/dependency-injection/Exception/LogicException.php b/vendor/symfony/dependency-injection/Exception/LogicException.php new file mode 100644 index 0000000000..b1d474668b --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/LogicException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * Base LogicException for Dependency Injection component. + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php b/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php new file mode 100644 index 0000000000..16fc7936c2 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * Base OutOfBoundsException for Dependency Injection component. + */ +class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php b/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php new file mode 100644 index 0000000000..83ba292079 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference in a parameter is detected. + * + * @author Fabien Potencier + */ +class ParameterCircularReferenceException extends RuntimeException +{ + /** + * @var mixed[] + */ + private $parameters; + public function __construct(array $parameters, \Throwable $previous = null) + { + parent::__construct(\sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], \implode('" > "', $parameters), $parameters[0]), 0, $previous); + $this->parameters = $parameters; + } + public function getParameters() + { + return $this->parameters; + } +} diff --git a/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php b/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php new file mode 100644 index 0000000000..39a5625afe --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +use MonorepoBuilderPrefix202310\Psr\Container\NotFoundExceptionInterface; +/** + * This exception is thrown when a non-existent parameter is used. + * + * @author Fabien Potencier + */ +class ParameterNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface +{ + /** + * @var string + */ + private $key; + /** + * @var string|null + */ + private $sourceId; + /** + * @var string|null + */ + private $sourceKey; + /** + * @var mixed[] + */ + private $alternatives; + /** + * @var string|null + */ + private $nonNestedAlternative; + /** + * @param string $key The requested parameter key + * @param string|null $sourceId The service id that references the non-existent parameter + * @param string|null $sourceKey The parameter key that references the non-existent parameter + * @param \Throwable|null $previous The previous exception + * @param string[] $alternatives Some parameter name alternatives + * @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters + */ + public function __construct(string $key, string $sourceId = null, string $sourceKey = null, \Throwable $previous = null, array $alternatives = [], string $nonNestedAlternative = null) + { + $this->key = $key; + $this->sourceId = $sourceId; + $this->sourceKey = $sourceKey; + $this->alternatives = $alternatives; + $this->nonNestedAlternative = $nonNestedAlternative; + parent::__construct('', 0, $previous); + $this->updateRepr(); + } + public function updateRepr() + { + if (null !== $this->sourceId) { + $this->message = \sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key); + } elseif (null !== $this->sourceKey) { + $this->message = \sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key); + } else { + $this->message = \sprintf('You have requested a non-existent parameter "%s".', $this->key); + } + if ($this->alternatives) { + if (1 == \count($this->alternatives)) { + $this->message .= ' Did you mean this: "'; + } else { + $this->message .= ' Did you mean one of these: "'; + } + $this->message .= \implode('", "', $this->alternatives) . '"?'; + } elseif (null !== $this->nonNestedAlternative) { + $this->message .= ' You cannot access nested array items, do you want to inject "' . $this->nonNestedAlternative . '" instead?'; + } + } + public function getKey() + { + return $this->key; + } + public function getSourceId() + { + return $this->sourceId; + } + public function getSourceKey() + { + return $this->sourceKey; + } + public function setSourceId(?string $sourceId) + { + $this->sourceId = $sourceId; + $this->updateRepr(); + } + public function setSourceKey(?string $sourceKey) + { + $this->sourceKey = $sourceKey; + $this->updateRepr(); + } +} diff --git a/vendor/symfony/dependency-injection/Exception/RuntimeException.php b/vendor/symfony/dependency-injection/Exception/RuntimeException.php new file mode 100644 index 0000000000..6be3b3b7d7 --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/RuntimeException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * Base RuntimeException for Dependency Injection component. + * + * @author Johannes M. Schmitt + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php b/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php new file mode 100644 index 0000000000..c33cd152fe --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference is detected. + * + * @author Johannes M. Schmitt + */ +class ServiceCircularReferenceException extends RuntimeException +{ + /** + * @var string + */ + private $serviceId; + /** + * @var mixed[] + */ + private $path; + public function __construct(string $serviceId, array $path, \Throwable $previous = null) + { + parent::__construct(\sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, \implode(' -> ', $path)), 0, $previous); + $this->serviceId = $serviceId; + $this->path = $path; + } + public function getServiceId() + { + return $this->serviceId; + } + public function getPath() + { + return $this->path; + } +} diff --git a/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php b/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php new file mode 100644 index 0000000000..8272a97e2b --- /dev/null +++ b/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception; + +use MonorepoBuilderPrefix202310\Psr\Container\NotFoundExceptionInterface; +/** + * This exception is thrown when a non-existent service is requested. + * + * @author Johannes M. Schmitt + */ +class ServiceNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface +{ + /** + * @var string + */ + private $id; + /** + * @var string|null + */ + private $sourceId; + /** + * @var mixed[] + */ + private $alternatives; + public function __construct(string $id, string $sourceId = null, \Throwable $previous = null, array $alternatives = [], string $msg = null) + { + if (null !== $msg) { + // no-op + } elseif (null === $sourceId) { + $msg = \sprintf('You have requested a non-existent service "%s".', $id); + } else { + $msg = \sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id); + } + if ($alternatives) { + if (1 == \count($alternatives)) { + $msg .= ' Did you mean this: "'; + } else { + $msg .= ' Did you mean one of these: "'; + } + $msg .= \implode('", "', $alternatives) . '"?'; + } + parent::__construct($msg, 0, $previous); + $this->id = $id; + $this->sourceId = $sourceId; + $this->alternatives = $alternatives; + } + public function getId() + { + return $this->id; + } + public function getSourceId() + { + return $this->sourceId; + } + public function getAlternatives() + { + return $this->alternatives; + } +} diff --git a/vendor/symfony/dependency-injection/ExpressionLanguage.php b/vendor/symfony/dependency-injection/ExpressionLanguage.php new file mode 100644 index 0000000000..5928ec3b8d --- /dev/null +++ b/vendor/symfony/dependency-injection/ExpressionLanguage.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Psr\Cache\CacheItemPoolInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage; +if (!\class_exists(BaseExpressionLanguage::class)) { + return; +} +/** + * Adds some function to the default ExpressionLanguage. + * + * @author Fabien Potencier + * + * @see ExpressionLanguageProvider + */ +class ExpressionLanguage extends BaseExpressionLanguage +{ + /** + * {@inheritdoc} + */ + public function __construct(CacheItemPoolInterface $cache = null, array $providers = [], callable $serviceCompiler = null, \Closure $getEnv = null) + { + // prepend the default provider to let users override it easily + \array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler, $getEnv)); + parent::__construct($cache, $providers); + } +} diff --git a/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php b/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php new file mode 100644 index 0000000000..a083d7fb55 --- /dev/null +++ b/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\ExpressionFunction; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; +/** + * Define some ExpressionLanguage functions. + * + * To get a service, use service('request'). + * To get a parameter, use parameter('kernel.debug'). + * To get an env variable, use env('SOME_VARIABLE'). + * + * @author Fabien Potencier + */ +class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface +{ + /** + * @var \Closure|null + */ + private $serviceCompiler; + /** + * @var \Closure|null + */ + private $getEnv; + public function __construct(callable $serviceCompiler = null, \Closure $getEnv = null) + { + $this->serviceCompiler = null === $serviceCompiler ? null : \Closure::fromCallable($serviceCompiler); + $this->getEnv = $getEnv; + } + public function getFunctions() : array + { + return [new ExpressionFunction('service', $this->serviceCompiler ?? function ($arg) { + return \sprintf('$this->get(%s)', $arg); + }, function (array $variables, $value) { + return $variables['container']->get($value); + }), new ExpressionFunction('parameter', function ($arg) { + return \sprintf('$this->getParameter(%s)', $arg); + }, function (array $variables, $value) { + return $variables['container']->getParameter($value); + }), new ExpressionFunction('env', function ($arg) { + return \sprintf('$this->getEnv(%s)', $arg); + }, function (array $variables, $value) { + if (!$this->getEnv) { + throw new LogicException('You need to pass a getEnv closure to the expression langage provider to use the "env" function.'); + } + return ($this->getEnv)($value); + }), new ExpressionFunction('arg', function ($arg) { + return \sprintf('$args?->get(%s)', $arg); + }, function (array $variables, $value) { + return ($nullsafeVariable1 = $variables['args']) ? $nullsafeVariable1->get($value) : null; + })]; + } +} diff --git a/vendor/symfony/dependency-injection/Extension/AbstractExtension.php b/vendor/symfony/dependency-injection/Extension/AbstractExtension.php new file mode 100644 index 0000000000..19b5c9a5db --- /dev/null +++ b/vendor/symfony/dependency-injection/Extension/AbstractExtension.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Configuration; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +/** + * An Extension that provides configuration hooks. + * + * @author Yonel Ceruto + */ +abstract class AbstractExtension extends Extension implements ConfigurableExtensionInterface, PrependExtensionInterface +{ + use ExtensionTrait; + public function configure(DefinitionConfigurator $definition) : void + { + } + public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder) : void + { + } + public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder) : void + { + } + public function getConfiguration(array $config, ContainerBuilder $container) : ?ConfigurationInterface + { + return new Configuration($this, $container, $this->getAlias()); + } + public final function prepend(ContainerBuilder $container) : void + { + $callback = function (ContainerConfigurator $configurator) use($container) { + $this->prependExtension($configurator, $container); + }; + $this->executeConfiguratorCallback($container, $callback, $this); + } + public final function load(array $configs, ContainerBuilder $container) : void + { + $config = $this->processConfiguration($this->getConfiguration([], $container), $configs); + $callback = function (ContainerConfigurator $configurator) use($config, $container) { + $this->loadExtension($config, $configurator, $container); + }; + $this->executeConfiguratorCallback($container, $callback, $this); + } +} diff --git a/vendor/symfony/dependency-injection/Extension/ConfigurableExtensionInterface.php b/vendor/symfony/dependency-injection/Extension/ConfigurableExtensionInterface.php new file mode 100644 index 0000000000..ad97903ea6 --- /dev/null +++ b/vendor/symfony/dependency-injection/Extension/ConfigurableExtensionInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurableInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +/** + * @author Yonel Ceruto + */ +interface ConfigurableExtensionInterface extends ConfigurableInterface +{ + /** + * Allows an extension to prepend the extension configurations. + */ + public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder) : void; + /** + * Loads a specific configuration. + */ + public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder) : void; +} diff --git a/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php b/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php new file mode 100644 index 0000000000..3b50ee6a3a --- /dev/null +++ b/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * ConfigurationExtensionInterface is the interface implemented by container extension classes. + * + * @author Kevin Bond + */ +interface ConfigurationExtensionInterface +{ + /** + * Returns extension configuration. + * + * @return ConfigurationInterface|null + */ + public function getConfiguration(array $config, ContainerBuilder $container); +} diff --git a/vendor/symfony/dependency-injection/Extension/Extension.php b/vendor/symfony/dependency-injection/Extension/Extension.php new file mode 100644 index 0000000000..0863b4e6f8 --- /dev/null +++ b/vendor/symfony/dependency-injection/Extension/Extension.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\ConfigurationInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Definition\Processor; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Container; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +/** + * Provides useful features shared by many extensions. + * + * @author Fabien Potencier + */ +abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface +{ + /** + * @var mixed[] + */ + private $processedConfigs = []; + /** + * {@inheritdoc} + */ + public function getXsdValidationBasePath() + { + return \false; + } + /** + * {@inheritdoc} + */ + public function getNamespace() + { + return 'http://example.org/schema/dic/' . $this->getAlias(); + } + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * This convention is to remove the "Extension" postfix from the class + * name and then lowercase and underscore the result. So: + * + * AcmeHelloExtension + * + * becomes + * + * acme_hello + * + * This can be overridden in a sub-class to specify the alias manually. + * + * @throws BadMethodCallException When the extension name does not follow conventions + */ + public function getAlias() : string + { + $className = static::class; + if (\substr_compare($className, 'Extension', -\strlen('Extension')) !== 0) { + throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.'); + } + $classBaseName = \substr(\strrchr($className, '\\'), 1, -9); + return Container::underscore($classBaseName); + } + /** + * {@inheritdoc} + */ + public function getConfiguration(array $config, ContainerBuilder $container) + { + $class = static::class; + if (\strpos($class, "\x00") !== \false) { + return null; + // ignore anonymous classes + } + $class = \substr_replace($class, '\\Configuration', \strrpos($class, '\\')); + $class = $container->getReflectionClass($class); + if (!$class) { + return null; + } + if (!$class->implementsInterface(ConfigurationInterface::class)) { + throw new LogicException(\sprintf('The extension configuration class "%s" must implement "%s".', $class->getName(), ConfigurationInterface::class)); + } + if (!($constructor = $class->getConstructor()) || !$constructor->getNumberOfRequiredParameters()) { + return $class->newInstance(); + } + return null; + } + protected final function processConfiguration(ConfigurationInterface $configuration, array $configs) : array + { + $processor = new Processor(); + return $this->processedConfigs[] = $processor->processConfiguration($configuration, $configs); + } + /** + * @internal + */ + public final function getProcessedConfigs() : array + { + try { + return $this->processedConfigs; + } finally { + $this->processedConfigs = []; + } + } + /** + * @throws InvalidArgumentException When the config is not enableable + */ + protected function isConfigEnabled(ContainerBuilder $container, array $config) : bool + { + if (!\array_key_exists('enabled', $config)) { + throw new InvalidArgumentException("The config array has no 'enabled' key."); + } + return (bool) $container->getParameterBag()->resolveValue($config['enabled']); + } +} diff --git a/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php b/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php new file mode 100644 index 0000000000..66f09a7296 --- /dev/null +++ b/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * ExtensionInterface is the interface implemented by container extension classes. + * + * @author Fabien Potencier + */ +interface ExtensionInterface +{ + /** + * Loads a specific configuration. + * + * @throws \InvalidArgumentException When provided tag is not defined in this extension + */ + public function load(array $configs, ContainerBuilder $container); + /** + * Returns the namespace to be used for this extension (XML namespace). + * + * @return string + */ + public function getNamespace(); + /** + * Returns the base path for the XSD files. + * + * @return string|false + */ + public function getXsdValidationBasePath(); + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * @return string + */ + public function getAlias(); +} diff --git a/vendor/symfony/dependency-injection/Extension/ExtensionTrait.php b/vendor/symfony/dependency-injection/Extension/ExtensionTrait.php new file mode 100644 index 0000000000..b6d18406c2 --- /dev/null +++ b/vendor/symfony/dependency-injection/Extension/ExtensionTrait.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder\ConfigBuilderGenerator; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\FileLocator; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\DelegatingLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\LoaderResolver; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\DirectoryLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\GlobFileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +/** + * @author Yonel Ceruto + */ +trait ExtensionTrait +{ + private function executeConfiguratorCallback(ContainerBuilder $container, \Closure $callback, ConfigurableExtensionInterface $subject) : void + { + $env = $container->getParameter('kernel.environment'); + $loader = $this->createContainerLoader($container, $env); + $file = (new \ReflectionObject($subject))->getFileName(); + $bundleLoader = $loader->getResolver()->resolve($file); + if (!$bundleLoader instanceof PhpFileLoader) { + throw new \LogicException('Unable to create the ContainerConfigurator.'); + } + $bundleLoader->setCurrentDir(\dirname($file)); + $instanceof =& \Closure::bind(function &() { + return $this->instanceof; + }, $bundleLoader, $bundleLoader)(); + try { + $callback(new ContainerConfigurator($container, $bundleLoader, $instanceof, $file, $file, $env)); + } finally { + $instanceof = []; + $bundleLoader->registerAliasesForSinglyImplementedInterfaces(); + } + } + private function createContainerLoader(ContainerBuilder $container, string $env) : DelegatingLoader + { + $buildDir = $container->getParameter('kernel.build_dir'); + $locator = new FileLocator(); + $resolver = new LoaderResolver([new XmlFileLoader($container, $locator, $env), new YamlFileLoader($container, $locator, $env), new IniFileLoader($container, $locator, $env), new PhpFileLoader($container, $locator, $env, new ConfigBuilderGenerator($buildDir)), new GlobFileLoader($container, $locator, $env), new DirectoryLoader($container, $locator, $env), new ClosureLoader($container, $env)]); + return new DelegatingLoader($resolver); + } +} diff --git a/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php b/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php new file mode 100644 index 0000000000..a4797bccb8 --- /dev/null +++ b/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +interface PrependExtensionInterface +{ + /** + * Allow an extension to prepend the extension configurations. + */ + public function prepend(ContainerBuilder $container); +} diff --git a/vendor/symfony/dependency-injection/LICENSE b/vendor/symfony/dependency-injection/LICENSE new file mode 100644 index 0000000000..0083704572 --- /dev/null +++ b/vendor/symfony/dependency-injection/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2023 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php b/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php new file mode 100644 index 0000000000..e87aa60c3f --- /dev/null +++ b/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\Instantiator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * Lazy proxy instantiator, capable of instantiating a proxy given a container, the + * service definitions and a callback that produces the real service instance. + * + * @author Marco Pivetta + */ +interface InstantiatorInterface +{ + /** + * Instantiates a proxy object. + * + * @param string $id Identifier of the requested service + * @param callable $realInstantiator Zero-argument callback that is capable of producing the real service instance + * + * @return object + */ + public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator); +} diff --git a/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php b/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php new file mode 100644 index 0000000000..54a6f08254 --- /dev/null +++ b/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\Instantiator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * {@inheritdoc} + * + * Noop proxy instantiator - produces the real service instead of a proxy instance. + * + * @author Marco Pivetta + */ +class RealServiceInstantiator implements InstantiatorInterface +{ + /** + * {@inheritdoc} + */ + public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator) : object + { + return $realInstantiator(); + } +} diff --git a/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php b/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php new file mode 100644 index 0000000000..fba59dd940 --- /dev/null +++ b/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\PhpDumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * Lazy proxy dumper capable of generating the instantiation logic PHP code for proxied services. + * + * @author Marco Pivetta + */ +interface DumperInterface +{ + /** + * Inspects whether the given definitions should produce proxy instantiation logic in the dumped container. + */ + public function isProxyCandidate(Definition $definition) : bool; + /** + * Generates the code to be used to instantiate a proxy in the dumped factory code. + */ + public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode) : string; + /** + * Generates the code for the lazy proxy. + */ + public function getProxyCode(Definition $definition) : string; +} diff --git a/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php b/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php new file mode 100644 index 0000000000..94d758438c --- /dev/null +++ b/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy\PhpDumper; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * Null dumper, negates any proxy code generation for any given service definition. + * + * @author Marco Pivetta + * + * @final + */ +class NullDumper implements DumperInterface +{ + /** + * {@inheritdoc} + */ + public function isProxyCandidate(Definition $definition) : bool + { + return \false; + } + /** + * {@inheritdoc} + */ + public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode) : string + { + return ''; + } + /** + * {@inheritdoc} + */ + public function getProxyCode(Definition $definition) : string + { + return ''; + } +} diff --git a/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php b/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php new file mode 100644 index 0000000000..07589e8e96 --- /dev/null +++ b/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\LazyProxy; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class ProxyHelper +{ + /** + * @return string|null The FQCN or builtin name of the type hint, or null when the type hint references an invalid self|parent context + */ + public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionParameter $p = null, bool $noBuiltin = \false) : ?string + { + if ($p instanceof \ReflectionParameter) { + $type = $p->getType(); + } else { + $type = $r->getReturnType(); + } + if (!$type) { + return null; + } + return self::getTypeHintForType($type, $r, $noBuiltin); + } + private static function getTypeHintForType(\ReflectionType $type, \ReflectionFunctionAbstract $r, bool $noBuiltin) : ?string + { + $types = []; + $glue = '|'; + if ($type instanceof \ReflectionUnionType) { + $reflectionTypes = $type->getTypes(); + } elseif ($type instanceof \ReflectionIntersectionType) { + $reflectionTypes = $type->getTypes(); + $glue = '&'; + } elseif ($type instanceof \ReflectionNamedType) { + $reflectionTypes = [$type]; + } else { + return null; + } + foreach ($reflectionTypes as $type) { + if ($type instanceof \ReflectionIntersectionType) { + $typeHint = self::getTypeHintForType($type, $r, $noBuiltin); + if (null === $typeHint) { + return null; + } + $types[] = \sprintf('(%s)', $typeHint); + continue; + } + if ($type->isBuiltin()) { + if (!$noBuiltin) { + $types[] = $type->getName(); + } + continue; + } + $lcName = \strtolower($type->getName()); + $prefix = $noBuiltin ? '' : '\\'; + if ('self' !== $lcName && 'parent' !== $lcName) { + $types[] = $prefix . $type->getName(); + continue; + } + if (!$r instanceof \ReflectionMethod) { + continue; + } + if ('self' === $lcName) { + $types[] = $prefix . $r->getDeclaringClass()->name; + } else { + $types[] = ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix . $parent->name : null; + } + } + \sort($types); + return $types ? \implode($glue, $types) : null; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/ClosureLoader.php b/vendor/symfony/dependency-injection/Loader/ClosureLoader.php new file mode 100644 index 0000000000..a932747848 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/ClosureLoader.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\Loader; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +/** + * ClosureLoader loads service definitions from a PHP closure. + * + * The Closure has access to the container as its first argument. + * + * @author Fabien Potencier + */ +class ClosureLoader extends Loader +{ + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder + */ + private $container; + public function __construct(ContainerBuilder $container, string $env = null) + { + $this->container = $container; + parent::__construct($env); + } + /** + * {@inheritdoc} + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + return $resource($this->container, $this->env); + } + /** + * {@inheritdoc} + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + return $resource instanceof \Closure; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php new file mode 100644 index 0000000000..80d4ef1892 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\ParamConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Parameter; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +abstract class AbstractConfigurator +{ + public const FACTORY = 'unknown'; + /** + * @var callable(mixed, bool)|null + */ + public static $valuePreProcessor; + /** @internal + * @var \Symfony\Component\DependencyInjection\Definition|\Symfony\Component\DependencyInjection\Alias|null */ + protected $definition = null; + public function __call(string $method, array $args) + { + if (\method_exists($this, 'set' . $method)) { + return $this->{'set' . $method}(...$args); + } + throw new \BadMethodCallException(\sprintf('Call to undefined method "%s::%s()".', static::class, $method)); + } + public function __sleep() : array + { + throw new \BadMethodCallException('Cannot serialize ' . __CLASS__); + } + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__); + } + /** + * Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value. + * + * @param bool $allowServices whether Definition and Reference are allowed; by default, only scalars and arrays are + * + * @return mixed the value, optionally cast to a Definition/Reference + * @param mixed $value + */ + public static function processValue($value, bool $allowServices = \false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = static::processValue($v, $allowServices); + } + return self::$valuePreProcessor ? (self::$valuePreProcessor)($value, $allowServices) : $value; + } + if (self::$valuePreProcessor) { + $value = (self::$valuePreProcessor)($value, $allowServices); + } + if ($value instanceof ReferenceConfigurator) { + $reference = new Reference($value->id, $value->invalidBehavior); + return $value instanceof ClosureReferenceConfigurator ? new ServiceClosureArgument($reference) : $reference; + } + if ($value instanceof InlineServiceConfigurator) { + $def = $value->definition; + $value->definition = null; + return $def; + } + if ($value instanceof ParamConfigurator) { + return (string) $value; + } + if ($value instanceof self) { + throw new InvalidArgumentException(\sprintf('"%s()" can be used only at the root of service configuration files.', $value::FACTORY)); + } + switch (\true) { + case null === $value: + case \is_scalar($value): + return $value; + case $value instanceof ArgumentInterface: + case $value instanceof Definition: + case $value instanceof Expression: + case $value instanceof Parameter: + case $value instanceof AbstractArgument: + case $value instanceof Reference: + if ($allowServices) { + return $value; + } + } + throw new InvalidArgumentException(\sprintf('Cannot use values of type "%s" in service configuration files.', \get_debug_type($value))); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php new file mode 100644 index 0000000000..8443a8b906 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +abstract class AbstractServiceConfigurator extends AbstractConfigurator +{ + protected $parent; + protected $id; + /** + * @var mixed[] + */ + private $defaultTags = []; + public function __construct(ServicesConfigurator $parent, Definition $definition, string $id = null, array $defaultTags = []) + { + $this->parent = $parent; + $this->definition = $definition; + $this->id = $id; + $this->defaultTags = $defaultTags; + } + public function __destruct() + { + // default tags should be added last + foreach ($this->defaultTags as $name => $attributes) { + foreach ($attributes as $attribute) { + $this->definition->addTag($name, $attribute); + } + } + $this->defaultTags = []; + } + /** + * Registers a service. + */ + public final function set(?string $id, string $class = null) : ServiceConfigurator + { + $this->__destruct(); + return $this->parent->set($id, $class); + } + /** + * Creates an alias. + */ + public final function alias(string $id, string $referencedId) : AliasConfigurator + { + $this->__destruct(); + return $this->parent->alias($id, $referencedId); + } + /** + * Registers a PSR-4 namespace using a glob pattern. + */ + public final function load(string $namespace, string $resource) : PrototypeConfigurator + { + $this->__destruct(); + return $this->parent->load($namespace, $resource); + } + /** + * Gets an already defined service definition. + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public final function get(string $id) : ServiceConfigurator + { + $this->__destruct(); + return $this->parent->get($id); + } + /** + * Removes an already defined service definition or alias. + */ + public final function remove(string $id) : ServicesConfigurator + { + $this->__destruct(); + return $this->parent->remove($id); + } + /** + * Registers a stack of decorator services. + * + * @param InlineServiceConfigurator[]|ReferenceConfigurator[] $services + */ + public final function stack(string $id, array $services) : AliasConfigurator + { + $this->__destruct(); + return $this->parent->stack($id, $services); + } + /** + * Registers a service. + */ + public final function __invoke(string $id, string $class = null) : ServiceConfigurator + { + $this->__destruct(); + return $this->parent->set($id, $class); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php new file mode 100644 index 0000000000..8d151a7a55 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +/** + * @author Nicolas Grekas + */ +class AliasConfigurator extends AbstractServiceConfigurator +{ + use Traits\DeprecateTrait; + use Traits\PublicTrait; + public const FACTORY = 'alias'; + public function __construct(ServicesConfigurator $parent, Alias $alias) + { + $this->parent = $parent; + $this->definition = $alias; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/ClosureReferenceConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/ClosureReferenceConfigurator.php new file mode 100644 index 0000000000..eae268dd2b --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/ClosureReferenceConfigurator.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +class ClosureReferenceConfigurator extends ReferenceConfigurator +{ +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php new file mode 100644 index 0000000000..6e32749048 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php @@ -0,0 +1,205 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\ParamConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * @author Nicolas Grekas + */ +class ContainerConfigurator extends AbstractConfigurator +{ + public const FACTORY = 'container'; + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder + */ + private $container; + /** + * @var \Symfony\Component\DependencyInjection\Loader\PhpFileLoader + */ + private $loader; + /** + * @var mixed[] + */ + private $instanceof; + /** + * @var string + */ + private $path; + /** + * @var string + */ + private $file; + /** + * @var int + */ + private $anonymousCount = 0; + /** + * @var string|null + */ + private $env; + public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path, string $file, string $env = null) + { + $this->container = $container; + $this->loader = $loader; + $this->instanceof =& $instanceof; + $this->path = $path; + $this->file = $file; + $this->env = $env; + } + public final function extension(string $namespace, array $config) + { + if (!$this->container->hasExtension($namespace)) { + $extensions = \array_filter(\array_map(function (ExtensionInterface $ext) { + return $ext->getAlias(); + }, $this->container->getExtensions())); + throw new InvalidArgumentException(\sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $namespace, $this->file, $namespace, $extensions ? \implode('", "', $extensions) : 'none')); + } + $this->container->loadFromExtension($namespace, static::processValue($config)); + } + /** + * @param bool|string $ignoreErrors + */ + public final function import(string $resource, string $type = null, $ignoreErrors = \false) + { + $this->loader->setCurrentDir(\dirname($this->path)); + $this->loader->import($resource, $type, $ignoreErrors, $this->file); + } + public final function parameters() : ParametersConfigurator + { + return new ParametersConfigurator($this->container); + } + public final function services() : ServicesConfigurator + { + return new ServicesConfigurator($this->container, $this->loader, $this->instanceof, $this->path, $this->anonymousCount); + } + /** + * Get the current environment to be able to write conditional configuration. + */ + public final function env() : ?string + { + return $this->env; + } + /** + * @return static + */ + public final function withPath(string $path) + { + $clone = clone $this; + $clone->path = $clone->file = $path; + $clone->loader->setCurrentDir(\dirname($path)); + return $clone; + } +} +/** + * @author Nicolas Grekas + */ +\class_alias('MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator', 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator', \false); +/** + * Creates a parameter. + */ +function param(string $name) : ParamConfigurator +{ + return new ParamConfigurator($name); +} +/** + * Creates a reference to a service. + */ +function service(string $serviceId) : ReferenceConfigurator +{ + return new ReferenceConfigurator($serviceId); +} +/** + * Creates an inline service. + */ +function inline_service(string $class = null) : InlineServiceConfigurator +{ + return new InlineServiceConfigurator(new Definition($class)); +} +/** + * Creates a service locator. + * + * @param ReferenceConfigurator[] $values + */ +function service_locator(array $values) : ServiceLocatorArgument +{ + return new ServiceLocatorArgument(AbstractConfigurator::processValue($values, \true)); +} +/** + * Creates a lazy iterator. + * + * @param ReferenceConfigurator[] $values + */ +function iterator(array $values) : IteratorArgument +{ + return new IteratorArgument(AbstractConfigurator::processValue($values, \true)); +} +/** + * Creates a lazy iterator by tag name. + * @param string|mixed[] $exclude + */ +function tagged_iterator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, string $defaultPriorityMethod = null, $exclude = []) : TaggedIteratorArgument +{ + return new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, \false, $defaultPriorityMethod, (array) $exclude); +} +/** + * Creates a service locator by tag name. + * @param string|mixed[] $exclude + */ +function tagged_locator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null, string $defaultPriorityMethod = null, $exclude = []) : ServiceLocatorArgument +{ + return new ServiceLocatorArgument(new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, \true, $defaultPriorityMethod, (array) $exclude)); +} +/** + * Creates an expression. + */ +function expr(string $expression) : Expression +{ + return new Expression($expression); +} +/** + * Creates an abstract argument. + */ +function abstract_arg(string $description) : AbstractArgument +{ + return new AbstractArgument($description); +} +/** + * Creates an environment variable reference. + */ +function env(string $name) : EnvConfigurator +{ + return new EnvConfigurator($name); +} +/** + * Creates a closure service reference. + */ +function service_closure(string $serviceId) : ClosureReferenceConfigurator +{ + return new ClosureReferenceConfigurator($serviceId); +} +/** + * Creates a closure. + * @param string|mixed[]|\Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator|\Symfony\Component\ExpressionLanguage\Expression $callable + */ +function closure($callable) : InlineServiceConfigurator +{ + return (new InlineServiceConfigurator(new Definition('Closure')))->factory(['Closure', 'fromCallable'])->args([$callable]); +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php new file mode 100644 index 0000000000..3e30de951a --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * @author Nicolas Grekas + */ +class DefaultsConfigurator extends AbstractServiceConfigurator +{ + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\PublicTrait; + public const FACTORY = 'defaults'; + /** + * @var string|null + */ + private $path; + public function __construct(ServicesConfigurator $parent, Definition $definition, string $path = null) + { + parent::__construct($parent, $definition, null, []); + $this->path = $path; + } + /** + * Adds a tag for this definition. + * + * @return $this + * + * @throws InvalidArgumentException when an invalid tag name or attribute is provided + */ + public final function tag(string $name, array $attributes = []) + { + if ('' === $name) { + throw new InvalidArgumentException('The tag name in "_defaults" must be a non-empty string.'); + } + foreach ($attributes as $attribute => $value) { + if (null !== $value && !\is_scalar($value)) { + throw new InvalidArgumentException(\sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type.', $name, $attribute)); + } + } + $this->definition->addTag($name, $attributes); + return $this; + } + /** + * Defines an instanceof-conditional to be applied to following service definitions. + */ + public final function instanceof(string $fqcn) : InstanceofConfigurator + { + return $this->parent->instanceof($fqcn); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/EnvConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/EnvConfigurator.php new file mode 100644 index 0000000000..91c7364f45 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/EnvConfigurator.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\ParamConfigurator; +class EnvConfigurator extends ParamConfigurator +{ + /** + * @var string[] + */ + private $stack; + public function __construct(string $name) + { + $this->stack = \explode(':', $name); + } + public function __toString() : string + { + return '%env(' . \implode(':', $this->stack) . ')%'; + } + /** + * @return $this + */ + public function __call(string $name, array $arguments) + { + $processor = \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], 'MonorepoBuilderPrefix202310\\1_\\2', $name)); + $this->custom($processor, ...$arguments); + return $this; + } + /** + * @return $this + */ + public function custom(string $processor, ...$args) + { + \array_unshift($this->stack, $processor, ...$args); + return $this; + } + /** + * @return $this + */ + public function base64() + { + \array_unshift($this->stack, 'base64'); + return $this; + } + /** + * @return $this + */ + public function bool() + { + \array_unshift($this->stack, 'bool'); + return $this; + } + /** + * @return $this + */ + public function not() + { + \array_unshift($this->stack, 'not'); + return $this; + } + /** + * @return $this + */ + public function const() + { + \array_unshift($this->stack, 'const'); + return $this; + } + /** + * @return $this + */ + public function csv() + { + \array_unshift($this->stack, 'csv'); + return $this; + } + /** + * @return $this + */ + public function file() + { + \array_unshift($this->stack, 'file'); + return $this; + } + /** + * @return $this + */ + public function float() + { + \array_unshift($this->stack, 'float'); + return $this; + } + /** + * @return $this + */ + public function int() + { + \array_unshift($this->stack, 'int'); + return $this; + } + /** + * @return $this + */ + public function json() + { + \array_unshift($this->stack, 'json'); + return $this; + } + /** + * @return $this + */ + public function key(string $key) + { + \array_unshift($this->stack, 'key', $key); + return $this; + } + /** + * @return $this + */ + public function url() + { + \array_unshift($this->stack, 'url'); + return $this; + } + /** + * @return $this + */ + public function queryString() + { + \array_unshift($this->stack, 'query_string'); + return $this; + } + /** + * @return $this + */ + public function resolve() + { + \array_unshift($this->stack, 'resolve'); + return $this; + } + /** + * @return $this + */ + public function default(string $fallbackParam) + { + \array_unshift($this->stack, 'default', $fallbackParam); + return $this; + } + /** + * @return $this + */ + public function string() + { + \array_unshift($this->stack, 'string'); + return $this; + } + /** + * @return $this + */ + public function trim() + { + \array_unshift($this->stack, 'trim'); + return $this; + } + /** + * @return $this + */ + public function require() + { + \array_unshift($this->stack, 'require'); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php new file mode 100644 index 0000000000..076a583205 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * @author Nicolas Grekas + */ +class InlineServiceConfigurator extends AbstractConfigurator +{ + use Traits\ArgumentTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ConfiguratorTrait; + use Traits\FactoryTrait; + use Traits\FileTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\PropertyTrait; + use Traits\TagTrait; + public const FACTORY = 'service'; + /** + * @var string + */ + private $id = '[inline]'; + /** + * @var bool + */ + private $allowParent = \true; + /** + * @var string|null + */ + private $path; + public function __construct(Definition $definition) + { + $this->definition = $definition; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php new file mode 100644 index 0000000000..ccad0374a8 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * @author Nicolas Grekas + */ +class InstanceofConfigurator extends AbstractServiceConfigurator +{ + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ConfiguratorTrait; + use Traits\LazyTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\TagTrait; + public const FACTORY = 'instanceof'; + /** + * @var string|null + */ + private $path; + public function __construct(ServicesConfigurator $parent, Definition $definition, string $id, string $path = null) + { + parent::__construct($parent, $definition, $id, []); + $this->path = $path; + } + /** + * Defines an instanceof-conditional to be applied to following service definitions. + */ + public final function instanceof(string $fqcn) : self + { + return $this->parent->instanceof($fqcn); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php new file mode 100644 index 0000000000..c1d4921201 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * @author Nicolas Grekas + */ +class ParametersConfigurator extends AbstractConfigurator +{ + public const FACTORY = 'parameters'; + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder + */ + private $container; + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } + /** + * @return $this + * @param mixed $value + */ + public final function set(string $name, $value) + { + if ($value instanceof Expression) { + throw new InvalidArgumentException(\sprintf('Using an expression in parameter "%s" is not allowed.', $name)); + } + $this->container->setParameter($name, static::processValue($value, \true)); + return $this; + } + /** + * @return $this + * @param mixed $value + */ + public final function __invoke(string $name, $value) + { + return $this->set($name, $value); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php new file mode 100644 index 0000000000..2eab03ac99 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +/** + * @author Nicolas Grekas + */ +class PrototypeConfigurator extends AbstractServiceConfigurator +{ + use Traits\AbstractTrait; + use Traits\ArgumentTrait; + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ConfiguratorTrait; + use Traits\DeprecateTrait; + use Traits\FactoryTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\TagTrait; + public const FACTORY = 'load'; + /** + * @var \Symfony\Component\DependencyInjection\Loader\PhpFileLoader + */ + private $loader; + /** + * @var string + */ + private $resource; + /** + * @var mixed[]|null + */ + private $excludes; + /** + * @var bool + */ + private $allowParent; + public function __construct(ServicesConfigurator $parent, PhpFileLoader $loader, Definition $defaults, string $namespace, string $resource, bool $allowParent) + { + $definition = new Definition(); + if (!$defaults->isPublic() || !$defaults->isPrivate()) { + $definition->setPublic($defaults->isPublic()); + } + $definition->setAutowired($defaults->isAutowired()); + $definition->setAutoconfigured($defaults->isAutoconfigured()); + // deep clone, to avoid multiple process of the same instance in the passes + $definition->setBindings(\unserialize(\serialize($defaults->getBindings()))); + $definition->setChanges([]); + $this->loader = $loader; + $this->resource = $resource; + $this->allowParent = $allowParent; + parent::__construct($parent, $definition, $namespace, $defaults->getTags()); + } + public function __destruct() + { + parent::__destruct(); + if (isset($this->loader)) { + $this->loader->registerClasses($this->definition, $this->id, $this->resource, $this->excludes); + } + unset($this->loader); + } + /** + * Excludes files from registration using glob patterns. + * + * @param string[]|string $excludes + * + * @return $this + */ + public final function exclude($excludes) + { + $this->excludes = (array) $excludes; + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php new file mode 100644 index 0000000000..d203cece79 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +/** + * @author Nicolas Grekas + */ +class ReferenceConfigurator extends AbstractConfigurator +{ + /** @internal + * @var string */ + protected $id; + /** @internal + * @var int */ + protected $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + public function __construct(string $id) + { + $this->id = $id; + } + /** + * @return $this + */ + public final function ignoreOnInvalid() + { + $this->invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + return $this; + } + /** + * @return $this + */ + public final function nullOnInvalid() + { + $this->invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + return $this; + } + /** + * @return $this + */ + public final function ignoreOnUninitialized() + { + $this->invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + return $this; + } + public function __toString() : string + { + return $this->id; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php new file mode 100644 index 0000000000..2610d1876e --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +/** + * @author Nicolas Grekas + */ +class ServiceConfigurator extends AbstractServiceConfigurator +{ + use Traits\AbstractTrait; + use Traits\ArgumentTrait; + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ClassTrait; + use Traits\ConfiguratorTrait; + use Traits\DecorateTrait; + use Traits\DeprecateTrait; + use Traits\FactoryTrait; + use Traits\FileTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\SyntheticTrait; + use Traits\TagTrait; + public const FACTORY = 'services'; + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder + */ + private $container; + /** + * @var mixed[] + */ + private $instanceof; + /** + * @var bool + */ + private $allowParent; + /** + * @var string|null + */ + private $path; + /** + * @var bool + */ + private $destructed = \false; + public function __construct(ContainerBuilder $container, array $instanceof, bool $allowParent, ServicesConfigurator $parent, Definition $definition, ?string $id, array $defaultTags, string $path = null) + { + $this->container = $container; + $this->instanceof = $instanceof; + $this->allowParent = $allowParent; + $this->path = $path; + parent::__construct($parent, $definition, $id, $defaultTags); + } + public function __destruct() + { + if ($this->destructed) { + return; + } + $this->destructed = \true; + parent::__destruct(); + $this->container->removeBindings($this->id); + $this->container->setDefinition($this->id, $this->definition->setInstanceofConditionals($this->instanceof)); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php b/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php new file mode 100644 index 0000000000..1f0a1d26f5 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php @@ -0,0 +1,182 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +/** + * @author Nicolas Grekas + */ +class ServicesConfigurator extends AbstractConfigurator +{ + public const FACTORY = 'services'; + /** + * @var \Symfony\Component\DependencyInjection\Definition + */ + private $defaults; + /** + * @var \Symfony\Component\DependencyInjection\ContainerBuilder + */ + private $container; + /** + * @var \Symfony\Component\DependencyInjection\Loader\PhpFileLoader + */ + private $loader; + /** + * @var mixed[] + */ + private $instanceof; + /** + * @var string|null + */ + private $path; + /** + * @var string + */ + private $anonymousHash; + /** + * @var int + */ + private $anonymousCount; + public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, string $path = null, int &$anonymousCount = 0) + { + $this->defaults = new Definition(); + $this->container = $container; + $this->loader = $loader; + $this->instanceof =& $instanceof; + $this->path = $path; + $this->anonymousHash = ContainerBuilder::hash($path ?: \mt_rand()); + $this->anonymousCount =& $anonymousCount; + $instanceof = []; + } + /** + * Defines a set of defaults for following service definitions. + */ + public final function defaults() : DefaultsConfigurator + { + return new DefaultsConfigurator($this, $this->defaults = new Definition(), $this->path); + } + /** + * Defines an instanceof-conditional to be applied to following service definitions. + */ + public final function instanceof(string $fqcn) : InstanceofConfigurator + { + $this->instanceof[$fqcn] = $definition = new ChildDefinition(''); + return new InstanceofConfigurator($this, $definition, $fqcn, $this->path); + } + /** + * Registers a service. + * + * @param string|null $id The service id, or null to create an anonymous service + * @param string|null $class The class of the service, or null when $id is also the class name + */ + public final function set(?string $id, string $class = null) : ServiceConfigurator + { + $defaults = $this->defaults; + $definition = new Definition(); + if (null === $id) { + if (!$class) { + throw new \LogicException('Anonymous services must have a class name.'); + } + $id = \sprintf('.%d_%s', ++$this->anonymousCount, \preg_replace('/^.*\\\\/', '', $class) . '~' . $this->anonymousHash); + } elseif (!$defaults->isPublic() || !$defaults->isPrivate()) { + $definition->setPublic($defaults->isPublic() && !$defaults->isPrivate()); + } + $definition->setAutowired($defaults->isAutowired()); + $definition->setAutoconfigured($defaults->isAutoconfigured()); + // deep clone, to avoid multiple process of the same instance in the passes + $definition->setBindings(\unserialize(\serialize($defaults->getBindings()))); + $definition->setChanges([]); + $configurator = new ServiceConfigurator($this->container, $this->instanceof, \true, $this, $definition, $id, $defaults->getTags(), $this->path); + return null !== $class ? $configurator->class($class) : $configurator; + } + /** + * Removes an already defined service definition or alias. + * + * @return $this + */ + public final function remove(string $id) + { + $this->container->removeDefinition($id); + $this->container->removeAlias($id); + return $this; + } + /** + * Creates an alias. + */ + public final function alias(string $id, string $referencedId) : AliasConfigurator + { + $ref = static::processValue($referencedId, \true); + $alias = new Alias((string) $ref); + if (!$this->defaults->isPublic() || !$this->defaults->isPrivate()) { + $alias->setPublic($this->defaults->isPublic()); + } + $this->container->setAlias($id, $alias); + return new AliasConfigurator($this, $alias); + } + /** + * Registers a PSR-4 namespace using a glob pattern. + */ + public final function load(string $namespace, string $resource) : PrototypeConfigurator + { + return new PrototypeConfigurator($this, $this->loader, $this->defaults, $namespace, $resource, \true); + } + /** + * Gets an already defined service definition. + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public final function get(string $id) : ServiceConfigurator + { + $definition = $this->container->getDefinition($id); + return new ServiceConfigurator($this->container, $definition->getInstanceofConditionals(), \true, $this, $definition, $id, []); + } + /** + * Registers a stack of decorator services. + * + * @param InlineServiceConfigurator[]|ReferenceConfigurator[] $services + */ + public final function stack(string $id, array $services) : AliasConfigurator + { + foreach ($services as $i => $service) { + if ($service instanceof InlineServiceConfigurator) { + $definition = $service->definition->setInstanceofConditionals($this->instanceof); + $changes = $definition->getChanges(); + $definition->setAutowired((isset($changes['autowired']) ? $definition : $this->defaults)->isAutowired()); + $definition->setAutoconfigured((isset($changes['autoconfigured']) ? $definition : $this->defaults)->isAutoconfigured()); + $definition->setBindings(\array_merge($this->defaults->getBindings(), $definition->getBindings())); + $definition->setChanges($changes); + $services[$i] = $definition; + } elseif (!$service instanceof ReferenceConfigurator) { + throw new InvalidArgumentException(\sprintf('"%s()" expects a list of definitions as returned by "%s()" or "%s()", "%s" given at index "%s" for service "%s".', __METHOD__, InlineServiceConfigurator::FACTORY, ReferenceConfigurator::FACTORY, $service instanceof AbstractConfigurator ? $service::FACTORY . '()' : \get_debug_type($service), $i, $id)); + } + } + $alias = $this->alias($id, ''); + $alias->definition = $this->set($id)->parent('')->args($services)->tag('container.stack')->definition; + return $alias; + } + /** + * Registers a service. + */ + public final function __invoke(string $id, string $class = null) : ServiceConfigurator + { + return $this->set($id, $class); + } + public function __destruct() + { + $this->loader->registerAliasesForSinglyImplementedInterfaces(); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php new file mode 100644 index 0000000000..d62fbdd359 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait AbstractTrait +{ + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @return $this + */ + public final function abstract(bool $abstract = \true) + { + $this->definition->setAbstract($abstract); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php new file mode 100644 index 0000000000..cffcac6bfc --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ArgumentTrait +{ + /** + * Sets the arguments to pass to the service constructor/factory method. + * + * @return $this + */ + public final function args(array $arguments) + { + $this->definition->setArguments(static::processValue($arguments, \true)); + return $this; + } + /** + * Sets one argument to pass to the service constructor/factory method. + * + * @return $this + * @param string|int $key + * @param mixed $value + */ + public final function arg($key, $value) + { + $this->definition->setArgument($key, static::processValue($value, \true)); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php new file mode 100644 index 0000000000..86141e906d --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +trait AutoconfigureTrait +{ + /** + * Sets whether or not instanceof conditionals should be prepended with a global set. + * + * @return $this + * + * @throws InvalidArgumentException when a parent is already set + */ + public final function autoconfigure(bool $autoconfigured = \true) + { + $this->definition->setAutoconfigured($autoconfigured); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php new file mode 100644 index 0000000000..fe0e58bfc1 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait AutowireTrait +{ + /** + * Enables/disables autowiring. + * + * @return $this + */ + public final function autowire(bool $autowired = \true) + { + $this->definition->setAutowired($autowired); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php new file mode 100644 index 0000000000..3a6ddbfb92 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\BoundArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\DefaultsConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\InstanceofConfigurator; +trait BindTrait +{ + /** + * Sets bindings. + * + * Bindings map $named or FQCN arguments to values that should be + * injected in the matching parameters (of the constructor, of methods + * called and of controller actions). + * + * @param string $nameOrFqcn A parameter name with its "$" prefix, or an FQCN + * @param mixed $valueOrRef The value or reference to bind + * + * @return $this + */ + public final function bind(string $nameOrFqcn, $valueOrRef) + { + $valueOrRef = static::processValue($valueOrRef, \true); + $bindings = $this->definition->getBindings(); + $type = $this instanceof DefaultsConfigurator ? BoundArgument::DEFAULTS_BINDING : ($this instanceof InstanceofConfigurator ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING); + $bindings[$nameOrFqcn] = new BoundArgument($valueOrRef, \true, $type, $this->path ?? null); + $this->definition->setBindings($bindings); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php new file mode 100644 index 0000000000..274ac5076d --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +trait CallTrait +{ + /** + * Adds a method to call after service initialization. + * + * @param string $method The method name to call + * @param array $arguments An array of arguments to pass to the method call + * @param bool $returnsClone Whether the call returns the service instance or not + * + * @return $this + * + * @throws InvalidArgumentException on empty $method param + */ + public final function call(string $method, array $arguments = [], bool $returnsClone = \false) + { + $this->definition->addMethodCall($method, static::processValue($arguments, \true), $returnsClone); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php new file mode 100644 index 0000000000..518f2d6fc6 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ClassTrait +{ + /** + * Sets the service class. + * + * @return $this + */ + public final function class(?string $class) + { + $this->definition->setClass($class); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php new file mode 100644 index 0000000000..3bc3291d1d --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; +trait ConfiguratorTrait +{ + /** + * Sets a configurator to call after the service is fully initialized. + * + * @return $this + * @param string|mixed[]|\Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator $configurator + */ + public final function configurator($configurator) + { + $this->definition->setConfigurator(static::processValue($configurator, \true)); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php new file mode 100644 index 0000000000..162f30f47f --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +trait DecorateTrait +{ + /** + * Sets the service that this service is decorating. + * + * @param string|null $id The decorated service id, use null to remove decoration + * + * @return $this + * + * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals + */ + public final function decorate(?string $id, string $renamedId = null, int $priority = 0, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + $this->definition->setDecoratedService($id, $renamedId, $priority, $invalidBehavior); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php new file mode 100644 index 0000000000..2022f12f08 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +trait DeprecateTrait +{ + /** + * Whether this definition is deprecated, that means it should not be called anymore. + * + * @param string $package The name of the composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message The deprecation message to use + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + public final function deprecate(string $package, string $version, string $message) + { + $this->definition->setDeprecated($package, $version, $message); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php new file mode 100644 index 0000000000..ec07e5c178 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +trait FactoryTrait +{ + /** + * Sets a factory. + * + * @return $this + * @param string|mixed[]|\Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator|\Symfony\Component\ExpressionLanguage\Expression $factory + */ + public final function factory($factory) + { + if (\is_string($factory) && 1 === \substr_count($factory, ':')) { + $factoryParts = \explode(':', $factory); + throw new InvalidArgumentException(\sprintf('Invalid factory "%s": the "service:method" notation is not available when using PHP-based DI configuration. Use "[service(\'%s\'), \'%s\']" instead.', $factory, $factoryParts[0], $factoryParts[1])); + } + if ($factory instanceof Expression) { + $factory = '@=' . $factory; + } + $this->definition->setFactory(static::processValue($factory, \true)); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php new file mode 100644 index 0000000000..ecb0720bd4 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait FileTrait +{ + /** + * Sets a file to require before creating the service. + * + * @return $this + */ + public final function file(string $file) + { + $this->definition->setFile($file); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php new file mode 100644 index 0000000000..5a90de8bf4 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait LazyTrait +{ + /** + * Sets the lazy flag of this service. + * + * @param bool|string $lazy A FQCN to derivate the lazy proxy from or `true` to make it extend from the definition's class + * + * @return $this + */ + public final function lazy($lazy = \true) + { + $this->definition->setLazy((bool) $lazy); + if (\is_string($lazy)) { + $this->definition->addTag('proxy', ['interface' => $lazy]); + } + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php new file mode 100644 index 0000000000..87aa0603c7 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +trait ParentTrait +{ + /** + * Sets the Definition to inherit from. + * + * @return $this + * + * @throws InvalidArgumentException when parent cannot be set + */ + public final function parent(string $parent) + { + if (!$this->allowParent) { + throw new InvalidArgumentException(\sprintf('A parent cannot be defined when either "_instanceof" or "_defaults" are also defined for service prototype "%s".', $this->id)); + } + if ($this->definition instanceof ChildDefinition) { + $this->definition->setParent($parent); + } else { + // cast Definition to ChildDefinition + $definition = \serialize($this->definition); + $definition = \substr_replace($definition, '53', 2, 2); + $definition = \substr_replace($definition, 'Child', 44, 0); + $definition = \unserialize($definition); + $this->definition = $definition->setParent($parent); + } + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php new file mode 100644 index 0000000000..222a9fb7c5 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait PropertyTrait +{ + /** + * Sets a specific property. + * + * @return $this + * @param mixed $value + */ + public final function property(string $name, $value) + { + $this->definition->setProperty($name, static::processValue($value, \true)); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php new file mode 100644 index 0000000000..5b93e8a142 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait PublicTrait +{ + /** + * @return $this + */ + public final function public() + { + $this->definition->setPublic(\true); + return $this; + } + /** + * @return $this + */ + public final function private() + { + $this->definition->setPublic(\false); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php new file mode 100644 index 0000000000..7410f851d8 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ShareTrait +{ + /** + * Sets if the service must be shared or not. + * + * @return $this + */ + public final function share(bool $shared = \true) + { + $this->definition->setShared($shared); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php new file mode 100644 index 0000000000..6460b039a0 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait SyntheticTrait +{ + /** + * Sets whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @return $this + */ + public final function synthetic(bool $synthetic = \true) + { + $this->definition->setSynthetic($synthetic); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php new file mode 100644 index 0000000000..ad62fdf212 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +trait TagTrait +{ + /** + * Adds a tag for this definition. + * + * @return $this + */ + public final function tag(string $name, array $attributes = []) + { + if ('' === $name) { + throw new InvalidArgumentException(\sprintf('The tag name for service "%s" must be a non-empty string.', $this->id)); + } + foreach ($attributes as $attribute => $value) { + if (!\is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(\sprintf('A tag attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $this->id, $name, $attribute)); + } + } + $this->definition->addTag($name, $attributes); + return $this; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php b/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php new file mode 100644 index 0000000000..37d36f0e37 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +/** + * DirectoryLoader is a recursive loader to go through directories. + * + * @author Sebastien Lavoie + */ +class DirectoryLoader extends FileLoader +{ + /** + * {@inheritdoc} + * @param mixed $file + * @return mixed + */ + public function load($file, string $type = null) + { + $file = \rtrim($file, '/'); + $path = $this->locator->locate($file); + $this->container->fileExists($path, \false); + foreach (\scandir($path) as $dir) { + if ('.' !== $dir[0]) { + if (\is_dir($path . '/' . $dir)) { + $dir .= '/'; + // append / to allow recursion + } + $this->setCurrentDir($path); + $this->import($dir, null, \false, $path); + } + } + return null; + } + /** + * {@inheritdoc} + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + if ('directory' === $type) { + return \true; + } + return null === $type && \is_string($resource) && \substr_compare($resource, '/', -\strlen('/')) === 0; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/FileLoader.php b/vendor/symfony/dependency-injection/Loader/FileLoader.php new file mode 100644 index 0000000000..7d06695847 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/FileLoader.php @@ -0,0 +1,215 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Exception\LoaderLoadException; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\FileLocatorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\FileLoader as BaseFileLoader; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Loader\Loader; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Resource\GlobResource; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\When; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Compiler\RegisterAutoconfigureAttributesPass; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * FileLoader is the abstract class used by all built-in loaders that are file based. + * + * @author Fabien Potencier + */ +abstract class FileLoader extends BaseFileLoader +{ + public const ANONYMOUS_ID_REGEXP = '/^\\.\\d+_[^~]*+~[._a-zA-Z\\d]{7}$/'; + protected $container; + protected $isLoadingInstanceof = \false; + protected $instanceof = []; + protected $interfaces = []; + protected $singlyImplemented = []; + protected $autoRegisterAliasesForSinglyImplementedInterfaces = \true; + public function __construct(ContainerBuilder $container, FileLocatorInterface $locator, string $env = null) + { + $this->container = $container; + parent::__construct($locator, $env); + } + /** + * {@inheritdoc} + * + * @param bool|string $ignoreErrors Whether errors should be ignored; pass "not_found" to ignore only when the loaded resource is not found + * @param mixed $resource + * @return mixed + */ + public function import($resource, string $type = null, $ignoreErrors = \false, string $sourceResource = null, $exclude = null) + { + $args = \func_get_args(); + if ($ignoreNotFound = 'not_found' === $ignoreErrors) { + $args[2] = \false; + } elseif (!\is_bool($ignoreErrors)) { + throw new \TypeError(\sprintf('Invalid argument $ignoreErrors provided to "%s::import()": boolean or "not_found" expected, "%s" given.', static::class, \get_debug_type($ignoreErrors))); + } + try { + return parent::import(...$args); + } catch (LoaderLoadException $e) { + if (!$ignoreNotFound || !($prev = $e->getPrevious()) instanceof FileLocatorFileNotFoundException) { + throw $e; + } + foreach ($prev->getTrace() as $frame) { + if ('import' === ($frame['function'] ?? null) && \is_a($frame['class'] ?? '', Loader::class, \true)) { + break; + } + } + if (__FILE__ !== $frame['file']) { + throw $e; + } + } + return null; + } + /** + * Registers a set of classes as services using PSR-4 for discovery. + * + * @param Definition $prototype A definition to use as template + * @param string $namespace The namespace prefix of classes in the scanned directory + * @param string $resource The directory to look for classes, glob-patterns allowed + * @param string|mixed[] $exclude A globbed path of files to exclude or an array of globbed paths of files to exclude + */ + public function registerClasses(Definition $prototype, string $namespace, string $resource, $exclude = null) + { + if (\substr_compare($namespace, '\\', -\strlen('\\')) !== 0) { + throw new InvalidArgumentException(\sprintf('Namespace prefix must end with a "\\": "%s".', $namespace)); + } + if (!\preg_match('/^(?:[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+\\\\)++$/', $namespace)) { + throw new InvalidArgumentException(\sprintf('Namespace is not a valid PSR-4 prefix: "%s".', $namespace)); + } + $autoconfigureAttributes = new RegisterAutoconfigureAttributesPass(); + $autoconfigureAttributes = $autoconfigureAttributes->accept($prototype) ? $autoconfigureAttributes : null; + $classes = $this->findClasses($namespace, $resource, (array) $exclude, $autoconfigureAttributes); + // prepare for deep cloning + $serializedPrototype = \serialize($prototype); + foreach ($classes as $class => $errorMessage) { + if (null === $errorMessage && $autoconfigureAttributes && $this->env) { + $r = $this->container->getReflectionClass($class); + $attribute = null; + foreach ($r->getAttributes(When::class) as $attribute) { + if ($this->env === $attribute->newInstance()->env) { + $attribute = null; + break; + } + } + if (null !== $attribute) { + continue; + } + } + if (\interface_exists($class, \false)) { + $this->interfaces[] = $class; + } else { + $this->setDefinition($class, $definition = \unserialize($serializedPrototype)); + if (null !== $errorMessage) { + $definition->addError($errorMessage); + continue; + } + foreach (\class_implements($class, \false) as $interface) { + $this->singlyImplemented[$interface] = ($this->singlyImplemented[$interface] ?? $class) !== $class ? \false : $class; + } + } + } + if ($this->autoRegisterAliasesForSinglyImplementedInterfaces) { + $this->registerAliasesForSinglyImplementedInterfaces(); + } + } + public function registerAliasesForSinglyImplementedInterfaces() + { + foreach ($this->interfaces as $interface) { + if (!empty($this->singlyImplemented[$interface]) && !$this->container->has($interface)) { + $this->container->setAlias($interface, $this->singlyImplemented[$interface]); + } + } + $this->interfaces = $this->singlyImplemented = []; + } + /** + * Registers a definition in the container with its instanceof-conditionals. + */ + protected function setDefinition(string $id, Definition $definition) + { + $this->container->removeBindings($id); + if ($this->isLoadingInstanceof) { + if (!$definition instanceof ChildDefinition) { + throw new InvalidArgumentException(\sprintf('Invalid type definition "%s": ChildDefinition expected, "%s" given.', $id, \get_debug_type($definition))); + } + $this->instanceof[$id] = $definition; + } else { + $this->container->setDefinition($id, $definition->setInstanceofConditionals($this->instanceof)); + } + } + private function findClasses(string $namespace, string $pattern, array $excludePatterns, ?RegisterAutoconfigureAttributesPass $autoconfigureAttributes) : array + { + $parameterBag = $this->container->getParameterBag(); + $excludePaths = []; + $excludePrefix = null; + $excludePatterns = $parameterBag->unescapeValue($parameterBag->resolveValue($excludePatterns)); + foreach ($excludePatterns as $excludePattern) { + foreach ($this->glob($excludePattern, \true, $resource, \true, \true) as $path => $info) { + if (null === $excludePrefix) { + $excludePrefix = $resource->getPrefix(); + } + // normalize Windows slashes and remove trailing slashes + $excludePaths[\rtrim(\str_replace('\\', '/', $path), '/')] = \true; + } + } + $pattern = $parameterBag->unescapeValue($parameterBag->resolveValue($pattern)); + $classes = []; + $extRegexp = '/\\.php$/'; + $prefixLen = null; + foreach ($this->glob($pattern, \true, $resource, \false, \false, $excludePaths) as $path => $info) { + if (null === $prefixLen) { + $prefixLen = \strlen($resource->getPrefix()); + if ($excludePrefix && \strncmp($excludePrefix, $resource->getPrefix(), \strlen($resource->getPrefix())) !== 0) { + throw new InvalidArgumentException(\sprintf('Invalid "exclude" pattern when importing classes for "%s": make sure your "exclude" pattern (%s) is a subset of the "resource" pattern (%s).', $namespace, $excludePattern, $pattern)); + } + } + if (isset($excludePaths[\str_replace('\\', '/', $path)])) { + continue; + } + if (!\preg_match($extRegexp, $path, $m) || !$info->isReadable()) { + continue; + } + $class = $namespace . \ltrim(\str_replace('/', '\\', \substr($path, $prefixLen, -\strlen($m[0]))), '\\'); + if (!\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:\\\\[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)*+$/', $class)) { + continue; + } + try { + $r = $this->container->getReflectionClass($class); + } catch (\ReflectionException $e) { + $classes[$class] = $e->getMessage(); + continue; + } + // check to make sure the expected class exists + if (!$r) { + throw new InvalidArgumentException(\sprintf('Expected to find class "%s" in file "%s" while importing services from resource "%s", but it was not found! Check the namespace prefix used with the resource.', $class, $path, $pattern)); + } + if ($r->isInstantiable() || $r->isInterface()) { + $classes[$class] = null; + } + if ($autoconfigureAttributes && !$r->isInstantiable()) { + $autoconfigureAttributes->processClass($this->container, $r); + } + } + // track only for new & removed files + if ($resource instanceof GlobResource) { + $this->container->addResource($resource); + } else { + foreach ($resource as $path) { + $this->container->fileExists($path, \false); + } + } + return $classes; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php b/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php new file mode 100644 index 0000000000..4733af3d06 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +/** + * GlobFileLoader loads files from a glob pattern. + * + * @author Nicolas Grekas + */ +class GlobFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + foreach ($this->glob($resource, \false, $globResource) as $path => $info) { + $this->import($path); + } + $this->container->addResource($globResource); + return null; + } + /** + * {@inheritdoc} + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + return 'glob' === $type; + } +} diff --git a/vendor/symfony/dependency-injection/Loader/IniFileLoader.php b/vendor/symfony/dependency-injection/Loader/IniFileLoader.php new file mode 100644 index 0000000000..e018811eaf --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/IniFileLoader.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Util\XmlUtils; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +/** + * IniFileLoader loads parameters from INI files. + * + * @author Fabien Potencier + */ +class IniFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + $path = $this->locator->locate($resource); + $this->container->fileExists($path); + // first pass to catch parsing errors + $result = \parse_ini_file($path, \true); + if (\false === $result || [] === $result) { + throw new InvalidArgumentException(\sprintf('The "%s" file is not valid.', $resource)); + } + // real raw parsing + $result = \parse_ini_file($path, \true, \INI_SCANNER_RAW); + if (isset($result['parameters']) && \is_array($result['parameters'])) { + foreach ($result['parameters'] as $key => $value) { + $this->container->setParameter($key, $this->phpize($value)); + } + } + if ($this->env && \is_array($result['parameters@' . $this->env] ?? null)) { + foreach ($result['parameters@' . $this->env] as $key => $value) { + $this->container->setParameter($key, $this->phpize($value)); + } + } + return null; + } + /** + * {@inheritdoc} + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + if (!\is_string($resource)) { + return \false; + } + if (null === $type && 'ini' === \pathinfo($resource, \PATHINFO_EXTENSION)) { + return \true; + } + return 'ini' === $type; + } + /** + * Note that the following features are not supported: + * * strings with escaped quotes are not supported "foo\"bar"; + * * string concatenation ("foo" "bar"). + * @return mixed + */ + private function phpize(string $value) + { + // trim on the right as comments removal keep whitespaces + if ($value !== ($v = \rtrim($value))) { + $value = '""' === \substr_replace($v, '', 1, -1) ? \substr($v, 1, -1) : $v; + } + $lowercaseValue = \strtolower($value); + switch (\true) { + case \defined($value): + return \constant($value); + case 'yes' === $lowercaseValue: + case 'on' === $lowercaseValue: + return \true; + case 'no' === $lowercaseValue: + case 'off' === $lowercaseValue: + case 'none' === $lowercaseValue: + return \false; + case isset($value[1]) && ("'" === $value[0] && "'" === $value[\strlen($value) - 1] || '"' === $value[0] && '"' === $value[\strlen($value) - 1]): + return \substr($value, 1, -1); + default: + return XmlUtils::phpize($value); + } + } +} diff --git a/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php b/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php new file mode 100644 index 0000000000..9800fc0c6e --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder\ConfigBuilderGenerator; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder\ConfigBuilderGeneratorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Builder\ConfigBuilderInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Config\FileLocatorInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Attribute\When; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Container; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +/** + * PhpFileLoader loads service definitions from a PHP file. + * + * The PHP file is required and the $container variable can be + * used within the file to change the container. + * + * @author Fabien Potencier + */ +class PhpFileLoader extends FileLoader +{ + protected $autoRegisterAliasesForSinglyImplementedInterfaces = \false; + /** + * @var \Symfony\Component\Config\Builder\ConfigBuilderGeneratorInterface|null + */ + private $generator; + public function __construct(ContainerBuilder $container, FileLocatorInterface $locator, string $env = null, ConfigBuilderGeneratorInterface $generator = null) + { + parent::__construct($container, $locator, $env); + $this->generator = $generator; + } + /** + * {@inheritdoc} + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + // the container and loader variables are exposed to the included file below + $container = $this->container; + $loader = $this; + $path = $this->locator->locate($resource); + $this->setCurrentDir(\dirname($path)); + $this->container->fileExists($path); + // the closure forbids access to the private scope in the included file + $load = \Closure::bind(function ($path, $env) use($container, $loader, $resource, $type) { + return include $path; + }, $this, ProtectedPhpFileLoader::class); + try { + $callback = $load($path, $this->env); + if (\is_object($callback) && \is_callable($callback)) { + // generic solution + $reflectionFunction = new \ReflectionFunction($callback); + $containerConfiguratorClass = $reflectionFunction->getParameters()[0]->getType()->getName(); + $this->executeCallback($callback, new $containerConfiguratorClass($this->container, $this, $this->instanceof, $path, $resource, $this->env), $path); + } + } finally { + $this->instanceof = []; + $this->registerAliasesForSinglyImplementedInterfaces(); + } + return null; + } + /** + * {@inheritdoc} + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + if (!\is_string($resource)) { + return \false; + } + if (null === $type && 'php' === \pathinfo($resource, \PATHINFO_EXTENSION)) { + return \true; + } + return 'php' === $type; + } + /** + * Resolve the parameters to the $callback and execute it. + */ + private function executeCallback(callable $callback, ContainerConfigurator $containerConfigurator, string $path) + { + $callback = \Closure::fromCallable($callback); + $arguments = []; + $configBuilders = []; + $r = new \ReflectionFunction($callback); + $attribute = null; + foreach (\method_exists($r, 'getAttributes') ? $r->getAttributes(When::class) : [] as $attribute) { + if ($this->env === $attribute->newInstance()->env) { + $attribute = null; + break; + } + } + if (null !== $attribute) { + return; + } + foreach ($r->getParameters() as $parameter) { + $reflectionType = $parameter->getType(); + if (!$reflectionType instanceof \ReflectionNamedType) { + throw new \InvalidArgumentException(\sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s" or "%s").', $parameter->getName(), $path, ContainerConfigurator::class, ContainerBuilder::class)); + } + $type = $reflectionType->getName(); + if (\is_a($type, ContainerConfigurator::class, \true)) { + $arguments[] = $containerConfigurator; + } else { + switch ($type) { + case ContainerBuilder::class: + $arguments[] = $this->container; + break; + case FileLoader::class: + case self::class: + $arguments[] = $this; + break; + default: + try { + $configBuilder = $this->configBuilder($type); + } catch (InvalidArgumentException|\LogicException $e) { + throw new \InvalidArgumentException(\sprintf('Could not resolve argument "%s" for "%s".', $type . ' $' . $parameter->getName(), $path), 0, $e); + } + $configBuilders[] = $configBuilder; + $arguments[] = $configBuilder; + } + } + } + // Force load ContainerConfigurator to make env(), param() etc available. + \class_exists(ContainerConfigurator::class); + $callback(...$arguments); + /** @var ConfigBuilderInterface $configBuilder */ + foreach ($configBuilders as $configBuilder) { + $containerConfigurator->extension($configBuilder->getExtensionAlias(), $configBuilder->toArray()); + } + } + /** + * @param string $namespace FQCN string for a class implementing ConfigBuilderInterface + */ + private function configBuilder(string $namespace) : ConfigBuilderInterface + { + if (!\class_exists(ConfigBuilderGenerator::class)) { + throw new \LogicException('You cannot use the config builder as the Config component is not installed. Try running "composer require symfony/config".'); + } + if (null === $this->generator) { + throw new \LogicException('You cannot use the ConfigBuilders without providing a class implementing ConfigBuilderGeneratorInterface.'); + } + // If class exists and implements ConfigBuilderInterface + if (\class_exists($namespace) && \is_subclass_of($namespace, ConfigBuilderInterface::class)) { + return new $namespace(); + } + // If it does not start with Symfony\Config\ we dont know how to handle this + if (\strncmp($namespace, 'Symfony\\Config\\', \strlen('Symfony\\Config\\')) !== 0) { + throw new InvalidArgumentException(\sprintf('Could not find or generate class "%s".', $namespace)); + } + // Try to get the extension alias + $alias = Container::underscore(\substr($namespace, 15, -6)); + if (\strpos($alias, '\\') !== \false) { + throw new InvalidArgumentException('You can only use "root" ConfigBuilders from "Symfony\\Config\\" namespace. Nested classes like "Symfony\\Config\\Framework\\CacheConfig" cannot be used.'); + } + if (!$this->container->hasExtension($alias)) { + $extensions = \array_filter(\array_map(function (ExtensionInterface $ext) { + return $ext->getAlias(); + }, $this->container->getExtensions())); + throw new InvalidArgumentException(\sprintf('There is no extension able to load the configuration for "%s". Looked for namespace "%s", found "%s".', $namespace, $alias, $extensions ? \implode('", "', $extensions) : 'none')); + } + $extension = $this->container->getExtension($alias); + if (!$extension instanceof ConfigurationExtensionInterface) { + throw new \LogicException(\sprintf('You cannot use the config builder for "%s" because the extension does not implement "%s".', $namespace, ConfigurationExtensionInterface::class)); + } + $configuration = $extension->getConfiguration([], $this->container); + $loader = $this->generator->build($configuration); + return $loader(); + } +} +/** + * @internal + */ +final class ProtectedPhpFileLoader extends PhpFileLoader +{ +} diff --git a/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php b/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php new file mode 100644 index 0000000000..defb97c095 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php @@ -0,0 +1,667 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\Config\Util\XmlUtils; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\BoundArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +/** + * XmlFileLoader loads XML files service definitions. + * + * @author Fabien Potencier + */ +class XmlFileLoader extends FileLoader +{ + public const NS = 'http://symfony.com/schema/dic/services'; + protected $autoRegisterAliasesForSinglyImplementedInterfaces = \false; + /** + * {@inheritdoc} + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + $path = $this->locator->locate($resource); + $xml = $this->parseFileToDOM($path); + $this->container->fileExists($path); + $this->loadXml($xml, $path); + if ($this->env) { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + foreach ($xpath->query(\sprintf('//container:when[@env="%s"]', $this->env)) ?: [] as $root) { + $env = $this->env; + $this->env = null; + try { + $this->loadXml($xml, $path, $root); + } finally { + $this->env = $env; + } + } + } + return null; + } + private function loadXml(\DOMDocument $xml, string $path, \DOMNode $root = null) : void + { + $defaults = $this->getServiceDefaults($xml, $path, $root); + // anonymous services + $this->processAnonymousServices($xml, $path, $root); + // imports + $this->parseImports($xml, $path, $root); + // parameters + $this->parseParameters($xml, $path, $root); + // extensions + $this->loadFromExtensions($xml, $root); + // services + try { + $this->parseDefinitions($xml, $path, $defaults, $root); + } finally { + $this->instanceof = []; + $this->registerAliasesForSinglyImplementedInterfaces(); + } + } + /** + * {@inheritdoc} + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + if (!\is_string($resource)) { + return \false; + } + if (null === $type && 'xml' === \pathinfo($resource, \PATHINFO_EXTENSION)) { + return \true; + } + return 'xml' === $type; + } + private function parseParameters(\DOMDocument $xml, string $file, \DOMNode $root = null) + { + if ($parameters = $this->getChildren($root ?? $xml->documentElement, 'parameters')) { + $this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter', $file)); + } + } + private function parseImports(\DOMDocument $xml, string $file, \DOMNode $root = null) + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + if (\false === ($imports = $xpath->query('.//container:imports/container:import', $root))) { + return; + } + $defaultDirectory = \dirname($file); + foreach ($imports as $import) { + $this->setCurrentDir($defaultDirectory); + $this->import($import->getAttribute('resource'), XmlUtils::phpize($import->getAttribute('type')) ?: null, XmlUtils::phpize($import->getAttribute('ignore-errors')) ?: \false, $file); + } + } + private function parseDefinitions(\DOMDocument $xml, string $file, Definition $defaults, \DOMNode $root = null) + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + if (\false === ($services = $xpath->query('.//container:services/container:service|.//container:services/container:prototype|.//container:services/container:stack', $root))) { + return; + } + $this->setCurrentDir(\dirname($file)); + $this->instanceof = []; + $this->isLoadingInstanceof = \true; + $instanceof = $xpath->query('.//container:services/container:instanceof', $root); + foreach ($instanceof as $service) { + $this->setDefinition((string) $service->getAttribute('id'), $this->parseDefinition($service, $file, new Definition())); + } + $this->isLoadingInstanceof = \false; + foreach ($services as $service) { + if ('stack' === $service->tagName) { + $service->setAttribute('parent', '-'); + $definition = $this->parseDefinition($service, $file, $defaults)->setTags(\array_merge_recursive(['container.stack' => [[]]], $defaults->getTags())); + $this->setDefinition($id = (string) $service->getAttribute('id'), $definition); + $stack = []; + foreach ($this->getChildren($service, 'service') as $k => $frame) { + $k = $frame->getAttribute('id') ?: $k; + $frame->setAttribute('id', $id . '" at index "' . $k); + if ($alias = $frame->getAttribute('alias')) { + $this->validateAlias($frame, $file); + $stack[$k] = new Reference($alias); + } else { + $stack[$k] = $this->parseDefinition($frame, $file, $defaults)->setInstanceofConditionals($this->instanceof); + } + } + $definition->setArguments($stack); + } elseif (null !== ($definition = $this->parseDefinition($service, $file, $defaults))) { + if ('prototype' === $service->tagName) { + $excludes = \array_column($this->getChildren($service, 'exclude'), 'nodeValue'); + if ($service->hasAttribute('exclude')) { + if (\count($excludes) > 0) { + throw new InvalidArgumentException('You cannot use both the attribute "exclude" and tags at the same time.'); + } + $excludes = [$service->getAttribute('exclude')]; + } + $this->registerClasses($definition, (string) $service->getAttribute('namespace'), (string) $service->getAttribute('resource'), $excludes); + } else { + $this->setDefinition((string) $service->getAttribute('id'), $definition); + } + } + } + } + private function getServiceDefaults(\DOMDocument $xml, string $file, \DOMNode $root = null) : Definition + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + if (null === ($defaultsNode = $xpath->query('.//container:services/container:defaults', $root)->item(0))) { + return new Definition(); + } + $defaultsNode->setAttribute('id', ''); + return $this->parseDefinition($defaultsNode, $file, new Definition()); + } + /** + * Parses an individual Definition. + */ + private function parseDefinition(\DOMElement $service, string $file, Definition $defaults) : ?Definition + { + if ($alias = $service->getAttribute('alias')) { + $this->validateAlias($service, $file); + $this->container->setAlias($service->getAttribute('id'), $alias = new Alias($alias)); + if ($publicAttr = $service->getAttribute('public')) { + $alias->setPublic(XmlUtils::phpize($publicAttr)); + } elseif ($defaults->getChanges()['public'] ?? \false) { + $alias->setPublic($defaults->isPublic()); + } + if ($deprecated = $this->getChildren($service, 'deprecated')) { + $message = $deprecated[0]->nodeValue ?: ''; + $package = $deprecated[0]->getAttribute('package') ?: ''; + $version = $deprecated[0]->getAttribute('version') ?: ''; + if (!$deprecated[0]->hasAttribute('package')) { + throw new InvalidArgumentException(\sprintf('Missing attribute "package" at node "deprecated" in "%s".', $file)); + } + if (!$deprecated[0]->hasAttribute('version')) { + throw new InvalidArgumentException(\sprintf('Missing attribute "version" at node "deprecated" in "%s".', $file)); + } + $alias->setDeprecated($package, $version, $message); + } + return null; + } + if ($this->isLoadingInstanceof) { + $definition = new ChildDefinition(''); + } elseif ($parent = $service->getAttribute('parent')) { + $definition = new ChildDefinition($parent); + } else { + $definition = new Definition(); + } + if ($defaults->getChanges()['public'] ?? \false) { + $definition->setPublic($defaults->isPublic()); + } + $definition->setAutowired($defaults->isAutowired()); + $definition->setAutoconfigured($defaults->isAutoconfigured()); + $definition->setChanges([]); + foreach (['class', 'public', 'shared', 'synthetic', 'abstract'] as $key) { + if ($value = $service->getAttribute($key)) { + $method = 'set' . $key; + $definition->{$method}($value = XmlUtils::phpize($value)); + } + } + if ($value = $service->getAttribute('lazy')) { + $definition->setLazy((bool) ($value = XmlUtils::phpize($value))); + if (\is_string($value)) { + $definition->addTag('proxy', ['interface' => $value]); + } + } + if ($value = $service->getAttribute('autowire')) { + $definition->setAutowired(XmlUtils::phpize($value)); + } + if ($value = $service->getAttribute('autoconfigure')) { + $definition->setAutoconfigured(XmlUtils::phpize($value)); + } + if ($files = $this->getChildren($service, 'file')) { + $definition->setFile($files[0]->nodeValue); + } + if ($deprecated = $this->getChildren($service, 'deprecated')) { + $message = $deprecated[0]->nodeValue ?: ''; + $package = $deprecated[0]->getAttribute('package') ?: ''; + $version = $deprecated[0]->getAttribute('version') ?: ''; + if (!$deprecated[0]->hasAttribute('package')) { + throw new InvalidArgumentException(\sprintf('Missing attribute "package" at node "deprecated" in "%s".', $file)); + } + if (!$deprecated[0]->hasAttribute('version')) { + throw new InvalidArgumentException(\sprintf('Missing attribute "version" at node "deprecated" in "%s".', $file)); + } + $definition->setDeprecated($package, $version, $message); + } + $definition->setArguments($this->getArgumentsAsPhp($service, 'argument', $file, $definition instanceof ChildDefinition)); + $definition->setProperties($this->getArgumentsAsPhp($service, 'property', $file)); + if ($factories = $this->getChildren($service, 'factory')) { + $factory = $factories[0]; + if ($function = $factory->getAttribute('function')) { + $definition->setFactory($function); + } elseif ($expression = $factory->getAttribute('expression')) { + if (!\class_exists(Expression::class)) { + throw new \LogicException('The "expression" attribute cannot be used on factories without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); + } + $definition->setFactory('@=' . $expression); + } else { + if ($childService = $factory->getAttribute('service')) { + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } else { + $class = $factory->hasAttribute('class') ? $factory->getAttribute('class') : null; + } + $definition->setFactory([$class, $factory->getAttribute('method') ?: '__invoke']); + } + } + if ($configurators = $this->getChildren($service, 'configurator')) { + $configurator = $configurators[0]; + if ($function = $configurator->getAttribute('function')) { + $definition->setConfigurator($function); + } else { + if ($childService = $configurator->getAttribute('service')) { + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } else { + $class = $configurator->getAttribute('class'); + } + $definition->setConfigurator([$class, $configurator->getAttribute('method') ?: '__invoke']); + } + } + foreach ($this->getChildren($service, 'call') as $call) { + $definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file), XmlUtils::phpize($call->getAttribute('returns-clone'))); + } + $tags = $this->getChildren($service, 'tag'); + foreach ($tags as $tag) { + $parameters = []; + $tagName = $tag->nodeValue; + foreach ($tag->attributes as $name => $node) { + if ('name' === $name && '' === $tagName) { + continue; + } + if (\strpos($name, '-') !== \false && \strpos($name, '_') === \false && !\array_key_exists($normalizedName = \str_replace('-', '_', $name), $parameters)) { + $parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue); + } + // keep not normalized key + $parameters[$name] = XmlUtils::phpize($node->nodeValue); + } + if ('' === $tagName && '' === ($tagName = $tag->getAttribute('name'))) { + throw new InvalidArgumentException(\sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', $service->getAttribute('id'), $file)); + } + $definition->addTag($tagName, $parameters); + } + $definition->setTags(\array_merge_recursive($definition->getTags(), $defaults->getTags())); + $bindings = $this->getArgumentsAsPhp($service, 'bind', $file); + $bindingType = $this->isLoadingInstanceof ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING; + foreach ($bindings as $argument => $value) { + $bindings[$argument] = new BoundArgument($value, \true, $bindingType, $file); + } + // deep clone, to avoid multiple process of the same instance in the passes + $bindings = \array_merge(\unserialize(\serialize($defaults->getBindings())), $bindings); + if ($bindings) { + $definition->setBindings($bindings); + } + if ($decorates = $service->getAttribute('decorates')) { + $decorationOnInvalid = $service->getAttribute('decoration-on-invalid') ?: 'exception'; + if ('exception' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } elseif ('ignore' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif ('null' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } else { + throw new InvalidArgumentException(\sprintf('Invalid value "%s" for attribute "decoration-on-invalid" on service "%s". Did you mean "exception", "ignore" or "null" in "%s"?', $decorationOnInvalid, $service->getAttribute('id'), $file)); + } + $renameId = $service->hasAttribute('decoration-inner-name') ? $service->getAttribute('decoration-inner-name') : null; + $priority = $service->hasAttribute('decoration-priority') ? $service->getAttribute('decoration-priority') : 0; + $definition->setDecoratedService($decorates, $renameId, $priority, $invalidBehavior); + } + return $definition; + } + /** + * Parses an XML file to a \DOMDocument. + * + * @throws InvalidArgumentException When loading of XML file returns error + */ + private function parseFileToDOM(string $file) : \DOMDocument + { + try { + $dom = XmlUtils::loadFile($file, \Closure::fromCallable([$this, 'validateSchema'])); + } catch (\InvalidArgumentException $e) { + throw new InvalidArgumentException(\sprintf('Unable to parse file "%s": ', $file) . $e->getMessage(), $e->getCode(), $e); + } + $this->validateExtensions($dom, $file); + return $dom; + } + /** + * Processes anonymous services. + */ + private function processAnonymousServices(\DOMDocument $xml, string $file, \DOMNode $root = null) + { + $definitions = []; + $count = 0; + $suffix = '~' . ContainerBuilder::hash($file); + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + // anonymous services as arguments/properties + if (\false !== ($nodes = $xpath->query('.//container:argument[@type="service"][not(@id)]|.//container:property[@type="service"][not(@id)]|.//container:bind[not(@id)]|.//container:factory[not(@service)]|.//container:configurator[not(@service)]', $root))) { + foreach ($nodes as $node) { + if ($services = $this->getChildren($node, 'service')) { + // give it a unique name + $id = \sprintf('.%d_%s', ++$count, \preg_replace('/^.*\\\\/', '', $services[0]->getAttribute('class')) . $suffix); + $node->setAttribute('id', $id); + $node->setAttribute('service', $id); + $definitions[$id] = [$services[0], $file]; + $services[0]->setAttribute('id', $id); + // anonymous services are always private + // we could not use the constant false here, because of XML parsing + $services[0]->setAttribute('public', 'false'); + } + } + } + // anonymous services "in the wild" + if (\false !== ($nodes = $xpath->query('.//container:services/container:service[not(@id)]', $root))) { + foreach ($nodes as $node) { + throw new InvalidArgumentException(\sprintf('Top-level services must have "id" attribute, none found in "%s" at line %d.', $file, $node->getLineNo())); + } + } + // resolve definitions + \uksort($definitions, 'strnatcmp'); + foreach (\array_reverse($definitions) as $id => [$domElement, $file]) { + if (null !== ($definition = $this->parseDefinition($domElement, $file, new Definition()))) { + $this->setDefinition($id, $definition); + } + } + } + private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file, bool $isChildDefinition = \false) : array + { + $arguments = []; + foreach ($this->getChildren($node, $name) as $arg) { + if ($arg->hasAttribute('name')) { + $arg->setAttribute('key', $arg->getAttribute('name')); + } + // this is used by ChildDefinition to overwrite a specific + // argument of the parent definition + if ($arg->hasAttribute('index')) { + $key = ($isChildDefinition ? 'index_' : '') . $arg->getAttribute('index'); + } elseif (!$arg->hasAttribute('key')) { + // Append an empty argument, then fetch its key to overwrite it later + $arguments[] = null; + $keys = \array_keys($arguments); + $key = \array_pop($keys); + } else { + $key = $arg->getAttribute('key'); + } + $onInvalid = $arg->getAttribute('on-invalid'); + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if ('ignore' == $onInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif ('ignore_uninitialized' == $onInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + } elseif ('null' == $onInvalid) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } + switch ($type = $arg->getAttribute('type')) { + case 'service': + if ('' === $arg->getAttribute('id')) { + throw new InvalidArgumentException(\sprintf('Tag "<%s>" with type="service" has no or empty "id" attribute in "%s".', $name, $file)); + } + $arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior); + break; + case 'expression': + if (!\class_exists(Expression::class)) { + throw new \LogicException('The type="expression" attribute cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); + } + $arguments[$key] = new Expression($arg->nodeValue); + break; + case 'collection': + $arguments[$key] = $this->getArgumentsAsPhp($arg, $name, $file); + break; + case 'iterator': + $arg = $this->getArgumentsAsPhp($arg, $name, $file); + $arguments[$key] = new IteratorArgument($arg); + break; + case 'closure': + case 'service_closure': + if ('' !== $arg->getAttribute('id')) { + $arg = new Reference($arg->getAttribute('id'), $invalidBehavior); + } else { + $arg = $this->getArgumentsAsPhp($arg, $name, $file); + } + switch ($type) { + case 'service_closure': + $arguments[$key] = new ServiceClosureArgument($arg); + break; + case 'closure': + $arguments[$key] = (new Definition('Closure'))->setFactory(['Closure', 'fromCallable'])->addArgument($arg); + break; + } + break; + case 'service_locator': + $arg = $this->getArgumentsAsPhp($arg, $name, $file); + $arguments[$key] = new ServiceLocatorArgument($arg); + break; + case 'tagged': + case 'tagged_iterator': + case 'tagged_locator': + $forLocator = 'tagged_locator' === $type; + if (!$arg->getAttribute('tag')) { + throw new InvalidArgumentException(\sprintf('Tag "<%s>" with type="%s" has no or empty "tag" attribute in "%s".', $name, $type, $file)); + } + $arguments[$key] = new TaggedIteratorArgument($arg->getAttribute('tag'), $arg->getAttribute('index-by') ?: null, $arg->getAttribute('default-index-method') ?: null, $forLocator, $arg->getAttribute('default-priority-method') ?: null); + if ($forLocator) { + $arguments[$key] = new ServiceLocatorArgument($arguments[$key]); + } + break; + case 'binary': + if (\false === ($value = \base64_decode($arg->nodeValue))) { + throw new InvalidArgumentException(\sprintf('Tag "<%s>" with type="binary" is not a valid base64 encoded string.', $name)); + } + $arguments[$key] = $value; + break; + case 'abstract': + $arguments[$key] = new AbstractArgument($arg->nodeValue); + break; + case 'string': + $arguments[$key] = $arg->nodeValue; + break; + case 'constant': + $arguments[$key] = \constant(\trim($arg->nodeValue)); + break; + default: + $arguments[$key] = XmlUtils::phpize($arg->nodeValue); + } + } + return $arguments; + } + /** + * Get child elements by name. + * + * @return \DOMElement[] + */ + private function getChildren(\DOMNode $node, string $name) : array + { + $children = []; + foreach ($node->childNodes as $child) { + if ($child instanceof \DOMElement && $child->localName === $name && self::NS === $child->namespaceURI) { + $children[] = $child; + } + } + return $children; + } + /** + * Validates a documents XML schema. + * + * @throws RuntimeException When extension references a non-existent XSD file + */ + public function validateSchema(\DOMDocument $dom) : bool + { + $schemaLocations = ['http://symfony.com/schema/dic/services' => \str_replace('\\', '/', __DIR__ . '/schema/dic/services/services-1.0.xsd')]; + if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) { + $items = \preg_split('/\\s+/', $element); + for ($i = 0, $nb = \count($items); $i < $nb; $i += 2) { + if (!$this->container->hasExtension($items[$i])) { + continue; + } + if (($extension = $this->container->getExtension($items[$i])) && \false !== $extension->getXsdValidationBasePath()) { + $ns = $extension->getNamespace(); + $path = \str_replace([$ns, \str_replace('http://', 'https://', $ns)], \str_replace('\\', '/', $extension->getXsdValidationBasePath()) . '/', $items[$i + 1]); + if (!\is_file($path)) { + throw new RuntimeException(\sprintf('Extension "%s" references a non-existent XSD file "%s".', \get_debug_type($extension), $path)); + } + $schemaLocations[$items[$i]] = $path; + } + } + } + $tmpfiles = []; + $imports = ''; + foreach ($schemaLocations as $namespace => $location) { + $parts = \explode('/', $location); + $locationstart = 'file:///'; + if (0 === \stripos($location, 'phar://')) { + $tmpfile = \tempnam(\sys_get_temp_dir(), 'symfony'); + if ($tmpfile) { + \copy($location, $tmpfile); + $tmpfiles[] = $tmpfile; + $parts = \explode('/', \str_replace('\\', '/', $tmpfile)); + } else { + \array_shift($parts); + $locationstart = 'phar:///'; + } + } elseif ('\\' === \DIRECTORY_SEPARATOR && \strncmp($location, '\\\\', \strlen('\\\\')) === 0) { + $locationstart = ''; + } + $drive = '\\' === \DIRECTORY_SEPARATOR ? \array_shift($parts) . '/' : ''; + $location = $locationstart . $drive . \implode('/', \array_map('rawurlencode', $parts)); + $imports .= \sprintf(' ' . "\n", $namespace, $location); + } + $source = << + + + +{$imports} + +EOF; + if ($this->shouldEnableEntityLoader()) { + $disableEntities = \libxml_disable_entity_loader(\false); + $valid = @$dom->schemaValidateSource($source); + \libxml_disable_entity_loader($disableEntities); + } else { + $valid = @$dom->schemaValidateSource($source); + } + foreach ($tmpfiles as $tmpfile) { + @\unlink($tmpfile); + } + return $valid; + } + private function shouldEnableEntityLoader() : bool + { + static $dom, $schema; + if (null === $dom) { + $dom = new \DOMDocument(); + $dom->loadXML(''); + $tmpfile = \tempnam(\sys_get_temp_dir(), 'symfony'); + \register_shutdown_function(static function () use($tmpfile) { + @\unlink($tmpfile); + }); + $schema = ' + + +'; + \file_put_contents($tmpfile, ' + + + +'); + } + return !@$dom->schemaValidateSource($schema); + } + private function validateAlias(\DOMElement $alias, string $file) + { + foreach ($alias->attributes as $name => $node) { + if (!\in_array($name, ['alias', 'id', 'public'])) { + throw new InvalidArgumentException(\sprintf('Invalid attribute "%s" defined for alias "%s" in "%s".', $name, $alias->getAttribute('id'), $file)); + } + } + foreach ($alias->childNodes as $child) { + if (!$child instanceof \DOMElement || self::NS !== $child->namespaceURI) { + continue; + } + if (!\in_array($child->localName, ['deprecated'], \true)) { + throw new InvalidArgumentException(\sprintf('Invalid child element "%s" defined for alias "%s" in "%s".', $child->localName, $alias->getAttribute('id'), $file)); + } + } + } + /** + * Validates an extension. + * + * @throws InvalidArgumentException When no extension is found corresponding to a tag + */ + private function validateExtensions(\DOMDocument $dom, string $file) + { + foreach ($dom->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) { + continue; + } + // can it be handled by an extension? + if (!$this->container->hasExtension($node->namespaceURI)) { + $extensionNamespaces = \array_filter(\array_map(function (ExtensionInterface $ext) { + return $ext->getNamespace(); + }, $this->container->getExtensions())); + throw new InvalidArgumentException(\sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $node->tagName, $file, $node->namespaceURI, $extensionNamespaces ? \implode('", "', $extensionNamespaces) : 'none')); + } + } + } + /** + * Loads from an extension. + */ + private function loadFromExtensions(\DOMDocument $xml) + { + foreach ($xml->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement || self::NS === $node->namespaceURI) { + continue; + } + $values = static::convertDomElementToArray($node); + if (!\is_array($values)) { + $values = []; + } + $this->container->loadFromExtension($node->namespaceURI, $values); + } + } + /** + * Converts a \DOMElement object to a PHP array. + * + * The following rules applies during the conversion: + * + * * Each tag is converted to a key value or an array + * if there is more than one "value" + * + * * The content of a tag is set under a "value" key (bar) + * if the tag also has some nested tags + * + * * The attributes are converted to keys () + * + * * The nested-tags are converted to keys (bar) + * + * @param \DOMElement $element A \DOMElement instance + * @return mixed + */ + public static function convertDomElementToArray(\DOMElement $element) + { + return XmlUtils::convertDomElementToArray($element); + } +} diff --git a/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php b/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php new file mode 100644 index 0000000000..ff009268c0 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php @@ -0,0 +1,741 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Loader; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Alias; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\AbstractArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\BoundArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ChildDefinition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerBuilder; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Definition; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Reference; +use MonorepoBuilderPrefix202310\Symfony\Component\ExpressionLanguage\Expression; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Exception\ParseException; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Parser as YamlParser; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Tag\TaggedValue; +use MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Yaml; +/** + * YamlFileLoader loads YAML files service definitions. + * + * @author Fabien Potencier + */ +class YamlFileLoader extends FileLoader +{ + private const SERVICE_KEYWORDS = ['alias' => 'alias', 'parent' => 'parent', 'class' => 'class', 'shared' => 'shared', 'synthetic' => 'synthetic', 'lazy' => 'lazy', 'public' => 'public', 'abstract' => 'abstract', 'deprecated' => 'deprecated', 'factory' => 'factory', 'file' => 'file', 'arguments' => 'arguments', 'properties' => 'properties', 'configurator' => 'configurator', 'calls' => 'calls', 'tags' => 'tags', 'decorates' => 'decorates', 'decoration_inner_name' => 'decoration_inner_name', 'decoration_priority' => 'decoration_priority', 'decoration_on_invalid' => 'decoration_on_invalid', 'autowire' => 'autowire', 'autoconfigure' => 'autoconfigure', 'bind' => 'bind']; + private const PROTOTYPE_KEYWORDS = ['resource' => 'resource', 'namespace' => 'namespace', 'exclude' => 'exclude', 'parent' => 'parent', 'shared' => 'shared', 'lazy' => 'lazy', 'public' => 'public', 'abstract' => 'abstract', 'deprecated' => 'deprecated', 'factory' => 'factory', 'arguments' => 'arguments', 'properties' => 'properties', 'configurator' => 'configurator', 'calls' => 'calls', 'tags' => 'tags', 'autowire' => 'autowire', 'autoconfigure' => 'autoconfigure', 'bind' => 'bind']; + private const INSTANCEOF_KEYWORDS = ['shared' => 'shared', 'lazy' => 'lazy', 'public' => 'public', 'properties' => 'properties', 'configurator' => 'configurator', 'calls' => 'calls', 'tags' => 'tags', 'autowire' => 'autowire', 'bind' => 'bind']; + private const DEFAULTS_KEYWORDS = ['public' => 'public', 'tags' => 'tags', 'autowire' => 'autowire', 'autoconfigure' => 'autoconfigure', 'bind' => 'bind']; + /** + * @var YamlParser + */ + private $yamlParser; + /** + * @var int + */ + private $anonymousServicesCount; + /** + * @var string + */ + private $anonymousServicesSuffix; + protected $autoRegisterAliasesForSinglyImplementedInterfaces = \false; + /** + * {@inheritdoc} + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + $path = $this->locator->locate($resource); + $content = $this->loadFile($path); + $this->container->fileExists($path); + // empty file + if (null === $content) { + return null; + } + $this->loadContent($content, $path); + // per-env configuration + if ($this->env && isset($content['when@' . $this->env])) { + if (!\is_array($content['when@' . $this->env])) { + throw new InvalidArgumentException(\sprintf('The "when@%s" key should contain an array in "%s". Check your YAML syntax.', $this->env, $path)); + } + $env = $this->env; + $this->env = null; + try { + $this->loadContent($content['when@' . $env], $path); + } finally { + $this->env = $env; + } + } + return null; + } + private function loadContent(array $content, string $path) + { + // imports + $this->parseImports($content, $path); + // parameters + if (isset($content['parameters'])) { + if (!\is_array($content['parameters'])) { + throw new InvalidArgumentException(\sprintf('The "parameters" key should contain an array in "%s". Check your YAML syntax.', $path)); + } + foreach ($content['parameters'] as $key => $value) { + $this->container->setParameter($key, $this->resolveServices($value, $path, \true)); + } + } + // extensions + $this->loadFromExtensions($content); + // services + $this->anonymousServicesCount = 0; + $this->anonymousServicesSuffix = '~' . ContainerBuilder::hash($path); + $this->setCurrentDir(\dirname($path)); + try { + $this->parseDefinitions($content, $path); + } finally { + $this->instanceof = []; + $this->registerAliasesForSinglyImplementedInterfaces(); + } + } + /** + * {@inheritdoc} + * @param mixed $resource + */ + public function supports($resource, string $type = null) : bool + { + if (!\is_string($resource)) { + return \false; + } + if (null === $type && \in_array(\pathinfo($resource, \PATHINFO_EXTENSION), ['yaml', 'yml'], \true)) { + return \true; + } + return \in_array($type, ['yaml', 'yml'], \true); + } + private function parseImports(array $content, string $file) + { + if (!isset($content['imports'])) { + return; + } + if (!\is_array($content['imports'])) { + throw new InvalidArgumentException(\sprintf('The "imports" key should contain an array in "%s". Check your YAML syntax.', $file)); + } + $defaultDirectory = \dirname($file); + foreach ($content['imports'] as $import) { + if (!\is_array($import)) { + $import = ['resource' => $import]; + } + if (!isset($import['resource'])) { + throw new InvalidArgumentException(\sprintf('An import should provide a resource in "%s". Check your YAML syntax.', $file)); + } + $this->setCurrentDir($defaultDirectory); + $this->import($import['resource'], $import['type'] ?? null, $import['ignore_errors'] ?? \false, $file); + } + } + private function parseDefinitions(array $content, string $file, bool $trackBindings = \true) + { + if (!isset($content['services'])) { + return; + } + if (!\is_array($content['services'])) { + throw new InvalidArgumentException(\sprintf('The "services" key should contain an array in "%s". Check your YAML syntax.', $file)); + } + if (\array_key_exists('_instanceof', $content['services'])) { + $instanceof = $content['services']['_instanceof']; + unset($content['services']['_instanceof']); + if (!\is_array($instanceof)) { + throw new InvalidArgumentException(\sprintf('Service "_instanceof" key must be an array, "%s" given in "%s".', \get_debug_type($instanceof), $file)); + } + $this->instanceof = []; + $this->isLoadingInstanceof = \true; + foreach ($instanceof as $id => $service) { + if (!$service || !\is_array($service)) { + throw new InvalidArgumentException(\sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in "%s". Check your YAML syntax.', $id, $file)); + } + if (\is_string($service) && \strncmp($service, '@', \strlen('@')) === 0) { + throw new InvalidArgumentException(\sprintf('Type definition "%s" cannot be an alias within "_instanceof" in "%s". Check your YAML syntax.', $id, $file)); + } + $this->parseDefinition($id, $service, $file, [], \false, $trackBindings); + } + } + $this->isLoadingInstanceof = \false; + $defaults = $this->parseDefaults($content, $file); + foreach ($content['services'] as $id => $service) { + $this->parseDefinition($id, $service, $file, $defaults, \false, $trackBindings); + } + } + /** + * @throws InvalidArgumentException + */ + private function parseDefaults(array &$content, string $file) : array + { + if (!\array_key_exists('_defaults', $content['services'])) { + return []; + } + $defaults = $content['services']['_defaults']; + unset($content['services']['_defaults']); + if (!\is_array($defaults)) { + throw new InvalidArgumentException(\sprintf('Service "_defaults" key must be an array, "%s" given in "%s".', \get_debug_type($defaults), $file)); + } + foreach ($defaults as $key => $default) { + if (!isset(self::DEFAULTS_KEYWORDS[$key])) { + throw new InvalidArgumentException(\sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, \implode('", "', self::DEFAULTS_KEYWORDS))); + } + } + if (isset($defaults['tags'])) { + if (!\is_array($tags = $defaults['tags'])) { + throw new InvalidArgumentException(\sprintf('Parameter "tags" in "_defaults" must be an array in "%s". Check your YAML syntax.', $file)); + } + foreach ($tags as $tag) { + if (!\is_array($tag)) { + $tag = ['name' => $tag]; + } + if (1 === \count($tag) && \is_array(\current($tag))) { + $name = \key($tag); + $tag = \current($tag); + } else { + if (!isset($tag['name'])) { + throw new InvalidArgumentException(\sprintf('A "tags" entry in "_defaults" is missing a "name" key in "%s".', $file)); + } + $name = $tag['name']; + unset($tag['name']); + } + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException(\sprintf('The tag name in "_defaults" must be a non-empty string in "%s".', $file)); + } + foreach ($tag as $attribute => $value) { + if (!\is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(\sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type in "%s". Check your YAML syntax.', $name, $attribute, $file)); + } + } + } + } + if (isset($defaults['bind'])) { + if (!\is_array($defaults['bind'])) { + throw new InvalidArgumentException(\sprintf('Parameter "bind" in "_defaults" must be an array in "%s". Check your YAML syntax.', $file)); + } + foreach ($this->resolveServices($defaults['bind'], $file) as $argument => $value) { + $defaults['bind'][$argument] = new BoundArgument($value, \true, BoundArgument::DEFAULTS_BINDING, $file); + } + } + return $defaults; + } + private function isUsingShortSyntax(array $service) : bool + { + foreach ($service as $key => $value) { + if (\is_string($key) && ('' === $key || '$' !== $key[0] && \strpos($key, '\\') === \false)) { + return \false; + } + } + return \true; + } + /** + * @throws InvalidArgumentException When tags are invalid + * @param mixed[]|string|null $service + */ + private function parseDefinition(string $id, $service, string $file, array $defaults, bool $return = \false, bool $trackBindings = \true) + { + if (\preg_match('/^_[a-zA-Z0-9_]*$/', $id)) { + throw new InvalidArgumentException(\sprintf('Service names that start with an underscore are reserved. Rename the "%s" service or define it in XML instead.', $id)); + } + if (\is_string($service) && \strncmp($service, '@', \strlen('@')) === 0) { + $alias = new Alias(\substr($service, 1)); + if (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + return $return ? $alias : $this->container->setAlias($id, $alias); + } + if (\is_array($service) && $this->isUsingShortSyntax($service)) { + $service = ['arguments' => $service]; + } + if (null === $service) { + $service = []; + } + if (!\is_array($service)) { + throw new InvalidArgumentException(\sprintf('A service definition must be an array or a string starting with "@" but "%s" found for service "%s" in "%s". Check your YAML syntax.', \get_debug_type($service), $id, $file)); + } + if (isset($service['stack'])) { + if (!\is_array($service['stack'])) { + throw new InvalidArgumentException(\sprintf('A stack must be an array of definitions, "%s" given for service "%s" in "%s". Check your YAML syntax.', \get_debug_type($service), $id, $file)); + } + $stack = []; + foreach ($service['stack'] as $k => $frame) { + if (\is_array($frame) && 1 === \count($frame) && !isset(self::SERVICE_KEYWORDS[\key($frame)])) { + $frame = ['class' => \key($frame), 'arguments' => \current($frame)]; + } + if (\is_array($frame) && isset($frame['stack'])) { + throw new InvalidArgumentException(\sprintf('Service stack "%s" cannot contain another stack in "%s".', $id, $file)); + } + $definition = $this->parseDefinition($id . '" at index "' . $k, $frame, $file, $defaults, \true); + if ($definition instanceof Definition) { + $definition->setInstanceofConditionals($this->instanceof); + } + $stack[$k] = $definition; + } + if ($diff = \array_diff(\array_keys($service), ['stack', 'public', 'deprecated'])) { + throw new InvalidArgumentException(\sprintf('Invalid attribute "%s"; supported ones are "public" and "deprecated" for service "%s" in "%s". Check your YAML syntax.', \implode('", "', $diff), $id, $file)); + } + $service = ['parent' => '', 'arguments' => $stack, 'tags' => ['container.stack'], 'public' => $service['public'] ?? null, 'deprecated' => $service['deprecated'] ?? null]; + } + $definition = isset($service[0]) && $service[0] instanceof Definition ? \array_shift($service) : null; + $return = null === $definition ? $return : \true; + $this->checkDefinition($id, $service, $file); + if (isset($service['alias'])) { + $alias = new Alias($service['alias']); + if (isset($service['public'])) { + $alias->setPublic($service['public']); + } elseif (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + foreach ($service as $key => $value) { + if (!\in_array($key, ['alias', 'public', 'deprecated'])) { + throw new InvalidArgumentException(\sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias", "public" and "deprecated".', $key, $id, $file)); + } + if ('deprecated' === $key) { + $deprecation = \is_array($value) ? $value : ['message' => $value]; + if (!isset($deprecation['package'])) { + throw new InvalidArgumentException(\sprintf('Missing attribute "package" of the "deprecated" option in "%s".', $file)); + } + if (!isset($deprecation['version'])) { + throw new InvalidArgumentException(\sprintf('Missing attribute "version" of the "deprecated" option in "%s".', $file)); + } + $alias->setDeprecated($deprecation['package'] ?? '', $deprecation['version'] ?? '', $deprecation['message'] ?? ''); + } + } + return $return ? $alias : $this->container->setAlias($id, $alias); + } + if (null !== $definition) { + // no-op + } elseif ($this->isLoadingInstanceof) { + $definition = new ChildDefinition(''); + } elseif (isset($service['parent'])) { + if ('' !== $service['parent'] && '@' === $service['parent'][0]) { + throw new InvalidArgumentException(\sprintf('The value of the "parent" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['parent'], \substr($service['parent'], 1))); + } + $definition = new ChildDefinition($service['parent']); + } else { + $definition = new Definition(); + } + if (isset($defaults['public'])) { + $definition->setPublic($defaults['public']); + } + if (isset($defaults['autowire'])) { + $definition->setAutowired($defaults['autowire']); + } + if (isset($defaults['autoconfigure'])) { + $definition->setAutoconfigured($defaults['autoconfigure']); + } + $definition->setChanges([]); + if (isset($service['class'])) { + $definition->setClass($service['class']); + } + if (isset($service['shared'])) { + $definition->setShared($service['shared']); + } + if (isset($service['synthetic'])) { + $definition->setSynthetic($service['synthetic']); + } + if (isset($service['lazy'])) { + $definition->setLazy((bool) $service['lazy']); + if (\is_string($service['lazy'])) { + $definition->addTag('proxy', ['interface' => $service['lazy']]); + } + } + if (isset($service['public'])) { + $definition->setPublic($service['public']); + } + if (isset($service['abstract'])) { + $definition->setAbstract($service['abstract']); + } + if (isset($service['deprecated'])) { + $deprecation = \is_array($service['deprecated']) ? $service['deprecated'] : ['message' => $service['deprecated']]; + if (!isset($deprecation['package'])) { + throw new InvalidArgumentException(\sprintf('Missing attribute "package" of the "deprecated" option in "%s".', $file)); + } + if (!isset($deprecation['version'])) { + throw new InvalidArgumentException(\sprintf('Missing attribute "version" of the "deprecated" option in "%s".', $file)); + } + $definition->setDeprecated($deprecation['package'] ?? '', $deprecation['version'] ?? '', $deprecation['message'] ?? ''); + } + if (isset($service['factory'])) { + $definition->setFactory($this->parseCallable($service['factory'], 'factory', $id, $file)); + } + if (isset($service['file'])) { + $definition->setFile($service['file']); + } + if (isset($service['arguments'])) { + $definition->setArguments($this->resolveServices($service['arguments'], $file)); + } + if (isset($service['properties'])) { + $definition->setProperties($this->resolveServices($service['properties'], $file)); + } + if (isset($service['configurator'])) { + $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file)); + } + if (isset($service['calls'])) { + if (!\is_array($service['calls'])) { + throw new InvalidArgumentException(\sprintf('Parameter "calls" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + foreach ($service['calls'] as $k => $call) { + if (!\is_array($call) && (!\is_string($k) || !$call instanceof TaggedValue)) { + throw new InvalidArgumentException(\sprintf('Invalid method call for service "%s": expected map or array, "%s" given in "%s".', $id, $call instanceof TaggedValue ? '!' . $call->getTag() : \get_debug_type($call), $file)); + } + if (\is_string($k)) { + throw new InvalidArgumentException(\sprintf('Invalid method call for service "%s", did you forgot a leading dash before "%s: ..." in "%s"?', $id, $k, $file)); + } + if (isset($call['method']) && \is_string($call['method'])) { + $method = $call['method']; + $args = $call['arguments'] ?? []; + $returnsClone = $call['returns_clone'] ?? \false; + } else { + if (1 === \count($call) && \is_string(\key($call))) { + $method = \key($call); + $args = $call[$method]; + if ($args instanceof TaggedValue) { + if ('returns_clone' !== $args->getTag()) { + throw new InvalidArgumentException(\sprintf('Unsupported tag "!%s", did you mean "!returns_clone" for service "%s" in "%s"?', $args->getTag(), $id, $file)); + } + $returnsClone = \true; + $args = $args->getValue(); + } else { + $returnsClone = \false; + } + } elseif (empty($call[0])) { + throw new InvalidArgumentException(\sprintf('Invalid call for service "%s": the method must be defined as the first index of an array or as the only key of a map in "%s".', $id, $file)); + } else { + $method = $call[0]; + $args = $call[1] ?? []; + $returnsClone = $call[2] ?? \false; + } + } + if (!\is_array($args)) { + throw new InvalidArgumentException(\sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in "%s". Check your YAML syntax.', $method, $id, $file)); + } + $args = $this->resolveServices($args, $file); + $definition->addMethodCall($method, $args, $returnsClone); + } + } + $tags = $service['tags'] ?? []; + if (!\is_array($tags)) { + throw new InvalidArgumentException(\sprintf('Parameter "tags" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + if (isset($defaults['tags'])) { + $tags = \array_merge($tags, $defaults['tags']); + } + foreach ($tags as $tag) { + if (!\is_array($tag)) { + $tag = ['name' => $tag]; + } + if (1 === \count($tag) && \is_array(\current($tag))) { + $name = \key($tag); + $tag = \current($tag); + } else { + if (!isset($tag['name'])) { + throw new InvalidArgumentException(\sprintf('A "tags" entry is missing a "name" key for service "%s" in "%s".', $id, $file)); + } + $name = $tag['name']; + unset($tag['name']); + } + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException(\sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', $id, $file)); + } + foreach ($tag as $attribute => $value) { + if (!\is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(\sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in "%s". Check your YAML syntax.', $id, $name, $attribute, $file)); + } + } + $definition->addTag($name, $tag); + } + if (null !== ($decorates = $service['decorates'] ?? null)) { + if ('' !== $decorates && '@' === $decorates[0]) { + throw new InvalidArgumentException(\sprintf('The value of the "decorates" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['decorates'], \substr($decorates, 1))); + } + $decorationOnInvalid = \array_key_exists('decoration_on_invalid', $service) ? $service['decoration_on_invalid'] : 'exception'; + if ('exception' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } elseif ('ignore' === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif (null === $decorationOnInvalid) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } elseif ('null' === $decorationOnInvalid) { + throw new InvalidArgumentException(\sprintf('Invalid value "%s" for attribute "decoration_on_invalid" on service "%s". Did you mean null (without quotes) in "%s"?', $decorationOnInvalid, $id, $file)); + } else { + throw new InvalidArgumentException(\sprintf('Invalid value "%s" for attribute "decoration_on_invalid" on service "%s". Did you mean "exception", "ignore" or null in "%s"?', $decorationOnInvalid, $id, $file)); + } + $renameId = $service['decoration_inner_name'] ?? null; + $priority = $service['decoration_priority'] ?? 0; + $definition->setDecoratedService($decorates, $renameId, $priority, $invalidBehavior); + } + if (isset($service['autowire'])) { + $definition->setAutowired($service['autowire']); + } + if (isset($defaults['bind']) || isset($service['bind'])) { + // deep clone, to avoid multiple process of the same instance in the passes + $bindings = $definition->getBindings(); + $bindings += isset($defaults['bind']) ? \unserialize(\serialize($defaults['bind'])) : []; + if (isset($service['bind'])) { + if (!\is_array($service['bind'])) { + throw new InvalidArgumentException(\sprintf('Parameter "bind" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + $bindings = \array_merge($bindings, $this->resolveServices($service['bind'], $file)); + $bindingType = $this->isLoadingInstanceof ? BoundArgument::INSTANCEOF_BINDING : BoundArgument::SERVICE_BINDING; + foreach ($bindings as $argument => $value) { + if (!$value instanceof BoundArgument) { + $bindings[$argument] = new BoundArgument($value, $trackBindings, $bindingType, $file); + } + } + } + $definition->setBindings($bindings); + } + if (isset($service['autoconfigure'])) { + $definition->setAutoconfigured($service['autoconfigure']); + } + if (\array_key_exists('namespace', $service) && !\array_key_exists('resource', $service)) { + throw new InvalidArgumentException(\sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + if ($return) { + if (\array_key_exists('resource', $service)) { + throw new InvalidArgumentException(\sprintf('Invalid "resource" attribute found for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + return $definition; + } + if (\array_key_exists('resource', $service)) { + if (!\is_string($service['resource'])) { + throw new InvalidArgumentException(\sprintf('A "resource" attribute must be of type string for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + $exclude = $service['exclude'] ?? null; + $namespace = $service['namespace'] ?? $id; + $this->registerClasses($definition, $namespace, $service['resource'], $exclude); + } else { + $this->setDefinition($id, $definition); + } + } + /** + * @throws InvalidArgumentException When errors occur + * @return string|mixed[]|\Symfony\Component\DependencyInjection\Reference + * @param mixed $callable + */ + private function parseCallable($callable, string $parameter, string $id, string $file) + { + if (\is_string($callable)) { + if (\strncmp($callable, '@=', \strlen('@=')) === 0) { + if ('factory' !== $parameter) { + throw new InvalidArgumentException(\sprintf('Using expressions in "%s" for the "%s" service is not supported in "%s".', $parameter, $id, $file)); + } + if (!\class_exists(Expression::class)) { + throw new \LogicException('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); + } + return $callable; + } + if ('' !== $callable && '@' === $callable[0]) { + if (\strpos($callable, ':') === \false) { + return [$this->resolveServices($callable, $file), '__invoke']; + } + throw new InvalidArgumentException(\sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s" in "%s").', $parameter, $id, $callable, \substr($callable, 1), $file)); + } + return $callable; + } + if (\is_array($callable)) { + if (isset($callable[0]) && isset($callable[1])) { + return [$this->resolveServices($callable[0], $file), $callable[1]]; + } + if ('factory' === $parameter && isset($callable[1]) && null === $callable[0]) { + return $callable; + } + throw new InvalidArgumentException(\sprintf('Parameter "%s" must contain an array with two elements for service "%s" in "%s". Check your YAML syntax.', $parameter, $id, $file)); + } + throw new InvalidArgumentException(\sprintf('Parameter "%s" must be a string or an array for service "%s" in "%s". Check your YAML syntax.', $parameter, $id, $file)); + } + /** + * Loads a YAML file. + * + * @throws InvalidArgumentException when the given file is not a local file or when it does not exist + */ + protected function loadFile(string $file) : ?array + { + if (!\class_exists(\MonorepoBuilderPrefix202310\Symfony\Component\Yaml\Parser::class)) { + throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.'); + } + if (!\stream_is_local($file)) { + throw new InvalidArgumentException(\sprintf('This is not a local file "%s".', $file)); + } + if (!\is_file($file)) { + throw new InvalidArgumentException(\sprintf('The file "%s" does not exist.', $file)); + } + $this->yamlParser = $this->yamlParser ?? new YamlParser(); + try { + $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS); + } catch (ParseException $e) { + throw new InvalidArgumentException(\sprintf('The file "%s" does not contain valid YAML: ', $file) . $e->getMessage(), 0, $e); + } + return $this->validate($configuration, $file); + } + /** + * Validates a YAML file. + * + * @throws InvalidArgumentException When service file is not valid + * @param mixed $content + */ + private function validate($content, string $file) : ?array + { + if (null === $content) { + return $content; + } + if (!\is_array($content)) { + throw new InvalidArgumentException(\sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file)); + } + foreach ($content as $namespace => $data) { + if (\in_array($namespace, ['imports', 'parameters', 'services']) || \strncmp($namespace, 'when@', \strlen('when@')) === 0) { + continue; + } + if (!$this->container->hasExtension($namespace)) { + $extensionNamespaces = \array_filter(\array_map(function (ExtensionInterface $ext) { + return $ext->getAlias(); + }, $this->container->getExtensions())); + throw new InvalidArgumentException(\sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $namespace, $file, $namespace, $extensionNamespaces ? \sprintf('"%s"', \implode('", "', $extensionNamespaces)) : 'none')); + } + } + return $content; + } + /** + * @param mixed $value + * @return mixed + */ + private function resolveServices($value, string $file, bool $isParameter = \false) + { + if ($value instanceof TaggedValue) { + $argument = $value->getValue(); + if ('closure' === $value->getTag()) { + $argument = $this->resolveServices($argument, $file, $isParameter); + return (new Definition('Closure'))->setFactory(['Closure', 'fromCallable'])->addArgument($argument); + } + if ('iterator' === $value->getTag()) { + if (!\is_array($argument)) { + throw new InvalidArgumentException(\sprintf('"!iterator" tag only accepts sequences in "%s".', $file)); + } + $argument = $this->resolveServices($argument, $file, $isParameter); + return new IteratorArgument($argument); + } + if ('service_closure' === $value->getTag()) { + $argument = $this->resolveServices($argument, $file, $isParameter); + return new ServiceClosureArgument($argument); + } + if ('service_locator' === $value->getTag()) { + if (!\is_array($argument)) { + throw new InvalidArgumentException(\sprintf('"!service_locator" tag only accepts maps in "%s".', $file)); + } + $argument = $this->resolveServices($argument, $file, $isParameter); + return new ServiceLocatorArgument($argument); + } + if (\in_array($value->getTag(), ['tagged', 'tagged_iterator', 'tagged_locator'], \true)) { + $forLocator = 'tagged_locator' === $value->getTag(); + if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) { + if ($diff = \array_diff(\array_keys($argument), ['tag', 'index_by', 'default_index_method', 'default_priority_method'])) { + throw new InvalidArgumentException(\sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by", "default_index_method", and "default_priority_method".', $value->getTag(), \implode('", "', $diff))); + } + $argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null); + } elseif (\is_string($argument) && $argument) { + $argument = new TaggedIteratorArgument($argument, null, null, $forLocator); + } else { + throw new InvalidArgumentException(\sprintf('"!%s" tags only accept a non empty string or an array with a key "tag" in "%s".', $value->getTag(), $file)); + } + if ($forLocator) { + $argument = new ServiceLocatorArgument($argument); + } + return $argument; + } + if ('service' === $value->getTag()) { + if ($isParameter) { + throw new InvalidArgumentException(\sprintf('Using an anonymous service in a parameter is not allowed in "%s".', $file)); + } + $isLoadingInstanceof = $this->isLoadingInstanceof; + $this->isLoadingInstanceof = \false; + $instanceof = $this->instanceof; + $this->instanceof = []; + $id = \sprintf('.%d_%s', ++$this->anonymousServicesCount, \preg_replace('/^.*\\\\/', '', $argument['class'] ?? '') . $this->anonymousServicesSuffix); + $this->parseDefinition($id, $argument, $file, []); + if (!$this->container->hasDefinition($id)) { + throw new InvalidArgumentException(\sprintf('Creating an alias using the tag "!service" is not allowed in "%s".', $file)); + } + $this->container->getDefinition($id); + $this->isLoadingInstanceof = $isLoadingInstanceof; + $this->instanceof = $instanceof; + return new Reference($id); + } + if ('abstract' === $value->getTag()) { + return new AbstractArgument($value->getValue()); + } + throw new InvalidArgumentException(\sprintf('Unsupported tag "!%s".', $value->getTag())); + } + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = $this->resolveServices($v, $file, $isParameter); + } + } elseif (\is_string($value) && \strncmp($value, '@=', \strlen('@=')) === 0) { + if ($isParameter) { + throw new InvalidArgumentException(\sprintf('Using expressions in parameters is not allowed in "%s".', $file)); + } + if (!\class_exists(Expression::class)) { + throw new \LogicException('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'); + } + return new Expression(\substr($value, 2)); + } elseif (\is_string($value) && \strncmp($value, '@', \strlen('@')) === 0) { + if (\strncmp($value, '@@', \strlen('@@')) === 0) { + $value = \substr($value, 1); + $invalidBehavior = null; + } elseif (\strncmp($value, '@!', \strlen('@!')) === 0) { + $value = \substr($value, 2); + $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + } elseif (\strncmp($value, '@?', \strlen('@?')) === 0) { + $value = \substr($value, 2); + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } else { + $value = \substr($value, 1); + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } + if (null !== $invalidBehavior) { + $value = new Reference($value, $invalidBehavior); + } + } + return $value; + } + private function loadFromExtensions(array $content) + { + foreach ($content as $namespace => $values) { + if (\in_array($namespace, ['imports', 'parameters', 'services']) || \strncmp($namespace, 'when@', \strlen('when@')) === 0) { + continue; + } + if (!\is_array($values) && null !== $values) { + $values = []; + } + $this->container->loadFromExtension($namespace, $values); + } + } + private function checkDefinition(string $id, array $definition, string $file) + { + if ($this->isLoadingInstanceof) { + $keywords = self::INSTANCEOF_KEYWORDS; + } elseif (isset($definition['resource']) || isset($definition['namespace'])) { + $keywords = self::PROTOTYPE_KEYWORDS; + } else { + $keywords = self::SERVICE_KEYWORDS; + } + foreach ($definition as $key => $value) { + if (!isset($keywords[$key])) { + throw new InvalidArgumentException(\sprintf('The configuration key "%s" is unsupported for definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, \implode('", "', $keywords))); + } + } + } +} diff --git a/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd b/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd new file mode 100644 index 0000000000..ec642212c2 --- /dev/null +++ b/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/symfony/dependency-injection/PATCHES.txt b/vendor/symfony/dependency-injection/PATCHES.txt new file mode 100644 index 0000000000..b910adf724 --- /dev/null +++ b/vendor/symfony/dependency-injection/PATCHES.txt @@ -0,0 +1,7 @@ +This file was automatically generated by Composer Patches (https://github.com/cweagans/composer-patches) +Patches applied to this directory: + +0 +Source: https://raw.githubusercontent.com/symplify/vendor-patch-files/main/patches/generic-php-config-loader.patch + + diff --git a/vendor/symfony/dependency-injection/Parameter.php b/vendor/symfony/dependency-injection/Parameter.php new file mode 100644 index 0000000000..873f87bb76 --- /dev/null +++ b/vendor/symfony/dependency-injection/Parameter.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * Parameter represents a parameter reference. + * + * @author Fabien Potencier + */ +class Parameter +{ + /** + * @var string + */ + private $id; + public function __construct(string $id) + { + $this->id = $id; + } + public function __toString() : string + { + return $this->id; + } +} diff --git a/vendor/symfony/dependency-injection/ParameterBag/ContainerBag.php b/vendor/symfony/dependency-injection/ParameterBag/ContainerBag.php new file mode 100644 index 0000000000..b25ed2dfc2 --- /dev/null +++ b/vendor/symfony/dependency-injection/ParameterBag/ContainerBag.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Container; +/** + * @author Nicolas Grekas + */ +class ContainerBag extends FrozenParameterBag implements ContainerBagInterface +{ + /** + * @var \Symfony\Component\DependencyInjection\Container + */ + private $container; + public function __construct(Container $container) + { + $this->container = $container; + } + /** + * {@inheritdoc} + */ + public function all() : array + { + return $this->container->getParameterBag()->all(); + } + /** + * {@inheritdoc} + * @return mixed[]|bool|string|int|float|\UnitEnum|null + */ + public function get(string $name) + { + return $this->container->getParameter($name); + } + /** + * {@inheritdoc} + */ + public function has(string $name) : bool + { + return $this->container->hasParameter($name); + } +} diff --git a/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php b/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php new file mode 100644 index 0000000000..15d0f6b597 --- /dev/null +++ b/vendor/symfony/dependency-injection/ParameterBag/ContainerBagInterface.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +/** + * ContainerBagInterface is the interface implemented by objects that manage service container parameters. + * + * @author Nicolas Grekas + */ +interface ContainerBagInterface extends ContainerInterface +{ + /** + * Gets the service container parameters. + */ + public function all() : array; + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @param mixed $value + */ + public function resolveValue($value); + /** + * Escape parameter placeholders %. + * @param mixed $value + * @return mixed + */ + public function escapeValue($value); + /** + * Unescape parameter placeholders %. + * @param mixed $value + * @return mixed + */ + public function unescapeValue($value); +} diff --git a/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php b/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php new file mode 100644 index 0000000000..ceedf7c677 --- /dev/null +++ b/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php @@ -0,0 +1,153 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * @author Nicolas Grekas + */ +class EnvPlaceholderParameterBag extends ParameterBag +{ + /** + * @var string + */ + private $envPlaceholderUniquePrefix; + /** + * @var mixed[] + */ + private $envPlaceholders = []; + /** + * @var mixed[] + */ + private $unusedEnvPlaceholders = []; + /** + * @var mixed[] + */ + private $providedTypes = []; + /** + * @var int + */ + private static $counter = 0; + /** + * {@inheritdoc} + * @return mixed[]|bool|string|int|float|\UnitEnum|null + */ + public function get(string $name) + { + if (\strncmp($name, 'env(', \strlen('env(')) === 0 && \substr_compare($name, ')', -\strlen(')')) === 0 && 'env()' !== $name) { + $env = \substr($name, 4, -1); + if (isset($this->envPlaceholders[$env])) { + foreach ($this->envPlaceholders[$env] as $placeholder) { + return $placeholder; + // return first result + } + } + if (isset($this->unusedEnvPlaceholders[$env])) { + foreach ($this->unusedEnvPlaceholders[$env] as $placeholder) { + return $placeholder; + // return first result + } + } + if (!\preg_match('/^(?:[-.\\w]*+:)*+\\w++$/', $env)) { + throw new InvalidArgumentException(\sprintf('Invalid %s name: only "word" characters are allowed.', $name)); + } + if ($this->has($name) && null !== ($defaultValue = parent::get($name)) && !\is_string($defaultValue)) { + throw new RuntimeException(\sprintf('The default value of an env() parameter must be a string or null, but "%s" given to "%s".', \get_debug_type($defaultValue), $name)); + } + $uniqueName = \md5($name . '_' . self::$counter++); + $placeholder = \sprintf('%s_%s_%s', $this->getEnvPlaceholderUniquePrefix(), \strtr($env, ':-.', '___'), $uniqueName); + $this->envPlaceholders[$env][$placeholder] = $placeholder; + return $placeholder; + } + return parent::get($name); + } + /** + * Gets the common env placeholder prefix for env vars created by this bag. + */ + public function getEnvPlaceholderUniquePrefix() : string + { + if (!isset($this->envPlaceholderUniquePrefix)) { + $reproducibleEntropy = \unserialize(\serialize($this->parameters)); + \array_walk_recursive($reproducibleEntropy, function (&$v) { + $v = null; + }); + $this->envPlaceholderUniquePrefix = 'env_' . \substr(\md5(\serialize($reproducibleEntropy)), -16); + } + return $this->envPlaceholderUniquePrefix; + } + /** + * Returns the map of env vars used in the resolved parameter values to their placeholders. + * + * @return string[][] A map of env var names to their placeholders + */ + public function getEnvPlaceholders() : array + { + return $this->envPlaceholders; + } + public function getUnusedEnvPlaceholders() : array + { + return $this->unusedEnvPlaceholders; + } + public function clearUnusedEnvPlaceholders() + { + $this->unusedEnvPlaceholders = []; + } + /** + * Merges the env placeholders of another EnvPlaceholderParameterBag. + */ + public function mergeEnvPlaceholders(self $bag) + { + if ($newPlaceholders = $bag->getEnvPlaceholders()) { + $this->envPlaceholders += $newPlaceholders; + foreach ($newPlaceholders as $env => $placeholders) { + $this->envPlaceholders[$env] += $placeholders; + } + } + if ($newUnusedPlaceholders = $bag->getUnusedEnvPlaceholders()) { + $this->unusedEnvPlaceholders += $newUnusedPlaceholders; + foreach ($newUnusedPlaceholders as $env => $placeholders) { + $this->unusedEnvPlaceholders[$env] += $placeholders; + } + } + } + /** + * Maps env prefixes to their corresponding PHP types. + */ + public function setProvidedTypes(array $providedTypes) + { + $this->providedTypes = $providedTypes; + } + /** + * Gets the PHP types corresponding to env() parameter prefixes. + * + * @return string[][] + */ + public function getProvidedTypes() : array + { + return $this->providedTypes; + } + /** + * {@inheritdoc} + */ + public function resolve() + { + if ($this->resolved) { + return; + } + parent::resolve(); + foreach ($this->envPlaceholders as $env => $placeholders) { + if ($this->has($name = "env({$env})") && null !== ($default = $this->parameters[$name]) && !\is_string($default)) { + throw new RuntimeException(\sprintf('The default value of env parameter "%s" must be a string or null, "%s" given.', $env, \get_debug_type($default))); + } + } + } +} diff --git a/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php b/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php new file mode 100644 index 0000000000..5e9673f0ac --- /dev/null +++ b/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +/** + * Holds read-only parameters. + * + * @author Fabien Potencier + */ +class FrozenParameterBag extends ParameterBag +{ + /** + * For performance reasons, the constructor assumes that + * all keys are already lowercased. + * + * This is always the case when used internally. + * + * @param array $parameters An array of parameters + */ + public function __construct(array $parameters = []) + { + $this->parameters = $parameters; + $this->resolved = \true; + } + /** + * {@inheritdoc} + */ + public function clear() + { + throw new LogicException('Impossible to call clear() on a frozen ParameterBag.'); + } + /** + * {@inheritdoc} + */ + public function add(array $parameters) + { + throw new LogicException('Impossible to call add() on a frozen ParameterBag.'); + } + /** + * {@inheritdoc} + * @param mixed[]|bool|string|int|float|\UnitEnum|null $value + */ + public function set(string $name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + /** + * {@inheritdoc} + */ + public function remove(string $name) + { + throw new LogicException('Impossible to call remove() on a frozen ParameterBag.'); + } +} diff --git a/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php b/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php new file mode 100644 index 0000000000..c8c0cb001b --- /dev/null +++ b/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php @@ -0,0 +1,238 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +/** + * Holds parameters. + * + * @author Fabien Potencier + */ +class ParameterBag implements ParameterBagInterface +{ + protected $parameters = []; + protected $resolved = \false; + public function __construct(array $parameters = []) + { + $this->add($parameters); + } + /** + * {@inheritdoc} + */ + public function clear() + { + $this->parameters = []; + } + /** + * {@inheritdoc} + */ + public function add(array $parameters) + { + foreach ($parameters as $key => $value) { + $this->set($key, $value); + } + } + /** + * {@inheritdoc} + */ + public function all() : array + { + return $this->parameters; + } + /** + * {@inheritdoc} + * @return mixed[]|bool|string|int|float|\UnitEnum|null + */ + public function get(string $name) + { + if (!\array_key_exists($name, $this->parameters)) { + if (!$name) { + throw new ParameterNotFoundException($name); + } + $alternatives = []; + foreach ($this->parameters as $key => $parameterValue) { + $lev = \levenshtein($name, $key); + if ($lev <= \strlen($name) / 3 || \strpos($key, $name) !== \false) { + $alternatives[] = $key; + } + } + $nonNestedAlternative = null; + if (!\count($alternatives) && \strpos($name, '.') !== \false) { + $namePartsLength = \array_map('strlen', \explode('.', $name)); + $key = \substr($name, 0, -1 * (1 + \array_pop($namePartsLength))); + while (\count($namePartsLength)) { + if ($this->has($key)) { + if (\is_array($this->get($key))) { + $nonNestedAlternative = $key; + } + break; + } + $key = \substr($key, 0, -1 * (1 + \array_pop($namePartsLength))); + } + } + throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative); + } + return $this->parameters[$name]; + } + /** + * {@inheritdoc} + * @param mixed[]|bool|string|int|float|\UnitEnum|null $value + */ + public function set(string $name, $value) + { + $this->parameters[$name] = $value; + } + /** + * {@inheritdoc} + */ + public function has(string $name) : bool + { + return \array_key_exists($name, $this->parameters); + } + /** + * {@inheritdoc} + */ + public function remove(string $name) + { + unset($this->parameters[$name]); + } + /** + * {@inheritdoc} + */ + public function resolve() + { + if ($this->resolved) { + return; + } + $parameters = []; + foreach ($this->parameters as $key => $value) { + try { + $value = $this->resolveValue($value); + $parameters[$key] = $this->unescapeValue($value); + } catch (ParameterNotFoundException $e) { + $e->setSourceKey($key); + throw $e; + } + } + $this->parameters = $parameters; + $this->resolved = \true; + } + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem + * @param mixed $value + * @return mixed + */ + public function resolveValue($value, array $resolving = []) + { + if (\is_array($value)) { + $args = []; + foreach ($value as $k => $v) { + $args[\is_string($k) ? $this->resolveValue($k, $resolving) : $k] = $this->resolveValue($v, $resolving); + } + return $args; + } + if (!\is_string($value) || 2 > \strlen($value)) { + return $value; + } + return $this->resolveString($value, $resolving); + } + /** + * Resolves parameters inside a string. + * + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem + * @return mixed + */ + public function resolveString(string $value, array $resolving = []) + { + // we do this to deal with non string values (Boolean, integer, ...) + // as the preg_replace_callback throw an exception when trying + // a non-string in a parameter value + if (\preg_match('/^%([^%\\s]+)%$/', $value, $match)) { + $key = $match[1]; + if (isset($resolving[$key])) { + throw new ParameterCircularReferenceException(\array_keys($resolving)); + } + $resolving[$key] = \true; + return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving); + } + return \preg_replace_callback('/%%|%([^%\\s]+)%/', function ($match) use($resolving, $value) { + // skip %% + if (!isset($match[1])) { + return '%%'; + } + $key = $match[1]; + if (isset($resolving[$key])) { + throw new ParameterCircularReferenceException(\array_keys($resolving)); + } + $resolved = $this->get($key); + if (!\is_string($resolved) && !\is_numeric($resolved)) { + throw new RuntimeException(\sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type "%s" inside string value "%s".', $key, \get_debug_type($resolved), $value)); + } + $resolved = (string) $resolved; + $resolving[$key] = \true; + return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving); + }, $value); + } + public function isResolved() + { + return $this->resolved; + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + public function escapeValue($value) + { + if (\is_string($value)) { + return \str_replace('%', '%%', $value); + } + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[$k] = $this->escapeValue($v); + } + return $result; + } + return $value; + } + /** + * {@inheritdoc} + * @param mixed $value + * @return mixed + */ + public function unescapeValue($value) + { + if (\is_string($value)) { + return \str_replace('%%', '%', $value); + } + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[$k] = $this->unescapeValue($v); + } + return $result; + } + return $value; + } +} diff --git a/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php b/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php new file mode 100644 index 0000000000..5b51159f40 --- /dev/null +++ b/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\ParameterBag; + +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +/** + * ParameterBagInterface is the interface implemented by objects that manage service container parameters. + * + * @author Fabien Potencier + */ +interface ParameterBagInterface +{ + /** + * Clears all parameters. + * + * @throws LogicException if the ParameterBagInterface cannot be cleared + */ + public function clear(); + /** + * Adds parameters to the service container parameters. + * + * @throws LogicException if the parameter cannot be added + */ + public function add(array $parameters); + /** + * Gets the service container parameters. + */ + public function all() : array; + /** + * Gets a service container parameter. + * + * @throws ParameterNotFoundException if the parameter is not defined + * @return mixed[]|bool|string|int|float|\UnitEnum|null + */ + public function get(string $name); + /** + * Removes a parameter. + */ + public function remove(string $name); + /** + * Sets a service container parameter. + * + * @throws LogicException if the parameter cannot be set + * @param mixed[]|bool|string|int|float|\UnitEnum|null $value + */ + public function set(string $name, $value); + /** + * Returns true if a parameter name is defined. + */ + public function has(string $name) : bool; + /** + * Replaces parameter placeholders (%name%) by their values for all parameters. + */ + public function resolve(); + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @param mixed $value + */ + public function resolveValue($value); + /** + * Escape parameter placeholders %. + * @param mixed $value + * @return mixed + */ + public function escapeValue($value); + /** + * Unescape parameter placeholders %. + * @param mixed $value + * @return mixed + */ + public function unescapeValue($value); +} diff --git a/vendor/symfony/dependency-injection/README.md b/vendor/symfony/dependency-injection/README.md new file mode 100644 index 0000000000..fa6719a799 --- /dev/null +++ b/vendor/symfony/dependency-injection/README.md @@ -0,0 +1,14 @@ +DependencyInjection Component +============================= + +The DependencyInjection component allows you to standardize and centralize the +way objects are constructed in your application. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/dependency_injection.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/dependency-injection/Reference.php b/vendor/symfony/dependency-injection/Reference.php new file mode 100644 index 0000000000..075bd40cc3 --- /dev/null +++ b/vendor/symfony/dependency-injection/Reference.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * Reference represents a service reference. + * + * @author Fabien Potencier + */ +class Reference +{ + /** + * @var string + */ + private $id; + /** + * @var int + */ + private $invalidBehavior; + public function __construct(string $id, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + $this->id = $id; + $this->invalidBehavior = $invalidBehavior; + } + public function __toString() : string + { + return $this->id; + } + /** + * Returns the behavior to be used when the service does not exist. + */ + public function getInvalidBehavior() : int + { + return $this->invalidBehavior; + } +} diff --git a/vendor/symfony/dependency-injection/ReverseContainer.php b/vendor/symfony/dependency-injection/ReverseContainer.php new file mode 100644 index 0000000000..1e7ff49c97 --- /dev/null +++ b/vendor/symfony/dependency-injection/ReverseContainer.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +/** + * Turns public and "container.reversible" services back to their ids. + * + * @author Nicolas Grekas + */ +final class ReverseContainer +{ + /** + * @var \Symfony\Component\DependencyInjection\Container + */ + private $serviceContainer; + /** + * @var \Psr\Container\ContainerInterface + */ + private $reversibleLocator; + /** + * @var string + */ + private $tagName; + /** + * @var \Closure + */ + private $getServiceId; + public function __construct(Container $serviceContainer, ContainerInterface $reversibleLocator, string $tagName = 'container.reversible') + { + $this->serviceContainer = $serviceContainer; + $this->reversibleLocator = $reversibleLocator; + $this->tagName = $tagName; + $this->getServiceId = \Closure::bind(function (object $service) : ?string { + return (\array_search($service, $this->services, \true) ?: \array_search($service, $this->privates, \true)) ?: null; + }, $serviceContainer, Container::class); + } + /** + * Returns the id of the passed object when it exists as a service. + * + * To be reversible, services need to be either public or be tagged with "container.reversible". + */ + public function getId(object $service) : ?string + { + if ($this->serviceContainer === $service) { + return 'service_container'; + } + if (null === ($id = ($this->getServiceId)($service))) { + return null; + } + if ($this->serviceContainer->has($id) || $this->reversibleLocator->has($id)) { + return $id; + } + return null; + } + /** + * @throws ServiceNotFoundException When the service is not reversible + */ + public function getService(string $id) : object + { + if ($this->reversibleLocator->has($id)) { + return $this->reversibleLocator->get($id); + } + if (isset($this->serviceContainer->getRemovedIds()[$id])) { + throw new ServiceNotFoundException($id, null, null, [], \sprintf('The "%s" service is private and cannot be accessed by reference. You should either make it public, or tag it as "%s".', $id, $this->tagName)); + } + return $this->serviceContainer->get($id); + } +} diff --git a/vendor/symfony/dependency-injection/ServiceLocator.php b/vendor/symfony/dependency-injection/ServiceLocator.php new file mode 100644 index 0000000000..bc229bbe10 --- /dev/null +++ b/vendor/symfony/dependency-injection/ServiceLocator.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerExceptionInterface; +use MonorepoBuilderPrefix202310\Psr\Container\NotFoundExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceLocatorTrait; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceProviderInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceSubscriberInterface; +/** + * @author Robin Chalas + * @author Nicolas Grekas + */ +class ServiceLocator implements ServiceProviderInterface, \Countable +{ + use ServiceLocatorTrait { + get as private doGet; + } + /** + * @var string|null + */ + private $externalId; + /** + * @var \Symfony\Component\DependencyInjection\Container|null + */ + private $container; + /** + * {@inheritdoc} + * @return mixed + */ + public function get(string $id) + { + if (!$this->externalId) { + return $this->doGet($id); + } + try { + return $this->doGet($id); + } catch (RuntimeException $e) { + $what = \sprintf('service "%s" required by "%s"', $id, $this->externalId); + $message = \preg_replace('/service "\\.service_locator\\.[^"]++"/', $what, $e->getMessage()); + if ($e->getMessage() === $message) { + $message = \sprintf('Cannot resolve %s: %s', $what, $message); + } + $r = new \ReflectionProperty($e, 'message'); + $r->setAccessible(\true); + $r->setValue($e, $message); + throw $e; + } + } + public function __invoke(string $id) + { + return isset($this->factories[$id]) ? $this->get($id) : null; + } + /** + * @internal + * @return static + */ + public function withContext(string $externalId, Container $container) + { + $locator = clone $this; + $locator->externalId = $externalId; + $locator->container = $container; + return $locator; + } + public function count() : int + { + return \count($this->getProvidedServices()); + } + private function createNotFoundException(string $id) : NotFoundExceptionInterface + { + if ($this->loading) { + $msg = \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', \end($this->loading), $id, $this->formatAlternatives()); + return new ServiceNotFoundException($id, \end($this->loading) ?: null, null, [], $msg); + } + $class = \debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 4); + $class = isset($class[3]['object']) ? \get_class($class[3]['object']) : null; + $externalId = $this->externalId ?: $class; + $msg = []; + $msg[] = \sprintf('Service "%s" not found:', $id); + if (!$this->container) { + $class = null; + } elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) { + $msg[] = 'even though it exists in the app\'s container,'; + } else { + try { + $this->container->get($id); + $class = null; + } catch (ServiceNotFoundException $e) { + if ($e->getAlternatives()) { + $msg[] = \sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or')); + } else { + $class = null; + } + } + } + if ($externalId) { + $msg[] = \sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives()); + } else { + $msg[] = \sprintf('the current service locator %s', $this->formatAlternatives()); + } + if (!$class) { + // no-op + } elseif (\is_subclass_of($class, ServiceSubscriberInterface::class)) { + $msg[] = \sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', \preg_replace('/([^\\\\]++\\\\)++/', '', $class)); + } else { + $msg[] = 'Try using dependency injection instead.'; + } + return new ServiceNotFoundException($id, \end($this->loading) ?: null, null, [], \implode(' ', $msg)); + } + private function createCircularReferenceException(string $id, array $path) : ContainerExceptionInterface + { + return new ServiceCircularReferenceException($id, $path); + } + private function formatAlternatives(array $alternatives = null, string $separator = 'and') : string + { + $format = '"%s"%s'; + if (null === $alternatives) { + if (!($alternatives = \array_keys($this->factories))) { + return 'is empty...'; + } + $format = \sprintf('only knows about the %s service%s.', $format, 1 < \count($alternatives) ? 's' : ''); + } + $last = \array_pop($alternatives); + return \sprintf($format, $alternatives ? \implode('", "', $alternatives) : $last, $alternatives ? \sprintf(' %s "%s"', $separator, $last) : ''); + } +} diff --git a/vendor/symfony/dependency-injection/TaggedContainerInterface.php b/vendor/symfony/dependency-injection/TaggedContainerInterface.php new file mode 100644 index 0000000000..18f256d066 --- /dev/null +++ b/vendor/symfony/dependency-injection/TaggedContainerInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * TaggedContainerInterface is the interface implemented when a container knows how to deals with tags. + * + * @author Fabien Potencier + */ +interface TaggedContainerInterface extends ContainerInterface +{ + /** + * Returns service ids for a given tag. + * + * @param string $name The tag name + */ + public function findTaggedServiceIds(string $name) : array; +} diff --git a/vendor/symfony/dependency-injection/TypedReference.php b/vendor/symfony/dependency-injection/TypedReference.php new file mode 100644 index 0000000000..8f6ece672a --- /dev/null +++ b/vendor/symfony/dependency-injection/TypedReference.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * Represents a PHP type-hinted service reference. + * + * @author Nicolas Grekas + */ +class TypedReference extends Reference +{ + /** + * @var string + */ + private $type; + /** + * @var string|null + */ + private $name; + /** + * @param string $id The service identifier + * @param string $type The PHP type of the identified service + * @param int $invalidBehavior The behavior when the service does not exist + * @param string|null $name The name of the argument targeting the service + */ + public function __construct(string $id, string $type, int $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, string $name = null) + { + $this->name = $type === $id ? $name : null; + parent::__construct($id, $invalidBehavior); + $this->type = $type; + } + public function getType() + { + return $this->type; + } + public function getName() : ?string + { + return $this->name; + } +} diff --git a/vendor/symfony/dependency-injection/Variable.php b/vendor/symfony/dependency-injection/Variable.php new file mode 100644 index 0000000000..05177ba2ad --- /dev/null +++ b/vendor/symfony/dependency-injection/Variable.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\DependencyInjection; + +/** + * Represents a variable. + * + * $var = new Variable('a'); + * + * will be dumped as + * + * $a + * + * by the PHP dumper. + * + * @author Johannes M. Schmitt + */ +class Variable +{ + /** + * @var string + */ + private $name; + public function __construct(string $name) + { + $this->name = $name; + } + public function __toString() : string + { + return $this->name; + } +} diff --git a/vendor/symfony/dependency-injection/composer.json b/vendor/symfony/dependency-injection/composer.json new file mode 100644 index 0000000000..9cf23b0fdc --- /dev/null +++ b/vendor/symfony/dependency-injection/composer.json @@ -0,0 +1,56 @@ +{ + "name": "symfony\/dependency-injection", + "type": "library", + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "keywords": [], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1", + "psr\/container": "^1.1|^2.0", + "symfony\/deprecation-contracts": "^2.1|^3", + "symfony\/service-contracts": "^1.1.6|^2.0|^3.0" + }, + "require-dev": { + "symfony\/yaml": "^5.4|^6.0", + "symfony\/config": "^6.1", + "symfony\/expression-language": "^5.4|^6.0" + }, + "suggest": { + "symfony\/yaml": "", + "symfony\/config": "", + "symfony\/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony\/expression-language": "For using expressions in service container configuration", + "symfony\/proxy-manager-bridge": "Generate service proxies to lazy load them" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony\/config": "<6.1", + "symfony\/finder": "<5.4", + "symfony\/proxy-manager-bridge": "<5.4", + "symfony\/yaml": "<5.4" + }, + "provide": { + "psr\/container-implementation": "1.1|2.0", + "symfony\/service-implementation": "1.1|2.0|3.0" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/vendor/symfony/deprecation-contracts/CHANGELOG.md b/vendor/symfony/deprecation-contracts/CHANGELOG.md new file mode 100644 index 0000000000..7932e26132 --- /dev/null +++ b/vendor/symfony/deprecation-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/vendor/symfony/deprecation-contracts/LICENSE b/vendor/symfony/deprecation-contracts/LICENSE new file mode 100644 index 0000000000..0ed3a24655 --- /dev/null +++ b/vendor/symfony/deprecation-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/deprecation-contracts/README.md b/vendor/symfony/deprecation-contracts/README.md new file mode 100644 index 0000000000..9814864c03 --- /dev/null +++ b/vendor/symfony/deprecation-contracts/README.md @@ -0,0 +1,26 @@ +Symfony Deprecation Contracts +============================= + +A generic function and convention to trigger deprecation notices. + +This package provides a single global function named `trigger_deprecation()` that triggers silenced deprecation notices. + +By using a custom PHP error handler such as the one provided by the Symfony ErrorHandler component, +the triggered deprecations can be caught and logged for later discovery, both on dev and prod environments. + +The function requires at least 3 arguments: + - the name of the Composer package that is triggering the deprecation + - the version of the package that introduced the deprecation + - the message of the deprecation + - more arguments can be provided: they will be inserted in the message using `printf()` formatting + +Example: +```php +trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use "%s" instead.', 'bitcoin', 'fabcoin'); +``` + +This will generate the following message: +`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.` + +While not recommended, the deprecation notices can be completely ignored by declaring an empty +`function trigger_deprecation() {}` in your application. diff --git a/vendor/symfony/deprecation-contracts/composer.json b/vendor/symfony/deprecation-contracts/composer.json new file mode 100644 index 0000000000..768470a951 --- /dev/null +++ b/vendor/symfony/deprecation-contracts/composer.json @@ -0,0 +1,35 @@ +{ + "name": "symfony\/deprecation-contracts", + "type": "library", + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1" + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony\/contracts", + "url": "https:\/\/github.com\/symfony\/contracts" + } + } +} \ No newline at end of file diff --git a/vendor/symfony/deprecation-contracts/function.php b/vendor/symfony/deprecation-contracts/function.php new file mode 100644 index 0000000000..d4371504a0 --- /dev/null +++ b/vendor/symfony/deprecation-contracts/function.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (!function_exists('trigger_deprecation')) { + /** + * Triggers a silenced deprecation notice. + * + * @param string $package The name of the Composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message The message of the deprecation + * @param mixed ...$args Values to insert in the message using printf() formatting + * + * @author Nicolas Grekas + */ + function trigger_deprecation(string $package, string $version, string $message, ...$args): void + { + @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED); + } +} diff --git a/vendor/symfony/filesystem/CHANGELOG.md b/vendor/symfony/filesystem/CHANGELOG.md new file mode 100644 index 0000000000..fcb7170ca5 --- /dev/null +++ b/vendor/symfony/filesystem/CHANGELOG.md @@ -0,0 +1,82 @@ +CHANGELOG +========= + +5.4 +--- + + * Add `Path` class + * Add `$lock` argument to `Filesystem::appendToFile()` + +5.0.0 +----- + + * `Filesystem::dumpFile()` and `appendToFile()` don't accept arrays anymore + +4.4.0 +----- + + * support for passing a `null` value to `Filesystem::isAbsolutePath()` is deprecated and will be removed in 5.0 + * `tempnam()` now accepts a third argument `$suffix`. + +4.3.0 +----- + + * support for passing arrays to `Filesystem::dumpFile()` is deprecated and will be removed in 5.0 + * support for passing arrays to `Filesystem::appendToFile()` is deprecated and will be removed in 5.0 + +4.0.0 +----- + + * removed `LockHandler` + * Support for passing relative paths to `Filesystem::makePathRelative()` has been removed. + +3.4.0 +----- + + * support for passing relative paths to `Filesystem::makePathRelative()` is deprecated and will be removed in 4.0 + +3.3.0 +----- + + * added `appendToFile()` to append contents to existing files + +3.2.0 +----- + + * added `readlink()` as a platform independent method to read links + +3.0.0 +----- + + * removed `$mode` argument from `Filesystem::dumpFile()` + +2.8.0 +----- + + * added tempnam() a stream aware version of PHP's native tempnam() + +2.6.0 +----- + + * added LockHandler + +2.3.12 +------ + + * deprecated dumpFile() file mode argument. + +2.3.0 +----- + + * added the dumpFile() method to atomically write files + +2.2.0 +----- + + * added a delete option for the mirror() method + +2.1.0 +----- + + * 24eb396 : BC Break : mkdir() function now throws exception in case of failure instead of returning Boolean value + * created the component diff --git a/vendor/symfony/filesystem/Exception/ExceptionInterface.php b/vendor/symfony/filesystem/Exception/ExceptionInterface.php new file mode 100644 index 0000000000..99aceff415 --- /dev/null +++ b/vendor/symfony/filesystem/Exception/ExceptionInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Romain Neutron + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/filesystem/Exception/FileNotFoundException.php b/vendor/symfony/filesystem/Exception/FileNotFoundException.php new file mode 100644 index 0000000000..9f2207c001 --- /dev/null +++ b/vendor/symfony/filesystem/Exception/FileNotFoundException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception; + +/** + * Exception class thrown when a file couldn't be found. + * + * @author Fabien Potencier + * @author Christian Gärtner + */ +class FileNotFoundException extends IOException +{ + public function __construct(string $message = null, int $code = 0, \Throwable $previous = null, string $path = null) + { + if (null === $message) { + if (null === $path) { + $message = 'File could not be found.'; + } else { + $message = \sprintf('File "%s" could not be found.', $path); + } + } + parent::__construct($message, $code, $previous, $path); + } +} diff --git a/vendor/symfony/filesystem/Exception/IOException.php b/vendor/symfony/filesystem/Exception/IOException.php new file mode 100644 index 0000000000..f53f206d7d --- /dev/null +++ b/vendor/symfony/filesystem/Exception/IOException.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception; + +/** + * Exception class thrown when a filesystem operation failure happens. + * + * @author Romain Neutron + * @author Christian Gärtner + * @author Fabien Potencier + */ +class IOException extends \RuntimeException implements IOExceptionInterface +{ + /** + * @var string|null + */ + private $path; + public function __construct(string $message, int $code = 0, \Throwable $previous = null, string $path = null) + { + $this->path = $path; + parent::__construct($message, $code, $previous); + } + public function getPath() : ?string + { + return $this->path; + } +} diff --git a/vendor/symfony/filesystem/Exception/IOExceptionInterface.php b/vendor/symfony/filesystem/Exception/IOExceptionInterface.php new file mode 100644 index 0000000000..2ff225f3fb --- /dev/null +++ b/vendor/symfony/filesystem/Exception/IOExceptionInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception; + +/** + * IOException interface for file and input/output stream related exceptions thrown by the component. + * + * @author Christian Gärtner + */ +interface IOExceptionInterface extends ExceptionInterface +{ + /** + * Returns the associated path for the exception. + */ + public function getPath() : ?string; +} diff --git a/vendor/symfony/filesystem/Exception/InvalidArgumentException.php b/vendor/symfony/filesystem/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000..9a3c86a3e7 --- /dev/null +++ b/vendor/symfony/filesystem/Exception/InvalidArgumentException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception; + +/** + * @author Christian Flothmann + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/filesystem/Exception/RuntimeException.php b/vendor/symfony/filesystem/Exception/RuntimeException.php new file mode 100644 index 0000000000..920e80dc9b --- /dev/null +++ b/vendor/symfony/filesystem/Exception/RuntimeException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception; + +/** + * @author Théo Fidry + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/filesystem/Filesystem.php b/vendor/symfony/filesystem/Filesystem.php new file mode 100644 index 0000000000..24cf236dab --- /dev/null +++ b/vendor/symfony/filesystem/Filesystem.php @@ -0,0 +1,667 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem; + +use MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception\FileNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception\IOException; +/** + * Provides basic utility to manipulate the file system. + * + * @author Fabien Potencier + */ +class Filesystem +{ + private static $lastError; + /** + * Copies a file. + * + * If the target file is older than the origin file, it's always overwritten. + * If the target file is newer, it is overwritten only when the + * $overwriteNewerFiles option is set to true. + * + * @return void + * + * @throws FileNotFoundException When originFile doesn't exist + * @throws IOException When copy fails + */ + public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = \false) + { + $originIsLocal = \stream_is_local($originFile) || 0 === \stripos($originFile, 'file://'); + if ($originIsLocal && !\is_file($originFile)) { + throw new FileNotFoundException(\sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile); + } + $this->mkdir(\dirname($targetFile)); + $doCopy = \true; + if (!$overwriteNewerFiles && null === \parse_url($originFile, \PHP_URL_HOST) && \is_file($targetFile)) { + $doCopy = \filemtime($originFile) > \filemtime($targetFile); + } + if ($doCopy) { + // https://bugs.php.net/64634 + if (!($source = self::box('fopen', $originFile, 'r'))) { + throw new IOException(\sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading: ', $originFile, $targetFile) . self::$lastError, 0, null, $originFile); + } + // Stream context created to allow files overwrite when using FTP stream wrapper - disabled by default + if (!($target = self::box('fopen', $targetFile, 'w', \false, \stream_context_create(['ftp' => ['overwrite' => \true]])))) { + throw new IOException(\sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing: ', $originFile, $targetFile) . self::$lastError, 0, null, $originFile); + } + $bytesCopied = \stream_copy_to_stream($source, $target); + \fclose($source); + \fclose($target); + unset($source, $target); + if (!\is_file($targetFile)) { + throw new IOException(\sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile); + } + if ($originIsLocal) { + // Like `cp`, preserve executable permission bits + self::box('chmod', $targetFile, \fileperms($targetFile) | \fileperms($originFile) & 0111); + if ($bytesCopied !== ($bytesOrigin = \filesize($originFile))) { + 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); + } + } + } + } + /** + * Creates a directory recursively. + * + * @return void + * + * @throws IOException On any directory creation failure + * @param string|iterable $dirs + */ + public function mkdir($dirs, int $mode = 0777) + { + foreach ($this->toIterable($dirs) as $dir) { + if (\is_dir($dir)) { + continue; + } + if (!self::box('mkdir', $dir, $mode, \true) && !\is_dir($dir)) { + throw new IOException(\sprintf('Failed to create "%s": ', $dir) . self::$lastError, 0, null, $dir); + } + } + } + /** + * Checks the existence of files or directories. + * @param string|iterable $files + */ + public function exists($files) : bool + { + $maxPathLength = \PHP_MAXPATHLEN - 2; + foreach ($this->toIterable($files) as $file) { + if (\strlen($file) > $maxPathLength) { + throw new IOException(\sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file); + } + if (!\file_exists($file)) { + return \false; + } + } + return \true; + } + /** + * Sets access and modification time of file. + * + * @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used + * @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used + * + * @return void + * + * @throws IOException When touch fails + * @param string|iterable $files + */ + public function touch($files, int $time = null, int $atime = null) + { + foreach ($this->toIterable($files) as $file) { + if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) { + throw new IOException(\sprintf('Failed to touch "%s": ', $file) . self::$lastError, 0, null, $file); + } + } + } + /** + * Removes files or directories. + * + * @return void + * + * @throws IOException When removal fails + * @param string|iterable $files + */ + public function remove($files) + { + if ($files instanceof \Traversable) { + $files = \iterator_to_array($files, \false); + } elseif (!\is_array($files)) { + $files = [$files]; + } + self::doRemove($files, \false); + } + private static function doRemove(array $files, bool $isRecursive) : void + { + $files = \array_reverse($files); + foreach ($files as $file) { + if (\is_link($file)) { + // See https://bugs.php.net/52176 + if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && \file_exists($file)) { + throw new IOException(\sprintf('Failed to remove symlink "%s": ', $file) . self::$lastError); + } + } elseif (\is_dir($file)) { + if (!$isRecursive) { + $tmpName = \dirname(\realpath($file)) . '/.' . \strrev(\strtr(\base64_encode(\random_bytes(2)), '/=', '-_')); + if (\file_exists($tmpName)) { + try { + self::doRemove([$tmpName], \true); + } catch (IOException $exception) { + } + } + if (!\file_exists($tmpName) && self::box('rename', $file, $tmpName)) { + $origFile = $file; + $file = $tmpName; + } else { + $origFile = null; + } + } + $filesystemIterator = new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS); + self::doRemove(\iterator_to_array($filesystemIterator, \true), \true); + if (!self::box('rmdir', $file) && \file_exists($file) && !$isRecursive) { + $lastError = self::$lastError; + if (null !== $origFile && self::box('rename', $file, $origFile)) { + $file = $origFile; + } + throw new IOException(\sprintf('Failed to remove directory "%s": ', $file) . $lastError); + } + } elseif (!self::box('unlink', $file) && (\strpos(self::$lastError, 'Permission denied') !== \false || \file_exists($file))) { + throw new IOException(\sprintf('Failed to remove file "%s": ', $file) . self::$lastError); + } + } + } + /** + * Change mode for an array of files or directories. + * + * @param int $mode The new mode (octal) + * @param int $umask The mode mask (octal) + * @param bool $recursive Whether change the mod recursively or not + * + * @return void + * + * @throws IOException When the change fails + * @param string|iterable $files + */ + public function chmod($files, int $mode, int $umask = 00, bool $recursive = \false) + { + foreach ($this->toIterable($files) as $file) { + if (!self::box('chmod', $file, $mode & ~$umask)) { + throw new IOException(\sprintf('Failed to chmod file "%s": ', $file) . self::$lastError, 0, null, $file); + } + if ($recursive && \is_dir($file) && !\is_link($file)) { + $this->chmod(new \FilesystemIterator($file), $mode, $umask, \true); + } + } + } + /** + * Change the owner of an array of files or directories. + * + * @param string|int $user A user name or number + * @param bool $recursive Whether change the owner recursively or not + * + * @return void + * + * @throws IOException When the change fails + * @param string|iterable $files + */ + public function chown($files, $user, bool $recursive = \false) + { + foreach ($this->toIterable($files) as $file) { + if ($recursive && \is_dir($file) && !\is_link($file)) { + $this->chown(new \FilesystemIterator($file), $user, \true); + } + if (\is_link($file) && \function_exists('lchown')) { + if (!self::box('lchown', $file, $user)) { + throw new IOException(\sprintf('Failed to chown file "%s": ', $file) . self::$lastError, 0, null, $file); + } + } else { + if (!self::box('chown', $file, $user)) { + throw new IOException(\sprintf('Failed to chown file "%s": ', $file) . self::$lastError, 0, null, $file); + } + } + } + } + /** + * Change the group of an array of files or directories. + * + * @param string|int $group A group name or number + * @param bool $recursive Whether change the group recursively or not + * + * @return void + * + * @throws IOException When the change fails + * @param string|iterable $files + */ + public function chgrp($files, $group, bool $recursive = \false) + { + foreach ($this->toIterable($files) as $file) { + if ($recursive && \is_dir($file) && !\is_link($file)) { + $this->chgrp(new \FilesystemIterator($file), $group, \true); + } + if (\is_link($file) && \function_exists('lchgrp')) { + if (!self::box('lchgrp', $file, $group)) { + throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file) . self::$lastError, 0, null, $file); + } + } else { + if (!self::box('chgrp', $file, $group)) { + throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file) . self::$lastError, 0, null, $file); + } + } + } + } + /** + * Renames a file or a directory. + * + * @return void + * + * @throws IOException When target file or directory already exists + * @throws IOException When origin cannot be renamed + */ + public function rename(string $origin, string $target, bool $overwrite = \false) + { + // we check that target does not exist + if (!$overwrite && $this->isReadable($target)) { + throw new IOException(\sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target); + } + if (!self::box('rename', $origin, $target)) { + if (\is_dir($origin)) { + // See https://bugs.php.net/54097 & https://php.net/rename#113943 + $this->mirror($origin, $target, null, ['override' => $overwrite, 'delete' => $overwrite]); + $this->remove($origin); + return; + } + throw new IOException(\sprintf('Cannot rename "%s" to "%s": ', $origin, $target) . self::$lastError, 0, null, $target); + } + } + /** + * Tells whether a file exists and is readable. + * + * @throws IOException When windows path is longer than 258 characters + */ + private function isReadable(string $filename) : bool + { + $maxPathLength = \PHP_MAXPATHLEN - 2; + if (\strlen($filename) > $maxPathLength) { + throw new IOException(\sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename); + } + return \is_readable($filename); + } + /** + * Creates a symbolic link or copy a directory. + * + * @return void + * + * @throws IOException When symlink fails + */ + public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = \false) + { + self::assertFunctionExists('symlink'); + if ('\\' === \DIRECTORY_SEPARATOR) { + $originDir = \strtr($originDir, '/', '\\'); + $targetDir = \strtr($targetDir, '/', '\\'); + if ($copyOnWindows) { + $this->mirror($originDir, $targetDir); + return; + } + } + $this->mkdir(\dirname($targetDir)); + if (\is_link($targetDir)) { + if (\readlink($targetDir) === $originDir) { + return; + } + $this->remove($targetDir); + } + if (!self::box('symlink', $originDir, $targetDir)) { + $this->linkException($originDir, $targetDir, 'symbolic'); + } + } + /** + * Creates a hard link, or several hard links to a file. + * + * @param string|string[] $targetFiles The target file(s) + * + * @return void + * + * @throws FileNotFoundException When original file is missing or not a file + * @throws IOException When link fails, including if link already exists + */ + public function hardlink(string $originFile, $targetFiles) + { + self::assertFunctionExists('link'); + if (!$this->exists($originFile)) { + throw new FileNotFoundException(null, 0, null, $originFile); + } + if (!\is_file($originFile)) { + throw new FileNotFoundException(\sprintf('Origin file "%s" is not a file.', $originFile)); + } + foreach ($this->toIterable($targetFiles) as $targetFile) { + if (\is_file($targetFile)) { + if (\fileinode($originFile) === \fileinode($targetFile)) { + continue; + } + $this->remove($targetFile); + } + if (!self::box('link', $originFile, $targetFile)) { + $this->linkException($originFile, $targetFile, 'hard'); + } + } + } + /** + * @param string $linkType Name of the link type, typically 'symbolic' or 'hard' + * @return never + */ + private function linkException(string $origin, string $target, string $linkType) + { + if (self::$lastError) { + if ('\\' === \DIRECTORY_SEPARATOR && \strpos(self::$lastError, 'error code(1314)') !== \false) { + throw new IOException(\sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target); + } + } + throw new IOException(\sprintf('Failed to create "%s" link from "%s" to "%s": ', $linkType, $origin, $target) . self::$lastError, 0, null, $target); + } + /** + * Resolves links in paths. + * + * With $canonicalize = false (default) + * - if $path does not exist or is not a link, returns null + * - if $path is a link, returns the next direct target of the link without considering the existence of the target + * + * With $canonicalize = true + * - if $path does not exist, returns null + * - if $path exists, returns its absolute fully resolved final version + */ + public function readlink(string $path, bool $canonicalize = \false) : ?string + { + if (!$canonicalize && !\is_link($path)) { + return null; + } + if ($canonicalize) { + if (!$this->exists($path)) { + return null; + } + return \realpath($path); + } + return \readlink($path); + } + /** + * Given an existing path, convert it to a path relative to a given starting path. + */ + public function makePathRelative(string $endPath, string $startPath) : string + { + if (!$this->isAbsolutePath($startPath)) { + throw new InvalidArgumentException(\sprintf('The start path "%s" is not absolute.', $startPath)); + } + if (!$this->isAbsolutePath($endPath)) { + throw new InvalidArgumentException(\sprintf('The end path "%s" is not absolute.', $endPath)); + } + // Normalize separators on Windows + if ('\\' === \DIRECTORY_SEPARATOR) { + $endPath = \str_replace('\\', '/', $endPath); + $startPath = \str_replace('\\', '/', $startPath); + } + $splitDriveLetter = function ($path) { + return \strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && \ctype_alpha($path[0]) ? [\substr($path, 2), \strtoupper($path[0])] : [$path, null]; + }; + $splitPath = function ($path) { + $result = []; + foreach (\explode('/', \trim($path, '/')) as $segment) { + if ('..' === $segment) { + \array_pop($result); + } elseif ('.' !== $segment && '' !== $segment) { + $result[] = $segment; + } + } + return $result; + }; + [$endPath, $endDriveLetter] = $splitDriveLetter($endPath); + [$startPath, $startDriveLetter] = $splitDriveLetter($startPath); + $startPathArr = $splitPath($startPath); + $endPathArr = $splitPath($endPath); + if ($endDriveLetter && $startDriveLetter && $endDriveLetter != $startDriveLetter) { + // End path is on another drive, so no relative path exists + return $endDriveLetter . ':/' . ($endPathArr ? \implode('/', $endPathArr) . '/' : ''); + } + // Find for which directory the common path stops + $index = 0; + while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) { + ++$index; + } + // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels) + if (1 === \count($startPathArr) && '' === $startPathArr[0]) { + $depth = 0; + } else { + $depth = \count($startPathArr) - $index; + } + // Repeated "../" for each level need to reach the common path + $traverser = \str_repeat('../', $depth); + $endPathRemainder = \implode('/', \array_slice($endPathArr, $index)); + // Construct $endPath from traversing to the common path, then to the remaining $endPath + $relativePath = $traverser . ('' !== $endPathRemainder ? $endPathRemainder . '/' : ''); + return '' === $relativePath ? './' : $relativePath; + } + /** + * Mirrors a directory to another. + * + * Copies files and directories from the origin directory into the target directory. By default: + * + * - existing files in the target directory will be overwritten, except if they are newer (see the `override` option) + * - files in the target directory that do not exist in the source directory will not be deleted (see the `delete` option) + * + * @param \Traversable|null $iterator Iterator that filters which files and directories to copy, if null a recursive iterator is created + * @param array $options An array of boolean options + * Valid options are: + * - $options['override'] If true, target files newer than origin files are overwritten (see copy(), defaults to false) + * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false) + * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) + * + * @return void + * + * @throws IOException When file type is unknown + */ + public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = []) + { + $targetDir = \rtrim($targetDir, '/\\'); + $originDir = \rtrim($originDir, '/\\'); + $originDirLen = \strlen($originDir); + if (!$this->exists($originDir)) { + throw new IOException(\sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir); + } + // Iterate in destination folder to remove obsolete entries + if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) { + $deleteIterator = $iterator; + if (null === $deleteIterator) { + $flags = \FilesystemIterator::SKIP_DOTS; + $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST); + } + $targetDirLen = \strlen($targetDir); + foreach ($deleteIterator as $file) { + $origin = $originDir . \substr($file->getPathname(), $targetDirLen); + if (!$this->exists($origin)) { + $this->remove($file); + } + } + } + $copyOnWindows = $options['copy_on_windows'] ?? \false; + if (null === $iterator) { + $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS; + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST); + } + $this->mkdir($targetDir); + $filesCreatedWhileMirroring = []; + foreach ($iterator as $file) { + if ($file->getPathname() === $targetDir || $file->getRealPath() === $targetDir || isset($filesCreatedWhileMirroring[$file->getRealPath()])) { + continue; + } + $target = $targetDir . \substr($file->getPathname(), $originDirLen); + $filesCreatedWhileMirroring[$target] = \true; + if (!$copyOnWindows && \is_link($file)) { + $this->symlink($file->getLinkTarget(), $target); + } elseif (\is_dir($file)) { + $this->mkdir($target); + } elseif (\is_file($file)) { + $this->copy($file, $target, $options['override'] ?? \false); + } else { + throw new IOException(\sprintf('Unable to guess "%s" file type.', $file), 0, null, $file); + } + } + } + /** + * Returns whether the file path is an absolute path. + */ + public function isAbsolutePath(string $file) : bool + { + return '' !== $file && (\strspn($file, '/\\', 0, 1) || \strlen($file) > 3 && \ctype_alpha($file[0]) && ':' === $file[1] && \strspn($file, '/\\', 2, 1) || null !== \parse_url($file, \PHP_URL_SCHEME)); + } + /** + * Creates a temporary file with support for custom stream wrappers. + * + * @param string $prefix The prefix of the generated temporary filename + * Note: Windows uses only the first three characters of prefix + * @param string $suffix The suffix of the generated temporary filename + * + * @return string The new temporary filename (with path), or throw an exception on failure + */ + public function tempnam(string $dir, string $prefix, string $suffix = '') : string + { + [$scheme, $hierarchy] = $this->getSchemeAndHierarchy($dir); + // If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem + if ((null === $scheme || 'file' === $scheme || 'gs' === $scheme) && '' === $suffix) { + // If tempnam failed or no scheme return the filename otherwise prepend the scheme + if ($tmpFile = self::box('tempnam', $hierarchy, $prefix)) { + if (null !== $scheme && 'gs' !== $scheme) { + return $scheme . '://' . $tmpFile; + } + return $tmpFile; + } + throw new IOException('A temporary file could not be created: ' . self::$lastError); + } + // Loop until we create a valid temp file or have reached 10 attempts + for ($i = 0; $i < 10; ++$i) { + // Create a unique filename + $tmpFile = $dir . '/' . $prefix . \uniqid(\mt_rand(), \true) . $suffix; + // Use fopen instead of file_exists as some streams do not support stat + // Use mode 'x+' to atomically check existence and create to avoid a TOCTOU vulnerability + if (!($handle = self::box('fopen', $tmpFile, 'x+'))) { + continue; + } + // Close the file if it was successfully opened + self::box('fclose', $handle); + return $tmpFile; + } + throw new IOException('A temporary file could not be created: ' . self::$lastError); + } + /** + * Atomically dumps content into a file. + * + * @param string|resource $content The data to write into the file + * + * @return void + * + * @throws IOException if the file cannot be written to + */ + public function dumpFile(string $filename, $content) + { + if (\is_array($content)) { + throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); + } + $dir = \dirname($filename); + if (\is_link($filename) && ($linkTarget = $this->readlink($filename))) { + $this->dumpFile(Path::makeAbsolute($linkTarget, $dir), $content); + return; + } + if (!\is_dir($dir)) { + $this->mkdir($dir); + } + // Will create a temp file with 0600 access rights + // when the filesystem supports chmod. + $tmpFile = $this->tempnam($dir, \basename($filename)); + try { + if (\false === self::box('file_put_contents', $tmpFile, $content)) { + throw new IOException(\sprintf('Failed to write file "%s": ', $filename) . self::$lastError, 0, null, $filename); + } + self::box('chmod', $tmpFile, \file_exists($filename) ? \fileperms($filename) : 0666 & ~\umask()); + $this->rename($tmpFile, $filename, \true); + } finally { + if (\file_exists($tmpFile)) { + self::box('unlink', $tmpFile); + } + } + } + /** + * Appends content to an existing file. + * + * @param string|resource $content The content to append + * @param bool $lock Whether the file should be locked when writing to it + * + * @return void + * + * @throws IOException If the file is not writable + */ + public function appendToFile(string $filename, $content) + { + if (\is_array($content)) { + throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); + } + $dir = \dirname($filename); + if (!\is_dir($dir)) { + $this->mkdir($dir); + } + $lock = \func_num_args() > 2 && \func_get_arg(2); + if (\false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) { + throw new IOException(\sprintf('Failed to write file "%s": ', $filename) . self::$lastError, 0, null, $filename); + } + } + /** + * @param string|iterable $files + */ + private function toIterable($files) : iterable + { + return \is_iterable($files) ? $files : [$files]; + } + /** + * Gets a 2-tuple of scheme (may be null) and hierarchical part of a filename (e.g. file:///tmp -> [file, tmp]). + */ + private function getSchemeAndHierarchy(string $filename) : array + { + $components = \explode('://', $filename, 2); + return 2 === \count($components) ? [$components[0], $components[1]] : [null, $components[0]]; + } + private static function assertFunctionExists(string $func) : void + { + if (!\function_exists($func)) { + throw new IOException(\sprintf('Unable to perform filesystem operation because the "%s()" function has been disabled.', $func)); + } + } + /** + * @param mixed ...$args + * @return mixed + */ + private static function box(string $func, ...$args) + { + self::assertFunctionExists($func); + self::$lastError = null; + \set_error_handler(__CLASS__ . '::handleError'); + try { + return $func(...$args); + } finally { + \restore_error_handler(); + } + } + /** + * @internal + */ + public static function handleError(int $type, string $msg) : void + { + self::$lastError = $msg; + } +} diff --git a/vendor/symfony/filesystem/LICENSE b/vendor/symfony/filesystem/LICENSE new file mode 100644 index 0000000000..0138f8f071 --- /dev/null +++ b/vendor/symfony/filesystem/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/filesystem/Path.php b/vendor/symfony/filesystem/Path.php new file mode 100644 index 0000000000..22a0c57888 --- /dev/null +++ b/vendor/symfony/filesystem/Path.php @@ -0,0 +1,708 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Filesystem; + +use MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Filesystem\Exception\RuntimeException; +/** + * Contains utility methods for handling path strings. + * + * The methods in this class are able to deal with both UNIX and Windows paths + * with both forward and backward slashes. All methods return normalized parts + * containing only forward slashes and no excess "." and ".." segments. + * + * @author Bernhard Schussek + * @author Thomas Schulz + * @author Théo Fidry + */ +final class Path +{ + /** + * The number of buffer entries that triggers a cleanup operation. + */ + private const CLEANUP_THRESHOLD = 1250; + /** + * The buffer size after the cleanup operation. + */ + private const CLEANUP_SIZE = 1000; + /** + * Buffers input/output of {@link canonicalize()}. + * + * @var array + */ + private static $buffer = []; + /** + * @var int + */ + private static $bufferSize = 0; + /** + * Canonicalizes the given path. + * + * During normalization, all slashes are replaced by forward slashes ("/"). + * Furthermore, all "." and ".." segments are removed as far as possible. + * ".." segments at the beginning of relative paths are not removed. + * + * ```php + * echo Path::canonicalize("\symfony\puli\..\css\style.css"); + * // => /symfony/css/style.css + * + * echo Path::canonicalize("../css/./style.css"); + * // => ../css/style.css + * ``` + * + * This method is able to deal with both UNIX and Windows paths. + */ + public static function canonicalize(string $path) : string + { + if ('' === $path) { + return ''; + } + // This method is called by many other methods in this class. Buffer + // the canonicalized paths to make up for the severe performance + // decrease. + if (isset(self::$buffer[$path])) { + return self::$buffer[$path]; + } + // Replace "~" with user's home directory. + if ('~' === $path[0]) { + $path = self::getHomeDirectory() . \substr($path, 1); + } + $path = self::normalize($path); + [$root, $pathWithoutRoot] = self::split($path); + $canonicalParts = self::findCanonicalParts($root, $pathWithoutRoot); + // Add the root directory again + self::$buffer[$path] = $canonicalPath = $root . \implode('/', $canonicalParts); + ++self::$bufferSize; + // Clean up regularly to prevent memory leaks + if (self::$bufferSize > self::CLEANUP_THRESHOLD) { + self::$buffer = \array_slice(self::$buffer, -self::CLEANUP_SIZE, null, \true); + self::$bufferSize = self::CLEANUP_SIZE; + } + return $canonicalPath; + } + /** + * Normalizes the given path. + * + * During normalization, all slashes are replaced by forward slashes ("/"). + * Contrary to {@link canonicalize()}, this method does not remove invalid + * or dot path segments. Consequently, it is much more efficient and should + * be used whenever the given path is known to be a valid, absolute system + * path. + * + * This method is able to deal with both UNIX and Windows paths. + */ + public static function normalize(string $path) : string + { + return \str_replace('\\', '/', $path); + } + /** + * Returns the directory part of the path. + * + * This method is similar to PHP's dirname(), but handles various cases + * where dirname() returns a weird result: + * + * - dirname() does not accept backslashes on UNIX + * - dirname("C:/symfony") returns "C:", not "C:/" + * - dirname("C:/") returns ".", not "C:/" + * - dirname("C:") returns ".", not "C:/" + * - dirname("symfony") returns ".", not "" + * - dirname() does not canonicalize the result + * + * This method fixes these shortcomings and behaves like dirname() + * otherwise. + * + * The result is a canonical path. + * + * @return string The canonical directory part. Returns the root directory + * if the root directory is passed. Returns an empty string + * if a relative path is passed that contains no slashes. + * Returns an empty string if an empty string is passed. + */ + public static function getDirectory(string $path) : string + { + if ('' === $path) { + return ''; + } + $path = self::canonicalize($path); + // Maintain scheme + if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) { + $scheme = \substr($path, 0, $schemeSeparatorPosition + 3); + $path = \substr($path, $schemeSeparatorPosition + 3); + } else { + $scheme = ''; + } + if (\false === ($dirSeparatorPosition = \strrpos($path, '/'))) { + return ''; + } + // Directory equals root directory "/" + if (0 === $dirSeparatorPosition) { + return $scheme . '/'; + } + // Directory equals Windows root "C:/" + if (2 === $dirSeparatorPosition && \ctype_alpha($path[0]) && ':' === $path[1]) { + return $scheme . \substr($path, 0, 3); + } + return $scheme . \substr($path, 0, $dirSeparatorPosition); + } + /** + * Returns canonical path of the user's home directory. + * + * Supported operating systems: + * + * - UNIX + * - Windows8 and upper + * + * If your operating system or environment isn't supported, an exception is thrown. + * + * The result is a canonical path. + * + * @throws RuntimeException If your operating system or environment isn't supported + */ + public static function getHomeDirectory() : string + { + // For UNIX support + if (\getenv('HOME')) { + return self::canonicalize(\getenv('HOME')); + } + // For >= Windows8 support + if (\getenv('HOMEDRIVE') && \getenv('HOMEPATH')) { + return self::canonicalize(\getenv('HOMEDRIVE') . \getenv('HOMEPATH')); + } + throw new RuntimeException("Cannot find the home directory path: Your environment or operating system isn't supported."); + } + /** + * Returns the root directory of a path. + * + * The result is a canonical path. + * + * @return string The canonical root directory. Returns an empty string if + * the given path is relative or empty. + */ + public static function getRoot(string $path) : string + { + if ('' === $path) { + return ''; + } + // Maintain scheme + if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) { + $scheme = \substr($path, 0, $schemeSeparatorPosition + 3); + $path = \substr($path, $schemeSeparatorPosition + 3); + } else { + $scheme = ''; + } + $firstCharacter = $path[0]; + // UNIX root "/" or "\" (Windows style) + if ('/' === $firstCharacter || '\\' === $firstCharacter) { + return $scheme . '/'; + } + $length = \strlen($path); + // Windows root + if ($length > 1 && ':' === $path[1] && \ctype_alpha($firstCharacter)) { + // Special case: "C:" + if (2 === $length) { + return $scheme . $path . '/'; + } + // Normal case: "C:/ or "C:\" + if ('/' === $path[2] || '\\' === $path[2]) { + return $scheme . $firstCharacter . $path[1] . '/'; + } + } + return ''; + } + /** + * Returns the file name without the extension from a file path. + * + * @param string|null $extension if specified, only that extension is cut + * off (may contain leading dot) + */ + public static function getFilenameWithoutExtension(string $path, string $extension = null) : string + { + if ('' === $path) { + return ''; + } + if (null !== $extension) { + // remove extension and trailing dot + return \rtrim(\basename($path, $extension), '.'); + } + return \pathinfo($path, \PATHINFO_FILENAME); + } + /** + * Returns the extension from a file path (without leading dot). + * + * @param bool $forceLowerCase forces the extension to be lower-case + */ + public static function getExtension(string $path, bool $forceLowerCase = \false) : string + { + if ('' === $path) { + return ''; + } + $extension = \pathinfo($path, \PATHINFO_EXTENSION); + if ($forceLowerCase) { + $extension = self::toLower($extension); + } + return $extension; + } + /** + * Returns whether the path has an (or the specified) extension. + * + * @param string $path the path string + * @param string|string[]|null $extensions if null or not provided, checks if + * an extension exists, otherwise + * checks for the specified extension + * or array of extensions (with or + * without leading dot) + * @param bool $ignoreCase whether to ignore case-sensitivity + */ + public static function hasExtension(string $path, $extensions = null, bool $ignoreCase = \false) : bool + { + if ('' === $path) { + return \false; + } + $actualExtension = self::getExtension($path, $ignoreCase); + // Only check if path has any extension + if ([] === $extensions || null === $extensions) { + return '' !== $actualExtension; + } + if (\is_string($extensions)) { + $extensions = [$extensions]; + } + foreach ($extensions as $key => $extension) { + if ($ignoreCase) { + $extension = self::toLower($extension); + } + // remove leading '.' in extensions array + $extensions[$key] = \ltrim($extension, '.'); + } + return \in_array($actualExtension, $extensions, \true); + } + /** + * Changes the extension of a path string. + * + * @param string $path The path string with filename.ext to change. + * @param string $extension new extension (with or without leading dot) + * + * @return string the path string with new file extension + */ + public static function changeExtension(string $path, string $extension) : string + { + if ('' === $path) { + return ''; + } + $actualExtension = self::getExtension($path); + $extension = \ltrim($extension, '.'); + // No extension for paths + if ('/' === \substr($path, -1)) { + return $path; + } + // No actual extension in path + if (empty($actualExtension)) { + return $path . ('.' === \substr($path, -1) ? '' : '.') . $extension; + } + return \substr($path, 0, -\strlen($actualExtension)) . $extension; + } + public static function isAbsolute(string $path) : bool + { + if ('' === $path) { + return \false; + } + // Strip scheme + if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) { + $path = \substr($path, $schemeSeparatorPosition + 3); + } + $firstCharacter = $path[0]; + // UNIX root "/" or "\" (Windows style) + if ('/' === $firstCharacter || '\\' === $firstCharacter) { + return \true; + } + // Windows root + if (\strlen($path) > 1 && \ctype_alpha($firstCharacter) && ':' === $path[1]) { + // Special case: "C:" + if (2 === \strlen($path)) { + return \true; + } + // Normal case: "C:/ or "C:\" + if ('/' === $path[2] || '\\' === $path[2]) { + return \true; + } + } + return \false; + } + public static function isRelative(string $path) : bool + { + return !self::isAbsolute($path); + } + /** + * Turns a relative path into an absolute path in canonical form. + * + * Usually, the relative path is appended to the given base path. Dot + * segments ("." and "..") are removed/collapsed and all slashes turned + * into forward slashes. + * + * ```php + * echo Path::makeAbsolute("../style.css", "/symfony/puli/css"); + * // => /symfony/puli/style.css + * ``` + * + * If an absolute path is passed, that path is returned unless its root + * directory is different than the one of the base path. In that case, an + * exception is thrown. + * + * ```php + * Path::makeAbsolute("/style.css", "/symfony/puli/css"); + * // => /style.css + * + * Path::makeAbsolute("C:/style.css", "C:/symfony/puli/css"); + * // => C:/style.css + * + * Path::makeAbsolute("C:/style.css", "/symfony/puli/css"); + * // InvalidArgumentException + * ``` + * + * If the base path is not an absolute path, an exception is thrown. + * + * The result is a canonical path. + * + * @param string $basePath an absolute base path + * + * @throws InvalidArgumentException if the base path is not absolute or if + * the given path is an absolute path with + * a different root than the base path + */ + public static function makeAbsolute(string $path, string $basePath) : string + { + if ('' === $basePath) { + throw new InvalidArgumentException(\sprintf('The base path must be a non-empty string. Got: "%s".', $basePath)); + } + if (!self::isAbsolute($basePath)) { + throw new InvalidArgumentException(\sprintf('The base path "%s" is not an absolute path.', $basePath)); + } + if (self::isAbsolute($path)) { + return self::canonicalize($path); + } + if (\false !== ($schemeSeparatorPosition = \strpos($basePath, '://'))) { + $scheme = \substr($basePath, 0, $schemeSeparatorPosition + 3); + $basePath = \substr($basePath, $schemeSeparatorPosition + 3); + } else { + $scheme = ''; + } + return $scheme . self::canonicalize(\rtrim($basePath, '/\\') . '/' . $path); + } + /** + * Turns a path into a relative path. + * + * The relative path is created relative to the given base path: + * + * ```php + * echo Path::makeRelative("/symfony/style.css", "/symfony/puli"); + * // => ../style.css + * ``` + * + * If a relative path is passed and the base path is absolute, the relative + * path is returned unchanged: + * + * ```php + * Path::makeRelative("style.css", "/symfony/puli/css"); + * // => style.css + * ``` + * + * If both paths are relative, the relative path is created with the + * assumption that both paths are relative to the same directory: + * + * ```php + * Path::makeRelative("style.css", "symfony/puli/css"); + * // => ../../../style.css + * ``` + * + * If both paths are absolute, their root directory must be the same, + * otherwise an exception is thrown: + * + * ```php + * Path::makeRelative("C:/symfony/style.css", "/symfony/puli"); + * // InvalidArgumentException + * ``` + * + * If the passed path is absolute, but the base path is not, an exception + * is thrown as well: + * + * ```php + * Path::makeRelative("/symfony/style.css", "symfony/puli"); + * // InvalidArgumentException + * ``` + * + * If the base path is not an absolute path, an exception is thrown. + * + * The result is a canonical path. + * + * @throws InvalidArgumentException if the base path is not absolute or if + * the given path has a different root + * than the base path + */ + public static function makeRelative(string $path, string $basePath) : string + { + $path = self::canonicalize($path); + $basePath = self::canonicalize($basePath); + [$root, $relativePath] = self::split($path); + [$baseRoot, $relativeBasePath] = self::split($basePath); + // If the base path is given as absolute path and the path is already + // relative, consider it to be relative to the given absolute path + // already + if ('' === $root && '' !== $baseRoot) { + // If base path is already in its root + if ('' === $relativeBasePath) { + $relativePath = \ltrim($relativePath, './\\'); + } + return $relativePath; + } + // If the passed path is absolute, but the base path is not, we + // cannot generate a relative path + if ('' !== $root && '' === $baseRoot) { + throw new InvalidArgumentException(\sprintf('The absolute path "%s" cannot be made relative to the relative path "%s". You should provide an absolute base path instead.', $path, $basePath)); + } + // Fail if the roots of the two paths are different + if ($baseRoot && $root !== $baseRoot) { + throw new InvalidArgumentException(\sprintf('The path "%s" cannot be made relative to "%s", because they have different roots ("%s" and "%s").', $path, $basePath, $root, $baseRoot)); + } + if ('' === $relativeBasePath) { + return $relativePath; + } + // Build a "../../" prefix with as many "../" parts as necessary + $parts = \explode('/', $relativePath); + $baseParts = \explode('/', $relativeBasePath); + $dotDotPrefix = ''; + // Once we found a non-matching part in the prefix, we need to add + // "../" parts for all remaining parts + $match = \true; + foreach ($baseParts as $index => $basePart) { + if ($match && isset($parts[$index]) && $basePart === $parts[$index]) { + unset($parts[$index]); + continue; + } + $match = \false; + $dotDotPrefix .= '../'; + } + return \rtrim($dotDotPrefix . \implode('/', $parts), '/'); + } + /** + * Returns whether the given path is on the local filesystem. + */ + public static function isLocal(string $path) : bool + { + return '' !== $path && \strpos($path, '://') === \false; + } + /** + * Returns the longest common base path in canonical form of a set of paths or + * `null` if the paths are on different Windows partitions. + * + * Dot segments ("." and "..") are removed/collapsed and all slashes turned + * into forward slashes. + * + * ```php + * $basePath = Path::getLongestCommonBasePath( + * '/symfony/css/style.css', + * '/symfony/css/..' + * ); + * // => /symfony + * ``` + * + * The root is returned if no common base path can be found: + * + * ```php + * $basePath = Path::getLongestCommonBasePath( + * '/symfony/css/style.css', + * '/puli/css/..' + * ); + * // => / + * ``` + * + * If the paths are located on different Windows partitions, `null` is + * returned. + * + * ```php + * $basePath = Path::getLongestCommonBasePath( + * 'C:/symfony/css/style.css', + * 'D:/symfony/css/..' + * ); + * // => null + * ``` + */ + public static function getLongestCommonBasePath(string ...$paths) : ?string + { + [$bpRoot, $basePath] = self::split(self::canonicalize(\reset($paths))); + for (\next($paths); null !== \key($paths) && '' !== $basePath; \next($paths)) { + [$root, $path] = self::split(self::canonicalize(\current($paths))); + // If we deal with different roots (e.g. C:/ vs. D:/), it's time + // to quit + if ($root !== $bpRoot) { + return null; + } + // Make the base path shorter until it fits into path + while (\true) { + if ('.' === $basePath) { + // No more base paths + $basePath = ''; + // next path + continue 2; + } + // Prevent false positives for common prefixes + // see isBasePath() + if (\strncmp($path . '/', $basePath . '/', \strlen($basePath . '/')) === 0) { + // next path + continue 2; + } + $basePath = \dirname($basePath); + } + } + return $bpRoot . $basePath; + } + /** + * Joins two or more path strings into a canonical path. + */ + public static function join(string ...$paths) : string + { + $finalPath = null; + $wasScheme = \false; + foreach ($paths as $path) { + if ('' === $path) { + continue; + } + if (null === $finalPath) { + // For first part we keep slashes, like '/top', 'C:\' or 'phar://' + $finalPath = $path; + $wasScheme = \strpos($path, '://') !== \false; + continue; + } + // Only add slash if previous part didn't end with '/' or '\' + if (!\in_array(\substr($finalPath, -1), ['/', '\\'])) { + $finalPath .= '/'; + } + // If first part included a scheme like 'phar://' we allow \current part to start with '/', otherwise trim + $finalPath .= $wasScheme ? $path : \ltrim($path, '/'); + $wasScheme = \false; + } + if (null === $finalPath) { + return ''; + } + return self::canonicalize($finalPath); + } + /** + * Returns whether a path is a base path of another path. + * + * Dot segments ("." and "..") are removed/collapsed and all slashes turned + * into forward slashes. + * + * ```php + * Path::isBasePath('/symfony', '/symfony/css'); + * // => true + * + * Path::isBasePath('/symfony', '/symfony'); + * // => true + * + * Path::isBasePath('/symfony', '/symfony/..'); + * // => false + * + * Path::isBasePath('/symfony', '/puli'); + * // => false + * ``` + */ + public static function isBasePath(string $basePath, string $ofPath) : bool + { + $basePath = self::canonicalize($basePath); + $ofPath = self::canonicalize($ofPath); + // Append slashes to prevent false positives when two paths have + // a common prefix, for example /base/foo and /base/foobar. + // Don't append a slash for the root "/", because then that root + // won't be discovered as common prefix ("//" is not a prefix of + // "/foobar/"). + return \strncmp($ofPath . '/', \rtrim($basePath, '/') . '/', \strlen(\rtrim($basePath, '/') . '/')) === 0; + } + /** + * @return string[] + */ + private static function findCanonicalParts(string $root, string $pathWithoutRoot) : array + { + $parts = \explode('/', $pathWithoutRoot); + $canonicalParts = []; + // Collapse "." and "..", if possible + foreach ($parts as $part) { + if ('.' === $part || '' === $part) { + continue; + } + // Collapse ".." with the previous part, if one exists + // Don't collapse ".." if the previous part is also ".." + if ('..' === $part && \count($canonicalParts) > 0 && '..' !== $canonicalParts[\count($canonicalParts) - 1]) { + \array_pop($canonicalParts); + continue; + } + // Only add ".." prefixes for relative paths + if ('..' !== $part || '' === $root) { + $canonicalParts[] = $part; + } + } + return $canonicalParts; + } + /** + * Splits a canonical path into its root directory and the remainder. + * + * If the path has no root directory, an empty root directory will be + * returned. + * + * If the root directory is a Windows style partition, the resulting root + * will always contain a trailing slash. + * + * list ($root, $path) = Path::split("C:/symfony") + * // => ["C:/", "symfony"] + * + * list ($root, $path) = Path::split("C:") + * // => ["C:/", ""] + * + * @return array{string, string} an array with the root directory and the remaining relative path + */ + private static function split(string $path) : array + { + if ('' === $path) { + return ['', '']; + } + // Remember scheme as part of the root, if any + if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) { + $root = \substr($path, 0, $schemeSeparatorPosition + 3); + $path = \substr($path, $schemeSeparatorPosition + 3); + } else { + $root = ''; + } + $length = \strlen($path); + // Remove and remember root directory + if (\strncmp($path, '/', \strlen('/')) === 0) { + $root .= '/'; + $path = $length > 1 ? \substr($path, 1) : ''; + } elseif ($length > 1 && \ctype_alpha($path[0]) && ':' === $path[1]) { + if (2 === $length) { + // Windows special case: "C:" + $root .= $path . '/'; + $path = ''; + } elseif ('/' === $path[2]) { + // Windows normal case: "C:/".. + $root .= \substr($path, 0, 3); + $path = $length > 3 ? \substr($path, 3) : ''; + } + } + return [$root, $path]; + } + private static function toLower(string $string) : string + { + if (\false !== ($encoding = \mb_detect_encoding($string, null, \true))) { + return \mb_strtolower($string, $encoding); + } + return \strtolower($string); + } + private function __construct() + { + } +} diff --git a/vendor/symfony/filesystem/README.md b/vendor/symfony/filesystem/README.md new file mode 100644 index 0000000000..f2f6d45f73 --- /dev/null +++ b/vendor/symfony/filesystem/README.md @@ -0,0 +1,13 @@ +Filesystem Component +==================== + +The Filesystem component provides basic utilities for the filesystem. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/filesystem.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/filesystem/composer.json b/vendor/symfony/filesystem/composer.json new file mode 100644 index 0000000000..48513597c5 --- /dev/null +++ b/vendor/symfony/filesystem/composer.json @@ -0,0 +1,32 @@ +{ + "name": "symfony\/filesystem", + "type": "library", + "description": "Provides basic utilities for the filesystem", + "keywords": [], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1", + "symfony\/polyfill-ctype": "~1.8", + "symfony\/polyfill-mbstring": "~1.8" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/vendor/symfony/finder/CHANGELOG.md b/vendor/symfony/finder/CHANGELOG.md new file mode 100644 index 0000000000..1a12afe650 --- /dev/null +++ b/vendor/symfony/finder/CHANGELOG.md @@ -0,0 +1,98 @@ +CHANGELOG +========= + +6.2 +--- + + * Add `Finder::sortByExtension()` and `Finder::sortBySize()` + * Add `Finder::sortByCaseInsensitiveName()` to sort by name with case insensitive sorting methods + +6.0 +--- + + * Remove `Comparator::setTarget()` and `Comparator::setOperator()` + +5.4.0 +----- + + * Deprecate `Comparator::setTarget()` and `Comparator::setOperator()` + * Add a constructor to `Comparator` that allows setting target and operator + * Finder's iterator has now `Symfony\Component\Finder\SplFileInfo` inner type specified + * Add recursive .gitignore files support + +5.0.0 +----- + + * added `$useNaturalSort` argument to `Finder::sortByName()` + +4.3.0 +----- + + * added Finder::ignoreVCSIgnored() to ignore files based on rules listed in .gitignore + +4.2.0 +----- + + * added $useNaturalSort option to Finder::sortByName() method + * the `Finder::sortByName()` method will have a new `$useNaturalSort` + argument in version 5.0, not defining it is deprecated + * added `Finder::reverseSorting()` to reverse the sorting + +4.0.0 +----- + + * removed `ExceptionInterface` + * removed `Symfony\Component\Finder\Iterator\FilterIterator` + +3.4.0 +----- + + * deprecated `Symfony\Component\Finder\Iterator\FilterIterator` + * added Finder::hasResults() method to check if any results were found + +3.3.0 +----- + + * added double-star matching to Glob::toRegex() + +3.0.0 +----- + + * removed deprecated classes + +2.8.0 +----- + + * deprecated adapters and related classes + +2.5.0 +----- + * added support for GLOB_BRACE in the paths passed to Finder::in() + +2.3.0 +----- + + * added a way to ignore unreadable directories (via Finder::ignoreUnreadableDirs()) + * unified the way subfolders that are not executable are handled by always throwing an AccessDeniedException exception + +2.2.0 +----- + + * added Finder::path() and Finder::notPath() methods + * added finder adapters to improve performance on specific platforms + * added support for wildcard characters (glob patterns) in the paths passed + to Finder::in() + +2.1.0 +----- + + * added Finder::sortByAccessedTime(), Finder::sortByChangedTime(), and + Finder::sortByModifiedTime() + * added Countable to Finder + * added support for an array of directories as an argument to + Finder::exclude() + * added searching based on the file content via Finder::contains() and + Finder::notContains() + * added support for the != operator in the Comparator + * [BC BREAK] filter expressions (used for file name and content) are no more + considered as regexps but glob patterns when they are enclosed in '*' or '?' diff --git a/vendor/symfony/finder/Comparator/Comparator.php b/vendor/symfony/finder/Comparator/Comparator.php new file mode 100644 index 0000000000..2eb67378f8 --- /dev/null +++ b/vendor/symfony/finder/Comparator/Comparator.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Comparator; + +/** + * @author Fabien Potencier + */ +class Comparator +{ + /** + * @var string + */ + private $target; + /** + * @var string + */ + private $operator; + public function __construct(string $target, string $operator = '==') + { + if (!\in_array($operator, ['>', '<', '>=', '<=', '==', '!='])) { + throw new \InvalidArgumentException(\sprintf('Invalid operator "%s".', $operator)); + } + $this->target = $target; + $this->operator = $operator; + } + /** + * Gets the target value. + */ + public function getTarget() : string + { + return $this->target; + } + /** + * Gets the comparison operator. + */ + public function getOperator() : string + { + return $this->operator; + } + /** + * Tests against the target. + * @param mixed $test + */ + public function test($test) : bool + { + switch ($this->operator) { + case '>': + return $test > $this->target; + case '>=': + return $test >= $this->target; + case '<': + return $test < $this->target; + case '<=': + return $test <= $this->target; + case '!=': + return $test != $this->target; + default: + return $test == $this->target; + } + } +} diff --git a/vendor/symfony/finder/Comparator/DateComparator.php b/vendor/symfony/finder/Comparator/DateComparator.php new file mode 100644 index 0000000000..056fc20abb --- /dev/null +++ b/vendor/symfony/finder/Comparator/DateComparator.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Comparator; + +/** + * DateCompare compiles date comparisons. + * + * @author Fabien Potencier + */ +class DateComparator extends Comparator +{ + /** + * @param string $test A comparison string + * + * @throws \InvalidArgumentException If the test is not understood + */ + public function __construct(string $test) + { + if (!\preg_match('#^\\s*(==|!=|[<>]=?|after|since|before|until)?\\s*(.+?)\\s*$#i', $test, $matches)) { + throw new \InvalidArgumentException(\sprintf('Don\'t understand "%s" as a date test.', $test)); + } + try { + $date = new \DateTimeImmutable($matches[2]); + $target = $date->format('U'); + } catch (\Exception $exception) { + throw new \InvalidArgumentException(\sprintf('"%s" is not a valid date.', $matches[2])); + } + $operator = $matches[1] ?? '=='; + if ('since' === $operator || 'after' === $operator) { + $operator = '>'; + } + if ('until' === $operator || 'before' === $operator) { + $operator = '<'; + } + parent::__construct($target, $operator); + } +} diff --git a/vendor/symfony/finder/Comparator/NumberComparator.php b/vendor/symfony/finder/Comparator/NumberComparator.php new file mode 100644 index 0000000000..ee8152c7e1 --- /dev/null +++ b/vendor/symfony/finder/Comparator/NumberComparator.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Comparator; + +/** + * NumberComparator compiles a simple comparison to an anonymous + * subroutine, which you can call with a value to be tested again. + * + * Now this would be very pointless, if NumberCompare didn't understand + * magnitudes. + * + * The target value may use magnitudes of kilobytes (k, ki), + * megabytes (m, mi), or gigabytes (g, gi). Those suffixed + * with an i use the appropriate 2**n version in accordance with the + * IEC standard: http://physics.nist.gov/cuu/Units/binary.html + * + * Based on the Perl Number::Compare module. + * + * @author Fabien Potencier PHP port + * @author Richard Clamp Perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + * + * @see http://physics.nist.gov/cuu/Units/binary.html + */ +class NumberComparator extends Comparator +{ + /** + * @param string|null $test A comparison string or null + * + * @throws \InvalidArgumentException If the test is not understood + */ + public function __construct(?string $test) + { + if (null === $test || !\preg_match('#^\\s*(==|!=|[<>]=?)?\\s*([0-9\\.]+)\\s*([kmg]i?)?\\s*$#i', $test, $matches)) { + throw new \InvalidArgumentException(\sprintf('Don\'t understand "%s" as a number test.', $test ?? 'null')); + } + $target = $matches[2]; + if (!\is_numeric($target)) { + throw new \InvalidArgumentException(\sprintf('Invalid number "%s".', $target)); + } + if (isset($matches[3])) { + // magnitude + switch (\strtolower($matches[3])) { + case 'k': + $target *= 1000; + break; + case 'ki': + $target *= 1024; + break; + case 'm': + $target *= 1000000; + break; + case 'mi': + $target *= 1024 * 1024; + break; + case 'g': + $target *= 1000000000; + break; + case 'gi': + $target *= 1024 * 1024 * 1024; + break; + } + } + parent::__construct($target, $matches[1] ?: '=='); + } +} diff --git a/vendor/symfony/finder/Exception/AccessDeniedException.php b/vendor/symfony/finder/Exception/AccessDeniedException.php new file mode 100644 index 0000000000..8401fa2bf2 --- /dev/null +++ b/vendor/symfony/finder/Exception/AccessDeniedException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Exception; + +/** + * @author Jean-François Simon + */ +class AccessDeniedException extends \UnexpectedValueException +{ +} diff --git a/vendor/symfony/finder/Exception/DirectoryNotFoundException.php b/vendor/symfony/finder/Exception/DirectoryNotFoundException.php new file mode 100644 index 0000000000..5d5d287b09 --- /dev/null +++ b/vendor/symfony/finder/Exception/DirectoryNotFoundException.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Exception; + +/** + * @author Andreas Erhard + */ +class DirectoryNotFoundException extends \InvalidArgumentException +{ +} diff --git a/vendor/symfony/finder/Finder.php b/vendor/symfony/finder/Finder.php new file mode 100644 index 0000000000..7e05a3c853 --- /dev/null +++ b/vendor/symfony/finder/Finder.php @@ -0,0 +1,804 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Comparator\DateComparator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Comparator\NumberComparator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Exception\DirectoryNotFoundException; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\CustomFilterIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\DateRangeFilterIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\DepthRangeFilterIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\FilecontentFilterIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\FilenameFilterIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\LazyIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\SizeRangeFilterIterator; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator\SortableIterator; +/** + * Finder allows to build rules to find files and directories. + * + * It is a thin wrapper around several specialized iterator classes. + * + * All rules may be invoked several times. + * + * All methods return the current Finder object to allow chaining: + * + * $finder = Finder::create()->files()->name('*.php')->in(__DIR__); + * + * @author Fabien Potencier + * + * @implements \IteratorAggregate + */ +class Finder implements \IteratorAggregate, \Countable +{ + public const IGNORE_VCS_FILES = 1; + public const IGNORE_DOT_FILES = 2; + public const IGNORE_VCS_IGNORED_FILES = 4; + /** + * @var int + */ + private $mode = 0; + /** + * @var mixed[] + */ + private $names = []; + /** + * @var mixed[] + */ + private $notNames = []; + /** + * @var mixed[] + */ + private $exclude = []; + /** + * @var mixed[] + */ + private $filters = []; + /** + * @var mixed[] + */ + private $depths = []; + /** + * @var mixed[] + */ + private $sizes = []; + /** + * @var bool + */ + private $followLinks = \false; + /** + * @var bool + */ + private $reverseSorting = \false; + /** + * @var \Closure|int|false + */ + private $sort = \false; + /** + * @var int + */ + private $ignore = 0; + /** + * @var mixed[] + */ + private $dirs = []; + /** + * @var mixed[] + */ + private $dates = []; + /** + * @var mixed[] + */ + private $iterators = []; + /** + * @var mixed[] + */ + private $contains = []; + /** + * @var mixed[] + */ + private $notContains = []; + /** + * @var mixed[] + */ + private $paths = []; + /** + * @var mixed[] + */ + private $notPaths = []; + /** + * @var bool + */ + private $ignoreUnreadableDirs = \false; + /** + * @var mixed[] + */ + private static $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg']; + public function __construct() + { + $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES; + } + /** + * Creates a new Finder. + * @return static + */ + public static function create() + { + return new static(); + } + /** + * Restricts the matching to directories only. + * + * @return $this + */ + public function directories() + { + $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES; + return $this; + } + /** + * Restricts the matching to files only. + * + * @return $this + */ + public function files() + { + $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES; + return $this; + } + /** + * Adds tests for the directory depth. + * + * Usage: + * + * $finder->depth('> 1') // the Finder will start matching at level 1. + * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point. + * $finder->depth(['>= 1', '< 3']) + * + * @param string|int|string[]|int[] $levels The depth level expression or an array of depth levels + * + * @return $this + * + * @see DepthRangeFilterIterator + * @see NumberComparator + */ + public function depth($levels) + { + foreach ((array) $levels as $level) { + $this->depths[] = new Comparator\NumberComparator($level); + } + return $this; + } + /** + * Adds tests for file dates (last modified). + * + * The date must be something that strtotime() is able to parse: + * + * $finder->date('since yesterday'); + * $finder->date('until 2 days ago'); + * $finder->date('> now - 2 hours'); + * $finder->date('>= 2005-10-15'); + * $finder->date(['>= 2005-10-15', '<= 2006-05-27']); + * + * @param string|string[] $dates A date range string or an array of date ranges + * + * @return $this + * + * @see strtotime + * @see DateRangeFilterIterator + * @see DateComparator + */ + public function date($dates) + { + foreach ((array) $dates as $date) { + $this->dates[] = new Comparator\DateComparator($date); + } + return $this; + } + /** + * Adds rules that files must match. + * + * You can use patterns (delimited with / sign), globs or simple strings. + * + * $finder->name('/\.php$/') + * $finder->name('*.php') // same as above, without dot files + * $finder->name('test.php') + * $finder->name(['test.py', 'test.php']) + * + * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function name($patterns) + { + $this->names = \array_merge($this->names, (array) $patterns); + return $this; + } + /** + * Adds rules that files must not match. + * + * @param string|string[] $patterns A pattern (a regexp, a glob, or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function notName($patterns) + { + $this->notNames = \array_merge($this->notNames, (array) $patterns); + return $this; + } + /** + * Adds tests that file contents must match. + * + * Strings or PCRE patterns can be used: + * + * $finder->contains('Lorem ipsum') + * $finder->contains('/Lorem ipsum/i') + * $finder->contains(['dolor', '/ipsum/i']) + * + * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns + * + * @return $this + * + * @see FilecontentFilterIterator + */ + public function contains($patterns) + { + $this->contains = \array_merge($this->contains, (array) $patterns); + return $this; + } + /** + * Adds tests that file contents must not match. + * + * Strings or PCRE patterns can be used: + * + * $finder->notContains('Lorem ipsum') + * $finder->notContains('/Lorem ipsum/i') + * $finder->notContains(['lorem', '/dolor/i']) + * + * @param string|string[] $patterns A pattern (string or regexp) or an array of patterns + * + * @return $this + * + * @see FilecontentFilterIterator + */ + public function notContains($patterns) + { + $this->notContains = \array_merge($this->notContains, (array) $patterns); + return $this; + } + /** + * Adds rules that filenames must match. + * + * You can use patterns (delimited with / sign) or simple strings. + * + * $finder->path('some/special/dir') + * $finder->path('/some\/special\/dir/') // same as above + * $finder->path(['some dir', 'another/dir']) + * + * Use only / as dirname separator. + * + * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function path($patterns) + { + $this->paths = \array_merge($this->paths, (array) $patterns); + return $this; + } + /** + * Adds rules that filenames must not match. + * + * You can use patterns (delimited with / sign) or simple strings. + * + * $finder->notPath('some/special/dir') + * $finder->notPath('/some\/special\/dir/') // same as above + * $finder->notPath(['some/file.txt', 'another/file.log']) + * + * Use only / as dirname separator. + * + * @param string|string[] $patterns A pattern (a regexp or a string) or an array of patterns + * + * @return $this + * + * @see FilenameFilterIterator + */ + public function notPath($patterns) + { + $this->notPaths = \array_merge($this->notPaths, (array) $patterns); + return $this; + } + /** + * Adds tests for file sizes. + * + * $finder->size('> 10K'); + * $finder->size('<= 1Ki'); + * $finder->size(4); + * $finder->size(['> 10K', '< 20K']) + * + * @param string|int|string[]|int[] $sizes A size range string or an integer or an array of size ranges + * + * @return $this + * + * @see SizeRangeFilterIterator + * @see NumberComparator + */ + public function size($sizes) + { + foreach ((array) $sizes as $size) { + $this->sizes[] = new Comparator\NumberComparator($size); + } + return $this; + } + /** + * Excludes directories. + * + * Directories passed as argument must be relative to the ones defined with the `in()` method. For example: + * + * $finder->in(__DIR__)->exclude('ruby'); + * + * @param string|array $dirs A directory path or an array of directories + * + * @return $this + * + * @see ExcludeDirectoryFilterIterator + */ + public function exclude($dirs) + { + $this->exclude = \array_merge($this->exclude, (array) $dirs); + return $this; + } + /** + * Excludes "hidden" directories and files (starting with a dot). + * + * This option is enabled by default. + * + * @return $this + * + * @see ExcludeDirectoryFilterIterator + */ + public function ignoreDotFiles(bool $ignoreDotFiles) + { + if ($ignoreDotFiles) { + $this->ignore |= static::IGNORE_DOT_FILES; + } else { + $this->ignore &= ~static::IGNORE_DOT_FILES; + } + return $this; + } + /** + * Forces the finder to ignore version control directories. + * + * This option is enabled by default. + * + * @return $this + * + * @see ExcludeDirectoryFilterIterator + */ + public function ignoreVCS(bool $ignoreVCS) + { + if ($ignoreVCS) { + $this->ignore |= static::IGNORE_VCS_FILES; + } else { + $this->ignore &= ~static::IGNORE_VCS_FILES; + } + return $this; + } + /** + * Forces Finder to obey .gitignore and ignore files based on rules listed there. + * + * This option is disabled by default. + * + * @return $this + */ + public function ignoreVCSIgnored(bool $ignoreVCSIgnored) + { + if ($ignoreVCSIgnored) { + $this->ignore |= static::IGNORE_VCS_IGNORED_FILES; + } else { + $this->ignore &= ~static::IGNORE_VCS_IGNORED_FILES; + } + return $this; + } + /** + * Adds VCS patterns. + * + * @see ignoreVCS() + * + * @param string|string[] $pattern VCS patterns to ignore + * + * @return void + */ + public static function addVCSPattern($pattern) + { + foreach ((array) $pattern as $p) { + self::$vcsPatterns[] = $p; + } + self::$vcsPatterns = \array_unique(self::$vcsPatterns); + } + /** + * Sorts files and directories by an anonymous function. + * + * The anonymous function receives two \SplFileInfo instances to compare. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sort(\Closure $closure) + { + $this->sort = $closure; + return $this; + } + /** + * Sorts files and directories by extension. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByExtension() + { + $this->sort = Iterator\SortableIterator::SORT_BY_EXTENSION; + return $this; + } + /** + * Sorts files and directories by name. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByName(bool $useNaturalSort = \false) + { + $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME; + return $this; + } + /** + * Sorts files and directories by name case insensitive. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByCaseInsensitiveName(bool $useNaturalSort = \false) + { + $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE : Iterator\SortableIterator::SORT_BY_NAME_CASE_INSENSITIVE; + return $this; + } + /** + * Sorts files and directories by size. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortBySize() + { + $this->sort = Iterator\SortableIterator::SORT_BY_SIZE; + return $this; + } + /** + * Sorts files and directories by type (directories before files), then by name. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByType() + { + $this->sort = Iterator\SortableIterator::SORT_BY_TYPE; + return $this; + } + /** + * Sorts files and directories by the last accessed time. + * + * This is the time that the file was last accessed, read or written to. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByAccessedTime() + { + $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME; + return $this; + } + /** + * Reverses the sorting. + * + * @return $this + */ + public function reverseSorting() + { + $this->reverseSorting = \true; + return $this; + } + /** + * Sorts files and directories by the last inode changed time. + * + * This is the time that the inode information was last modified (permissions, owner, group or other metadata). + * + * On Windows, since inode is not available, changed time is actually the file creation time. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByChangedTime() + { + $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME; + return $this; + } + /** + * Sorts files and directories by the last modified time. + * + * This is the last time the actual contents of the file were last modified. + * + * This can be slow as all the matching files and directories must be retrieved for comparison. + * + * @return $this + * + * @see SortableIterator + */ + public function sortByModifiedTime() + { + $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME; + return $this; + } + /** + * Filters the iterator with an anonymous function. + * + * The anonymous function receives a \SplFileInfo and must return false + * to remove files. + * + * @return $this + * + * @see CustomFilterIterator + */ + public function filter(\Closure $closure) + { + $this->filters[] = $closure; + return $this; + } + /** + * Forces the following of symlinks. + * + * @return $this + */ + public function followLinks() + { + $this->followLinks = \true; + return $this; + } + /** + * Tells finder to ignore unreadable directories. + * + * By default, scanning unreadable directories content throws an AccessDeniedException. + * + * @return $this + */ + public function ignoreUnreadableDirs(bool $ignore = \true) + { + $this->ignoreUnreadableDirs = $ignore; + return $this; + } + /** + * Searches files and directories which match defined rules. + * + * @param string|string[] $dirs A directory path or an array of directories + * + * @return $this + * + * @throws DirectoryNotFoundException if one of the directories does not exist + */ + public function in($dirs) + { + $resolvedDirs = []; + foreach ((array) $dirs as $dir) { + if (\is_dir($dir)) { + $resolvedDirs[] = [$this->normalizeDir($dir)]; + } elseif ($glob = \glob($dir, (\defined('GLOB_BRACE') ? \GLOB_BRACE : 0) | \GLOB_ONLYDIR | \GLOB_NOSORT)) { + \sort($glob); + $resolvedDirs[] = \array_map(\Closure::fromCallable([$this, 'normalizeDir']), $glob); + } else { + throw new DirectoryNotFoundException(\sprintf('The "%s" directory does not exist.', $dir)); + } + } + $this->dirs = \array_merge($this->dirs, ...$resolvedDirs); + return $this; + } + /** + * Returns an Iterator for the current Finder configuration. + * + * This method implements the IteratorAggregate interface. + * + * @return \Iterator + * + * @throws \LogicException if the in() method has not been called + */ + public function getIterator() : \Iterator + { + if (0 === \count($this->dirs) && 0 === \count($this->iterators)) { + throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.'); + } + if (1 === \count($this->dirs) && 0 === \count($this->iterators)) { + $iterator = $this->searchInDirectory($this->dirs[0]); + if ($this->sort || $this->reverseSorting) { + $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); + } + return $iterator; + } + $iterator = new \AppendIterator(); + foreach ($this->dirs as $dir) { + $iterator->append(new \IteratorIterator(new LazyIterator(function () use($dir) { + return $this->searchInDirectory($dir); + }))); + } + foreach ($this->iterators as $it) { + $iterator->append($it); + } + if ($this->sort || $this->reverseSorting) { + $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); + } + return $iterator; + } + /** + * Appends an existing set of files/directories to the finder. + * + * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array. + * + * @return $this + * + * @throws \InvalidArgumentException when the given argument is not iterable + */ + public function append(iterable $iterator) + { + if ($iterator instanceof \IteratorAggregate) { + $this->iterators[] = $iterator->getIterator(); + } elseif ($iterator instanceof \Iterator) { + $this->iterators[] = $iterator; + } elseif (\is_iterable($iterator)) { + $it = new \ArrayIterator(); + foreach ($iterator as $file) { + $file = $file instanceof \SplFileInfo ? $file : new \SplFileInfo($file); + $it[$file->getPathname()] = $file; + } + $this->iterators[] = $it; + } else { + throw new \InvalidArgumentException('Finder::append() method wrong argument type.'); + } + return $this; + } + /** + * Check if any results were found. + */ + public function hasResults() : bool + { + foreach ($this->getIterator() as $_) { + return \true; + } + return \false; + } + /** + * Counts all the results collected by the iterators. + */ + public function count() : int + { + return \iterator_count($this->getIterator()); + } + private function searchInDirectory(string $dir) : \Iterator + { + $exclude = $this->exclude; + $notPaths = $this->notPaths; + if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) { + $exclude = \array_merge($exclude, self::$vcsPatterns); + } + if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) { + $notPaths[] = '#(^|/)\\..+(/|$)#'; + } + $minDepth = 0; + $maxDepth = \PHP_INT_MAX; + foreach ($this->depths as $comparator) { + switch ($comparator->getOperator()) { + case '>': + $minDepth = $comparator->getTarget() + 1; + break; + case '>=': + $minDepth = $comparator->getTarget(); + break; + case '<': + $maxDepth = $comparator->getTarget() - 1; + break; + case '<=': + $maxDepth = $comparator->getTarget(); + break; + default: + $minDepth = $maxDepth = $comparator->getTarget(); + } + } + $flags = \RecursiveDirectoryIterator::SKIP_DOTS; + if ($this->followLinks) { + $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS; + } + $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs); + if ($exclude) { + $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $exclude); + } + $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST); + if ($minDepth > 0 || $maxDepth < \PHP_INT_MAX) { + $iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth); + } + if ($this->mode) { + $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode); + } + if ($this->names || $this->notNames) { + $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames); + } + if ($this->contains || $this->notContains) { + $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains); + } + if ($this->sizes) { + $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes); + } + if ($this->dates) { + $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates); + } + if ($this->filters) { + $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters); + } + if ($this->paths || $notPaths) { + $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $notPaths); + } + if (static::IGNORE_VCS_IGNORED_FILES === (static::IGNORE_VCS_IGNORED_FILES & $this->ignore)) { + $iterator = new Iterator\VcsIgnoredFilterIterator($iterator, $dir); + } + return $iterator; + } + /** + * Normalizes given directory names by removing trailing slashes. + * + * Excluding: (s)ftp:// or ssh2.(s)ftp:// wrapper + */ + private function normalizeDir(string $dir) : string + { + if ('/' === $dir) { + return $dir; + } + $dir = \rtrim($dir, '/' . \DIRECTORY_SEPARATOR); + if (\preg_match('#^(ssh2\\.)?s?ftp://#', $dir)) { + $dir .= '/'; + } + return $dir; + } +} diff --git a/vendor/symfony/finder/Gitignore.php b/vendor/symfony/finder/Gitignore.php new file mode 100644 index 0000000000..891c2d2371 --- /dev/null +++ b/vendor/symfony/finder/Gitignore.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder; + +/** + * Gitignore matches against text. + * + * @author Michael Voříšek + * @author Ahmed Abdou + */ +class Gitignore +{ + /** + * Returns a regexp which is the equivalent of the gitignore pattern. + * + * Format specification: https://git-scm.com/docs/gitignore#_pattern_format + */ + public static function toRegex(string $gitignoreFileContent) : string + { + return self::buildRegex($gitignoreFileContent, \false); + } + public static function toRegexMatchingNegatedPatterns(string $gitignoreFileContent) : string + { + return self::buildRegex($gitignoreFileContent, \true); + } + private static function buildRegex(string $gitignoreFileContent, bool $inverted) : string + { + $gitignoreFileContent = \preg_replace('~(? + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder; + +/** + * Glob matches globbing patterns against text. + * + * if match_glob("foo.*", "foo.bar") echo "matched\n"; + * + * // prints foo.bar and foo.baz + * $regex = glob_to_regex("foo.*"); + * for (['foo.bar', 'foo.baz', 'foo', 'bar'] as $t) + * { + * if (/$regex/) echo "matched: $car\n"; + * } + * + * Glob implements glob(3) style matching that can be used to match + * against text, rather than fetching names from a filesystem. + * + * Based on the Perl Text::Glob module. + * + * @author Fabien Potencier PHP port + * @author Richard Clamp Perl version + * @copyright 2004-2005 Fabien Potencier + * @copyright 2002 Richard Clamp + */ +class Glob +{ + /** + * Returns a regexp which is the equivalent of the glob pattern. + */ + public static function toRegex(string $glob, bool $strictLeadingDot = \true, bool $strictWildcardSlash = \true, string $delimiter = '#') : string + { + $firstByte = \true; + $escaping = \false; + $inCurlies = 0; + $regex = ''; + $sizeGlob = \strlen($glob); + for ($i = 0; $i < $sizeGlob; ++$i) { + $car = $glob[$i]; + if ($firstByte && $strictLeadingDot && '.' !== $car) { + $regex .= '(?=[^\\.])'; + } + $firstByte = '/' === $car; + if ($firstByte && $strictWildcardSlash && isset($glob[$i + 2]) && '**' === $glob[$i + 1] . $glob[$i + 2] && (!isset($glob[$i + 3]) || '/' === $glob[$i + 3])) { + $car = '[^/]++/'; + if (!isset($glob[$i + 3])) { + $car .= '?'; + } + if ($strictLeadingDot) { + $car = '(?=[^\\.])' . $car; + } + $car = '/(?:' . $car . ')*'; + $i += 2 + isset($glob[$i + 3]); + if ('/' === $delimiter) { + $car = \str_replace('/', '\\/', $car); + } + } + if ($delimiter === $car || '.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) { + $regex .= "\\{$car}"; + } elseif ('*' === $car) { + $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*'); + } elseif ('?' === $car) { + $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.'); + } elseif ('{' === $car) { + $regex .= $escaping ? '\\{' : '('; + if (!$escaping) { + ++$inCurlies; + } + } elseif ('}' === $car && $inCurlies) { + $regex .= $escaping ? '}' : ')'; + if (!$escaping) { + --$inCurlies; + } + } elseif (',' === $car && $inCurlies) { + $regex .= $escaping ? ',' : '|'; + } elseif ('\\' === $car) { + if ($escaping) { + $regex .= '\\\\'; + $escaping = \false; + } else { + $escaping = \true; + } + continue; + } else { + $regex .= $car; + } + $escaping = \false; + } + return $delimiter . '^' . $regex . '$' . $delimiter; + } +} diff --git a/vendor/symfony/finder/Iterator/CustomFilterIterator.php b/vendor/symfony/finder/Iterator/CustomFilterIterator.php new file mode 100644 index 0000000000..648176411e --- /dev/null +++ b/vendor/symfony/finder/Iterator/CustomFilterIterator.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +/** + * CustomFilterIterator filters files by applying anonymous functions. + * + * The anonymous function receives a \SplFileInfo and must return false + * to remove files. + * + * @author Fabien Potencier + * + * @extends \FilterIterator + */ +class CustomFilterIterator extends \FilterIterator +{ + /** + * @var mixed[] + */ + private $filters = []; + /** + * @param \Iterator $iterator The Iterator to filter + * @param callable[] $filters An array of PHP callbacks + * + * @throws \InvalidArgumentException + */ + public function __construct(\Iterator $iterator, array $filters) + { + foreach ($filters as $filter) { + if (!\is_callable($filter)) { + throw new \InvalidArgumentException('Invalid PHP callback.'); + } + } + $this->filters = $filters; + parent::__construct($iterator); + } + /** + * Filters the iterator values. + */ + public function accept() : bool + { + $fileinfo = $this->current(); + foreach ($this->filters as $filter) { + if (\false === $filter($fileinfo)) { + return \false; + } + } + return \true; + } +} diff --git a/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php b/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php new file mode 100644 index 0000000000..6497afc287 --- /dev/null +++ b/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Comparator\DateComparator; +/** + * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates). + * + * @author Fabien Potencier + * + * @extends \FilterIterator + */ +class DateRangeFilterIterator extends \FilterIterator +{ + /** + * @var mixed[] + */ + private $comparators = []; + /** + * @param \Iterator $iterator + * @param DateComparator[] $comparators + */ + public function __construct(\Iterator $iterator, array $comparators) + { + $this->comparators = $comparators; + parent::__construct($iterator); + } + /** + * Filters the iterator values. + */ + public function accept() : bool + { + $fileinfo = $this->current(); + if (!\file_exists($fileinfo->getPathname())) { + return \false; + } + $filedate = $fileinfo->getMTime(); + foreach ($this->comparators as $compare) { + if (!$compare->test($filedate)) { + return \false; + } + } + return \true; + } +} diff --git a/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php b/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php new file mode 100644 index 0000000000..c10c75ee89 --- /dev/null +++ b/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +/** + * DepthRangeFilterIterator limits the directory depth. + * + * @author Fabien Potencier + * + * @template-covariant TKey + * @template-covariant TValue + * + * @extends \FilterIterator + */ +class DepthRangeFilterIterator extends \FilterIterator +{ + /** + * @var int + */ + private $minDepth = 0; + /** + * @param \RecursiveIteratorIterator<\RecursiveIterator> $iterator The Iterator to filter + * @param int $minDepth The min depth + * @param int $maxDepth The max depth + */ + public function __construct(\RecursiveIteratorIterator $iterator, int $minDepth = 0, int $maxDepth = \PHP_INT_MAX) + { + $this->minDepth = $minDepth; + $iterator->setMaxDepth(\PHP_INT_MAX === $maxDepth ? -1 : $maxDepth); + parent::__construct($iterator); + } + /** + * Filters the iterator values. + */ + public function accept() : bool + { + return $this->getInnerIterator()->getDepth() >= $this->minDepth; + } +} diff --git a/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php b/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php new file mode 100644 index 0000000000..3be4c8ce16 --- /dev/null +++ b/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\SplFileInfo; +/** + * ExcludeDirectoryFilterIterator filters out directories. + * + * @author Fabien Potencier + * + * @extends \FilterIterator + * + * @implements \RecursiveIterator + */ +class ExcludeDirectoryFilterIterator extends \FilterIterator implements \RecursiveIterator +{ + /** @var \Iterator */ + private $iterator; + /** + * @var bool + */ + private $isRecursive; + /** + * @var mixed[] + */ + private $excludedDirs = []; + /** + * @var string|null + */ + private $excludedPattern; + /** + * @param \Iterator $iterator The Iterator to filter + * @param string[] $directories An array of directories to exclude + */ + public function __construct(\Iterator $iterator, array $directories) + { + $this->iterator = $iterator; + $this->isRecursive = $iterator instanceof \RecursiveIterator; + $patterns = []; + foreach ($directories as $directory) { + $directory = \rtrim($directory, '/'); + if (!$this->isRecursive || \strpos($directory, '/') !== \false) { + $patterns[] = \preg_quote($directory, '#'); + } else { + $this->excludedDirs[$directory] = \true; + } + } + if ($patterns) { + $this->excludedPattern = '#(?:^|/)(?:' . \implode('|', $patterns) . ')(?:/|$)#'; + } + parent::__construct($iterator); + } + /** + * Filters the iterator values. + */ + public function accept() : bool + { + if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) { + return \false; + } + if ($this->excludedPattern) { + $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath(); + $path = \str_replace('\\', '/', $path); + return !\preg_match($this->excludedPattern, $path); + } + return \true; + } + public function hasChildren() : bool + { + return $this->isRecursive && $this->iterator->hasChildren(); + } + public function getChildren() : self + { + $children = new self($this->iterator->getChildren(), []); + $children->excludedDirs = $this->excludedDirs; + $children->excludedPattern = $this->excludedPattern; + return $children; + } +} diff --git a/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php b/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php new file mode 100644 index 0000000000..0e0018c7c6 --- /dev/null +++ b/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +/** + * FileTypeFilterIterator only keeps files, directories, or both. + * + * @author Fabien Potencier + * + * @extends \FilterIterator + */ +class FileTypeFilterIterator extends \FilterIterator +{ + public const ONLY_FILES = 1; + public const ONLY_DIRECTORIES = 2; + /** + * @var int + */ + private $mode; + /** + * @param \Iterator $iterator The Iterator to filter + * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES) + */ + public function __construct(\Iterator $iterator, int $mode) + { + $this->mode = $mode; + parent::__construct($iterator); + } + /** + * Filters the iterator values. + */ + public function accept() : bool + { + $fileinfo = $this->current(); + if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) { + return \false; + } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) { + return \false; + } + return \true; + } +} diff --git a/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php b/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php new file mode 100644 index 0000000000..66f6676469 --- /dev/null +++ b/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\SplFileInfo; +/** + * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings). + * + * @author Fabien Potencier + * @author Włodzimierz Gajda + * + * @extends MultiplePcreFilterIterator + */ +class FilecontentFilterIterator extends MultiplePcreFilterIterator +{ + /** + * Filters the iterator values. + */ + public function accept() : bool + { + if (!$this->matchRegexps && !$this->noMatchRegexps) { + return \true; + } + $fileinfo = $this->current(); + if ($fileinfo->isDir() || !$fileinfo->isReadable()) { + return \false; + } + $content = $fileinfo->getContents(); + if (!$content) { + return \false; + } + return $this->isAccepted($content); + } + /** + * Converts string to regexp if necessary. + * + * @param string $str Pattern: string or regexp + */ + protected function toRegex(string $str) : string + { + return $this->isRegex($str) ? $str : '/' . \preg_quote($str, '/') . '/'; + } +} diff --git a/vendor/symfony/finder/Iterator/FilenameFilterIterator.php b/vendor/symfony/finder/Iterator/FilenameFilterIterator.php new file mode 100644 index 0000000000..a374c29b17 --- /dev/null +++ b/vendor/symfony/finder/Iterator/FilenameFilterIterator.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Glob; +/** + * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string). + * + * @author Fabien Potencier + * + * @extends MultiplePcreFilterIterator + */ +class FilenameFilterIterator extends MultiplePcreFilterIterator +{ + /** + * Filters the iterator values. + */ + public function accept() : bool + { + return $this->isAccepted($this->current()->getFilename()); + } + /** + * Converts glob to regexp. + * + * PCRE patterns are left unchanged. + * Glob strings are transformed with Glob::toRegex(). + * + * @param string $str Pattern: glob or regexp + */ + protected function toRegex(string $str) : string + { + return $this->isRegex($str) ? $str : Glob::toRegex($str); + } +} diff --git a/vendor/symfony/finder/Iterator/LazyIterator.php b/vendor/symfony/finder/Iterator/LazyIterator.php new file mode 100644 index 0000000000..42a59491d0 --- /dev/null +++ b/vendor/symfony/finder/Iterator/LazyIterator.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +/** + * @author Jérémy Derussé + * + * @internal + */ +class LazyIterator implements \IteratorAggregate +{ + /** + * @var \Closure + */ + private $iteratorFactory; + public function __construct(callable $iteratorFactory) + { + $this->iteratorFactory = \Closure::fromCallable($iteratorFactory); + } + public function getIterator() : \Traversable + { + yield from ($this->iteratorFactory)(); + } +} diff --git a/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php b/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php new file mode 100644 index 0000000000..d24830c9d4 --- /dev/null +++ b/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +/** + * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings). + * + * @author Fabien Potencier + * + * @template-covariant TKey + * @template-covariant TValue + * + * @extends \FilterIterator + */ +abstract class MultiplePcreFilterIterator extends \FilterIterator +{ + protected $matchRegexps = []; + protected $noMatchRegexps = []; + /** + * @param \Iterator $iterator The Iterator to filter + * @param string[] $matchPatterns An array of patterns that need to match + * @param string[] $noMatchPatterns An array of patterns that need to not match + */ + public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns) + { + foreach ($matchPatterns as $pattern) { + $this->matchRegexps[] = $this->toRegex($pattern); + } + foreach ($noMatchPatterns as $pattern) { + $this->noMatchRegexps[] = $this->toRegex($pattern); + } + parent::__construct($iterator); + } + /** + * Checks whether the string is accepted by the regex filters. + * + * If there is no regexps defined in the class, this method will accept the string. + * Such case can be handled by child classes before calling the method if they want to + * apply a different behavior. + */ + protected function isAccepted(string $string) : bool + { + // should at least not match one rule to exclude + foreach ($this->noMatchRegexps as $regex) { + if (\preg_match($regex, $string)) { + return \false; + } + } + // should at least match one rule + if ($this->matchRegexps) { + foreach ($this->matchRegexps as $regex) { + if (\preg_match($regex, $string)) { + return \true; + } + } + return \false; + } + // If there is no match rules, the file is accepted + return \true; + } + /** + * Checks whether the string is a regex. + */ + protected function isRegex(string $str) : bool + { + $availableModifiers = 'imsxuADU'; + if (\PHP_VERSION_ID >= 80200) { + $availableModifiers .= 'n'; + } + if (\preg_match('/^(.{3,}?)[' . $availableModifiers . ']*$/', $str, $m)) { + $start = \substr($m[1], 0, 1); + $end = \substr($m[1], -1); + if ($start === $end) { + return !\preg_match('/[*?[:alnum:] \\\\]/', $start); + } + foreach ([['{', '}'], ['(', ')'], ['[', ']'], ['<', '>']] as $delimiters) { + if ($start === $delimiters[0] && $end === $delimiters[1]) { + return \true; + } + } + } + return \false; + } + /** + * Converts string into regexp. + */ + protected abstract function toRegex(string $str) : string; +} diff --git a/vendor/symfony/finder/Iterator/PathFilterIterator.php b/vendor/symfony/finder/Iterator/PathFilterIterator.php new file mode 100644 index 0000000000..6e92fbde20 --- /dev/null +++ b/vendor/symfony/finder/Iterator/PathFilterIterator.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\SplFileInfo; +/** + * PathFilterIterator filters files by path patterns (e.g. some/special/dir). + * + * @author Fabien Potencier + * @author Włodzimierz Gajda + * + * @extends MultiplePcreFilterIterator + */ +class PathFilterIterator extends MultiplePcreFilterIterator +{ + /** + * Filters the iterator values. + */ + public function accept() : bool + { + $filename = $this->current()->getRelativePathname(); + if ('\\' === \DIRECTORY_SEPARATOR) { + $filename = \str_replace('\\', '/', $filename); + } + return $this->isAccepted($filename); + } + /** + * Converts strings to regexp. + * + * PCRE patterns are left unchanged. + * + * Default conversion: + * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/' + * + * Use only / as directory separator (on Windows also). + * + * @param string $str Pattern: regexp or dirname + */ + protected function toRegex(string $str) : string + { + return $this->isRegex($str) ? $str : '/' . \preg_quote($str, '/') . '/'; + } +} diff --git a/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php new file mode 100644 index 0000000000..86cf5900af --- /dev/null +++ b/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Exception\AccessDeniedException; +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\SplFileInfo; +/** + * Extends the \RecursiveDirectoryIterator to support relative paths. + * + * @author Victor Berchet + * + * @extends \RecursiveDirectoryIterator + */ +class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator +{ + /** + * @var bool + */ + private $ignoreUnreadableDirs; + /** + * @var bool + */ + private $ignoreFirstRewind = \true; + // these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations + /** + * @var string + */ + private $rootPath; + /** + * @var string + */ + private $subPath; + /** + * @var string + */ + private $directorySeparator = '/'; + /** + * @throws \RuntimeException + */ + public function __construct(string $path, int $flags, bool $ignoreUnreadableDirs = \false) + { + if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) { + throw new \RuntimeException('This iterator only support returning current as fileinfo.'); + } + parent::__construct($path, $flags); + $this->ignoreUnreadableDirs = $ignoreUnreadableDirs; + $this->rootPath = $path; + if ('/' !== \DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) { + $this->directorySeparator = \DIRECTORY_SEPARATOR; + } + } + /** + * Return an instance of SplFileInfo with support for relative paths. + */ + public function current() : SplFileInfo + { + // the logic here avoids redoing the same work in all iterations + if (!isset($this->subPath)) { + $this->subPath = $this->getSubPath(); + } + $subPathname = $this->subPath; + if ('' !== $subPathname) { + $subPathname .= $this->directorySeparator; + } + $subPathname .= $this->getFilename(); + if ('/' !== ($basePath = $this->rootPath)) { + $basePath .= $this->directorySeparator; + } + return new SplFileInfo($basePath . $subPathname, $this->subPath, $subPathname); + } + public function hasChildren($allowLinks = \false) : bool + { + $hasChildren = parent::hasChildren($allowLinks); + if (!$hasChildren || !$this->ignoreUnreadableDirs) { + return $hasChildren; + } + try { + parent::getChildren(); + return \true; + } catch (\UnexpectedValueException $exception) { + // If directory is unreadable and finder is set to ignore it, skip children + return \false; + } + } + /** + * @throws AccessDeniedException + */ + public function getChildren() : \RecursiveDirectoryIterator + { + try { + $children = parent::getChildren(); + if ($children instanceof self) { + // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore + $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs; + // performance optimization to avoid redoing the same work in all children + $children->rootPath = $this->rootPath; + } + return $children; + } catch (\UnexpectedValueException $e) { + throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e); + } + } + public function next() : void + { + $this->ignoreFirstRewind = \false; + parent::next(); + } + public function rewind() : void + { + // some streams like FTP are not rewindable, ignore the first rewind after creation, + // as newly created DirectoryIterator does not need to be rewound + if ($this->ignoreFirstRewind) { + $this->ignoreFirstRewind = \false; + return; + } + parent::rewind(); + } +} diff --git a/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php b/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php new file mode 100644 index 0000000000..64b06831a7 --- /dev/null +++ b/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Comparator\NumberComparator; +/** + * SizeRangeFilterIterator filters out files that are not in the given size range. + * + * @author Fabien Potencier + * + * @extends \FilterIterator + */ +class SizeRangeFilterIterator extends \FilterIterator +{ + /** + * @var mixed[] + */ + private $comparators = []; + /** + * @param \Iterator $iterator + * @param NumberComparator[] $comparators + */ + public function __construct(\Iterator $iterator, array $comparators) + { + $this->comparators = $comparators; + parent::__construct($iterator); + } + /** + * Filters the iterator values. + */ + public function accept() : bool + { + $fileinfo = $this->current(); + if (!$fileinfo->isFile()) { + return \true; + } + $filesize = $fileinfo->getSize(); + foreach ($this->comparators as $compare) { + if (!$compare->test($filesize)) { + return \false; + } + } + return \true; + } +} diff --git a/vendor/symfony/finder/Iterator/SortableIterator.php b/vendor/symfony/finder/Iterator/SortableIterator.php new file mode 100644 index 0000000000..567f1f831c --- /dev/null +++ b/vendor/symfony/finder/Iterator/SortableIterator.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +/** + * SortableIterator applies a sort on a given Iterator. + * + * @author Fabien Potencier + * + * @implements \IteratorAggregate + */ +class SortableIterator implements \IteratorAggregate +{ + public const SORT_BY_NONE = 0; + public const SORT_BY_NAME = 1; + public const SORT_BY_TYPE = 2; + public const SORT_BY_ACCESSED_TIME = 3; + public const SORT_BY_CHANGED_TIME = 4; + public const SORT_BY_MODIFIED_TIME = 5; + public const SORT_BY_NAME_NATURAL = 6; + public const SORT_BY_NAME_CASE_INSENSITIVE = 7; + public const SORT_BY_NAME_NATURAL_CASE_INSENSITIVE = 8; + public const SORT_BY_EXTENSION = 9; + public const SORT_BY_SIZE = 10; + /** @var \Traversable */ + private $iterator; + /** + * @var \Closure|int + */ + private $sort; + /** + * @param \Traversable $iterator + * @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback) + * + * @throws \InvalidArgumentException + */ + public function __construct(\Traversable $iterator, $sort, bool $reverseOrder = \false) + { + $this->iterator = $iterator; + $order = $reverseOrder ? -1 : 1; + if (self::SORT_BY_NAME === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * \strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); + }; + } elseif (self::SORT_BY_NAME_NATURAL === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * \strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); + }; + } elseif (self::SORT_BY_NAME_CASE_INSENSITIVE === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * \strcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); + }; + } elseif (self::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * \strnatcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); + }; + } elseif (self::SORT_BY_TYPE === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + if ($a->isDir() && $b->isFile()) { + return -$order; + } elseif ($a->isFile() && $b->isDir()) { + return $order; + } + return $order * \strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname()); + }; + } elseif (self::SORT_BY_ACCESSED_TIME === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * ($a->getATime() - $b->getATime()); + }; + } elseif (self::SORT_BY_CHANGED_TIME === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * ($a->getCTime() - $b->getCTime()); + }; + } elseif (self::SORT_BY_MODIFIED_TIME === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * ($a->getMTime() - $b->getMTime()); + }; + } elseif (self::SORT_BY_EXTENSION === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * \strnatcmp($a->getExtension(), $b->getExtension()); + }; + } elseif (self::SORT_BY_SIZE === $sort) { + $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use($order) { + return $order * ($a->getSize() - $b->getSize()); + }; + } elseif (self::SORT_BY_NONE === $sort) { + $this->sort = $order; + } elseif (\is_callable($sort)) { + $this->sort = $reverseOrder ? static function (\SplFileInfo $a, \SplFileInfo $b) use($sort) { + return -$sort($a, $b); + } : \Closure::fromCallable($sort); + } else { + throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.'); + } + } + public function getIterator() : \Traversable + { + if (1 === $this->sort) { + return $this->iterator; + } + $array = \iterator_to_array($this->iterator, \true); + if (-1 === $this->sort) { + $array = \array_reverse($array); + } else { + \uasort($array, $this->sort); + } + return new \ArrayIterator($array); + } +} diff --git a/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php b/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php new file mode 100644 index 0000000000..2e14a08011 --- /dev/null +++ b/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder\Iterator; + +use MonorepoBuilderPrefix202310\Symfony\Component\Finder\Gitignore; +/** + * @extends \FilterIterator + */ +final class VcsIgnoredFilterIterator extends \FilterIterator +{ + /** + * @var string + */ + private $baseDir; + /** + * @var array + */ + private $gitignoreFilesCache = []; + /** + * @var array + */ + private $ignoredPathsCache = []; + /** + * @param \Iterator $iterator + */ + public function __construct(\Iterator $iterator, string $baseDir) + { + $this->baseDir = $this->normalizePath($baseDir); + foreach ($this->parentDirectoriesUpwards($this->baseDir) as $parentDirectory) { + if (@\is_dir("{$parentDirectory}/.git")) { + $this->baseDir = $parentDirectory; + break; + } + } + parent::__construct($iterator); + } + public function accept() : bool + { + $file = $this->current(); + $fileRealPath = $this->normalizePath($file->getRealPath()); + return !$this->isIgnored($fileRealPath); + } + private function isIgnored(string $fileRealPath) : bool + { + if (\is_dir($fileRealPath) && \substr_compare($fileRealPath, '/', -\strlen('/')) !== 0) { + $fileRealPath .= '/'; + } + if (isset($this->ignoredPathsCache[$fileRealPath])) { + return $this->ignoredPathsCache[$fileRealPath]; + } + $ignored = \false; + foreach ($this->parentDirectoriesDownwards($fileRealPath) as $parentDirectory) { + if ($this->isIgnored($parentDirectory)) { + // rules in ignored directories are ignored, no need to check further. + break; + } + $fileRelativePath = \substr($fileRealPath, \strlen($parentDirectory) + 1); + if (null === ($regexps = $this->readGitignoreFile("{$parentDirectory}/.gitignore"))) { + continue; + } + [$exclusionRegex, $inclusionRegex] = $regexps; + if (\preg_match($exclusionRegex, $fileRelativePath)) { + $ignored = \true; + continue; + } + if (\preg_match($inclusionRegex, $fileRelativePath)) { + $ignored = \false; + } + } + return $this->ignoredPathsCache[$fileRealPath] = $ignored; + } + /** + * @return list + */ + private function parentDirectoriesUpwards(string $from) : array + { + $parentDirectories = []; + $parentDirectory = $from; + while (\true) { + $newParentDirectory = \dirname($parentDirectory); + // dirname('/') = '/' + if ($newParentDirectory === $parentDirectory) { + break; + } + $parentDirectories[] = $parentDirectory = $newParentDirectory; + } + return $parentDirectories; + } + private function parentDirectoriesUpTo(string $from, string $upTo) : array + { + return \array_filter($this->parentDirectoriesUpwards($from), static function (string $directory) use($upTo) : bool { + return \strncmp($directory, $upTo, \strlen($upTo)) === 0; + }); + } + /** + * @return list + */ + private function parentDirectoriesDownwards(string $fileRealPath) : array + { + return \array_reverse($this->parentDirectoriesUpTo($fileRealPath, $this->baseDir)); + } + /** + * @return array{0: string, 1: string}|null + */ + private function readGitignoreFile(string $path) : ?array + { + if (\array_key_exists($path, $this->gitignoreFilesCache)) { + return $this->gitignoreFilesCache[$path]; + } + if (!\file_exists($path)) { + return $this->gitignoreFilesCache[$path] = null; + } + if (!\is_file($path) || !\is_readable($path)) { + throw new \RuntimeException("The \"ignoreVCSIgnored\" option cannot be used by the Finder as the \"{$path}\" file is not readable."); + } + $gitignoreFileContent = \file_get_contents($path); + return $this->gitignoreFilesCache[$path] = [Gitignore::toRegex($gitignoreFileContent), Gitignore::toRegexMatchingNegatedPatterns($gitignoreFileContent)]; + } + private function normalizePath(string $path) : string + { + if ('\\' === \DIRECTORY_SEPARATOR) { + return \str_replace('\\', '/', $path); + } + return $path; + } +} diff --git a/vendor/symfony/finder/LICENSE b/vendor/symfony/finder/LICENSE new file mode 100644 index 0000000000..0138f8f071 --- /dev/null +++ b/vendor/symfony/finder/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/finder/README.md b/vendor/symfony/finder/README.md new file mode 100644 index 0000000000..22bdeb9bcf --- /dev/null +++ b/vendor/symfony/finder/README.md @@ -0,0 +1,14 @@ +Finder Component +================ + +The Finder component finds files and directories via an intuitive fluent +interface. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/finder.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/finder/SplFileInfo.php b/vendor/symfony/finder/SplFileInfo.php new file mode 100644 index 0000000000..abee8ac2e1 --- /dev/null +++ b/vendor/symfony/finder/SplFileInfo.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Finder; + +/** + * Extends \SplFileInfo to support relative paths. + * + * @author Fabien Potencier + */ +class SplFileInfo extends \SplFileInfo +{ + /** + * @var string + */ + private $relativePath; + /** + * @var string + */ + private $relativePathname; + /** + * @param string $file The file name + * @param string $relativePath The relative path + * @param string $relativePathname The relative path name + */ + public function __construct(string $file, string $relativePath, string $relativePathname) + { + parent::__construct($file); + $this->relativePath = $relativePath; + $this->relativePathname = $relativePathname; + } + /** + * Returns the relative path. + * + * This path does not contain the file name. + */ + public function getRelativePath() : string + { + return $this->relativePath; + } + /** + * Returns the relative path name. + * + * This path contains the file name. + */ + public function getRelativePathname() : string + { + return $this->relativePathname; + } + public function getFilenameWithoutExtension() : string + { + $filename = $this->getFilename(); + return \pathinfo($filename, \PATHINFO_FILENAME); + } + /** + * Returns the contents of the file. + * + * @throws \RuntimeException + */ + public function getContents() : string + { + \set_error_handler(function ($type, $msg) use(&$error) { + $error = $msg; + }); + try { + $content = \file_get_contents($this->getPathname()); + } finally { + \restore_error_handler(); + } + if (\false === $content) { + throw new \RuntimeException($error); + } + return $content; + } +} diff --git a/vendor/symfony/finder/composer.json b/vendor/symfony/finder/composer.json new file mode 100644 index 0000000000..b951d9d458 --- /dev/null +++ b/vendor/symfony/finder/composer.json @@ -0,0 +1,33 @@ +{ + "name": "symfony\/finder", + "type": "library", + "description": "Finds files and directories via an intuitive fluent interface", + "keywords": [], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony\/filesystem": "^6.0" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/vendor/symfony/polyfill-ctype/Ctype.php b/vendor/symfony/polyfill-ctype/Ctype.php new file mode 100644 index 0000000000..357ccc1792 --- /dev/null +++ b/vendor/symfony/polyfill-ctype/Ctype.php @@ -0,0 +1,205 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Symfony\Polyfill\Ctype; + +/** + * Ctype implementation through regex. + * + * @internal + * + * @author Gert de Pagter + */ +final class Ctype +{ + /** + * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. + * + * @see https://php.net/ctype-alnum + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_alnum($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^A-Za-z0-9]/', $text); + } + /** + * Returns TRUE if every character in text is a letter, FALSE otherwise. + * + * @see https://php.net/ctype-alpha + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_alpha($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^A-Za-z]/', $text); + } + /** + * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. + * + * @see https://php.net/ctype-cntrl + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_cntrl($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^\\x00-\\x1f\\x7f]/', $text); + } + /** + * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. + * + * @see https://php.net/ctype-digit + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_digit($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^0-9]/', $text); + } + /** + * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. + * + * @see https://php.net/ctype-graph + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_graph($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^!-~]/', $text); + } + /** + * Returns TRUE if every character in text is a lowercase letter. + * + * @see https://php.net/ctype-lower + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_lower($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^a-z]/', $text); + } + /** + * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. + * + * @see https://php.net/ctype-print + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_print($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^ -~]/', $text); + } + /** + * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. + * + * @see https://php.net/ctype-punct + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_punct($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^!-\\/\\:-@\\[-`\\{-~]/', $text); + } + /** + * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. + * + * @see https://php.net/ctype-space + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_space($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^\\s]/', $text); + } + /** + * Returns TRUE if every character in text is an uppercase letter. + * + * @see https://php.net/ctype-upper + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_upper($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^A-Z]/', $text); + } + /** + * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. + * + * @see https://php.net/ctype-xdigit + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_xdigit($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + return \is_string($text) && '' !== $text && !\preg_match('/[^A-Fa-f0-9]/', $text); + } + /** + * Converts integers to their char versions according to normal ctype behaviour, if needed. + * + * If an integer between -128 and 255 inclusive is provided, + * it is interpreted as the ASCII value of a single character + * (negative values have 256 added in order to allow characters in the Extended ASCII range). + * Any other integer is interpreted as a string containing the decimal digits of the integer. + * + * @param mixed $int + * @param string $function + * + * @return mixed + */ + private static function convert_int_to_char_for_ctype($int, $function) + { + if (!\is_int($int)) { + return $int; + } + if ($int < -128 || $int > 255) { + return (string) $int; + } + if (\PHP_VERSION_ID >= 80100) { + @\trigger_error($function . '(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED); + } + if ($int < 0) { + $int += 256; + } + return \chr($int); + } +} diff --git a/vendor/symfony/polyfill-ctype/LICENSE b/vendor/symfony/polyfill-ctype/LICENSE new file mode 100644 index 0000000000..7536caeae8 --- /dev/null +++ b/vendor/symfony/polyfill-ctype/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-ctype/README.md b/vendor/symfony/polyfill-ctype/README.md new file mode 100644 index 0000000000..b144d03c3c --- /dev/null +++ b/vendor/symfony/polyfill-ctype/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / Ctype +======================== + +This component provides `ctype_*` functions to users who run php versions without the ctype extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-ctype/bootstrap.php b/vendor/symfony/polyfill-ctype/bootstrap.php new file mode 100644 index 0000000000..d54524b31b --- /dev/null +++ b/vendor/symfony/polyfill-ctype/bootstrap.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit($text) { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph($text) { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower($text) { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print($text) { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct($text) { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space($text) { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper($text) { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } +} diff --git a/vendor/symfony/polyfill-ctype/bootstrap80.php b/vendor/symfony/polyfill-ctype/bootstrap80.php new file mode 100644 index 0000000000..2b540ea41a --- /dev/null +++ b/vendor/symfony/polyfill-ctype/bootstrap80.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (!function_exists('ctype_alnum')) { + /** + * @param mixed $text + */ + function ctype_alnum($text): bool { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + /** + * @param mixed $text + */ + function ctype_alpha($text): bool { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + /** + * @param mixed $text + */ + function ctype_cntrl($text): bool { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + /** + * @param mixed $text + */ + function ctype_digit($text): bool { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + /** + * @param mixed $text + */ + function ctype_graph($text): bool { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + /** + * @param mixed $text + */ + function ctype_lower($text): bool { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + /** + * @param mixed $text + */ + function ctype_print($text): bool { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + /** + * @param mixed $text + */ + function ctype_punct($text): bool { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + /** + * @param mixed $text + */ + function ctype_space($text): bool { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + /** + * @param mixed $text + */ + function ctype_upper($text): bool { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + /** + * @param mixed $text + */ + function ctype_xdigit($text): bool { return p\Ctype::ctype_xdigit($text); } +} diff --git a/vendor/symfony/polyfill-ctype/composer.json b/vendor/symfony/polyfill-ctype/composer.json new file mode 100644 index 0000000000..1c57a8377f --- /dev/null +++ b/vendor/symfony/polyfill-ctype/composer.json @@ -0,0 +1,50 @@ +{ + "name": "symfony\/polyfill-ctype", + "type": "library", + "description": "Symfony polyfill for ctype functions", + "keywords": [ + "polyfill", + "compatibility", + "portable", + "ctype" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + } +} \ No newline at end of file diff --git a/vendor/symfony/polyfill-intl-grapheme/Grapheme.php b/vendor/symfony/polyfill-intl-grapheme/Grapheme.php new file mode 100644 index 0000000000..dfaea0d098 --- /dev/null +++ b/vendor/symfony/polyfill-intl-grapheme/Grapheme.php @@ -0,0 +1,210 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Symfony\Polyfill\Intl\Grapheme; + +\define('SYMFONY_GRAPHEME_CLUSTER_RX', ((float) \PCRE_VERSION < 10 ? (float) \PCRE_VERSION >= 8.32 : (float) \PCRE_VERSION >= 10.39) ? '\\X' : \Symfony\Polyfill\Intl\Grapheme\Grapheme::GRAPHEME_CLUSTER_RX); +/** + * Partial intl implementation in pure PHP. + * + * Implemented: + * - grapheme_extract - Extract a sequence of grapheme clusters from a text buffer, which must be encoded in UTF-8 + * - grapheme_stripos - Find position (in grapheme units) of first occurrence of a case-insensitive string + * - grapheme_stristr - Returns part of haystack string from the first occurrence of case-insensitive needle to the end of haystack + * - grapheme_strlen - Get string length in grapheme units + * - grapheme_strpos - Find position (in grapheme units) of first occurrence of a string + * - grapheme_strripos - Find position (in grapheme units) of last occurrence of a case-insensitive string + * - grapheme_strrpos - Find position (in grapheme units) of last occurrence of a string + * - grapheme_strstr - Returns part of haystack string from the first occurrence of needle to the end of haystack + * - grapheme_substr - Return part of a string + * + * @author Nicolas Grekas + * + * @internal + */ +final class Grapheme +{ + // (CRLF|([ZWNJ-ZWJ]|T+|L*(LV?V+|LV|LVT)T*|L+|[^Control])[Extend]*|[Control]) + // This regular expression is a work around for http://bugs.exim.org/1279 + public const GRAPHEME_CLUSTER_RX = '(?:\\r\\n|(?:[ -~\\x{200C}\\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}])[\\p{Mn}\\p{Me}\\x{09BE}\\x{09D7}\\x{0B3E}\\x{0B57}\\x{0BBE}\\x{0BD7}\\x{0CC2}\\x{0CD5}\\x{0CD6}\\x{0D3E}\\x{0D57}\\x{0DCF}\\x{0DDF}\\x{200C}\\x{200D}\\x{1D165}\\x{1D16E}-\\x{1D172}]*|[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}])'; + private const CASE_FOLD = [['µ', 'ſ', "ͅ", 'ς', "ϐ", "ϑ", "ϕ", "ϖ", "ϰ", "ϱ", "ϵ", "ẛ", "ι"], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "ṡ", 'ι']]; + public static function grapheme_extract($s, $size, $type = \GRAPHEME_EXTR_COUNT, $start = 0, &$next = 0) + { + if (0 > $start) { + $start = \strlen($s) + $start; + } + if (!\is_scalar($s)) { + $hasError = \false; + \set_error_handler(function () use(&$hasError) { + $hasError = \true; + }); + $next = \substr($s, $start); + \restore_error_handler(); + if ($hasError) { + \substr($s, $start); + $s = ''; + } else { + $s = $next; + } + } else { + $s = \substr($s, $start); + } + $size = (int) $size; + $type = (int) $type; + $start = (int) $start; + if (\GRAPHEME_EXTR_COUNT !== $type && \GRAPHEME_EXTR_MAXBYTES !== $type && \GRAPHEME_EXTR_MAXCHARS !== $type) { + if (80000 > \PHP_VERSION_ID) { + return \false; + } + throw new \ValueError('grapheme_extract(): Argument #3 ($type) must be one of GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS'); + } + if (!isset($s[0]) || 0 > $size || 0 > $start) { + return \false; + } + if (0 === $size) { + return ''; + } + $next = $start; + $s = \preg_split('/(' . \SYMFONY_GRAPHEME_CLUSTER_RX . ')/u', "\r\n" . $s, $size + 1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE); + if (!isset($s[1])) { + return \false; + } + $i = 1; + $ret = ''; + do { + if (\GRAPHEME_EXTR_COUNT === $type) { + --$size; + } elseif (\GRAPHEME_EXTR_MAXBYTES === $type) { + $size -= \strlen($s[$i]); + } else { + $size -= \iconv_strlen($s[$i], 'UTF-8//IGNORE'); + } + if ($size >= 0) { + $ret .= $s[$i]; + } + } while (isset($s[++$i]) && $size > 0); + $next += \strlen($ret); + return $ret; + } + public static function grapheme_strlen($s) + { + \preg_replace('/' . \SYMFONY_GRAPHEME_CLUSTER_RX . '/u', '', $s, -1, $len); + return 0 === $len && '' !== $s ? null : $len; + } + public static function grapheme_substr($s, $start, $len = null) + { + if (null === $len) { + $len = 2147483647; + } + \preg_match_all('/' . \SYMFONY_GRAPHEME_CLUSTER_RX . '/u', $s, $s); + $slen = \count($s[0]); + $start = (int) $start; + if (0 > $start) { + $start += $slen; + } + if (0 > $start) { + if (\PHP_VERSION_ID < 80000) { + return \false; + } + $start = 0; + } + if ($start >= $slen) { + return \PHP_VERSION_ID >= 80000 ? '' : \false; + } + $rem = $slen - $start; + if (0 > $len) { + $len += $rem; + } + if (0 === $len) { + return ''; + } + if (0 > $len) { + return \PHP_VERSION_ID >= 80000 ? '' : \false; + } + if ($len > $rem) { + $len = $rem; + } + return \implode('', \array_slice($s[0], $start, $len)); + } + public static function grapheme_strpos($s, $needle, $offset = 0) + { + return self::grapheme_position($s, $needle, $offset, 0); + } + public static function grapheme_stripos($s, $needle, $offset = 0) + { + return self::grapheme_position($s, $needle, $offset, 1); + } + public static function grapheme_strrpos($s, $needle, $offset = 0) + { + return self::grapheme_position($s, $needle, $offset, 2); + } + public static function grapheme_strripos($s, $needle, $offset = 0) + { + return self::grapheme_position($s, $needle, $offset, 3); + } + public static function grapheme_stristr($s, $needle, $beforeNeedle = \false) + { + return \mb_stristr($s, $needle, $beforeNeedle, 'UTF-8'); + } + public static function grapheme_strstr($s, $needle, $beforeNeedle = \false) + { + return \mb_strstr($s, $needle, $beforeNeedle, 'UTF-8'); + } + private static function grapheme_position($s, $needle, $offset, $mode) + { + $needle = (string) $needle; + if (80000 > \PHP_VERSION_ID && !\preg_match('/./us', $needle)) { + return \false; + } + $s = (string) $s; + if (!\preg_match('/./us', $s)) { + return \false; + } + if ($offset > 0) { + $s = self::grapheme_substr($s, $offset); + } elseif ($offset < 0) { + if (2 > $mode) { + $offset += self::grapheme_strlen($s); + $s = self::grapheme_substr($s, $offset); + if (0 > $offset) { + $offset = 0; + } + } elseif (0 > ($offset += self::grapheme_strlen($needle))) { + $s = self::grapheme_substr($s, 0, $offset); + $offset = 0; + } else { + $offset = 0; + } + } + // As UTF-8 is self-synchronizing, and we have ensured the strings are valid UTF-8, + // we can use normal binary string functions here. For case-insensitive searches, + // case fold the strings first. + $caseInsensitive = $mode & 1; + $reverse = $mode & 2; + if ($caseInsensitive) { + // Use the same case folding mode as mbstring does for mb_stripos(). + // Stick to SIMPLE case folding to avoid changing the length of the string, which + // might result in offsets being shifted. + $mode = \defined('MB_CASE_FOLD_SIMPLE') ? \MB_CASE_FOLD_SIMPLE : \MB_CASE_LOWER; + $s = \mb_convert_case($s, $mode, 'UTF-8'); + $needle = \mb_convert_case($needle, $mode, 'UTF-8'); + if (!\defined('MB_CASE_FOLD_SIMPLE')) { + $s = \str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s); + $needle = \str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $needle); + } + } + if ($reverse) { + $needlePos = \strrpos($s, $needle); + } else { + $needlePos = \strpos($s, $needle); + } + return \false !== $needlePos ? self::grapheme_strlen(\substr($s, 0, $needlePos)) + $offset : \false; + } +} diff --git a/vendor/symfony/polyfill-intl-grapheme/LICENSE b/vendor/symfony/polyfill-intl-grapheme/LICENSE new file mode 100644 index 0000000000..6e3afce692 --- /dev/null +++ b/vendor/symfony/polyfill-intl-grapheme/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-intl-grapheme/README.md b/vendor/symfony/polyfill-intl-grapheme/README.md new file mode 100644 index 0000000000..f55d92c5c3 --- /dev/null +++ b/vendor/symfony/polyfill-intl-grapheme/README.md @@ -0,0 +1,31 @@ +Symfony Polyfill / Intl: Grapheme +================================= + +This component provides a partial, native PHP implementation of the +[Grapheme functions](https://php.net/intl.grapheme) from the +[Intl](https://php.net/intl) extension. + +- [`grapheme_extract`](https://php.net/grapheme_extract): Extract a sequence of grapheme + clusters from a text buffer, which must be encoded in UTF-8 +- [`grapheme_stripos`](https://php.net/grapheme_stripos): Find position (in grapheme units) + of first occurrence of a case-insensitive string +- [`grapheme_stristr`](https://php.net/grapheme_stristr): Returns part of haystack string + from the first occurrence of case-insensitive needle to the end of haystack +- [`grapheme_strlen`](https://php.net/grapheme_strlen): Get string length in grapheme units +- [`grapheme_strpos`](https://php.net/grapheme_strpos): Find position (in grapheme units) + of first occurrence of a string +- [`grapheme_strripos`](https://php.net/grapheme_strripos): Find position (in grapheme units) + of last occurrence of a case-insensitive string +- [`grapheme_strrpos`](https://php.net/grapheme_strrpos): Find position (in grapheme units) + of last occurrence of a string +- [`grapheme_strstr`](https://php.net/grapheme_strstr): Returns part of haystack string from + the first occurrence of needle to the end of haystack +- [`grapheme_substr`](https://php.net/grapheme_substr): Return part of a string + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-intl-grapheme/bootstrap.php b/vendor/symfony/polyfill-intl-grapheme/bootstrap.php new file mode 100644 index 0000000000..a9ea03c7e5 --- /dev/null +++ b/vendor/symfony/polyfill-intl-grapheme/bootstrap.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Grapheme as p; + +if (extension_loaded('intl')) { + return; +} + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!defined('GRAPHEME_EXTR_COUNT')) { + define('GRAPHEME_EXTR_COUNT', 0); +} +if (!defined('GRAPHEME_EXTR_MAXBYTES')) { + define('GRAPHEME_EXTR_MAXBYTES', 1); +} +if (!defined('GRAPHEME_EXTR_MAXCHARS')) { + define('GRAPHEME_EXTR_MAXCHARS', 2); +} + +if (!function_exists('grapheme_extract')) { + function grapheme_extract($haystack, $size, $type = 0, $start = 0, &$next = 0) { return p\Grapheme::grapheme_extract($haystack, $size, $type, $start, $next); } +} +if (!function_exists('grapheme_stripos')) { + function grapheme_stripos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_stripos($haystack, $needle, $offset); } +} +if (!function_exists('grapheme_stristr')) { + function grapheme_stristr($haystack, $needle, $beforeNeedle = false) { return p\Grapheme::grapheme_stristr($haystack, $needle, $beforeNeedle); } +} +if (!function_exists('grapheme_strlen')) { + function grapheme_strlen($input) { return p\Grapheme::grapheme_strlen($input); } +} +if (!function_exists('grapheme_strpos')) { + function grapheme_strpos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strpos($haystack, $needle, $offset); } +} +if (!function_exists('grapheme_strripos')) { + function grapheme_strripos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strripos($haystack, $needle, $offset); } +} +if (!function_exists('grapheme_strrpos')) { + function grapheme_strrpos($haystack, $needle, $offset = 0) { return p\Grapheme::grapheme_strrpos($haystack, $needle, $offset); } +} +if (!function_exists('grapheme_strstr')) { + function grapheme_strstr($haystack, $needle, $beforeNeedle = false) { return p\Grapheme::grapheme_strstr($haystack, $needle, $beforeNeedle); } +} +if (!function_exists('grapheme_substr')) { + function grapheme_substr($string, $offset, $length = null) { return p\Grapheme::grapheme_substr($string, $offset, $length); } +} diff --git a/vendor/symfony/polyfill-intl-grapheme/bootstrap80.php b/vendor/symfony/polyfill-intl-grapheme/bootstrap80.php new file mode 100644 index 0000000000..23a1fa5088 --- /dev/null +++ b/vendor/symfony/polyfill-intl-grapheme/bootstrap80.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Grapheme as p; + +if (!defined('GRAPHEME_EXTR_COUNT')) { + define('GRAPHEME_EXTR_COUNT', 0); +} +if (!defined('GRAPHEME_EXTR_MAXBYTES')) { + define('GRAPHEME_EXTR_MAXBYTES', 1); +} +if (!defined('GRAPHEME_EXTR_MAXCHARS')) { + define('GRAPHEME_EXTR_MAXCHARS', 2); +} + +if (!function_exists('grapheme_extract')) { + /** + * @return string|false + */ + function grapheme_extract(?string $haystack, ?int $size, ?int $type = GRAPHEME_EXTR_COUNT, ?int $offset = 0, &$next = null) { return p\Grapheme::grapheme_extract((string) $haystack, (int) $size, (int) $type, (int) $offset, $next); } +} +if (!function_exists('grapheme_stripos')) { + /** + * @return int|false + */ + function grapheme_stripos(?string $haystack, ?string $needle, ?int $offset = 0) { return p\Grapheme::grapheme_stripos((string) $haystack, (string) $needle, (int) $offset); } +} +if (!function_exists('grapheme_stristr')) { + /** + * @return string|false + */ + function grapheme_stristr(?string $haystack, ?string $needle, ?bool $beforeNeedle = false) { return p\Grapheme::grapheme_stristr((string) $haystack, (string) $needle, (bool) $beforeNeedle); } +} +if (!function_exists('grapheme_strlen')) { + /** + * @return int|false|null + */ + function grapheme_strlen(?string $string) { return p\Grapheme::grapheme_strlen((string) $string); } +} +if (!function_exists('grapheme_strpos')) { + /** + * @return int|false + */ + function grapheme_strpos(?string $haystack, ?string $needle, ?int $offset = 0) { return p\Grapheme::grapheme_strpos((string) $haystack, (string) $needle, (int) $offset); } +} +if (!function_exists('grapheme_strripos')) { + /** + * @return int|false + */ + function grapheme_strripos(?string $haystack, ?string $needle, ?int $offset = 0) { return p\Grapheme::grapheme_strripos((string) $haystack, (string) $needle, (int) $offset); } +} +if (!function_exists('grapheme_strrpos')) { + /** + * @return int|false + */ + function grapheme_strrpos(?string $haystack, ?string $needle, ?int $offset = 0) { return p\Grapheme::grapheme_strrpos((string) $haystack, (string) $needle, (int) $offset); } +} +if (!function_exists('grapheme_strstr')) { + /** + * @return string|false + */ + function grapheme_strstr(?string $haystack, ?string $needle, ?bool $beforeNeedle = false) { return p\Grapheme::grapheme_strstr((string) $haystack, (string) $needle, (bool) $beforeNeedle); } +} +if (!function_exists('grapheme_substr')) { + /** + * @return string|false + */ + function grapheme_substr(?string $string, ?int $offset, ?int $length = null) { return p\Grapheme::grapheme_substr((string) $string, (int) $offset, $length); } +} diff --git a/vendor/symfony/polyfill-intl-grapheme/composer.json b/vendor/symfony/polyfill-intl-grapheme/composer.json new file mode 100644 index 0000000000..f369e34605 --- /dev/null +++ b/vendor/symfony/polyfill-intl-grapheme/composer.json @@ -0,0 +1,49 @@ +{ + "name": "symfony\/polyfill-intl-grapheme", + "type": "library", + "description": "Symfony polyfill for intl's grapheme_* functions", + "keywords": [ + "polyfill", + "shim", + "compatibility", + "portable", + "intl", + "grapheme" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "suggest": { + "ext-intl": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + } +} \ No newline at end of file diff --git a/vendor/symfony/polyfill-intl-normalizer/LICENSE b/vendor/symfony/polyfill-intl-normalizer/LICENSE new file mode 100644 index 0000000000..6e3afce692 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-intl-normalizer/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Normalizer.php new file mode 100644 index 0000000000..8ec3ed0e93 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/Normalizer.php @@ -0,0 +1,258 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Symfony\Polyfill\Intl\Normalizer; + +/** + * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension. + * + * It has been validated with Unicode 6.3 Normalization Conformance Test. + * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations. + * + * @author Nicolas Grekas + * + * @internal + */ +class Normalizer +{ + public const FORM_D = \Normalizer::FORM_D; + public const FORM_KD = \Normalizer::FORM_KD; + public const FORM_C = \Normalizer::FORM_C; + public const FORM_KC = \Normalizer::FORM_KC; + public const NFD = \Normalizer::NFD; + public const NFKD = \Normalizer::NFKD; + public const NFC = \Normalizer::NFC; + public const NFKC = \Normalizer::NFKC; + private static $C; + private static $D; + private static $KD; + private static $cC; + private static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4]; + private static $ASCII = " eiasntrolud][cmp'\ng|hv.fb,:=-q10C2*yx)(L9AS/P\"EjMIk3>5T \PHP_VERSION_ID) { + return \false; + } + throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form'); + } + if ('' === $s) { + return ''; + } + if ($K && null === self::$KD) { + self::$KD = self::getData('compatibilityDecomposition'); + } + if (null === self::$D) { + self::$D = self::getData('canonicalDecomposition'); + self::$cC = self::getData('combiningClass'); + } + if (null !== ($mbEncoding = 2 & (int) \ini_get('mbstring.func_overload') ? \mb_internal_encoding() : null)) { + \mb_internal_encoding('8bit'); + } + $r = self::decompose($s, $K); + if ($C) { + if (null === self::$C) { + self::$C = self::getData('canonicalComposition'); + } + $r = self::recompose($r); + } + if (null !== $mbEncoding) { + \mb_internal_encoding($mbEncoding); + } + return $r; + } + private static function recompose($s) + { + $ASCII = self::$ASCII; + $compMap = self::$C; + $combClass = self::$cC; + $ulenMask = self::$ulenMask; + $result = $tail = ''; + $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xf0"]; + $len = \strlen($s); + $lastUchr = \substr($s, 0, $i); + $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0; + while ($i < $len) { + if ($s[$i] < "\x80") { + // ASCII chars + if ($tail) { + $lastUchr .= $tail; + $tail = ''; + } + if ($j = \strspn($s, $ASCII, $i + 1)) { + $lastUchr .= \substr($s, $i, $j); + $i += $j; + } + $result .= $lastUchr; + $lastUchr = $s[$i]; + $lastUcls = 0; + ++$i; + continue; + } + $ulen = $ulenMask[$s[$i] & "\xf0"]; + $uchr = \substr($s, $i, $ulen); + if ($lastUchr < "ᄀ" || "ᄒ" < $lastUchr || $uchr < "ᅡ" || "ᅵ" < $uchr || $lastUcls) { + // Table lookup and combining chars composition + $ucls = $combClass[$uchr] ?? 0; + if (isset($compMap[$lastUchr . $uchr]) && (!$lastUcls || $lastUcls < $ucls)) { + $lastUchr = $compMap[$lastUchr . $uchr]; + } elseif ($lastUcls = $ucls) { + $tail .= $uchr; + } else { + if ($tail) { + $lastUchr .= $tail; + $tail = ''; + } + $result .= $lastUchr; + $lastUchr = $uchr; + } + } else { + // Hangul chars + $L = \ord($lastUchr[2]) - 0x80; + $V = \ord($uchr[2]) - 0xa1; + $T = 0; + $uchr = \substr($s, $i + $ulen, 3); + if ("ᆧ" <= $uchr && $uchr <= "ᇂ") { + $T = \ord($uchr[2]) - 0xa7; + 0 > $T && ($T += 0x40); + $ulen += 3; + } + $L = 0xac00 + ($L * 21 + $V) * 28 + $T; + $lastUchr = \chr(0xe0 | $L >> 12) . \chr(0x80 | $L >> 6 & 0x3f) . \chr(0x80 | $L & 0x3f); + } + $i += $ulen; + } + return $result . $lastUchr . $tail; + } + private static function decompose($s, $c) + { + $result = ''; + $ASCII = self::$ASCII; + $decompMap = self::$D; + $combClass = self::$cC; + $ulenMask = self::$ulenMask; + if ($c) { + $compatMap = self::$KD; + } + $c = []; + $i = 0; + $len = \strlen($s); + while ($i < $len) { + if ($s[$i] < "\x80") { + // ASCII chars + if ($c) { + \ksort($c); + $result .= \implode('', $c); + $c = []; + } + $j = 1 + \strspn($s, $ASCII, $i + 1); + $result .= \substr($s, $i, $j); + $i += $j; + continue; + } + $ulen = $ulenMask[$s[$i] & "\xf0"]; + $uchr = \substr($s, $i, $ulen); + $i += $ulen; + if ($uchr < "가" || "힣" < $uchr) { + // Table lookup + if ($uchr !== ($j = $compatMap[$uchr] ?? $decompMap[$uchr] ?? $uchr)) { + $uchr = $j; + $j = \strlen($uchr); + $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xf0"]; + if ($ulen != $j) { + // Put trailing chars in $s + $j -= $ulen; + $i -= $j; + if (0 > $i) { + $s = \str_repeat(' ', -$i) . $s; + $len -= $i; + $i = 0; + } + while ($j--) { + $s[$i + $j] = $uchr[$ulen + $j]; + } + $uchr = \substr($uchr, 0, $ulen); + } + } + if (isset($combClass[$uchr])) { + // Combining chars, for sorting + if (!isset($c[$combClass[$uchr]])) { + $c[$combClass[$uchr]] = ''; + } + $c[$combClass[$uchr]] .= $uchr; + continue; + } + } else { + // Hangul chars + $uchr = \unpack('C*', $uchr); + $j = ($uchr[1] - 224 << 12) + ($uchr[2] - 128 << 6) + $uchr[3] - 0xac80; + $uchr = "\xe1\x84" . \chr(0x80 + (int) ($j / 588)) . "\xe1\x85" . \chr(0xa1 + (int) ($j % 588 / 28)); + if ($j %= 28) { + $uchr .= $j < 25 ? "\xe1\x86" . \chr(0xa7 + $j) : "\xe1\x87" . \chr(0x67 + $j); + } + } + if ($c) { + \ksort($c); + $result .= \implode('', $c); + $c = []; + } + $result .= $uchr; + } + if ($c) { + \ksort($c); + $result .= \implode('', $c); + } + return $result; + } + private static function getData($file) + { + if (\file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) { + return require $file; + } + return \false; + } +} diff --git a/vendor/symfony/polyfill-intl-normalizer/README.md b/vendor/symfony/polyfill-intl-normalizer/README.md new file mode 100644 index 0000000000..b9b762e850 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/README.md @@ -0,0 +1,14 @@ +Symfony Polyfill / Intl: Normalizer +=================================== + +This component provides a fallback implementation for the +[`Normalizer`](https://php.net/Normalizer) class provided +by the [Intl](https://php.net/intl) extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php b/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php new file mode 100644 index 0000000000..0fdfc890a2 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php @@ -0,0 +1,17 @@ + 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', 'Ç' => 'Ç', 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'ç' => 'ç', 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'ÿ' => 'ÿ', 'Ā' => 'Ā', 'ā' => 'ā', 'Ă' => 'Ă', 'ă' => 'ă', 'Ą' => 'Ą', 'ą' => 'ą', 'Ć' => 'Ć', 'ć' => 'ć', 'Ĉ' => 'Ĉ', 'ĉ' => 'ĉ', 'Ċ' => 'Ċ', 'ċ' => 'ċ', 'Č' => 'Č', 'č' => 'č', 'Ď' => 'Ď', 'ď' => 'ď', 'Ē' => 'Ē', 'ē' => 'ē', 'Ĕ' => 'Ĕ', 'ĕ' => 'ĕ', 'Ė' => 'Ė', 'ė' => 'ė', 'Ę' => 'Ę', 'ę' => 'ę', 'Ě' => 'Ě', 'ě' => 'ě', 'Ĝ' => 'Ĝ', 'ĝ' => 'ĝ', 'Ğ' => 'Ğ', 'ğ' => 'ğ', 'Ġ' => 'Ġ', 'ġ' => 'ġ', 'Ģ' => 'Ģ', 'ģ' => 'ģ', 'Ĥ' => 'Ĥ', 'ĥ' => 'ĥ', 'Ĩ' => 'Ĩ', 'ĩ' => 'ĩ', 'Ī' => 'Ī', 'ī' => 'ī', 'Ĭ' => 'Ĭ', 'ĭ' => 'ĭ', 'Į' => 'Į', 'į' => 'į', 'İ' => 'İ', 'Ĵ' => 'Ĵ', 'ĵ' => 'ĵ', 'Ķ' => 'Ķ', 'ķ' => 'ķ', 'Ĺ' => 'Ĺ', 'ĺ' => 'ĺ', 'Ļ' => 'Ļ', 'ļ' => 'ļ', 'Ľ' => 'Ľ', 'ľ' => 'ľ', 'Ń' => 'Ń', 'ń' => 'ń', 'Ņ' => 'Ņ', 'ņ' => 'ņ', 'Ň' => 'Ň', 'ň' => 'ň', 'Ō' => 'Ō', 'ō' => 'ō', 'Ŏ' => 'Ŏ', 'ŏ' => 'ŏ', 'Ő' => 'Ő', 'ő' => 'ő', 'Ŕ' => 'Ŕ', 'ŕ' => 'ŕ', 'Ŗ' => 'Ŗ', 'ŗ' => 'ŗ', 'Ř' => 'Ř', 'ř' => 'ř', 'Ś' => 'Ś', 'ś' => 'ś', 'Ŝ' => 'Ŝ', 'ŝ' => 'ŝ', 'Ş' => 'Ş', 'ş' => 'ş', 'Š' => 'Š', 'š' => 'š', 'Ţ' => 'Ţ', 'ţ' => 'ţ', 'Ť' => 'Ť', 'ť' => 'ť', 'Ũ' => 'Ũ', 'ũ' => 'ũ', 'Ū' => 'Ū', 'ū' => 'ū', 'Ŭ' => 'Ŭ', 'ŭ' => 'ŭ', 'Ů' => 'Ů', 'ů' => 'ů', 'Ű' => 'Ű', 'ű' => 'ű', 'Ų' => 'Ų', 'ų' => 'ų', 'Ŵ' => 'Ŵ', 'ŵ' => 'ŵ', 'Ŷ' => 'Ŷ', 'ŷ' => 'ŷ', 'Ÿ' => 'Ÿ', 'Ź' => 'Ź', 'ź' => 'ź', 'Ż' => 'Ż', 'ż' => 'ż', 'Ž' => 'Ž', 'ž' => 'ž', 'Ơ' => 'Ơ', 'ơ' => 'ơ', 'Ư' => 'Ư', 'ư' => 'ư', 'Ǎ' => 'Ǎ', 'ǎ' => 'ǎ', 'Ǐ' => 'Ǐ', 'ǐ' => 'ǐ', 'Ǒ' => 'Ǒ', 'ǒ' => 'ǒ', 'Ǔ' => 'Ǔ', 'ǔ' => 'ǔ', 'Ǖ' => 'Ǖ', 'ǖ' => 'ǖ', 'Ǘ' => 'Ǘ', 'ǘ' => 'ǘ', 'Ǚ' => 'Ǚ', 'ǚ' => 'ǚ', 'Ǜ' => 'Ǜ', 'ǜ' => 'ǜ', 'Ǟ' => 'Ǟ', 'ǟ' => 'ǟ', 'Ǡ' => 'Ǡ', 'ǡ' => 'ǡ', 'Ǣ' => 'Ǣ', 'ǣ' => 'ǣ', 'Ǧ' => 'Ǧ', 'ǧ' => 'ǧ', 'Ǩ' => 'Ǩ', 'ǩ' => 'ǩ', 'Ǫ' => 'Ǫ', 'ǫ' => 'ǫ', 'Ǭ' => 'Ǭ', 'ǭ' => 'ǭ', 'Ǯ' => 'Ǯ', 'ǯ' => 'ǯ', 'ǰ' => 'ǰ', 'Ǵ' => 'Ǵ', 'ǵ' => 'ǵ', 'Ǹ' => 'Ǹ', 'ǹ' => 'ǹ', 'Ǻ' => 'Ǻ', 'ǻ' => 'ǻ', 'Ǽ' => 'Ǽ', 'ǽ' => 'ǽ', 'Ǿ' => 'Ǿ', 'ǿ' => 'ǿ', 'Ȁ' => 'Ȁ', 'ȁ' => 'ȁ', 'Ȃ' => 'Ȃ', 'ȃ' => 'ȃ', 'Ȅ' => 'Ȅ', 'ȅ' => 'ȅ', 'Ȇ' => 'Ȇ', 'ȇ' => 'ȇ', 'Ȉ' => 'Ȉ', 'ȉ' => 'ȉ', 'Ȋ' => 'Ȋ', 'ȋ' => 'ȋ', 'Ȍ' => 'Ȍ', 'ȍ' => 'ȍ', 'Ȏ' => 'Ȏ', 'ȏ' => 'ȏ', 'Ȑ' => 'Ȑ', 'ȑ' => 'ȑ', 'Ȓ' => 'Ȓ', 'ȓ' => 'ȓ', 'Ȕ' => 'Ȕ', 'ȕ' => 'ȕ', 'Ȗ' => 'Ȗ', 'ȗ' => 'ȗ', 'Ș' => 'Ș', 'ș' => 'ș', 'Ț' => 'Ț', 'ț' => 'ț', 'Ȟ' => 'Ȟ', 'ȟ' => 'ȟ', 'Ȧ' => 'Ȧ', 'ȧ' => 'ȧ', 'Ȩ' => 'Ȩ', 'ȩ' => 'ȩ', 'Ȫ' => 'Ȫ', 'ȫ' => 'ȫ', 'Ȭ' => 'Ȭ', 'ȭ' => 'ȭ', 'Ȯ' => 'Ȯ', 'ȯ' => 'ȯ', 'Ȱ' => 'Ȱ', 'ȱ' => 'ȱ', 'Ȳ' => 'Ȳ', 'ȳ' => 'ȳ', '΅' => '΅', 'Ά' => 'Ά', 'Έ' => 'Έ', 'Ή' => 'Ή', 'Ί' => 'Ί', 'Ό' => 'Ό', 'Ύ' => 'Ύ', 'Ώ' => 'Ώ', 'ΐ' => 'ΐ', 'Ϊ' => 'Ϊ', 'Ϋ' => 'Ϋ', 'ά' => 'ά', 'έ' => 'έ', 'ή' => 'ή', 'ί' => 'ί', 'ΰ' => 'ΰ', 'ϊ' => 'ϊ', 'ϋ' => 'ϋ', 'ό' => 'ό', 'ύ' => 'ύ', 'ώ' => 'ώ', 'ϓ' => 'ϓ', 'ϔ' => 'ϔ', 'Ѐ' => 'Ѐ', 'Ё' => 'Ё', 'Ѓ' => 'Ѓ', 'Ї' => 'Ї', 'Ќ' => 'Ќ', 'Ѝ' => 'Ѝ', 'Ў' => 'Ў', 'Й' => 'Й', 'й' => 'й', 'ѐ' => 'ѐ', 'ё' => 'ё', 'ѓ' => 'ѓ', 'ї' => 'ї', 'ќ' => 'ќ', 'ѝ' => 'ѝ', 'ў' => 'ў', 'Ѷ' => 'Ѷ', 'ѷ' => 'ѷ', 'Ӂ' => 'Ӂ', 'ӂ' => 'ӂ', 'Ӑ' => 'Ӑ', 'ӑ' => 'ӑ', 'Ӓ' => 'Ӓ', 'ӓ' => 'ӓ', 'Ӗ' => 'Ӗ', 'ӗ' => 'ӗ', 'Ӛ' => 'Ӛ', 'ӛ' => 'ӛ', 'Ӝ' => 'Ӝ', 'ӝ' => 'ӝ', 'Ӟ' => 'Ӟ', 'ӟ' => 'ӟ', 'Ӣ' => 'Ӣ', 'ӣ' => 'ӣ', 'Ӥ' => 'Ӥ', 'ӥ' => 'ӥ', 'Ӧ' => 'Ӧ', 'ӧ' => 'ӧ', 'Ӫ' => 'Ӫ', 'ӫ' => 'ӫ', 'Ӭ' => 'Ӭ', 'ӭ' => 'ӭ', 'Ӯ' => 'Ӯ', 'ӯ' => 'ӯ', 'Ӱ' => 'Ӱ', 'ӱ' => 'ӱ', 'Ӳ' => 'Ӳ', 'ӳ' => 'ӳ', 'Ӵ' => 'Ӵ', 'ӵ' => 'ӵ', 'Ӹ' => 'Ӹ', 'ӹ' => 'ӹ', 'آ' => 'آ', 'أ' => 'أ', 'ؤ' => 'ؤ', 'إ' => 'إ', 'ئ' => 'ئ', 'ۀ' => 'ۀ', 'ۂ' => 'ۂ', 'ۓ' => 'ۓ', 'ऩ' => 'ऩ', 'ऱ' => 'ऱ', 'ऴ' => 'ऴ', 'ো' => 'ো', 'ৌ' => 'ৌ', 'ୈ' => 'ୈ', 'ୋ' => 'ୋ', 'ୌ' => 'ୌ', 'ஔ' => 'ஔ', 'ொ' => 'ொ', 'ோ' => 'ோ', 'ௌ' => 'ௌ', 'ై' => 'ై', 'ೀ' => 'ೀ', 'ೇ' => 'ೇ', 'ೈ' => 'ೈ', 'ೊ' => 'ೊ', 'ೋ' => 'ೋ', 'ൊ' => 'ൊ', 'ോ' => 'ോ', 'ൌ' => 'ൌ', 'ේ' => 'ේ', 'ො' => 'ො', 'ෝ' => 'ෝ', 'ෞ' => 'ෞ', 'ဦ' => 'ဦ', 'ᬆ' => 'ᬆ', 'ᬈ' => 'ᬈ', 'ᬊ' => 'ᬊ', 'ᬌ' => 'ᬌ', 'ᬎ' => 'ᬎ', 'ᬒ' => 'ᬒ', 'ᬻ' => 'ᬻ', 'ᬽ' => 'ᬽ', 'ᭀ' => 'ᭀ', 'ᭁ' => 'ᭁ', 'ᭃ' => 'ᭃ', 'Ḁ' => 'Ḁ', 'ḁ' => 'ḁ', 'Ḃ' => 'Ḃ', 'ḃ' => 'ḃ', 'Ḅ' => 'Ḅ', 'ḅ' => 'ḅ', 'Ḇ' => 'Ḇ', 'ḇ' => 'ḇ', 'Ḉ' => 'Ḉ', 'ḉ' => 'ḉ', 'Ḋ' => 'Ḋ', 'ḋ' => 'ḋ', 'Ḍ' => 'Ḍ', 'ḍ' => 'ḍ', 'Ḏ' => 'Ḏ', 'ḏ' => 'ḏ', 'Ḑ' => 'Ḑ', 'ḑ' => 'ḑ', 'Ḓ' => 'Ḓ', 'ḓ' => 'ḓ', 'Ḕ' => 'Ḕ', 'ḕ' => 'ḕ', 'Ḗ' => 'Ḗ', 'ḗ' => 'ḗ', 'Ḙ' => 'Ḙ', 'ḙ' => 'ḙ', 'Ḛ' => 'Ḛ', 'ḛ' => 'ḛ', 'Ḝ' => 'Ḝ', 'ḝ' => 'ḝ', 'Ḟ' => 'Ḟ', 'ḟ' => 'ḟ', 'Ḡ' => 'Ḡ', 'ḡ' => 'ḡ', 'Ḣ' => 'Ḣ', 'ḣ' => 'ḣ', 'Ḥ' => 'Ḥ', 'ḥ' => 'ḥ', 'Ḧ' => 'Ḧ', 'ḧ' => 'ḧ', 'Ḩ' => 'Ḩ', 'ḩ' => 'ḩ', 'Ḫ' => 'Ḫ', 'ḫ' => 'ḫ', 'Ḭ' => 'Ḭ', 'ḭ' => 'ḭ', 'Ḯ' => 'Ḯ', 'ḯ' => 'ḯ', 'Ḱ' => 'Ḱ', 'ḱ' => 'ḱ', 'Ḳ' => 'Ḳ', 'ḳ' => 'ḳ', 'Ḵ' => 'Ḵ', 'ḵ' => 'ḵ', 'Ḷ' => 'Ḷ', 'ḷ' => 'ḷ', 'Ḹ' => 'Ḹ', 'ḹ' => 'ḹ', 'Ḻ' => 'Ḻ', 'ḻ' => 'ḻ', 'Ḽ' => 'Ḽ', 'ḽ' => 'ḽ', 'Ḿ' => 'Ḿ', 'ḿ' => 'ḿ', 'Ṁ' => 'Ṁ', 'ṁ' => 'ṁ', 'Ṃ' => 'Ṃ', 'ṃ' => 'ṃ', 'Ṅ' => 'Ṅ', 'ṅ' => 'ṅ', 'Ṇ' => 'Ṇ', 'ṇ' => 'ṇ', 'Ṉ' => 'Ṉ', 'ṉ' => 'ṉ', 'Ṋ' => 'Ṋ', 'ṋ' => 'ṋ', 'Ṍ' => 'Ṍ', 'ṍ' => 'ṍ', 'Ṏ' => 'Ṏ', 'ṏ' => 'ṏ', 'Ṑ' => 'Ṑ', 'ṑ' => 'ṑ', 'Ṓ' => 'Ṓ', 'ṓ' => 'ṓ', 'Ṕ' => 'Ṕ', 'ṕ' => 'ṕ', 'Ṗ' => 'Ṗ', 'ṗ' => 'ṗ', 'Ṙ' => 'Ṙ', 'ṙ' => 'ṙ', 'Ṛ' => 'Ṛ', 'ṛ' => 'ṛ', 'Ṝ' => 'Ṝ', 'ṝ' => 'ṝ', 'Ṟ' => 'Ṟ', 'ṟ' => 'ṟ', 'Ṡ' => 'Ṡ', 'ṡ' => 'ṡ', 'Ṣ' => 'Ṣ', 'ṣ' => 'ṣ', 'Ṥ' => 'Ṥ', 'ṥ' => 'ṥ', 'Ṧ' => 'Ṧ', 'ṧ' => 'ṧ', 'Ṩ' => 'Ṩ', 'ṩ' => 'ṩ', 'Ṫ' => 'Ṫ', 'ṫ' => 'ṫ', 'Ṭ' => 'Ṭ', 'ṭ' => 'ṭ', 'Ṯ' => 'Ṯ', 'ṯ' => 'ṯ', 'Ṱ' => 'Ṱ', 'ṱ' => 'ṱ', 'Ṳ' => 'Ṳ', 'ṳ' => 'ṳ', 'Ṵ' => 'Ṵ', 'ṵ' => 'ṵ', 'Ṷ' => 'Ṷ', 'ṷ' => 'ṷ', 'Ṹ' => 'Ṹ', 'ṹ' => 'ṹ', 'Ṻ' => 'Ṻ', 'ṻ' => 'ṻ', 'Ṽ' => 'Ṽ', 'ṽ' => 'ṽ', 'Ṿ' => 'Ṿ', 'ṿ' => 'ṿ', 'Ẁ' => 'Ẁ', 'ẁ' => 'ẁ', 'Ẃ' => 'Ẃ', 'ẃ' => 'ẃ', 'Ẅ' => 'Ẅ', 'ẅ' => 'ẅ', 'Ẇ' => 'Ẇ', 'ẇ' => 'ẇ', 'Ẉ' => 'Ẉ', 'ẉ' => 'ẉ', 'Ẋ' => 'Ẋ', 'ẋ' => 'ẋ', 'Ẍ' => 'Ẍ', 'ẍ' => 'ẍ', 'Ẏ' => 'Ẏ', 'ẏ' => 'ẏ', 'Ẑ' => 'Ẑ', 'ẑ' => 'ẑ', 'Ẓ' => 'Ẓ', 'ẓ' => 'ẓ', 'Ẕ' => 'Ẕ', 'ẕ' => 'ẕ', 'ẖ' => 'ẖ', 'ẗ' => 'ẗ', 'ẘ' => 'ẘ', 'ẙ' => 'ẙ', 'ẛ' => 'ẛ', 'Ạ' => 'Ạ', 'ạ' => 'ạ', 'Ả' => 'Ả', 'ả' => 'ả', 'Ấ' => 'Ấ', 'ấ' => 'ấ', 'Ầ' => 'Ầ', 'ầ' => 'ầ', 'Ẩ' => 'Ẩ', 'ẩ' => 'ẩ', 'Ẫ' => 'Ẫ', 'ẫ' => 'ẫ', 'Ậ' => 'Ậ', 'ậ' => 'ậ', 'Ắ' => 'Ắ', 'ắ' => 'ắ', 'Ằ' => 'Ằ', 'ằ' => 'ằ', 'Ẳ' => 'Ẳ', 'ẳ' => 'ẳ', 'Ẵ' => 'Ẵ', 'ẵ' => 'ẵ', 'Ặ' => 'Ặ', 'ặ' => 'ặ', 'Ẹ' => 'Ẹ', 'ẹ' => 'ẹ', 'Ẻ' => 'Ẻ', 'ẻ' => 'ẻ', 'Ẽ' => 'Ẽ', 'ẽ' => 'ẽ', 'Ế' => 'Ế', 'ế' => 'ế', 'Ề' => 'Ề', 'ề' => 'ề', 'Ể' => 'Ể', 'ể' => 'ể', 'Ễ' => 'Ễ', 'ễ' => 'ễ', 'Ệ' => 'Ệ', 'ệ' => 'ệ', 'Ỉ' => 'Ỉ', 'ỉ' => 'ỉ', 'Ị' => 'Ị', 'ị' => 'ị', 'Ọ' => 'Ọ', 'ọ' => 'ọ', 'Ỏ' => 'Ỏ', 'ỏ' => 'ỏ', 'Ố' => 'Ố', 'ố' => 'ố', 'Ồ' => 'Ồ', 'ồ' => 'ồ', 'Ổ' => 'Ổ', 'ổ' => 'ổ', 'Ỗ' => 'Ỗ', 'ỗ' => 'ỗ', 'Ộ' => 'Ộ', 'ộ' => 'ộ', 'Ớ' => 'Ớ', 'ớ' => 'ớ', 'Ờ' => 'Ờ', 'ờ' => 'ờ', 'Ở' => 'Ở', 'ở' => 'ở', 'Ỡ' => 'Ỡ', 'ỡ' => 'ỡ', 'Ợ' => 'Ợ', 'ợ' => 'ợ', 'Ụ' => 'Ụ', 'ụ' => 'ụ', 'Ủ' => 'Ủ', 'ủ' => 'ủ', 'Ứ' => 'Ứ', 'ứ' => 'ứ', 'Ừ' => 'Ừ', 'ừ' => 'ừ', 'Ử' => 'Ử', 'ử' => 'ử', 'Ữ' => 'Ữ', 'ữ' => 'ữ', 'Ự' => 'Ự', 'ự' => 'ự', 'Ỳ' => 'Ỳ', 'ỳ' => 'ỳ', 'Ỵ' => 'Ỵ', 'ỵ' => 'ỵ', 'Ỷ' => 'Ỷ', 'ỷ' => 'ỷ', 'Ỹ' => 'Ỹ', 'ỹ' => 'ỹ', 'ἀ' => 'ἀ', 'ἁ' => 'ἁ', 'ἂ' => 'ἂ', 'ἃ' => 'ἃ', 'ἄ' => 'ἄ', 'ἅ' => 'ἅ', 'ἆ' => 'ἆ', 'ἇ' => 'ἇ', 'Ἀ' => 'Ἀ', 'Ἁ' => 'Ἁ', 'Ἂ' => 'Ἂ', 'Ἃ' => 'Ἃ', 'Ἄ' => 'Ἄ', 'Ἅ' => 'Ἅ', 'Ἆ' => 'Ἆ', 'Ἇ' => 'Ἇ', 'ἐ' => 'ἐ', 'ἑ' => 'ἑ', 'ἒ' => 'ἒ', 'ἓ' => 'ἓ', 'ἔ' => 'ἔ', 'ἕ' => 'ἕ', 'Ἐ' => 'Ἐ', 'Ἑ' => 'Ἑ', 'Ἒ' => 'Ἒ', 'Ἓ' => 'Ἓ', 'Ἔ' => 'Ἔ', 'Ἕ' => 'Ἕ', 'ἠ' => 'ἠ', 'ἡ' => 'ἡ', 'ἢ' => 'ἢ', 'ἣ' => 'ἣ', 'ἤ' => 'ἤ', 'ἥ' => 'ἥ', 'ἦ' => 'ἦ', 'ἧ' => 'ἧ', 'Ἠ' => 'Ἠ', 'Ἡ' => 'Ἡ', 'Ἢ' => 'Ἢ', 'Ἣ' => 'Ἣ', 'Ἤ' => 'Ἤ', 'Ἥ' => 'Ἥ', 'Ἦ' => 'Ἦ', 'Ἧ' => 'Ἧ', 'ἰ' => 'ἰ', 'ἱ' => 'ἱ', 'ἲ' => 'ἲ', 'ἳ' => 'ἳ', 'ἴ' => 'ἴ', 'ἵ' => 'ἵ', 'ἶ' => 'ἶ', 'ἷ' => 'ἷ', 'Ἰ' => 'Ἰ', 'Ἱ' => 'Ἱ', 'Ἲ' => 'Ἲ', 'Ἳ' => 'Ἳ', 'Ἴ' => 'Ἴ', 'Ἵ' => 'Ἵ', 'Ἶ' => 'Ἶ', 'Ἷ' => 'Ἷ', 'ὀ' => 'ὀ', 'ὁ' => 'ὁ', 'ὂ' => 'ὂ', 'ὃ' => 'ὃ', 'ὄ' => 'ὄ', 'ὅ' => 'ὅ', 'Ὀ' => 'Ὀ', 'Ὁ' => 'Ὁ', 'Ὂ' => 'Ὂ', 'Ὃ' => 'Ὃ', 'Ὄ' => 'Ὄ', 'Ὅ' => 'Ὅ', 'ὐ' => 'ὐ', 'ὑ' => 'ὑ', 'ὒ' => 'ὒ', 'ὓ' => 'ὓ', 'ὔ' => 'ὔ', 'ὕ' => 'ὕ', 'ὖ' => 'ὖ', 'ὗ' => 'ὗ', 'Ὑ' => 'Ὑ', 'Ὓ' => 'Ὓ', 'Ὕ' => 'Ὕ', 'Ὗ' => 'Ὗ', 'ὠ' => 'ὠ', 'ὡ' => 'ὡ', 'ὢ' => 'ὢ', 'ὣ' => 'ὣ', 'ὤ' => 'ὤ', 'ὥ' => 'ὥ', 'ὦ' => 'ὦ', 'ὧ' => 'ὧ', 'Ὠ' => 'Ὠ', 'Ὡ' => 'Ὡ', 'Ὢ' => 'Ὢ', 'Ὣ' => 'Ὣ', 'Ὤ' => 'Ὤ', 'Ὥ' => 'Ὥ', 'Ὦ' => 'Ὦ', 'Ὧ' => 'Ὧ', 'ὰ' => 'ὰ', 'ὲ' => 'ὲ', 'ὴ' => 'ὴ', 'ὶ' => 'ὶ', 'ὸ' => 'ὸ', 'ὺ' => 'ὺ', 'ὼ' => 'ὼ', 'ᾀ' => 'ᾀ', 'ᾁ' => 'ᾁ', 'ᾂ' => 'ᾂ', 'ᾃ' => 'ᾃ', 'ᾄ' => 'ᾄ', 'ᾅ' => 'ᾅ', 'ᾆ' => 'ᾆ', 'ᾇ' => 'ᾇ', 'ᾈ' => 'ᾈ', 'ᾉ' => 'ᾉ', 'ᾊ' => 'ᾊ', 'ᾋ' => 'ᾋ', 'ᾌ' => 'ᾌ', 'ᾍ' => 'ᾍ', 'ᾎ' => 'ᾎ', 'ᾏ' => 'ᾏ', 'ᾐ' => 'ᾐ', 'ᾑ' => 'ᾑ', 'ᾒ' => 'ᾒ', 'ᾓ' => 'ᾓ', 'ᾔ' => 'ᾔ', 'ᾕ' => 'ᾕ', 'ᾖ' => 'ᾖ', 'ᾗ' => 'ᾗ', 'ᾘ' => 'ᾘ', 'ᾙ' => 'ᾙ', 'ᾚ' => 'ᾚ', 'ᾛ' => 'ᾛ', 'ᾜ' => 'ᾜ', 'ᾝ' => 'ᾝ', 'ᾞ' => 'ᾞ', 'ᾟ' => 'ᾟ', 'ᾠ' => 'ᾠ', 'ᾡ' => 'ᾡ', 'ᾢ' => 'ᾢ', 'ᾣ' => 'ᾣ', 'ᾤ' => 'ᾤ', 'ᾥ' => 'ᾥ', 'ᾦ' => 'ᾦ', 'ᾧ' => 'ᾧ', 'ᾨ' => 'ᾨ', 'ᾩ' => 'ᾩ', 'ᾪ' => 'ᾪ', 'ᾫ' => 'ᾫ', 'ᾬ' => 'ᾬ', 'ᾭ' => 'ᾭ', 'ᾮ' => 'ᾮ', 'ᾯ' => 'ᾯ', 'ᾰ' => 'ᾰ', 'ᾱ' => 'ᾱ', 'ᾲ' => 'ᾲ', 'ᾳ' => 'ᾳ', 'ᾴ' => 'ᾴ', 'ᾶ' => 'ᾶ', 'ᾷ' => 'ᾷ', 'Ᾰ' => 'Ᾰ', 'Ᾱ' => 'Ᾱ', 'Ὰ' => 'Ὰ', 'ᾼ' => 'ᾼ', '῁' => '῁', 'ῂ' => 'ῂ', 'ῃ' => 'ῃ', 'ῄ' => 'ῄ', 'ῆ' => 'ῆ', 'ῇ' => 'ῇ', 'Ὲ' => 'Ὲ', 'Ὴ' => 'Ὴ', 'ῌ' => 'ῌ', '῍' => '῍', '῎' => '῎', '῏' => '῏', 'ῐ' => 'ῐ', 'ῑ' => 'ῑ', 'ῒ' => 'ῒ', 'ῖ' => 'ῖ', 'ῗ' => 'ῗ', 'Ῐ' => 'Ῐ', 'Ῑ' => 'Ῑ', 'Ὶ' => 'Ὶ', '῝' => '῝', '῞' => '῞', '῟' => '῟', 'ῠ' => 'ῠ', 'ῡ' => 'ῡ', 'ῢ' => 'ῢ', 'ῤ' => 'ῤ', 'ῥ' => 'ῥ', 'ῦ' => 'ῦ', 'ῧ' => 'ῧ', 'Ῠ' => 'Ῠ', 'Ῡ' => 'Ῡ', 'Ὺ' => 'Ὺ', 'Ῥ' => 'Ῥ', '῭' => '῭', 'ῲ' => 'ῲ', 'ῳ' => 'ῳ', 'ῴ' => 'ῴ', 'ῶ' => 'ῶ', 'ῷ' => 'ῷ', 'Ὸ' => 'Ὸ', 'Ὼ' => 'Ὼ', 'ῼ' => 'ῼ', '↚' => '↚', '↛' => '↛', '↮' => '↮', '⇍' => '⇍', '⇎' => '⇎', '⇏' => '⇏', '∄' => '∄', '∉' => '∉', '∌' => '∌', '∤' => '∤', '∦' => '∦', '≁' => '≁', '≄' => '≄', '≇' => '≇', '≉' => '≉', '≠' => '≠', '≢' => '≢', '≭' => '≭', '≮' => '≮', '≯' => '≯', '≰' => '≰', '≱' => '≱', '≴' => '≴', '≵' => '≵', '≸' => '≸', '≹' => '≹', '⊀' => '⊀', '⊁' => '⊁', '⊄' => '⊄', '⊅' => '⊅', '⊈' => '⊈', '⊉' => '⊉', '⊬' => '⊬', '⊭' => '⊭', '⊮' => '⊮', '⊯' => '⊯', '⋠' => '⋠', '⋡' => '⋡', '⋢' => '⋢', '⋣' => '⋣', '⋪' => '⋪', '⋫' => '⋫', '⋬' => '⋬', '⋭' => '⋭', 'が' => 'が', 'ぎ' => 'ぎ', 'ぐ' => 'ぐ', 'げ' => 'げ', 'ご' => 'ご', 'ざ' => 'ざ', 'じ' => 'じ', 'ず' => 'ず', 'ぜ' => 'ぜ', 'ぞ' => 'ぞ', 'だ' => 'だ', 'ぢ' => 'ぢ', 'づ' => 'づ', 'で' => 'で', 'ど' => 'ど', 'ば' => 'ば', 'ぱ' => 'ぱ', 'び' => 'び', 'ぴ' => 'ぴ', 'ぶ' => 'ぶ', 'ぷ' => 'ぷ', 'べ' => 'べ', 'ぺ' => 'ぺ', 'ぼ' => 'ぼ', 'ぽ' => 'ぽ', 'ゔ' => 'ゔ', 'ゞ' => 'ゞ', 'ガ' => 'ガ', 'ギ' => 'ギ', 'グ' => 'グ', 'ゲ' => 'ゲ', 'ゴ' => 'ゴ', 'ザ' => 'ザ', 'ジ' => 'ジ', 'ズ' => 'ズ', 'ゼ' => 'ゼ', 'ゾ' => 'ゾ', 'ダ' => 'ダ', 'ヂ' => 'ヂ', 'ヅ' => 'ヅ', 'デ' => 'デ', 'ド' => 'ド', 'バ' => 'バ', 'パ' => 'パ', 'ビ' => 'ビ', 'ピ' => 'ピ', 'ブ' => 'ブ', 'プ' => 'プ', 'ベ' => 'ベ', 'ペ' => 'ペ', 'ボ' => 'ボ', 'ポ' => 'ポ', 'ヴ' => 'ヴ', 'ヷ' => 'ヷ', 'ヸ' => 'ヸ', 'ヹ' => 'ヹ', 'ヺ' => 'ヺ', 'ヾ' => 'ヾ', '𑂚' => '𑂚', '𑂜' => '𑂜', '𑂫' => '𑂫', '𑄮' => '𑄮', '𑄯' => '𑄯', '𑍋' => '𑍋', '𑍌' => '𑍌', '𑒻' => '𑒻', '𑒼' => '𑒼', '𑒾' => '𑒾', '𑖺' => '𑖺', '𑖻' => '𑖻', '𑤸' => '𑤸'); diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php new file mode 100644 index 0000000000..76df5e54e4 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php @@ -0,0 +1,5 @@ + 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', 'Ç' => 'Ç', 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'ç' => 'ç', 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'ÿ' => 'ÿ', 'Ā' => 'Ā', 'ā' => 'ā', 'Ă' => 'Ă', 'ă' => 'ă', 'Ą' => 'Ą', 'ą' => 'ą', 'Ć' => 'Ć', 'ć' => 'ć', 'Ĉ' => 'Ĉ', 'ĉ' => 'ĉ', 'Ċ' => 'Ċ', 'ċ' => 'ċ', 'Č' => 'Č', 'č' => 'č', 'Ď' => 'Ď', 'ď' => 'ď', 'Ē' => 'Ē', 'ē' => 'ē', 'Ĕ' => 'Ĕ', 'ĕ' => 'ĕ', 'Ė' => 'Ė', 'ė' => 'ė', 'Ę' => 'Ę', 'ę' => 'ę', 'Ě' => 'Ě', 'ě' => 'ě', 'Ĝ' => 'Ĝ', 'ĝ' => 'ĝ', 'Ğ' => 'Ğ', 'ğ' => 'ğ', 'Ġ' => 'Ġ', 'ġ' => 'ġ', 'Ģ' => 'Ģ', 'ģ' => 'ģ', 'Ĥ' => 'Ĥ', 'ĥ' => 'ĥ', 'Ĩ' => 'Ĩ', 'ĩ' => 'ĩ', 'Ī' => 'Ī', 'ī' => 'ī', 'Ĭ' => 'Ĭ', 'ĭ' => 'ĭ', 'Į' => 'Į', 'į' => 'į', 'İ' => 'İ', 'Ĵ' => 'Ĵ', 'ĵ' => 'ĵ', 'Ķ' => 'Ķ', 'ķ' => 'ķ', 'Ĺ' => 'Ĺ', 'ĺ' => 'ĺ', 'Ļ' => 'Ļ', 'ļ' => 'ļ', 'Ľ' => 'Ľ', 'ľ' => 'ľ', 'Ń' => 'Ń', 'ń' => 'ń', 'Ņ' => 'Ņ', 'ņ' => 'ņ', 'Ň' => 'Ň', 'ň' => 'ň', 'Ō' => 'Ō', 'ō' => 'ō', 'Ŏ' => 'Ŏ', 'ŏ' => 'ŏ', 'Ő' => 'Ő', 'ő' => 'ő', 'Ŕ' => 'Ŕ', 'ŕ' => 'ŕ', 'Ŗ' => 'Ŗ', 'ŗ' => 'ŗ', 'Ř' => 'Ř', 'ř' => 'ř', 'Ś' => 'Ś', 'ś' => 'ś', 'Ŝ' => 'Ŝ', 'ŝ' => 'ŝ', 'Ş' => 'Ş', 'ş' => 'ş', 'Š' => 'Š', 'š' => 'š', 'Ţ' => 'Ţ', 'ţ' => 'ţ', 'Ť' => 'Ť', 'ť' => 'ť', 'Ũ' => 'Ũ', 'ũ' => 'ũ', 'Ū' => 'Ū', 'ū' => 'ū', 'Ŭ' => 'Ŭ', 'ŭ' => 'ŭ', 'Ů' => 'Ů', 'ů' => 'ů', 'Ű' => 'Ű', 'ű' => 'ű', 'Ų' => 'Ų', 'ų' => 'ų', 'Ŵ' => 'Ŵ', 'ŵ' => 'ŵ', 'Ŷ' => 'Ŷ', 'ŷ' => 'ŷ', 'Ÿ' => 'Ÿ', 'Ź' => 'Ź', 'ź' => 'ź', 'Ż' => 'Ż', 'ż' => 'ż', 'Ž' => 'Ž', 'ž' => 'ž', 'Ơ' => 'Ơ', 'ơ' => 'ơ', 'Ư' => 'Ư', 'ư' => 'ư', 'Ǎ' => 'Ǎ', 'ǎ' => 'ǎ', 'Ǐ' => 'Ǐ', 'ǐ' => 'ǐ', 'Ǒ' => 'Ǒ', 'ǒ' => 'ǒ', 'Ǔ' => 'Ǔ', 'ǔ' => 'ǔ', 'Ǖ' => 'Ǖ', 'ǖ' => 'ǖ', 'Ǘ' => 'Ǘ', 'ǘ' => 'ǘ', 'Ǚ' => 'Ǚ', 'ǚ' => 'ǚ', 'Ǜ' => 'Ǜ', 'ǜ' => 'ǜ', 'Ǟ' => 'Ǟ', 'ǟ' => 'ǟ', 'Ǡ' => 'Ǡ', 'ǡ' => 'ǡ', 'Ǣ' => 'Ǣ', 'ǣ' => 'ǣ', 'Ǧ' => 'Ǧ', 'ǧ' => 'ǧ', 'Ǩ' => 'Ǩ', 'ǩ' => 'ǩ', 'Ǫ' => 'Ǫ', 'ǫ' => 'ǫ', 'Ǭ' => 'Ǭ', 'ǭ' => 'ǭ', 'Ǯ' => 'Ǯ', 'ǯ' => 'ǯ', 'ǰ' => 'ǰ', 'Ǵ' => 'Ǵ', 'ǵ' => 'ǵ', 'Ǹ' => 'Ǹ', 'ǹ' => 'ǹ', 'Ǻ' => 'Ǻ', 'ǻ' => 'ǻ', 'Ǽ' => 'Ǽ', 'ǽ' => 'ǽ', 'Ǿ' => 'Ǿ', 'ǿ' => 'ǿ', 'Ȁ' => 'Ȁ', 'ȁ' => 'ȁ', 'Ȃ' => 'Ȃ', 'ȃ' => 'ȃ', 'Ȅ' => 'Ȅ', 'ȅ' => 'ȅ', 'Ȇ' => 'Ȇ', 'ȇ' => 'ȇ', 'Ȉ' => 'Ȉ', 'ȉ' => 'ȉ', 'Ȋ' => 'Ȋ', 'ȋ' => 'ȋ', 'Ȍ' => 'Ȍ', 'ȍ' => 'ȍ', 'Ȏ' => 'Ȏ', 'ȏ' => 'ȏ', 'Ȑ' => 'Ȑ', 'ȑ' => 'ȑ', 'Ȓ' => 'Ȓ', 'ȓ' => 'ȓ', 'Ȕ' => 'Ȕ', 'ȕ' => 'ȕ', 'Ȗ' => 'Ȗ', 'ȗ' => 'ȗ', 'Ș' => 'Ș', 'ș' => 'ș', 'Ț' => 'Ț', 'ț' => 'ț', 'Ȟ' => 'Ȟ', 'ȟ' => 'ȟ', 'Ȧ' => 'Ȧ', 'ȧ' => 'ȧ', 'Ȩ' => 'Ȩ', 'ȩ' => 'ȩ', 'Ȫ' => 'Ȫ', 'ȫ' => 'ȫ', 'Ȭ' => 'Ȭ', 'ȭ' => 'ȭ', 'Ȯ' => 'Ȯ', 'ȯ' => 'ȯ', 'Ȱ' => 'Ȱ', 'ȱ' => 'ȱ', 'Ȳ' => 'Ȳ', 'ȳ' => 'ȳ', '̀' => '̀', '́' => '́', '̓' => '̓', '̈́' => '̈́', 'ʹ' => 'ʹ', ';' => ';', '΅' => '΅', 'Ά' => 'Ά', '·' => '·', 'Έ' => 'Έ', 'Ή' => 'Ή', 'Ί' => 'Ί', 'Ό' => 'Ό', 'Ύ' => 'Ύ', 'Ώ' => 'Ώ', 'ΐ' => 'ΐ', 'Ϊ' => 'Ϊ', 'Ϋ' => 'Ϋ', 'ά' => 'ά', 'έ' => 'έ', 'ή' => 'ή', 'ί' => 'ί', 'ΰ' => 'ΰ', 'ϊ' => 'ϊ', 'ϋ' => 'ϋ', 'ό' => 'ό', 'ύ' => 'ύ', 'ώ' => 'ώ', 'ϓ' => 'ϓ', 'ϔ' => 'ϔ', 'Ѐ' => 'Ѐ', 'Ё' => 'Ё', 'Ѓ' => 'Ѓ', 'Ї' => 'Ї', 'Ќ' => 'Ќ', 'Ѝ' => 'Ѝ', 'Ў' => 'Ў', 'Й' => 'Й', 'й' => 'й', 'ѐ' => 'ѐ', 'ё' => 'ё', 'ѓ' => 'ѓ', 'ї' => 'ї', 'ќ' => 'ќ', 'ѝ' => 'ѝ', 'ў' => 'ў', 'Ѷ' => 'Ѷ', 'ѷ' => 'ѷ', 'Ӂ' => 'Ӂ', 'ӂ' => 'ӂ', 'Ӑ' => 'Ӑ', 'ӑ' => 'ӑ', 'Ӓ' => 'Ӓ', 'ӓ' => 'ӓ', 'Ӗ' => 'Ӗ', 'ӗ' => 'ӗ', 'Ӛ' => 'Ӛ', 'ӛ' => 'ӛ', 'Ӝ' => 'Ӝ', 'ӝ' => 'ӝ', 'Ӟ' => 'Ӟ', 'ӟ' => 'ӟ', 'Ӣ' => 'Ӣ', 'ӣ' => 'ӣ', 'Ӥ' => 'Ӥ', 'ӥ' => 'ӥ', 'Ӧ' => 'Ӧ', 'ӧ' => 'ӧ', 'Ӫ' => 'Ӫ', 'ӫ' => 'ӫ', 'Ӭ' => 'Ӭ', 'ӭ' => 'ӭ', 'Ӯ' => 'Ӯ', 'ӯ' => 'ӯ', 'Ӱ' => 'Ӱ', 'ӱ' => 'ӱ', 'Ӳ' => 'Ӳ', 'ӳ' => 'ӳ', 'Ӵ' => 'Ӵ', 'ӵ' => 'ӵ', 'Ӹ' => 'Ӹ', 'ӹ' => 'ӹ', 'آ' => 'آ', 'أ' => 'أ', 'ؤ' => 'ؤ', 'إ' => 'إ', 'ئ' => 'ئ', 'ۀ' => 'ۀ', 'ۂ' => 'ۂ', 'ۓ' => 'ۓ', 'ऩ' => 'ऩ', 'ऱ' => 'ऱ', 'ऴ' => 'ऴ', 'क़' => 'क़', 'ख़' => 'ख़', 'ग़' => 'ग़', 'ज़' => 'ज़', 'ड़' => 'ड़', 'ढ़' => 'ढ़', 'फ़' => 'फ़', 'य़' => 'य़', 'ো' => 'ো', 'ৌ' => 'ৌ', 'ড়' => 'ড়', 'ঢ়' => 'ঢ়', 'য়' => 'য়', 'ਲ਼' => 'ਲ਼', 'ਸ਼' => 'ਸ਼', 'ਖ਼' => 'ਖ਼', 'ਗ਼' => 'ਗ਼', 'ਜ਼' => 'ਜ਼', 'ਫ਼' => 'ਫ਼', 'ୈ' => 'ୈ', 'ୋ' => 'ୋ', 'ୌ' => 'ୌ', 'ଡ଼' => 'ଡ଼', 'ଢ଼' => 'ଢ଼', 'ஔ' => 'ஔ', 'ொ' => 'ொ', 'ோ' => 'ோ', 'ௌ' => 'ௌ', 'ై' => 'ై', 'ೀ' => 'ೀ', 'ೇ' => 'ೇ', 'ೈ' => 'ೈ', 'ೊ' => 'ೊ', 'ೋ' => 'ೋ', 'ൊ' => 'ൊ', 'ോ' => 'ോ', 'ൌ' => 'ൌ', 'ේ' => 'ේ', 'ො' => 'ො', 'ෝ' => 'ෝ', 'ෞ' => 'ෞ', 'གྷ' => 'གྷ', 'ཌྷ' => 'ཌྷ', 'དྷ' => 'དྷ', 'བྷ' => 'བྷ', 'ཛྷ' => 'ཛྷ', 'ཀྵ' => 'ཀྵ', 'ཱི' => 'ཱི', 'ཱུ' => 'ཱུ', 'ྲྀ' => 'ྲྀ', 'ླྀ' => 'ླྀ', 'ཱྀ' => 'ཱྀ', 'ྒྷ' => 'ྒྷ', 'ྜྷ' => 'ྜྷ', 'ྡྷ' => 'ྡྷ', 'ྦྷ' => 'ྦྷ', 'ྫྷ' => 'ྫྷ', 'ྐྵ' => 'ྐྵ', 'ဦ' => 'ဦ', 'ᬆ' => 'ᬆ', 'ᬈ' => 'ᬈ', 'ᬊ' => 'ᬊ', 'ᬌ' => 'ᬌ', 'ᬎ' => 'ᬎ', 'ᬒ' => 'ᬒ', 'ᬻ' => 'ᬻ', 'ᬽ' => 'ᬽ', 'ᭀ' => 'ᭀ', 'ᭁ' => 'ᭁ', 'ᭃ' => 'ᭃ', 'Ḁ' => 'Ḁ', 'ḁ' => 'ḁ', 'Ḃ' => 'Ḃ', 'ḃ' => 'ḃ', 'Ḅ' => 'Ḅ', 'ḅ' => 'ḅ', 'Ḇ' => 'Ḇ', 'ḇ' => 'ḇ', 'Ḉ' => 'Ḉ', 'ḉ' => 'ḉ', 'Ḋ' => 'Ḋ', 'ḋ' => 'ḋ', 'Ḍ' => 'Ḍ', 'ḍ' => 'ḍ', 'Ḏ' => 'Ḏ', 'ḏ' => 'ḏ', 'Ḑ' => 'Ḑ', 'ḑ' => 'ḑ', 'Ḓ' => 'Ḓ', 'ḓ' => 'ḓ', 'Ḕ' => 'Ḕ', 'ḕ' => 'ḕ', 'Ḗ' => 'Ḗ', 'ḗ' => 'ḗ', 'Ḙ' => 'Ḙ', 'ḙ' => 'ḙ', 'Ḛ' => 'Ḛ', 'ḛ' => 'ḛ', 'Ḝ' => 'Ḝ', 'ḝ' => 'ḝ', 'Ḟ' => 'Ḟ', 'ḟ' => 'ḟ', 'Ḡ' => 'Ḡ', 'ḡ' => 'ḡ', 'Ḣ' => 'Ḣ', 'ḣ' => 'ḣ', 'Ḥ' => 'Ḥ', 'ḥ' => 'ḥ', 'Ḧ' => 'Ḧ', 'ḧ' => 'ḧ', 'Ḩ' => 'Ḩ', 'ḩ' => 'ḩ', 'Ḫ' => 'Ḫ', 'ḫ' => 'ḫ', 'Ḭ' => 'Ḭ', 'ḭ' => 'ḭ', 'Ḯ' => 'Ḯ', 'ḯ' => 'ḯ', 'Ḱ' => 'Ḱ', 'ḱ' => 'ḱ', 'Ḳ' => 'Ḳ', 'ḳ' => 'ḳ', 'Ḵ' => 'Ḵ', 'ḵ' => 'ḵ', 'Ḷ' => 'Ḷ', 'ḷ' => 'ḷ', 'Ḹ' => 'Ḹ', 'ḹ' => 'ḹ', 'Ḻ' => 'Ḻ', 'ḻ' => 'ḻ', 'Ḽ' => 'Ḽ', 'ḽ' => 'ḽ', 'Ḿ' => 'Ḿ', 'ḿ' => 'ḿ', 'Ṁ' => 'Ṁ', 'ṁ' => 'ṁ', 'Ṃ' => 'Ṃ', 'ṃ' => 'ṃ', 'Ṅ' => 'Ṅ', 'ṅ' => 'ṅ', 'Ṇ' => 'Ṇ', 'ṇ' => 'ṇ', 'Ṉ' => 'Ṉ', 'ṉ' => 'ṉ', 'Ṋ' => 'Ṋ', 'ṋ' => 'ṋ', 'Ṍ' => 'Ṍ', 'ṍ' => 'ṍ', 'Ṏ' => 'Ṏ', 'ṏ' => 'ṏ', 'Ṑ' => 'Ṑ', 'ṑ' => 'ṑ', 'Ṓ' => 'Ṓ', 'ṓ' => 'ṓ', 'Ṕ' => 'Ṕ', 'ṕ' => 'ṕ', 'Ṗ' => 'Ṗ', 'ṗ' => 'ṗ', 'Ṙ' => 'Ṙ', 'ṙ' => 'ṙ', 'Ṛ' => 'Ṛ', 'ṛ' => 'ṛ', 'Ṝ' => 'Ṝ', 'ṝ' => 'ṝ', 'Ṟ' => 'Ṟ', 'ṟ' => 'ṟ', 'Ṡ' => 'Ṡ', 'ṡ' => 'ṡ', 'Ṣ' => 'Ṣ', 'ṣ' => 'ṣ', 'Ṥ' => 'Ṥ', 'ṥ' => 'ṥ', 'Ṧ' => 'Ṧ', 'ṧ' => 'ṧ', 'Ṩ' => 'Ṩ', 'ṩ' => 'ṩ', 'Ṫ' => 'Ṫ', 'ṫ' => 'ṫ', 'Ṭ' => 'Ṭ', 'ṭ' => 'ṭ', 'Ṯ' => 'Ṯ', 'ṯ' => 'ṯ', 'Ṱ' => 'Ṱ', 'ṱ' => 'ṱ', 'Ṳ' => 'Ṳ', 'ṳ' => 'ṳ', 'Ṵ' => 'Ṵ', 'ṵ' => 'ṵ', 'Ṷ' => 'Ṷ', 'ṷ' => 'ṷ', 'Ṹ' => 'Ṹ', 'ṹ' => 'ṹ', 'Ṻ' => 'Ṻ', 'ṻ' => 'ṻ', 'Ṽ' => 'Ṽ', 'ṽ' => 'ṽ', 'Ṿ' => 'Ṿ', 'ṿ' => 'ṿ', 'Ẁ' => 'Ẁ', 'ẁ' => 'ẁ', 'Ẃ' => 'Ẃ', 'ẃ' => 'ẃ', 'Ẅ' => 'Ẅ', 'ẅ' => 'ẅ', 'Ẇ' => 'Ẇ', 'ẇ' => 'ẇ', 'Ẉ' => 'Ẉ', 'ẉ' => 'ẉ', 'Ẋ' => 'Ẋ', 'ẋ' => 'ẋ', 'Ẍ' => 'Ẍ', 'ẍ' => 'ẍ', 'Ẏ' => 'Ẏ', 'ẏ' => 'ẏ', 'Ẑ' => 'Ẑ', 'ẑ' => 'ẑ', 'Ẓ' => 'Ẓ', 'ẓ' => 'ẓ', 'Ẕ' => 'Ẕ', 'ẕ' => 'ẕ', 'ẖ' => 'ẖ', 'ẗ' => 'ẗ', 'ẘ' => 'ẘ', 'ẙ' => 'ẙ', 'ẛ' => 'ẛ', 'Ạ' => 'Ạ', 'ạ' => 'ạ', 'Ả' => 'Ả', 'ả' => 'ả', 'Ấ' => 'Ấ', 'ấ' => 'ấ', 'Ầ' => 'Ầ', 'ầ' => 'ầ', 'Ẩ' => 'Ẩ', 'ẩ' => 'ẩ', 'Ẫ' => 'Ẫ', 'ẫ' => 'ẫ', 'Ậ' => 'Ậ', 'ậ' => 'ậ', 'Ắ' => 'Ắ', 'ắ' => 'ắ', 'Ằ' => 'Ằ', 'ằ' => 'ằ', 'Ẳ' => 'Ẳ', 'ẳ' => 'ẳ', 'Ẵ' => 'Ẵ', 'ẵ' => 'ẵ', 'Ặ' => 'Ặ', 'ặ' => 'ặ', 'Ẹ' => 'Ẹ', 'ẹ' => 'ẹ', 'Ẻ' => 'Ẻ', 'ẻ' => 'ẻ', 'Ẽ' => 'Ẽ', 'ẽ' => 'ẽ', 'Ế' => 'Ế', 'ế' => 'ế', 'Ề' => 'Ề', 'ề' => 'ề', 'Ể' => 'Ể', 'ể' => 'ể', 'Ễ' => 'Ễ', 'ễ' => 'ễ', 'Ệ' => 'Ệ', 'ệ' => 'ệ', 'Ỉ' => 'Ỉ', 'ỉ' => 'ỉ', 'Ị' => 'Ị', 'ị' => 'ị', 'Ọ' => 'Ọ', 'ọ' => 'ọ', 'Ỏ' => 'Ỏ', 'ỏ' => 'ỏ', 'Ố' => 'Ố', 'ố' => 'ố', 'Ồ' => 'Ồ', 'ồ' => 'ồ', 'Ổ' => 'Ổ', 'ổ' => 'ổ', 'Ỗ' => 'Ỗ', 'ỗ' => 'ỗ', 'Ộ' => 'Ộ', 'ộ' => 'ộ', 'Ớ' => 'Ớ', 'ớ' => 'ớ', 'Ờ' => 'Ờ', 'ờ' => 'ờ', 'Ở' => 'Ở', 'ở' => 'ở', 'Ỡ' => 'Ỡ', 'ỡ' => 'ỡ', 'Ợ' => 'Ợ', 'ợ' => 'ợ', 'Ụ' => 'Ụ', 'ụ' => 'ụ', 'Ủ' => 'Ủ', 'ủ' => 'ủ', 'Ứ' => 'Ứ', 'ứ' => 'ứ', 'Ừ' => 'Ừ', 'ừ' => 'ừ', 'Ử' => 'Ử', 'ử' => 'ử', 'Ữ' => 'Ữ', 'ữ' => 'ữ', 'Ự' => 'Ự', 'ự' => 'ự', 'Ỳ' => 'Ỳ', 'ỳ' => 'ỳ', 'Ỵ' => 'Ỵ', 'ỵ' => 'ỵ', 'Ỷ' => 'Ỷ', 'ỷ' => 'ỷ', 'Ỹ' => 'Ỹ', 'ỹ' => 'ỹ', 'ἀ' => 'ἀ', 'ἁ' => 'ἁ', 'ἂ' => 'ἂ', 'ἃ' => 'ἃ', 'ἄ' => 'ἄ', 'ἅ' => 'ἅ', 'ἆ' => 'ἆ', 'ἇ' => 'ἇ', 'Ἀ' => 'Ἀ', 'Ἁ' => 'Ἁ', 'Ἂ' => 'Ἂ', 'Ἃ' => 'Ἃ', 'Ἄ' => 'Ἄ', 'Ἅ' => 'Ἅ', 'Ἆ' => 'Ἆ', 'Ἇ' => 'Ἇ', 'ἐ' => 'ἐ', 'ἑ' => 'ἑ', 'ἒ' => 'ἒ', 'ἓ' => 'ἓ', 'ἔ' => 'ἔ', 'ἕ' => 'ἕ', 'Ἐ' => 'Ἐ', 'Ἑ' => 'Ἑ', 'Ἒ' => 'Ἒ', 'Ἓ' => 'Ἓ', 'Ἔ' => 'Ἔ', 'Ἕ' => 'Ἕ', 'ἠ' => 'ἠ', 'ἡ' => 'ἡ', 'ἢ' => 'ἢ', 'ἣ' => 'ἣ', 'ἤ' => 'ἤ', 'ἥ' => 'ἥ', 'ἦ' => 'ἦ', 'ἧ' => 'ἧ', 'Ἠ' => 'Ἠ', 'Ἡ' => 'Ἡ', 'Ἢ' => 'Ἢ', 'Ἣ' => 'Ἣ', 'Ἤ' => 'Ἤ', 'Ἥ' => 'Ἥ', 'Ἦ' => 'Ἦ', 'Ἧ' => 'Ἧ', 'ἰ' => 'ἰ', 'ἱ' => 'ἱ', 'ἲ' => 'ἲ', 'ἳ' => 'ἳ', 'ἴ' => 'ἴ', 'ἵ' => 'ἵ', 'ἶ' => 'ἶ', 'ἷ' => 'ἷ', 'Ἰ' => 'Ἰ', 'Ἱ' => 'Ἱ', 'Ἲ' => 'Ἲ', 'Ἳ' => 'Ἳ', 'Ἴ' => 'Ἴ', 'Ἵ' => 'Ἵ', 'Ἶ' => 'Ἶ', 'Ἷ' => 'Ἷ', 'ὀ' => 'ὀ', 'ὁ' => 'ὁ', 'ὂ' => 'ὂ', 'ὃ' => 'ὃ', 'ὄ' => 'ὄ', 'ὅ' => 'ὅ', 'Ὀ' => 'Ὀ', 'Ὁ' => 'Ὁ', 'Ὂ' => 'Ὂ', 'Ὃ' => 'Ὃ', 'Ὄ' => 'Ὄ', 'Ὅ' => 'Ὅ', 'ὐ' => 'ὐ', 'ὑ' => 'ὑ', 'ὒ' => 'ὒ', 'ὓ' => 'ὓ', 'ὔ' => 'ὔ', 'ὕ' => 'ὕ', 'ὖ' => 'ὖ', 'ὗ' => 'ὗ', 'Ὑ' => 'Ὑ', 'Ὓ' => 'Ὓ', 'Ὕ' => 'Ὕ', 'Ὗ' => 'Ὗ', 'ὠ' => 'ὠ', 'ὡ' => 'ὡ', 'ὢ' => 'ὢ', 'ὣ' => 'ὣ', 'ὤ' => 'ὤ', 'ὥ' => 'ὥ', 'ὦ' => 'ὦ', 'ὧ' => 'ὧ', 'Ὠ' => 'Ὠ', 'Ὡ' => 'Ὡ', 'Ὢ' => 'Ὢ', 'Ὣ' => 'Ὣ', 'Ὤ' => 'Ὤ', 'Ὥ' => 'Ὥ', 'Ὦ' => 'Ὦ', 'Ὧ' => 'Ὧ', 'ὰ' => 'ὰ', 'ά' => 'ά', 'ὲ' => 'ὲ', 'έ' => 'έ', 'ὴ' => 'ὴ', 'ή' => 'ή', 'ὶ' => 'ὶ', 'ί' => 'ί', 'ὸ' => 'ὸ', 'ό' => 'ό', 'ὺ' => 'ὺ', 'ύ' => 'ύ', 'ὼ' => 'ὼ', 'ώ' => 'ώ', 'ᾀ' => 'ᾀ', 'ᾁ' => 'ᾁ', 'ᾂ' => 'ᾂ', 'ᾃ' => 'ᾃ', 'ᾄ' => 'ᾄ', 'ᾅ' => 'ᾅ', 'ᾆ' => 'ᾆ', 'ᾇ' => 'ᾇ', 'ᾈ' => 'ᾈ', 'ᾉ' => 'ᾉ', 'ᾊ' => 'ᾊ', 'ᾋ' => 'ᾋ', 'ᾌ' => 'ᾌ', 'ᾍ' => 'ᾍ', 'ᾎ' => 'ᾎ', 'ᾏ' => 'ᾏ', 'ᾐ' => 'ᾐ', 'ᾑ' => 'ᾑ', 'ᾒ' => 'ᾒ', 'ᾓ' => 'ᾓ', 'ᾔ' => 'ᾔ', 'ᾕ' => 'ᾕ', 'ᾖ' => 'ᾖ', 'ᾗ' => 'ᾗ', 'ᾘ' => 'ᾘ', 'ᾙ' => 'ᾙ', 'ᾚ' => 'ᾚ', 'ᾛ' => 'ᾛ', 'ᾜ' => 'ᾜ', 'ᾝ' => 'ᾝ', 'ᾞ' => 'ᾞ', 'ᾟ' => 'ᾟ', 'ᾠ' => 'ᾠ', 'ᾡ' => 'ᾡ', 'ᾢ' => 'ᾢ', 'ᾣ' => 'ᾣ', 'ᾤ' => 'ᾤ', 'ᾥ' => 'ᾥ', 'ᾦ' => 'ᾦ', 'ᾧ' => 'ᾧ', 'ᾨ' => 'ᾨ', 'ᾩ' => 'ᾩ', 'ᾪ' => 'ᾪ', 'ᾫ' => 'ᾫ', 'ᾬ' => 'ᾬ', 'ᾭ' => 'ᾭ', 'ᾮ' => 'ᾮ', 'ᾯ' => 'ᾯ', 'ᾰ' => 'ᾰ', 'ᾱ' => 'ᾱ', 'ᾲ' => 'ᾲ', 'ᾳ' => 'ᾳ', 'ᾴ' => 'ᾴ', 'ᾶ' => 'ᾶ', 'ᾷ' => 'ᾷ', 'Ᾰ' => 'Ᾰ', 'Ᾱ' => 'Ᾱ', 'Ὰ' => 'Ὰ', 'Ά' => 'Ά', 'ᾼ' => 'ᾼ', 'ι' => 'ι', '῁' => '῁', 'ῂ' => 'ῂ', 'ῃ' => 'ῃ', 'ῄ' => 'ῄ', 'ῆ' => 'ῆ', 'ῇ' => 'ῇ', 'Ὲ' => 'Ὲ', 'Έ' => 'Έ', 'Ὴ' => 'Ὴ', 'Ή' => 'Ή', 'ῌ' => 'ῌ', '῍' => '῍', '῎' => '῎', '῏' => '῏', 'ῐ' => 'ῐ', 'ῑ' => 'ῑ', 'ῒ' => 'ῒ', 'ΐ' => 'ΐ', 'ῖ' => 'ῖ', 'ῗ' => 'ῗ', 'Ῐ' => 'Ῐ', 'Ῑ' => 'Ῑ', 'Ὶ' => 'Ὶ', 'Ί' => 'Ί', '῝' => '῝', '῞' => '῞', '῟' => '῟', 'ῠ' => 'ῠ', 'ῡ' => 'ῡ', 'ῢ' => 'ῢ', 'ΰ' => 'ΰ', 'ῤ' => 'ῤ', 'ῥ' => 'ῥ', 'ῦ' => 'ῦ', 'ῧ' => 'ῧ', 'Ῠ' => 'Ῠ', 'Ῡ' => 'Ῡ', 'Ὺ' => 'Ὺ', 'Ύ' => 'Ύ', 'Ῥ' => 'Ῥ', '῭' => '῭', '΅' => '΅', '`' => '`', 'ῲ' => 'ῲ', 'ῳ' => 'ῳ', 'ῴ' => 'ῴ', 'ῶ' => 'ῶ', 'ῷ' => 'ῷ', 'Ὸ' => 'Ὸ', 'Ό' => 'Ό', 'Ὼ' => 'Ὼ', 'Ώ' => 'Ώ', 'ῼ' => 'ῼ', '´' => '´', ' ' => ' ', ' ' => ' ', 'Ω' => 'Ω', 'K' => 'K', 'Å' => 'Å', '↚' => '↚', '↛' => '↛', '↮' => '↮', '⇍' => '⇍', '⇎' => '⇎', '⇏' => '⇏', '∄' => '∄', '∉' => '∉', '∌' => '∌', '∤' => '∤', '∦' => '∦', '≁' => '≁', '≄' => '≄', '≇' => '≇', '≉' => '≉', '≠' => '≠', '≢' => '≢', '≭' => '≭', '≮' => '≮', '≯' => '≯', '≰' => '≰', '≱' => '≱', '≴' => '≴', '≵' => '≵', '≸' => '≸', '≹' => '≹', '⊀' => '⊀', '⊁' => '⊁', '⊄' => '⊄', '⊅' => '⊅', '⊈' => '⊈', '⊉' => '⊉', '⊬' => '⊬', '⊭' => '⊭', '⊮' => '⊮', '⊯' => '⊯', '⋠' => '⋠', '⋡' => '⋡', '⋢' => '⋢', '⋣' => '⋣', '⋪' => '⋪', '⋫' => '⋫', '⋬' => '⋬', '⋭' => '⋭', '〈' => '〈', '〉' => '〉', '⫝̸' => '⫝̸', 'が' => 'が', 'ぎ' => 'ぎ', 'ぐ' => 'ぐ', 'げ' => 'げ', 'ご' => 'ご', 'ざ' => 'ざ', 'じ' => 'じ', 'ず' => 'ず', 'ぜ' => 'ぜ', 'ぞ' => 'ぞ', 'だ' => 'だ', 'ぢ' => 'ぢ', 'づ' => 'づ', 'で' => 'で', 'ど' => 'ど', 'ば' => 'ば', 'ぱ' => 'ぱ', 'び' => 'び', 'ぴ' => 'ぴ', 'ぶ' => 'ぶ', 'ぷ' => 'ぷ', 'べ' => 'べ', 'ぺ' => 'ぺ', 'ぼ' => 'ぼ', 'ぽ' => 'ぽ', 'ゔ' => 'ゔ', 'ゞ' => 'ゞ', 'ガ' => 'ガ', 'ギ' => 'ギ', 'グ' => 'グ', 'ゲ' => 'ゲ', 'ゴ' => 'ゴ', 'ザ' => 'ザ', 'ジ' => 'ジ', 'ズ' => 'ズ', 'ゼ' => 'ゼ', 'ゾ' => 'ゾ', 'ダ' => 'ダ', 'ヂ' => 'ヂ', 'ヅ' => 'ヅ', 'デ' => 'デ', 'ド' => 'ド', 'バ' => 'バ', 'パ' => 'パ', 'ビ' => 'ビ', 'ピ' => 'ピ', 'ブ' => 'ブ', 'プ' => 'プ', 'ベ' => 'ベ', 'ペ' => 'ペ', 'ボ' => 'ボ', 'ポ' => 'ポ', 'ヴ' => 'ヴ', 'ヷ' => 'ヷ', 'ヸ' => 'ヸ', 'ヹ' => 'ヹ', 'ヺ' => 'ヺ', 'ヾ' => 'ヾ', '豈' => '豈', '更' => '更', '車' => '車', '賈' => '賈', '滑' => '滑', '串' => '串', '句' => '句', '龜' => '龜', '龜' => '龜', '契' => '契', '金' => '金', '喇' => '喇', '奈' => '奈', '懶' => '懶', '癩' => '癩', '羅' => '羅', '蘿' => '蘿', '螺' => '螺', '裸' => '裸', '邏' => '邏', '樂' => '樂', '洛' => '洛', '烙' => '烙', '珞' => '珞', '落' => '落', '酪' => '酪', '駱' => '駱', '亂' => '亂', '卵' => '卵', '欄' => '欄', '爛' => '爛', '蘭' => '蘭', '鸞' => '鸞', '嵐' => '嵐', '濫' => '濫', '藍' => '藍', '襤' => '襤', '拉' => '拉', '臘' => '臘', '蠟' => '蠟', '廊' => '廊', '朗' => '朗', '浪' => '浪', '狼' => '狼', '郎' => '郎', '來' => '來', '冷' => '冷', '勞' => '勞', '擄' => '擄', '櫓' => '櫓', '爐' => '爐', '盧' => '盧', '老' => '老', '蘆' => '蘆', '虜' => '虜', '路' => '路', '露' => '露', '魯' => '魯', '鷺' => '鷺', '碌' => '碌', '祿' => '祿', '綠' => '綠', '菉' => '菉', '錄' => '錄', '鹿' => '鹿', '論' => '論', '壟' => '壟', '弄' => '弄', '籠' => '籠', '聾' => '聾', '牢' => '牢', '磊' => '磊', '賂' => '賂', '雷' => '雷', '壘' => '壘', '屢' => '屢', '樓' => '樓', '淚' => '淚', '漏' => '漏', '累' => '累', '縷' => '縷', '陋' => '陋', '勒' => '勒', '肋' => '肋', '凜' => '凜', '凌' => '凌', '稜' => '稜', '綾' => '綾', '菱' => '菱', '陵' => '陵', '讀' => '讀', '拏' => '拏', '樂' => '樂', '諾' => '諾', '丹' => '丹', '寧' => '寧', '怒' => '怒', '率' => '率', '異' => '異', '北' => '北', '磻' => '磻', '便' => '便', '復' => '復', '不' => '不', '泌' => '泌', '數' => '數', '索' => '索', '參' => '參', '塞' => '塞', '省' => '省', '葉' => '葉', '說' => '說', '殺' => '殺', '辰' => '辰', '沈' => '沈', '拾' => '拾', '若' => '若', '掠' => '掠', '略' => '略', '亮' => '亮', '兩' => '兩', '凉' => '凉', '梁' => '梁', '糧' => '糧', '良' => '良', '諒' => '諒', '量' => '量', '勵' => '勵', '呂' => '呂', '女' => '女', '廬' => '廬', '旅' => '旅', '濾' => '濾', '礪' => '礪', '閭' => '閭', '驪' => '驪', '麗' => '麗', '黎' => '黎', '力' => '力', '曆' => '曆', '歷' => '歷', '轢' => '轢', '年' => '年', '憐' => '憐', '戀' => '戀', '撚' => '撚', '漣' => '漣', '煉' => '煉', '璉' => '璉', '秊' => '秊', '練' => '練', '聯' => '聯', '輦' => '輦', '蓮' => '蓮', '連' => '連', '鍊' => '鍊', '列' => '列', '劣' => '劣', '咽' => '咽', '烈' => '烈', '裂' => '裂', '說' => '說', '廉' => '廉', '念' => '念', '捻' => '捻', '殮' => '殮', '簾' => '簾', '獵' => '獵', '令' => '令', '囹' => '囹', '寧' => '寧', '嶺' => '嶺', '怜' => '怜', '玲' => '玲', '瑩' => '瑩', '羚' => '羚', '聆' => '聆', '鈴' => '鈴', '零' => '零', '靈' => '靈', '領' => '領', '例' => '例', '禮' => '禮', '醴' => '醴', '隸' => '隸', '惡' => '惡', '了' => '了', '僚' => '僚', '寮' => '寮', '尿' => '尿', '料' => '料', '樂' => '樂', '燎' => '燎', '療' => '療', '蓼' => '蓼', '遼' => '遼', '龍' => '龍', '暈' => '暈', '阮' => '阮', '劉' => '劉', '杻' => '杻', '柳' => '柳', '流' => '流', '溜' => '溜', '琉' => '琉', '留' => '留', '硫' => '硫', '紐' => '紐', '類' => '類', '六' => '六', '戮' => '戮', '陸' => '陸', '倫' => '倫', '崙' => '崙', '淪' => '淪', '輪' => '輪', '律' => '律', '慄' => '慄', '栗' => '栗', '率' => '率', '隆' => '隆', '利' => '利', '吏' => '吏', '履' => '履', '易' => '易', '李' => '李', '梨' => '梨', '泥' => '泥', '理' => '理', '痢' => '痢', '罹' => '罹', '裏' => '裏', '裡' => '裡', '里' => '里', '離' => '離', '匿' => '匿', '溺' => '溺', '吝' => '吝', '燐' => '燐', '璘' => '璘', '藺' => '藺', '隣' => '隣', '鱗' => '鱗', '麟' => '麟', '林' => '林', '淋' => '淋', '臨' => '臨', '立' => '立', '笠' => '笠', '粒' => '粒', '狀' => '狀', '炙' => '炙', '識' => '識', '什' => '什', '茶' => '茶', '刺' => '刺', '切' => '切', '度' => '度', '拓' => '拓', '糖' => '糖', '宅' => '宅', '洞' => '洞', '暴' => '暴', '輻' => '輻', '行' => '行', '降' => '降', '見' => '見', '廓' => '廓', '兀' => '兀', '嗀' => '嗀', '塚' => '塚', '晴' => '晴', '凞' => '凞', '猪' => '猪', '益' => '益', '礼' => '礼', '神' => '神', '祥' => '祥', '福' => '福', '靖' => '靖', '精' => '精', '羽' => '羽', '蘒' => '蘒', '諸' => '諸', '逸' => '逸', '都' => '都', '飯' => '飯', '飼' => '飼', '館' => '館', '鶴' => '鶴', '郞' => '郞', '隷' => '隷', '侮' => '侮', '僧' => '僧', '免' => '免', '勉' => '勉', '勤' => '勤', '卑' => '卑', '喝' => '喝', '嘆' => '嘆', '器' => '器', '塀' => '塀', '墨' => '墨', '層' => '層', '屮' => '屮', '悔' => '悔', '慨' => '慨', '憎' => '憎', '懲' => '懲', '敏' => '敏', '既' => '既', '暑' => '暑', '梅' => '梅', '海' => '海', '渚' => '渚', '漢' => '漢', '煮' => '煮', '爫' => '爫', '琢' => '琢', '碑' => '碑', '社' => '社', '祉' => '祉', '祈' => '祈', '祐' => '祐', '祖' => '祖', '祝' => '祝', '禍' => '禍', '禎' => '禎', '穀' => '穀', '突' => '突', '節' => '節', '練' => '練', '縉' => '縉', '繁' => '繁', '署' => '署', '者' => '者', '臭' => '臭', '艹' => '艹', '艹' => '艹', '著' => '著', '褐' => '褐', '視' => '視', '謁' => '謁', '謹' => '謹', '賓' => '賓', '贈' => '贈', '辶' => '辶', '逸' => '逸', '難' => '難', '響' => '響', '頻' => '頻', '恵' => '恵', '𤋮' => '𤋮', '舘' => '舘', '並' => '並', '况' => '况', '全' => '全', '侀' => '侀', '充' => '充', '冀' => '冀', '勇' => '勇', '勺' => '勺', '喝' => '喝', '啕' => '啕', '喙' => '喙', '嗢' => '嗢', '塚' => '塚', '墳' => '墳', '奄' => '奄', '奔' => '奔', '婢' => '婢', '嬨' => '嬨', '廒' => '廒', '廙' => '廙', '彩' => '彩', '徭' => '徭', '惘' => '惘', '慎' => '慎', '愈' => '愈', '憎' => '憎', '慠' => '慠', '懲' => '懲', '戴' => '戴', '揄' => '揄', '搜' => '搜', '摒' => '摒', '敖' => '敖', '晴' => '晴', '朗' => '朗', '望' => '望', '杖' => '杖', '歹' => '歹', '殺' => '殺', '流' => '流', '滛' => '滛', '滋' => '滋', '漢' => '漢', '瀞' => '瀞', '煮' => '煮', '瞧' => '瞧', '爵' => '爵', '犯' => '犯', '猪' => '猪', '瑱' => '瑱', '甆' => '甆', '画' => '画', '瘝' => '瘝', '瘟' => '瘟', '益' => '益', '盛' => '盛', '直' => '直', '睊' => '睊', '着' => '着', '磌' => '磌', '窱' => '窱', '節' => '節', '类' => '类', '絛' => '絛', '練' => '練', '缾' => '缾', '者' => '者', '荒' => '荒', '華' => '華', '蝹' => '蝹', '襁' => '襁', '覆' => '覆', '視' => '視', '調' => '調', '諸' => '諸', '請' => '請', '謁' => '謁', '諾' => '諾', '諭' => '諭', '謹' => '謹', '變' => '變', '贈' => '贈', '輸' => '輸', '遲' => '遲', '醙' => '醙', '鉶' => '鉶', '陼' => '陼', '難' => '難', '靖' => '靖', '韛' => '韛', '響' => '響', '頋' => '頋', '頻' => '頻', '鬒' => '鬒', '龜' => '龜', '𢡊' => '𢡊', '𢡄' => '𢡄', '𣏕' => '𣏕', '㮝' => '㮝', '䀘' => '䀘', '䀹' => '䀹', '𥉉' => '𥉉', '𥳐' => '𥳐', '𧻓' => '𧻓', '齃' => '齃', '龎' => '龎', 'יִ' => 'יִ', 'ײַ' => 'ײַ', 'שׁ' => 'שׁ', 'שׂ' => 'שׂ', 'שּׁ' => 'שּׁ', 'שּׂ' => 'שּׂ', 'אַ' => 'אַ', 'אָ' => 'אָ', 'אּ' => 'אּ', 'בּ' => 'בּ', 'גּ' => 'גּ', 'דּ' => 'דּ', 'הּ' => 'הּ', 'וּ' => 'וּ', 'זּ' => 'זּ', 'טּ' => 'טּ', 'יּ' => 'יּ', 'ךּ' => 'ךּ', 'כּ' => 'כּ', 'לּ' => 'לּ', 'מּ' => 'מּ', 'נּ' => 'נּ', 'סּ' => 'סּ', 'ףּ' => 'ףּ', 'פּ' => 'פּ', 'צּ' => 'צּ', 'קּ' => 'קּ', 'רּ' => 'רּ', 'שּ' => 'שּ', 'תּ' => 'תּ', 'וֹ' => 'וֹ', 'בֿ' => 'בֿ', 'כֿ' => 'כֿ', 'פֿ' => 'פֿ', '𑂚' => '𑂚', '𑂜' => '𑂜', '𑂫' => '𑂫', '𑄮' => '𑄮', '𑄯' => '𑄯', '𑍋' => '𑍋', '𑍌' => '𑍌', '𑒻' => '𑒻', '𑒼' => '𑒼', '𑒾' => '𑒾', '𑖺' => '𑖺', '𑖻' => '𑖻', '𑤸' => '𑤸', '𝅗𝅥' => '𝅗𝅥', '𝅘𝅥' => '𝅘𝅥', '𝅘𝅥𝅮' => '𝅘𝅥𝅮', '𝅘𝅥𝅯' => '𝅘𝅥𝅯', '𝅘𝅥𝅰' => '𝅘𝅥𝅰', '𝅘𝅥𝅱' => '𝅘𝅥𝅱', '𝅘𝅥𝅲' => '𝅘𝅥𝅲', '𝆹𝅥' => '𝆹𝅥', '𝆺𝅥' => '𝆺𝅥', '𝆹𝅥𝅮' => '𝆹𝅥𝅮', '𝆺𝅥𝅮' => '𝆺𝅥𝅮', '𝆹𝅥𝅯' => '𝆹𝅥𝅯', '𝆺𝅥𝅯' => '𝆺𝅥𝅯', '丽' => '丽', '丸' => '丸', '乁' => '乁', '𠄢' => '𠄢', '你' => '你', '侮' => '侮', '侻' => '侻', '倂' => '倂', '偺' => '偺', '備' => '備', '僧' => '僧', '像' => '像', '㒞' => '㒞', '𠘺' => '𠘺', '免' => '免', '兔' => '兔', '兤' => '兤', '具' => '具', '𠔜' => '𠔜', '㒹' => '㒹', '內' => '內', '再' => '再', '𠕋' => '𠕋', '冗' => '冗', '冤' => '冤', '仌' => '仌', '冬' => '冬', '况' => '况', '𩇟' => '𩇟', '凵' => '凵', '刃' => '刃', '㓟' => '㓟', '刻' => '刻', '剆' => '剆', '割' => '割', '剷' => '剷', '㔕' => '㔕', '勇' => '勇', '勉' => '勉', '勤' => '勤', '勺' => '勺', '包' => '包', '匆' => '匆', '北' => '北', '卉' => '卉', '卑' => '卑', '博' => '博', '即' => '即', '卽' => '卽', '卿' => '卿', '卿' => '卿', '卿' => '卿', '𠨬' => '𠨬', '灰' => '灰', '及' => '及', '叟' => '叟', '𠭣' => '𠭣', '叫' => '叫', '叱' => '叱', '吆' => '吆', '咞' => '咞', '吸' => '吸', '呈' => '呈', '周' => '周', '咢' => '咢', '哶' => '哶', '唐' => '唐', '啓' => '啓', '啣' => '啣', '善' => '善', '善' => '善', '喙' => '喙', '喫' => '喫', '喳' => '喳', '嗂' => '嗂', '圖' => '圖', '嘆' => '嘆', '圗' => '圗', '噑' => '噑', '噴' => '噴', '切' => '切', '壮' => '壮', '城' => '城', '埴' => '埴', '堍' => '堍', '型' => '型', '堲' => '堲', '報' => '報', '墬' => '墬', '𡓤' => '𡓤', '売' => '売', '壷' => '壷', '夆' => '夆', '多' => '多', '夢' => '夢', '奢' => '奢', '𡚨' => '𡚨', '𡛪' => '𡛪', '姬' => '姬', '娛' => '娛', '娧' => '娧', '姘' => '姘', '婦' => '婦', '㛮' => '㛮', '㛼' => '㛼', '嬈' => '嬈', '嬾' => '嬾', '嬾' => '嬾', '𡧈' => '𡧈', '寃' => '寃', '寘' => '寘', '寧' => '寧', '寳' => '寳', '𡬘' => '𡬘', '寿' => '寿', '将' => '将', '当' => '当', '尢' => '尢', '㞁' => '㞁', '屠' => '屠', '屮' => '屮', '峀' => '峀', '岍' => '岍', '𡷤' => '𡷤', '嵃' => '嵃', '𡷦' => '𡷦', '嵮' => '嵮', '嵫' => '嵫', '嵼' => '嵼', '巡' => '巡', '巢' => '巢', '㠯' => '㠯', '巽' => '巽', '帨' => '帨', '帽' => '帽', '幩' => '幩', '㡢' => '㡢', '𢆃' => '𢆃', '㡼' => '㡼', '庰' => '庰', '庳' => '庳', '庶' => '庶', '廊' => '廊', '𪎒' => '𪎒', '廾' => '廾', '𢌱' => '𢌱', '𢌱' => '𢌱', '舁' => '舁', '弢' => '弢', '弢' => '弢', '㣇' => '㣇', '𣊸' => '𣊸', '𦇚' => '𦇚', '形' => '形', '彫' => '彫', '㣣' => '㣣', '徚' => '徚', '忍' => '忍', '志' => '志', '忹' => '忹', '悁' => '悁', '㤺' => '㤺', '㤜' => '㤜', '悔' => '悔', '𢛔' => '𢛔', '惇' => '惇', '慈' => '慈', '慌' => '慌', '慎' => '慎', '慌' => '慌', '慺' => '慺', '憎' => '憎', '憲' => '憲', '憤' => '憤', '憯' => '憯', '懞' => '懞', '懲' => '懲', '懶' => '懶', '成' => '成', '戛' => '戛', '扝' => '扝', '抱' => '抱', '拔' => '拔', '捐' => '捐', '𢬌' => '𢬌', '挽' => '挽', '拼' => '拼', '捨' => '捨', '掃' => '掃', '揤' => '揤', '𢯱' => '𢯱', '搢' => '搢', '揅' => '揅', '掩' => '掩', '㨮' => '㨮', '摩' => '摩', '摾' => '摾', '撝' => '撝', '摷' => '摷', '㩬' => '㩬', '敏' => '敏', '敬' => '敬', '𣀊' => '𣀊', '旣' => '旣', '書' => '書', '晉' => '晉', '㬙' => '㬙', '暑' => '暑', '㬈' => '㬈', '㫤' => '㫤', '冒' => '冒', '冕' => '冕', '最' => '最', '暜' => '暜', '肭' => '肭', '䏙' => '䏙', '朗' => '朗', '望' => '望', '朡' => '朡', '杞' => '杞', '杓' => '杓', '𣏃' => '𣏃', '㭉' => '㭉', '柺' => '柺', '枅' => '枅', '桒' => '桒', '梅' => '梅', '𣑭' => '𣑭', '梎' => '梎', '栟' => '栟', '椔' => '椔', '㮝' => '㮝', '楂' => '楂', '榣' => '榣', '槪' => '槪', '檨' => '檨', '𣚣' => '𣚣', '櫛' => '櫛', '㰘' => '㰘', '次' => '次', '𣢧' => '𣢧', '歔' => '歔', '㱎' => '㱎', '歲' => '歲', '殟' => '殟', '殺' => '殺', '殻' => '殻', '𣪍' => '𣪍', '𡴋' => '𡴋', '𣫺' => '𣫺', '汎' => '汎', '𣲼' => '𣲼', '沿' => '沿', '泍' => '泍', '汧' => '汧', '洖' => '洖', '派' => '派', '海' => '海', '流' => '流', '浩' => '浩', '浸' => '浸', '涅' => '涅', '𣴞' => '𣴞', '洴' => '洴', '港' => '港', '湮' => '湮', '㴳' => '㴳', '滋' => '滋', '滇' => '滇', '𣻑' => '𣻑', '淹' => '淹', '潮' => '潮', '𣽞' => '𣽞', '𣾎' => '𣾎', '濆' => '濆', '瀹' => '瀹', '瀞' => '瀞', '瀛' => '瀛', '㶖' => '㶖', '灊' => '灊', '災' => '災', '灷' => '灷', '炭' => '炭', '𠔥' => '𠔥', '煅' => '煅', '𤉣' => '𤉣', '熜' => '熜', '𤎫' => '𤎫', '爨' => '爨', '爵' => '爵', '牐' => '牐', '𤘈' => '𤘈', '犀' => '犀', '犕' => '犕', '𤜵' => '𤜵', '𤠔' => '𤠔', '獺' => '獺', '王' => '王', '㺬' => '㺬', '玥' => '玥', '㺸' => '㺸', '㺸' => '㺸', '瑇' => '瑇', '瑜' => '瑜', '瑱' => '瑱', '璅' => '璅', '瓊' => '瓊', '㼛' => '㼛', '甤' => '甤', '𤰶' => '𤰶', '甾' => '甾', '𤲒' => '𤲒', '異' => '異', '𢆟' => '𢆟', '瘐' => '瘐', '𤾡' => '𤾡', '𤾸' => '𤾸', '𥁄' => '𥁄', '㿼' => '㿼', '䀈' => '䀈', '直' => '直', '𥃳' => '𥃳', '𥃲' => '𥃲', '𥄙' => '𥄙', '𥄳' => '𥄳', '眞' => '眞', '真' => '真', '真' => '真', '睊' => '睊', '䀹' => '䀹', '瞋' => '瞋', '䁆' => '䁆', '䂖' => '䂖', '𥐝' => '𥐝', '硎' => '硎', '碌' => '碌', '磌' => '磌', '䃣' => '䃣', '𥘦' => '𥘦', '祖' => '祖', '𥚚' => '𥚚', '𥛅' => '𥛅', '福' => '福', '秫' => '秫', '䄯' => '䄯', '穀' => '穀', '穊' => '穊', '穏' => '穏', '𥥼' => '𥥼', '𥪧' => '𥪧', '𥪧' => '𥪧', '竮' => '竮', '䈂' => '䈂', '𥮫' => '𥮫', '篆' => '篆', '築' => '築', '䈧' => '䈧', '𥲀' => '𥲀', '糒' => '糒', '䊠' => '䊠', '糨' => '糨', '糣' => '糣', '紀' => '紀', '𥾆' => '𥾆', '絣' => '絣', '䌁' => '䌁', '緇' => '緇', '縂' => '縂', '繅' => '繅', '䌴' => '䌴', '𦈨' => '𦈨', '𦉇' => '𦉇', '䍙' => '䍙', '𦋙' => '𦋙', '罺' => '罺', '𦌾' => '𦌾', '羕' => '羕', '翺' => '翺', '者' => '者', '𦓚' => '𦓚', '𦔣' => '𦔣', '聠' => '聠', '𦖨' => '𦖨', '聰' => '聰', '𣍟' => '𣍟', '䏕' => '䏕', '育' => '育', '脃' => '脃', '䐋' => '䐋', '脾' => '脾', '媵' => '媵', '𦞧' => '𦞧', '𦞵' => '𦞵', '𣎓' => '𣎓', '𣎜' => '𣎜', '舁' => '舁', '舄' => '舄', '辞' => '辞', '䑫' => '䑫', '芑' => '芑', '芋' => '芋', '芝' => '芝', '劳' => '劳', '花' => '花', '芳' => '芳', '芽' => '芽', '苦' => '苦', '𦬼' => '𦬼', '若' => '若', '茝' => '茝', '荣' => '荣', '莭' => '莭', '茣' => '茣', '莽' => '莽', '菧' => '菧', '著' => '著', '荓' => '荓', '菊' => '菊', '菌' => '菌', '菜' => '菜', '𦰶' => '𦰶', '𦵫' => '𦵫', '𦳕' => '𦳕', '䔫' => '䔫', '蓱' => '蓱', '蓳' => '蓳', '蔖' => '蔖', '𧏊' => '𧏊', '蕤' => '蕤', '𦼬' => '𦼬', '䕝' => '䕝', '䕡' => '䕡', '𦾱' => '𦾱', '𧃒' => '𧃒', '䕫' => '䕫', '虐' => '虐', '虜' => '虜', '虧' => '虧', '虩' => '虩', '蚩' => '蚩', '蚈' => '蚈', '蜎' => '蜎', '蛢' => '蛢', '蝹' => '蝹', '蜨' => '蜨', '蝫' => '蝫', '螆' => '螆', '䗗' => '䗗', '蟡' => '蟡', '蠁' => '蠁', '䗹' => '䗹', '衠' => '衠', '衣' => '衣', '𧙧' => '𧙧', '裗' => '裗', '裞' => '裞', '䘵' => '䘵', '裺' => '裺', '㒻' => '㒻', '𧢮' => '𧢮', '𧥦' => '𧥦', '䚾' => '䚾', '䛇' => '䛇', '誠' => '誠', '諭' => '諭', '變' => '變', '豕' => '豕', '𧲨' => '𧲨', '貫' => '貫', '賁' => '賁', '贛' => '贛', '起' => '起', '𧼯' => '𧼯', '𠠄' => '𠠄', '跋' => '跋', '趼' => '趼', '跰' => '跰', '𠣞' => '𠣞', '軔' => '軔', '輸' => '輸', '𨗒' => '𨗒', '𨗭' => '𨗭', '邔' => '邔', '郱' => '郱', '鄑' => '鄑', '𨜮' => '𨜮', '鄛' => '鄛', '鈸' => '鈸', '鋗' => '鋗', '鋘' => '鋘', '鉼' => '鉼', '鏹' => '鏹', '鐕' => '鐕', '𨯺' => '𨯺', '開' => '開', '䦕' => '䦕', '閷' => '閷', '𨵷' => '𨵷', '䧦' => '䧦', '雃' => '雃', '嶲' => '嶲', '霣' => '霣', '𩅅' => '𩅅', '𩈚' => '𩈚', '䩮' => '䩮', '䩶' => '䩶', '韠' => '韠', '𩐊' => '𩐊', '䪲' => '䪲', '𩒖' => '𩒖', '頋' => '頋', '頋' => '頋', '頩' => '頩', '𩖶' => '𩖶', '飢' => '飢', '䬳' => '䬳', '餩' => '餩', '馧' => '馧', '駂' => '駂', '駾' => '駾', '䯎' => '䯎', '𩬰' => '𩬰', '鬒' => '鬒', '鱀' => '鱀', '鳽' => '鳽', '䳎' => '䳎', '䳭' => '䳭', '鵧' => '鵧', '𪃎' => '𪃎', '䳸' => '䳸', '𪄅' => '𪄅', '𪈎' => '𪈎', '𪊑' => '𪊑', '麻' => '麻', '䵖' => '䵖', '黹' => '黹', '黾' => '黾', '鼅' => '鼅', '鼏' => '鼏', '鼖' => '鼖', '鼻' => '鼻', '𪘀' => '𪘀'); diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php new file mode 100644 index 0000000000..781d29f438 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php @@ -0,0 +1,5 @@ + 230, '́' => 230, '̂' => 230, '̃' => 230, '̄' => 230, '̅' => 230, '̆' => 230, '̇' => 230, '̈' => 230, '̉' => 230, '̊' => 230, '̋' => 230, '̌' => 230, '̍' => 230, '̎' => 230, '̏' => 230, '̐' => 230, '̑' => 230, '̒' => 230, '̓' => 230, '̔' => 230, '̕' => 232, '̖' => 220, '̗' => 220, '̘' => 220, '̙' => 220, '̚' => 232, '̛' => 216, '̜' => 220, '̝' => 220, '̞' => 220, '̟' => 220, '̠' => 220, '̡' => 202, '̢' => 202, '̣' => 220, '̤' => 220, '̥' => 220, '̦' => 220, '̧' => 202, '̨' => 202, '̩' => 220, '̪' => 220, '̫' => 220, '̬' => 220, '̭' => 220, '̮' => 220, '̯' => 220, '̰' => 220, '̱' => 220, '̲' => 220, '̳' => 220, '̴' => 1, '̵' => 1, '̶' => 1, '̷' => 1, '̸' => 1, '̹' => 220, '̺' => 220, '̻' => 220, '̼' => 220, '̽' => 230, '̾' => 230, '̿' => 230, '̀' => 230, '́' => 230, '͂' => 230, '̓' => 230, '̈́' => 230, 'ͅ' => 240, '͆' => 230, '͇' => 220, '͈' => 220, '͉' => 220, '͊' => 230, '͋' => 230, '͌' => 230, '͍' => 220, '͎' => 220, '͐' => 230, '͑' => 230, '͒' => 230, '͓' => 220, '͔' => 220, '͕' => 220, '͖' => 220, '͗' => 230, '͘' => 232, '͙' => 220, '͚' => 220, '͛' => 230, '͜' => 233, '͝' => 234, '͞' => 234, '͟' => 233, '͠' => 234, '͡' => 234, '͢' => 233, 'ͣ' => 230, 'ͤ' => 230, 'ͥ' => 230, 'ͦ' => 230, 'ͧ' => 230, 'ͨ' => 230, 'ͩ' => 230, 'ͪ' => 230, 'ͫ' => 230, 'ͬ' => 230, 'ͭ' => 230, 'ͮ' => 230, 'ͯ' => 230, '҃' => 230, '҄' => 230, '҅' => 230, '҆' => 230, '҇' => 230, '֑' => 220, '֒' => 230, '֓' => 230, '֔' => 230, '֕' => 230, '֖' => 220, '֗' => 230, '֘' => 230, '֙' => 230, '֚' => 222, '֛' => 220, '֜' => 230, '֝' => 230, '֞' => 230, '֟' => 230, '֠' => 230, '֡' => 230, '֢' => 220, '֣' => 220, '֤' => 220, '֥' => 220, '֦' => 220, '֧' => 220, '֨' => 230, '֩' => 230, '֪' => 220, '֫' => 230, '֬' => 230, '֭' => 222, '֮' => 228, '֯' => 230, 'ְ' => 10, 'ֱ' => 11, 'ֲ' => 12, 'ֳ' => 13, 'ִ' => 14, 'ֵ' => 15, 'ֶ' => 16, 'ַ' => 17, 'ָ' => 18, 'ֹ' => 19, 'ֺ' => 19, 'ֻ' => 20, 'ּ' => 21, 'ֽ' => 22, 'ֿ' => 23, 'ׁ' => 24, 'ׂ' => 25, 'ׄ' => 230, 'ׅ' => 220, 'ׇ' => 18, 'ؐ' => 230, 'ؑ' => 230, 'ؒ' => 230, 'ؓ' => 230, 'ؔ' => 230, 'ؕ' => 230, 'ؖ' => 230, 'ؗ' => 230, 'ؘ' => 30, 'ؙ' => 31, 'ؚ' => 32, 'ً' => 27, 'ٌ' => 28, 'ٍ' => 29, 'َ' => 30, 'ُ' => 31, 'ِ' => 32, 'ّ' => 33, 'ْ' => 34, 'ٓ' => 230, 'ٔ' => 230, 'ٕ' => 220, 'ٖ' => 220, 'ٗ' => 230, '٘' => 230, 'ٙ' => 230, 'ٚ' => 230, 'ٛ' => 230, 'ٜ' => 220, 'ٝ' => 230, 'ٞ' => 230, 'ٟ' => 220, 'ٰ' => 35, 'ۖ' => 230, 'ۗ' => 230, 'ۘ' => 230, 'ۙ' => 230, 'ۚ' => 230, 'ۛ' => 230, 'ۜ' => 230, '۟' => 230, '۠' => 230, 'ۡ' => 230, 'ۢ' => 230, 'ۣ' => 220, 'ۤ' => 230, 'ۧ' => 230, 'ۨ' => 230, '۪' => 220, '۫' => 230, '۬' => 230, 'ۭ' => 220, 'ܑ' => 36, 'ܰ' => 230, 'ܱ' => 220, 'ܲ' => 230, 'ܳ' => 230, 'ܴ' => 220, 'ܵ' => 230, 'ܶ' => 230, 'ܷ' => 220, 'ܸ' => 220, 'ܹ' => 220, 'ܺ' => 230, 'ܻ' => 220, 'ܼ' => 220, 'ܽ' => 230, 'ܾ' => 220, 'ܿ' => 230, '݀' => 230, '݁' => 230, '݂' => 220, '݃' => 230, '݄' => 220, '݅' => 230, '݆' => 220, '݇' => 230, '݈' => 220, '݉' => 230, '݊' => 230, '߫' => 230, '߬' => 230, '߭' => 230, '߮' => 230, '߯' => 230, '߰' => 230, '߱' => 230, '߲' => 220, '߳' => 230, '߽' => 220, 'ࠖ' => 230, 'ࠗ' => 230, '࠘' => 230, '࠙' => 230, 'ࠛ' => 230, 'ࠜ' => 230, 'ࠝ' => 230, 'ࠞ' => 230, 'ࠟ' => 230, 'ࠠ' => 230, 'ࠡ' => 230, 'ࠢ' => 230, 'ࠣ' => 230, 'ࠥ' => 230, 'ࠦ' => 230, 'ࠧ' => 230, 'ࠩ' => 230, 'ࠪ' => 230, 'ࠫ' => 230, 'ࠬ' => 230, '࠭' => 230, '࡙' => 220, '࡚' => 220, '࡛' => 220, '࣓' => 220, 'ࣔ' => 230, 'ࣕ' => 230, 'ࣖ' => 230, 'ࣗ' => 230, 'ࣘ' => 230, 'ࣙ' => 230, 'ࣚ' => 230, 'ࣛ' => 230, 'ࣜ' => 230, 'ࣝ' => 230, 'ࣞ' => 230, 'ࣟ' => 230, '࣠' => 230, '࣡' => 230, 'ࣣ' => 220, 'ࣤ' => 230, 'ࣥ' => 230, 'ࣦ' => 220, 'ࣧ' => 230, 'ࣨ' => 230, 'ࣩ' => 220, '࣪' => 230, '࣫' => 230, '࣬' => 230, '࣭' => 220, '࣮' => 220, '࣯' => 220, 'ࣰ' => 27, 'ࣱ' => 28, 'ࣲ' => 29, 'ࣳ' => 230, 'ࣴ' => 230, 'ࣵ' => 230, 'ࣶ' => 220, 'ࣷ' => 230, 'ࣸ' => 230, 'ࣹ' => 220, 'ࣺ' => 220, 'ࣻ' => 230, 'ࣼ' => 230, 'ࣽ' => 230, 'ࣾ' => 230, 'ࣿ' => 230, '़' => 7, '्' => 9, '॑' => 230, '॒' => 220, '॓' => 230, '॔' => 230, '়' => 7, '্' => 9, '৾' => 230, '਼' => 7, '੍' => 9, '઼' => 7, '્' => 9, '଼' => 7, '୍' => 9, '்' => 9, '్' => 9, 'ౕ' => 84, 'ౖ' => 91, '಼' => 7, '್' => 9, '഻' => 9, '഼' => 9, '്' => 9, '්' => 9, 'ุ' => 103, 'ู' => 103, 'ฺ' => 9, '่' => 107, '้' => 107, '๊' => 107, '๋' => 107, 'ຸ' => 118, 'ູ' => 118, '຺' => 9, '່' => 122, '້' => 122, '໊' => 122, '໋' => 122, '༘' => 220, '༙' => 220, '༵' => 220, '༷' => 220, '༹' => 216, 'ཱ' => 129, 'ི' => 130, 'ུ' => 132, 'ེ' => 130, 'ཻ' => 130, 'ོ' => 130, 'ཽ' => 130, 'ྀ' => 130, 'ྂ' => 230, 'ྃ' => 230, '྄' => 9, '྆' => 230, '྇' => 230, '࿆' => 220, '့' => 7, '္' => 9, '်' => 9, 'ႍ' => 220, '፝' => 230, '፞' => 230, '፟' => 230, '᜔' => 9, '᜴' => 9, '្' => 9, '៝' => 230, 'ᢩ' => 228, '᤹' => 222, '᤺' => 230, '᤻' => 220, 'ᨗ' => 230, 'ᨘ' => 220, '᩠' => 9, '᩵' => 230, '᩶' => 230, '᩷' => 230, '᩸' => 230, '᩹' => 230, '᩺' => 230, '᩻' => 230, '᩼' => 230, '᩿' => 220, '᪰' => 230, '᪱' => 230, '᪲' => 230, '᪳' => 230, '᪴' => 230, '᪵' => 220, '᪶' => 220, '᪷' => 220, '᪸' => 220, '᪹' => 220, '᪺' => 220, '᪻' => 230, '᪼' => 230, '᪽' => 220, 'ᪿ' => 220, 'ᫀ' => 220, '᬴' => 7, '᭄' => 9, '᭫' => 230, '᭬' => 220, '᭭' => 230, '᭮' => 230, '᭯' => 230, '᭰' => 230, '᭱' => 230, '᭲' => 230, '᭳' => 230, '᮪' => 9, '᮫' => 9, '᯦' => 7, '᯲' => 9, '᯳' => 9, '᰷' => 7, '᳐' => 230, '᳑' => 230, '᳒' => 230, '᳔' => 1, '᳕' => 220, '᳖' => 220, '᳗' => 220, '᳘' => 220, '᳙' => 220, '᳚' => 230, '᳛' => 230, '᳜' => 220, '᳝' => 220, '᳞' => 220, '᳟' => 220, '᳠' => 230, '᳢' => 1, '᳣' => 1, '᳤' => 1, '᳥' => 1, '᳦' => 1, '᳧' => 1, '᳨' => 1, '᳭' => 220, '᳴' => 230, '᳸' => 230, '᳹' => 230, '᷀' => 230, '᷁' => 230, '᷂' => 220, '᷃' => 230, '᷄' => 230, '᷅' => 230, '᷆' => 230, '᷇' => 230, '᷈' => 230, '᷉' => 230, '᷊' => 220, '᷋' => 230, '᷌' => 230, '᷍' => 234, '᷎' => 214, '᷏' => 220, '᷐' => 202, '᷑' => 230, '᷒' => 230, 'ᷓ' => 230, 'ᷔ' => 230, 'ᷕ' => 230, 'ᷖ' => 230, 'ᷗ' => 230, 'ᷘ' => 230, 'ᷙ' => 230, 'ᷚ' => 230, 'ᷛ' => 230, 'ᷜ' => 230, 'ᷝ' => 230, 'ᷞ' => 230, 'ᷟ' => 230, 'ᷠ' => 230, 'ᷡ' => 230, 'ᷢ' => 230, 'ᷣ' => 230, 'ᷤ' => 230, 'ᷥ' => 230, 'ᷦ' => 230, 'ᷧ' => 230, 'ᷨ' => 230, 'ᷩ' => 230, 'ᷪ' => 230, 'ᷫ' => 230, 'ᷬ' => 230, 'ᷭ' => 230, 'ᷮ' => 230, 'ᷯ' => 230, 'ᷰ' => 230, 'ᷱ' => 230, 'ᷲ' => 230, 'ᷳ' => 230, 'ᷴ' => 230, '᷵' => 230, '᷶' => 232, '᷷' => 228, '᷸' => 228, '᷹' => 220, '᷻' => 230, '᷼' => 233, '᷽' => 220, '᷾' => 230, '᷿' => 220, '⃐' => 230, '⃑' => 230, '⃒' => 1, '⃓' => 1, '⃔' => 230, '⃕' => 230, '⃖' => 230, '⃗' => 230, '⃘' => 1, '⃙' => 1, '⃚' => 1, '⃛' => 230, '⃜' => 230, '⃡' => 230, '⃥' => 1, '⃦' => 1, '⃧' => 230, '⃨' => 220, '⃩' => 230, '⃪' => 1, '⃫' => 1, '⃬' => 220, '⃭' => 220, '⃮' => 220, '⃯' => 220, '⃰' => 230, '⳯' => 230, '⳰' => 230, '⳱' => 230, '⵿' => 9, 'ⷠ' => 230, 'ⷡ' => 230, 'ⷢ' => 230, 'ⷣ' => 230, 'ⷤ' => 230, 'ⷥ' => 230, 'ⷦ' => 230, 'ⷧ' => 230, 'ⷨ' => 230, 'ⷩ' => 230, 'ⷪ' => 230, 'ⷫ' => 230, 'ⷬ' => 230, 'ⷭ' => 230, 'ⷮ' => 230, 'ⷯ' => 230, 'ⷰ' => 230, 'ⷱ' => 230, 'ⷲ' => 230, 'ⷳ' => 230, 'ⷴ' => 230, 'ⷵ' => 230, 'ⷶ' => 230, 'ⷷ' => 230, 'ⷸ' => 230, 'ⷹ' => 230, 'ⷺ' => 230, 'ⷻ' => 230, 'ⷼ' => 230, 'ⷽ' => 230, 'ⷾ' => 230, 'ⷿ' => 230, '〪' => 218, '〫' => 228, '〬' => 232, '〭' => 222, '〮' => 224, '〯' => 224, '゙' => 8, '゚' => 8, '꙯' => 230, 'ꙴ' => 230, 'ꙵ' => 230, 'ꙶ' => 230, 'ꙷ' => 230, 'ꙸ' => 230, 'ꙹ' => 230, 'ꙺ' => 230, 'ꙻ' => 230, '꙼' => 230, '꙽' => 230, 'ꚞ' => 230, 'ꚟ' => 230, '꛰' => 230, '꛱' => 230, '꠆' => 9, '꠬' => 9, '꣄' => 9, '꣠' => 230, '꣡' => 230, '꣢' => 230, '꣣' => 230, '꣤' => 230, '꣥' => 230, '꣦' => 230, '꣧' => 230, '꣨' => 230, '꣩' => 230, '꣪' => 230, '꣫' => 230, '꣬' => 230, '꣭' => 230, '꣮' => 230, '꣯' => 230, '꣰' => 230, '꣱' => 230, '꤫' => 220, '꤬' => 220, '꤭' => 220, '꥓' => 9, '꦳' => 7, '꧀' => 9, 'ꪰ' => 230, 'ꪲ' => 230, 'ꪳ' => 230, 'ꪴ' => 220, 'ꪷ' => 230, 'ꪸ' => 230, 'ꪾ' => 230, '꪿' => 230, '꫁' => 230, '꫶' => 9, '꯭' => 9, 'ﬞ' => 26, '︠' => 230, '︡' => 230, '︢' => 230, '︣' => 230, '︤' => 230, '︥' => 230, '︦' => 230, '︧' => 220, '︨' => 220, '︩' => 220, '︪' => 220, '︫' => 220, '︬' => 220, '︭' => 220, '︮' => 230, '︯' => 230, '𐇽' => 220, '𐋠' => 220, '𐍶' => 230, '𐍷' => 230, '𐍸' => 230, '𐍹' => 230, '𐍺' => 230, '𐨍' => 220, '𐨏' => 230, '𐨸' => 230, '𐨹' => 1, '𐨺' => 220, '𐨿' => 9, '𐫥' => 230, '𐫦' => 220, '𐴤' => 230, '𐴥' => 230, '𐴦' => 230, '𐴧' => 230, '𐺫' => 230, '𐺬' => 230, '𐽆' => 220, '𐽇' => 220, '𐽈' => 230, '𐽉' => 230, '𐽊' => 230, '𐽋' => 220, '𐽌' => 230, '𐽍' => 220, '𐽎' => 220, '𐽏' => 220, '𐽐' => 220, '𑁆' => 9, '𑁿' => 9, '𑂹' => 9, '𑂺' => 7, '𑄀' => 230, '𑄁' => 230, '𑄂' => 230, '𑄳' => 9, '𑄴' => 9, '𑅳' => 7, '𑇀' => 9, '𑇊' => 7, '𑈵' => 9, '𑈶' => 7, '𑋩' => 7, '𑋪' => 9, '𑌻' => 7, '𑌼' => 7, '𑍍' => 9, '𑍦' => 230, '𑍧' => 230, '𑍨' => 230, '𑍩' => 230, '𑍪' => 230, '𑍫' => 230, '𑍬' => 230, '𑍰' => 230, '𑍱' => 230, '𑍲' => 230, '𑍳' => 230, '𑍴' => 230, '𑑂' => 9, '𑑆' => 7, '𑑞' => 230, '𑓂' => 9, '𑓃' => 7, '𑖿' => 9, '𑗀' => 7, '𑘿' => 9, '𑚶' => 9, '𑚷' => 7, '𑜫' => 9, '𑠹' => 9, '𑠺' => 7, '𑤽' => 9, '𑤾' => 9, '𑥃' => 7, '𑧠' => 9, '𑨴' => 9, '𑩇' => 9, '𑪙' => 9, '𑰿' => 9, '𑵂' => 7, '𑵄' => 9, '𑵅' => 9, '𑶗' => 9, '𖫰' => 1, '𖫱' => 1, '𖫲' => 1, '𖫳' => 1, '𖫴' => 1, '𖬰' => 230, '𖬱' => 230, '𖬲' => 230, '𖬳' => 230, '𖬴' => 230, '𖬵' => 230, '𖬶' => 230, '𖿰' => 6, '𖿱' => 6, '𛲞' => 1, '𝅥' => 216, '𝅦' => 216, '𝅧' => 1, '𝅨' => 1, '𝅩' => 1, '𝅭' => 226, '𝅮' => 216, '𝅯' => 216, '𝅰' => 216, '𝅱' => 216, '𝅲' => 216, '𝅻' => 220, '𝅼' => 220, '𝅽' => 220, '𝅾' => 220, '𝅿' => 220, '𝆀' => 220, '𝆁' => 220, '𝆂' => 220, '𝆅' => 230, '𝆆' => 230, '𝆇' => 230, '𝆈' => 230, '𝆉' => 230, '𝆊' => 220, '𝆋' => 220, '𝆪' => 230, '𝆫' => 230, '𝆬' => 230, '𝆭' => 230, '𝉂' => 230, '𝉃' => 230, '𝉄' => 230, '𞀀' => 230, '𞀁' => 230, '𞀂' => 230, '𞀃' => 230, '𞀄' => 230, '𞀅' => 230, '𞀆' => 230, '𞀈' => 230, '𞀉' => 230, '𞀊' => 230, '𞀋' => 230, '𞀌' => 230, '𞀍' => 230, '𞀎' => 230, '𞀏' => 230, '𞀐' => 230, '𞀑' => 230, '𞀒' => 230, '𞀓' => 230, '𞀔' => 230, '𞀕' => 230, '𞀖' => 230, '𞀗' => 230, '𞀘' => 230, '𞀛' => 230, '𞀜' => 230, '𞀝' => 230, '𞀞' => 230, '𞀟' => 230, '𞀠' => 230, '𞀡' => 230, '𞀣' => 230, '𞀤' => 230, '𞀦' => 230, '𞀧' => 230, '𞀨' => 230, '𞀩' => 230, '𞀪' => 230, '𞄰' => 230, '𞄱' => 230, '𞄲' => 230, '𞄳' => 230, '𞄴' => 230, '𞄵' => 230, '𞄶' => 230, '𞋬' => 230, '𞋭' => 230, '𞋮' => 230, '𞋯' => 230, '𞣐' => 220, '𞣑' => 220, '𞣒' => 220, '𞣓' => 220, '𞣔' => 220, '𞣕' => 220, '𞣖' => 220, '𞥄' => 230, '𞥅' => 230, '𞥆' => 230, '𞥇' => 230, '𞥈' => 230, '𞥉' => 230, '𞥊' => 7); diff --git a/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php new file mode 100644 index 0000000000..f8b8c4fef5 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php @@ -0,0 +1,5 @@ + ' ', '¨' => ' ̈', 'ª' => 'a', '¯' => ' ̄', '²' => '2', '³' => '3', '´' => ' ́', 'µ' => 'μ', '¸' => ' ̧', '¹' => '1', 'º' => 'o', '¼' => '1⁄4', '½' => '1⁄2', '¾' => '3⁄4', 'IJ' => 'IJ', 'ij' => 'ij', 'Ŀ' => 'L·', 'ŀ' => 'l·', 'ʼn' => 'ʼn', 'ſ' => 's', 'DŽ' => 'DŽ', 'Dž' => 'Dž', 'dž' => 'dž', 'LJ' => 'LJ', 'Lj' => 'Lj', 'lj' => 'lj', 'NJ' => 'NJ', 'Nj' => 'Nj', 'nj' => 'nj', 'DZ' => 'DZ', 'Dz' => 'Dz', 'dz' => 'dz', 'ʰ' => 'h', 'ʱ' => 'ɦ', 'ʲ' => 'j', 'ʳ' => 'r', 'ʴ' => 'ɹ', 'ʵ' => 'ɻ', 'ʶ' => 'ʁ', 'ʷ' => 'w', 'ʸ' => 'y', '˘' => ' ̆', '˙' => ' ̇', '˚' => ' ̊', '˛' => ' ̨', '˜' => ' ̃', '˝' => ' ̋', 'ˠ' => 'ɣ', 'ˡ' => 'l', 'ˢ' => 's', 'ˣ' => 'x', 'ˤ' => 'ʕ', 'ͺ' => ' ͅ', '΄' => ' ́', '΅' => ' ̈́', 'ϐ' => 'β', 'ϑ' => 'θ', 'ϒ' => 'Υ', 'ϓ' => 'Ύ', 'ϔ' => 'Ϋ', 'ϕ' => 'φ', 'ϖ' => 'π', 'ϰ' => 'κ', 'ϱ' => 'ρ', 'ϲ' => 'ς', 'ϴ' => 'Θ', 'ϵ' => 'ε', 'Ϲ' => 'Σ', 'և' => 'եւ', 'ٵ' => 'اٴ', 'ٶ' => 'وٴ', 'ٷ' => 'ۇٴ', 'ٸ' => 'يٴ', 'ำ' => 'ํา', 'ຳ' => 'ໍາ', 'ໜ' => 'ຫນ', 'ໝ' => 'ຫມ', '༌' => '་', 'ཷ' => 'ྲཱྀ', 'ཹ' => 'ླཱྀ', 'ჼ' => 'ნ', 'ᴬ' => 'A', 'ᴭ' => 'Æ', 'ᴮ' => 'B', 'ᴰ' => 'D', 'ᴱ' => 'E', 'ᴲ' => 'Ǝ', 'ᴳ' => 'G', 'ᴴ' => 'H', 'ᴵ' => 'I', 'ᴶ' => 'J', 'ᴷ' => 'K', 'ᴸ' => 'L', 'ᴹ' => 'M', 'ᴺ' => 'N', 'ᴼ' => 'O', 'ᴽ' => 'Ȣ', 'ᴾ' => 'P', 'ᴿ' => 'R', 'ᵀ' => 'T', 'ᵁ' => 'U', 'ᵂ' => 'W', 'ᵃ' => 'a', 'ᵄ' => 'ɐ', 'ᵅ' => 'ɑ', 'ᵆ' => 'ᴂ', 'ᵇ' => 'b', 'ᵈ' => 'd', 'ᵉ' => 'e', 'ᵊ' => 'ə', 'ᵋ' => 'ɛ', 'ᵌ' => 'ɜ', 'ᵍ' => 'g', 'ᵏ' => 'k', 'ᵐ' => 'm', 'ᵑ' => 'ŋ', 'ᵒ' => 'o', 'ᵓ' => 'ɔ', 'ᵔ' => 'ᴖ', 'ᵕ' => 'ᴗ', 'ᵖ' => 'p', 'ᵗ' => 't', 'ᵘ' => 'u', 'ᵙ' => 'ᴝ', 'ᵚ' => 'ɯ', 'ᵛ' => 'v', 'ᵜ' => 'ᴥ', 'ᵝ' => 'β', 'ᵞ' => 'γ', 'ᵟ' => 'δ', 'ᵠ' => 'φ', 'ᵡ' => 'χ', 'ᵢ' => 'i', 'ᵣ' => 'r', 'ᵤ' => 'u', 'ᵥ' => 'v', 'ᵦ' => 'β', 'ᵧ' => 'γ', 'ᵨ' => 'ρ', 'ᵩ' => 'φ', 'ᵪ' => 'χ', 'ᵸ' => 'н', 'ᶛ' => 'ɒ', 'ᶜ' => 'c', 'ᶝ' => 'ɕ', 'ᶞ' => 'ð', 'ᶟ' => 'ɜ', 'ᶠ' => 'f', 'ᶡ' => 'ɟ', 'ᶢ' => 'ɡ', 'ᶣ' => 'ɥ', 'ᶤ' => 'ɨ', 'ᶥ' => 'ɩ', 'ᶦ' => 'ɪ', 'ᶧ' => 'ᵻ', 'ᶨ' => 'ʝ', 'ᶩ' => 'ɭ', 'ᶪ' => 'ᶅ', 'ᶫ' => 'ʟ', 'ᶬ' => 'ɱ', 'ᶭ' => 'ɰ', 'ᶮ' => 'ɲ', 'ᶯ' => 'ɳ', 'ᶰ' => 'ɴ', 'ᶱ' => 'ɵ', 'ᶲ' => 'ɸ', 'ᶳ' => 'ʂ', 'ᶴ' => 'ʃ', 'ᶵ' => 'ƫ', 'ᶶ' => 'ʉ', 'ᶷ' => 'ʊ', 'ᶸ' => 'ᴜ', 'ᶹ' => 'ʋ', 'ᶺ' => 'ʌ', 'ᶻ' => 'z', 'ᶼ' => 'ʐ', 'ᶽ' => 'ʑ', 'ᶾ' => 'ʒ', 'ᶿ' => 'θ', 'ẚ' => 'aʾ', 'ẛ' => 'ṡ', '᾽' => ' ̓', '᾿' => ' ̓', '῀' => ' ͂', '῁' => ' ̈͂', '῍' => ' ̓̀', '῎' => ' ̓́', '῏' => ' ̓͂', '῝' => ' ̔̀', '῞' => ' ̔́', '῟' => ' ̔͂', '῭' => ' ̈̀', '΅' => ' ̈́', '´' => ' ́', '῾' => ' ̔', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', '‑' => '‐', '‗' => ' ̳', '․' => '.', '‥' => '..', '…' => '...', ' ' => ' ', '″' => '′′', '‴' => '′′′', '‶' => '‵‵', '‷' => '‵‵‵', '‼' => '!!', '‾' => ' ̅', '⁇' => '??', '⁈' => '?!', '⁉' => '!?', '⁗' => '′′′′', ' ' => ' ', '⁰' => '0', 'ⁱ' => 'i', '⁴' => '4', '⁵' => '5', '⁶' => '6', '⁷' => '7', '⁸' => '8', '⁹' => '9', '⁺' => '+', '⁻' => '−', '⁼' => '=', '⁽' => '(', '⁾' => ')', 'ⁿ' => 'n', '₀' => '0', '₁' => '1', '₂' => '2', '₃' => '3', '₄' => '4', '₅' => '5', '₆' => '6', '₇' => '7', '₈' => '8', '₉' => '9', '₊' => '+', '₋' => '−', '₌' => '=', '₍' => '(', '₎' => ')', 'ₐ' => 'a', 'ₑ' => 'e', 'ₒ' => 'o', 'ₓ' => 'x', 'ₔ' => 'ə', 'ₕ' => 'h', 'ₖ' => 'k', 'ₗ' => 'l', 'ₘ' => 'm', 'ₙ' => 'n', 'ₚ' => 'p', 'ₛ' => 's', 'ₜ' => 't', '₨' => 'Rs', '℀' => 'a/c', '℁' => 'a/s', 'ℂ' => 'C', '℃' => '°C', '℅' => 'c/o', '℆' => 'c/u', 'ℇ' => 'Ɛ', '℉' => '°F', 'ℊ' => 'g', 'ℋ' => 'H', 'ℌ' => 'H', 'ℍ' => 'H', 'ℎ' => 'h', 'ℏ' => 'ħ', 'ℐ' => 'I', 'ℑ' => 'I', 'ℒ' => 'L', 'ℓ' => 'l', 'ℕ' => 'N', '№' => 'No', 'ℙ' => 'P', 'ℚ' => 'Q', 'ℛ' => 'R', 'ℜ' => 'R', 'ℝ' => 'R', '℠' => 'SM', '℡' => 'TEL', '™' => 'TM', 'ℤ' => 'Z', 'ℨ' => 'Z', 'ℬ' => 'B', 'ℭ' => 'C', 'ℯ' => 'e', 'ℰ' => 'E', 'ℱ' => 'F', 'ℳ' => 'M', 'ℴ' => 'o', 'ℵ' => 'א', 'ℶ' => 'ב', 'ℷ' => 'ג', 'ℸ' => 'ד', 'ℹ' => 'i', '℻' => 'FAX', 'ℼ' => 'π', 'ℽ' => 'γ', 'ℾ' => 'Γ', 'ℿ' => 'Π', '⅀' => '∑', 'ⅅ' => 'D', 'ⅆ' => 'd', 'ⅇ' => 'e', 'ⅈ' => 'i', 'ⅉ' => 'j', '⅐' => '1⁄7', '⅑' => '1⁄9', '⅒' => '1⁄10', '⅓' => '1⁄3', '⅔' => '2⁄3', '⅕' => '1⁄5', '⅖' => '2⁄5', '⅗' => '3⁄5', '⅘' => '4⁄5', '⅙' => '1⁄6', '⅚' => '5⁄6', '⅛' => '1⁄8', '⅜' => '3⁄8', '⅝' => '5⁄8', '⅞' => '7⁄8', '⅟' => '1⁄', 'Ⅰ' => 'I', 'Ⅱ' => 'II', 'Ⅲ' => 'III', 'Ⅳ' => 'IV', 'Ⅴ' => 'V', 'Ⅵ' => 'VI', 'Ⅶ' => 'VII', 'Ⅷ' => 'VIII', 'Ⅸ' => 'IX', 'Ⅹ' => 'X', 'Ⅺ' => 'XI', 'Ⅻ' => 'XII', 'Ⅼ' => 'L', 'Ⅽ' => 'C', 'Ⅾ' => 'D', 'Ⅿ' => 'M', 'ⅰ' => 'i', 'ⅱ' => 'ii', 'ⅲ' => 'iii', 'ⅳ' => 'iv', 'ⅴ' => 'v', 'ⅵ' => 'vi', 'ⅶ' => 'vii', 'ⅷ' => 'viii', 'ⅸ' => 'ix', 'ⅹ' => 'x', 'ⅺ' => 'xi', 'ⅻ' => 'xii', 'ⅼ' => 'l', 'ⅽ' => 'c', 'ⅾ' => 'd', 'ⅿ' => 'm', '↉' => '0⁄3', '∬' => '∫∫', '∭' => '∫∫∫', '∯' => '∮∮', '∰' => '∮∮∮', '①' => '1', '②' => '2', '③' => '3', '④' => '4', '⑤' => '5', '⑥' => '6', '⑦' => '7', '⑧' => '8', '⑨' => '9', '⑩' => '10', '⑪' => '11', '⑫' => '12', '⑬' => '13', '⑭' => '14', '⑮' => '15', '⑯' => '16', '⑰' => '17', '⑱' => '18', '⑲' => '19', '⑳' => '20', '⑴' => '(1)', '⑵' => '(2)', '⑶' => '(3)', '⑷' => '(4)', '⑸' => '(5)', '⑹' => '(6)', '⑺' => '(7)', '⑻' => '(8)', '⑼' => '(9)', '⑽' => '(10)', '⑾' => '(11)', '⑿' => '(12)', '⒀' => '(13)', '⒁' => '(14)', '⒂' => '(15)', '⒃' => '(16)', '⒄' => '(17)', '⒅' => '(18)', '⒆' => '(19)', '⒇' => '(20)', '⒈' => '1.', '⒉' => '2.', '⒊' => '3.', '⒋' => '4.', '⒌' => '5.', '⒍' => '6.', '⒎' => '7.', '⒏' => '8.', '⒐' => '9.', '⒑' => '10.', '⒒' => '11.', '⒓' => '12.', '⒔' => '13.', '⒕' => '14.', '⒖' => '15.', '⒗' => '16.', '⒘' => '17.', '⒙' => '18.', '⒚' => '19.', '⒛' => '20.', '⒜' => '(a)', '⒝' => '(b)', '⒞' => '(c)', '⒟' => '(d)', '⒠' => '(e)', '⒡' => '(f)', '⒢' => '(g)', '⒣' => '(h)', '⒤' => '(i)', '⒥' => '(j)', '⒦' => '(k)', '⒧' => '(l)', '⒨' => '(m)', '⒩' => '(n)', '⒪' => '(o)', '⒫' => '(p)', '⒬' => '(q)', '⒭' => '(r)', '⒮' => '(s)', '⒯' => '(t)', '⒰' => '(u)', '⒱' => '(v)', '⒲' => '(w)', '⒳' => '(x)', '⒴' => '(y)', '⒵' => '(z)', 'Ⓐ' => 'A', 'Ⓑ' => 'B', 'Ⓒ' => 'C', 'Ⓓ' => 'D', 'Ⓔ' => 'E', 'Ⓕ' => 'F', 'Ⓖ' => 'G', 'Ⓗ' => 'H', 'Ⓘ' => 'I', 'Ⓙ' => 'J', 'Ⓚ' => 'K', 'Ⓛ' => 'L', 'Ⓜ' => 'M', 'Ⓝ' => 'N', 'Ⓞ' => 'O', 'Ⓟ' => 'P', 'Ⓠ' => 'Q', 'Ⓡ' => 'R', 'Ⓢ' => 'S', 'Ⓣ' => 'T', 'Ⓤ' => 'U', 'Ⓥ' => 'V', 'Ⓦ' => 'W', 'Ⓧ' => 'X', 'Ⓨ' => 'Y', 'Ⓩ' => 'Z', 'ⓐ' => 'a', 'ⓑ' => 'b', 'ⓒ' => 'c', 'ⓓ' => 'd', 'ⓔ' => 'e', 'ⓕ' => 'f', 'ⓖ' => 'g', 'ⓗ' => 'h', 'ⓘ' => 'i', 'ⓙ' => 'j', 'ⓚ' => 'k', 'ⓛ' => 'l', 'ⓜ' => 'm', 'ⓝ' => 'n', 'ⓞ' => 'o', 'ⓟ' => 'p', 'ⓠ' => 'q', 'ⓡ' => 'r', 'ⓢ' => 's', 'ⓣ' => 't', 'ⓤ' => 'u', 'ⓥ' => 'v', 'ⓦ' => 'w', 'ⓧ' => 'x', 'ⓨ' => 'y', 'ⓩ' => 'z', '⓪' => '0', '⨌' => '∫∫∫∫', '⩴' => '::=', '⩵' => '==', '⩶' => '===', 'ⱼ' => 'j', 'ⱽ' => 'V', 'ⵯ' => 'ⵡ', '⺟' => '母', '⻳' => '龟', '⼀' => '一', '⼁' => '丨', '⼂' => '丶', '⼃' => '丿', '⼄' => '乙', '⼅' => '亅', '⼆' => '二', '⼇' => '亠', '⼈' => '人', '⼉' => '儿', '⼊' => '入', '⼋' => '八', '⼌' => '冂', '⼍' => '冖', '⼎' => '冫', '⼏' => '几', '⼐' => '凵', '⼑' => '刀', '⼒' => '力', '⼓' => '勹', '⼔' => '匕', '⼕' => '匚', '⼖' => '匸', '⼗' => '十', '⼘' => '卜', '⼙' => '卩', '⼚' => '厂', '⼛' => '厶', '⼜' => '又', '⼝' => '口', '⼞' => '囗', '⼟' => '土', '⼠' => '士', '⼡' => '夂', '⼢' => '夊', '⼣' => '夕', '⼤' => '大', '⼥' => '女', '⼦' => '子', '⼧' => '宀', '⼨' => '寸', '⼩' => '小', '⼪' => '尢', '⼫' => '尸', '⼬' => '屮', '⼭' => '山', '⼮' => '巛', '⼯' => '工', '⼰' => '己', '⼱' => '巾', '⼲' => '干', '⼳' => '幺', '⼴' => '广', '⼵' => '廴', '⼶' => '廾', '⼷' => '弋', '⼸' => '弓', '⼹' => '彐', '⼺' => '彡', '⼻' => '彳', '⼼' => '心', '⼽' => '戈', '⼾' => '戶', '⼿' => '手', '⽀' => '支', '⽁' => '攴', '⽂' => '文', '⽃' => '斗', '⽄' => '斤', '⽅' => '方', '⽆' => '无', '⽇' => '日', '⽈' => '曰', '⽉' => '月', '⽊' => '木', '⽋' => '欠', '⽌' => '止', '⽍' => '歹', '⽎' => '殳', '⽏' => '毋', '⽐' => '比', '⽑' => '毛', '⽒' => '氏', '⽓' => '气', '⽔' => '水', '⽕' => '火', '⽖' => '爪', '⽗' => '父', '⽘' => '爻', '⽙' => '爿', '⽚' => '片', '⽛' => '牙', '⽜' => '牛', '⽝' => '犬', '⽞' => '玄', '⽟' => '玉', '⽠' => '瓜', '⽡' => '瓦', '⽢' => '甘', '⽣' => '生', '⽤' => '用', '⽥' => '田', '⽦' => '疋', '⽧' => '疒', '⽨' => '癶', '⽩' => '白', '⽪' => '皮', '⽫' => '皿', '⽬' => '目', '⽭' => '矛', '⽮' => '矢', '⽯' => '石', '⽰' => '示', '⽱' => '禸', '⽲' => '禾', '⽳' => '穴', '⽴' => '立', '⽵' => '竹', '⽶' => '米', '⽷' => '糸', '⽸' => '缶', '⽹' => '网', '⽺' => '羊', '⽻' => '羽', '⽼' => '老', '⽽' => '而', '⽾' => '耒', '⽿' => '耳', '⾀' => '聿', '⾁' => '肉', '⾂' => '臣', '⾃' => '自', '⾄' => '至', '⾅' => '臼', '⾆' => '舌', '⾇' => '舛', '⾈' => '舟', '⾉' => '艮', '⾊' => '色', '⾋' => '艸', '⾌' => '虍', '⾍' => '虫', '⾎' => '血', '⾏' => '行', '⾐' => '衣', '⾑' => '襾', '⾒' => '見', '⾓' => '角', '⾔' => '言', '⾕' => '谷', '⾖' => '豆', '⾗' => '豕', '⾘' => '豸', '⾙' => '貝', '⾚' => '赤', '⾛' => '走', '⾜' => '足', '⾝' => '身', '⾞' => '車', '⾟' => '辛', '⾠' => '辰', '⾡' => '辵', '⾢' => '邑', '⾣' => '酉', '⾤' => '釆', '⾥' => '里', '⾦' => '金', '⾧' => '長', '⾨' => '門', '⾩' => '阜', '⾪' => '隶', '⾫' => '隹', '⾬' => '雨', '⾭' => '靑', '⾮' => '非', '⾯' => '面', '⾰' => '革', '⾱' => '韋', '⾲' => '韭', '⾳' => '音', '⾴' => '頁', '⾵' => '風', '⾶' => '飛', '⾷' => '食', '⾸' => '首', '⾹' => '香', '⾺' => '馬', '⾻' => '骨', '⾼' => '高', '⾽' => '髟', '⾾' => '鬥', '⾿' => '鬯', '⿀' => '鬲', '⿁' => '鬼', '⿂' => '魚', '⿃' => '鳥', '⿄' => '鹵', '⿅' => '鹿', '⿆' => '麥', '⿇' => '麻', '⿈' => '黃', '⿉' => '黍', '⿊' => '黑', '⿋' => '黹', '⿌' => '黽', '⿍' => '鼎', '⿎' => '鼓', '⿏' => '鼠', '⿐' => '鼻', '⿑' => '齊', '⿒' => '齒', '⿓' => '龍', '⿔' => '龜', '⿕' => '龠', ' ' => ' ', '〶' => '〒', '〸' => '十', '〹' => '卄', '〺' => '卅', '゛' => ' ゙', '゜' => ' ゚', 'ゟ' => 'より', 'ヿ' => 'コト', 'ㄱ' => 'ᄀ', 'ㄲ' => 'ᄁ', 'ㄳ' => 'ᆪ', 'ㄴ' => 'ᄂ', 'ㄵ' => 'ᆬ', 'ㄶ' => 'ᆭ', 'ㄷ' => 'ᄃ', 'ㄸ' => 'ᄄ', 'ㄹ' => 'ᄅ', 'ㄺ' => 'ᆰ', 'ㄻ' => 'ᆱ', 'ㄼ' => 'ᆲ', 'ㄽ' => 'ᆳ', 'ㄾ' => 'ᆴ', 'ㄿ' => 'ᆵ', 'ㅀ' => 'ᄚ', 'ㅁ' => 'ᄆ', 'ㅂ' => 'ᄇ', 'ㅃ' => 'ᄈ', 'ㅄ' => 'ᄡ', 'ㅅ' => 'ᄉ', 'ㅆ' => 'ᄊ', 'ㅇ' => 'ᄋ', 'ㅈ' => 'ᄌ', 'ㅉ' => 'ᄍ', 'ㅊ' => 'ᄎ', 'ㅋ' => 'ᄏ', 'ㅌ' => 'ᄐ', 'ㅍ' => 'ᄑ', 'ㅎ' => 'ᄒ', 'ㅏ' => 'ᅡ', 'ㅐ' => 'ᅢ', 'ㅑ' => 'ᅣ', 'ㅒ' => 'ᅤ', 'ㅓ' => 'ᅥ', 'ㅔ' => 'ᅦ', 'ㅕ' => 'ᅧ', 'ㅖ' => 'ᅨ', 'ㅗ' => 'ᅩ', 'ㅘ' => 'ᅪ', 'ㅙ' => 'ᅫ', 'ㅚ' => 'ᅬ', 'ㅛ' => 'ᅭ', 'ㅜ' => 'ᅮ', 'ㅝ' => 'ᅯ', 'ㅞ' => 'ᅰ', 'ㅟ' => 'ᅱ', 'ㅠ' => 'ᅲ', 'ㅡ' => 'ᅳ', 'ㅢ' => 'ᅴ', 'ㅣ' => 'ᅵ', 'ㅤ' => 'ᅠ', 'ㅥ' => 'ᄔ', 'ㅦ' => 'ᄕ', 'ㅧ' => 'ᇇ', 'ㅨ' => 'ᇈ', 'ㅩ' => 'ᇌ', 'ㅪ' => 'ᇎ', 'ㅫ' => 'ᇓ', 'ㅬ' => 'ᇗ', 'ㅭ' => 'ᇙ', 'ㅮ' => 'ᄜ', 'ㅯ' => 'ᇝ', 'ㅰ' => 'ᇟ', 'ㅱ' => 'ᄝ', 'ㅲ' => 'ᄞ', 'ㅳ' => 'ᄠ', 'ㅴ' => 'ᄢ', 'ㅵ' => 'ᄣ', 'ㅶ' => 'ᄧ', 'ㅷ' => 'ᄩ', 'ㅸ' => 'ᄫ', 'ㅹ' => 'ᄬ', 'ㅺ' => 'ᄭ', 'ㅻ' => 'ᄮ', 'ㅼ' => 'ᄯ', 'ㅽ' => 'ᄲ', 'ㅾ' => 'ᄶ', 'ㅿ' => 'ᅀ', 'ㆀ' => 'ᅇ', 'ㆁ' => 'ᅌ', 'ㆂ' => 'ᇱ', 'ㆃ' => 'ᇲ', 'ㆄ' => 'ᅗ', 'ㆅ' => 'ᅘ', 'ㆆ' => 'ᅙ', 'ㆇ' => 'ᆄ', 'ㆈ' => 'ᆅ', 'ㆉ' => 'ᆈ', 'ㆊ' => 'ᆑ', 'ㆋ' => 'ᆒ', 'ㆌ' => 'ᆔ', 'ㆍ' => 'ᆞ', 'ㆎ' => 'ᆡ', '㆒' => '一', '㆓' => '二', '㆔' => '三', '㆕' => '四', '㆖' => '上', '㆗' => '中', '㆘' => '下', '㆙' => '甲', '㆚' => '乙', '㆛' => '丙', '㆜' => '丁', '㆝' => '天', '㆞' => '地', '㆟' => '人', '㈀' => '(ᄀ)', '㈁' => '(ᄂ)', '㈂' => '(ᄃ)', '㈃' => '(ᄅ)', '㈄' => '(ᄆ)', '㈅' => '(ᄇ)', '㈆' => '(ᄉ)', '㈇' => '(ᄋ)', '㈈' => '(ᄌ)', '㈉' => '(ᄎ)', '㈊' => '(ᄏ)', '㈋' => '(ᄐ)', '㈌' => '(ᄑ)', '㈍' => '(ᄒ)', '㈎' => '(가)', '㈏' => '(나)', '㈐' => '(다)', '㈑' => '(라)', '㈒' => '(마)', '㈓' => '(바)', '㈔' => '(사)', '㈕' => '(아)', '㈖' => '(자)', '㈗' => '(차)', '㈘' => '(카)', '㈙' => '(타)', '㈚' => '(파)', '㈛' => '(하)', '㈜' => '(주)', '㈝' => '(오전)', '㈞' => '(오후)', '㈠' => '(一)', '㈡' => '(二)', '㈢' => '(三)', '㈣' => '(四)', '㈤' => '(五)', '㈥' => '(六)', '㈦' => '(七)', '㈧' => '(八)', '㈨' => '(九)', '㈩' => '(十)', '㈪' => '(月)', '㈫' => '(火)', '㈬' => '(水)', '㈭' => '(木)', '㈮' => '(金)', '㈯' => '(土)', '㈰' => '(日)', '㈱' => '(株)', '㈲' => '(有)', '㈳' => '(社)', '㈴' => '(名)', '㈵' => '(特)', '㈶' => '(財)', '㈷' => '(祝)', '㈸' => '(労)', '㈹' => '(代)', '㈺' => '(呼)', '㈻' => '(学)', '㈼' => '(監)', '㈽' => '(企)', '㈾' => '(資)', '㈿' => '(協)', '㉀' => '(祭)', '㉁' => '(休)', '㉂' => '(自)', '㉃' => '(至)', '㉄' => '問', '㉅' => '幼', '㉆' => '文', '㉇' => '箏', '㉐' => 'PTE', '㉑' => '21', '㉒' => '22', '㉓' => '23', '㉔' => '24', '㉕' => '25', '㉖' => '26', '㉗' => '27', '㉘' => '28', '㉙' => '29', '㉚' => '30', '㉛' => '31', '㉜' => '32', '㉝' => '33', '㉞' => '34', '㉟' => '35', '㉠' => 'ᄀ', '㉡' => 'ᄂ', '㉢' => 'ᄃ', '㉣' => 'ᄅ', '㉤' => 'ᄆ', '㉥' => 'ᄇ', '㉦' => 'ᄉ', '㉧' => 'ᄋ', '㉨' => 'ᄌ', '㉩' => 'ᄎ', '㉪' => 'ᄏ', '㉫' => 'ᄐ', '㉬' => 'ᄑ', '㉭' => 'ᄒ', '㉮' => '가', '㉯' => '나', '㉰' => '다', '㉱' => '라', '㉲' => '마', '㉳' => '바', '㉴' => '사', '㉵' => '아', '㉶' => '자', '㉷' => '차', '㉸' => '카', '㉹' => '타', '㉺' => '파', '㉻' => '하', '㉼' => '참고', '㉽' => '주의', '㉾' => '우', '㊀' => '一', '㊁' => '二', '㊂' => '三', '㊃' => '四', '㊄' => '五', '㊅' => '六', '㊆' => '七', '㊇' => '八', '㊈' => '九', '㊉' => '十', '㊊' => '月', '㊋' => '火', '㊌' => '水', '㊍' => '木', '㊎' => '金', '㊏' => '土', '㊐' => '日', '㊑' => '株', '㊒' => '有', '㊓' => '社', '㊔' => '名', '㊕' => '特', '㊖' => '財', '㊗' => '祝', '㊘' => '労', '㊙' => '秘', '㊚' => '男', '㊛' => '女', '㊜' => '適', '㊝' => '優', '㊞' => '印', '㊟' => '注', '㊠' => '項', '㊡' => '休', '㊢' => '写', '㊣' => '正', '㊤' => '上', '㊥' => '中', '㊦' => '下', '㊧' => '左', '㊨' => '右', '㊩' => '医', '㊪' => '宗', '㊫' => '学', '㊬' => '監', '㊭' => '企', '㊮' => '資', '㊯' => '協', '㊰' => '夜', '㊱' => '36', '㊲' => '37', '㊳' => '38', '㊴' => '39', '㊵' => '40', '㊶' => '41', '㊷' => '42', '㊸' => '43', '㊹' => '44', '㊺' => '45', '㊻' => '46', '㊼' => '47', '㊽' => '48', '㊾' => '49', '㊿' => '50', '㋀' => '1月', '㋁' => '2月', '㋂' => '3月', '㋃' => '4月', '㋄' => '5月', '㋅' => '6月', '㋆' => '7月', '㋇' => '8月', '㋈' => '9月', '㋉' => '10月', '㋊' => '11月', '㋋' => '12月', '㋌' => 'Hg', '㋍' => 'erg', '㋎' => 'eV', '㋏' => 'LTD', '㋐' => 'ア', '㋑' => 'イ', '㋒' => 'ウ', '㋓' => 'エ', '㋔' => 'オ', '㋕' => 'カ', '㋖' => 'キ', '㋗' => 'ク', '㋘' => 'ケ', '㋙' => 'コ', '㋚' => 'サ', '㋛' => 'シ', '㋜' => 'ス', '㋝' => 'セ', '㋞' => 'ソ', '㋟' => 'タ', '㋠' => 'チ', '㋡' => 'ツ', '㋢' => 'テ', '㋣' => 'ト', '㋤' => 'ナ', '㋥' => 'ニ', '㋦' => 'ヌ', '㋧' => 'ネ', '㋨' => 'ノ', '㋩' => 'ハ', '㋪' => 'ヒ', '㋫' => 'フ', '㋬' => 'ヘ', '㋭' => 'ホ', '㋮' => 'マ', '㋯' => 'ミ', '㋰' => 'ム', '㋱' => 'メ', '㋲' => 'モ', '㋳' => 'ヤ', '㋴' => 'ユ', '㋵' => 'ヨ', '㋶' => 'ラ', '㋷' => 'リ', '㋸' => 'ル', '㋹' => 'レ', '㋺' => 'ロ', '㋻' => 'ワ', '㋼' => 'ヰ', '㋽' => 'ヱ', '㋾' => 'ヲ', '㋿' => '令和', '㌀' => 'アパート', '㌁' => 'アルファ', '㌂' => 'アンペア', '㌃' => 'アール', '㌄' => 'イニング', '㌅' => 'インチ', '㌆' => 'ウォン', '㌇' => 'エスクード', '㌈' => 'エーカー', '㌉' => 'オンス', '㌊' => 'オーム', '㌋' => 'カイリ', '㌌' => 'カラット', '㌍' => 'カロリー', '㌎' => 'ガロン', '㌏' => 'ガンマ', '㌐' => 'ギガ', '㌑' => 'ギニー', '㌒' => 'キュリー', '㌓' => 'ギルダー', '㌔' => 'キロ', '㌕' => 'キログラム', '㌖' => 'キロメートル', '㌗' => 'キロワット', '㌘' => 'グラム', '㌙' => 'グラムトン', '㌚' => 'クルゼイロ', '㌛' => 'クローネ', '㌜' => 'ケース', '㌝' => 'コルナ', '㌞' => 'コーポ', '㌟' => 'サイクル', '㌠' => 'サンチーム', '㌡' => 'シリング', '㌢' => 'センチ', '㌣' => 'セント', '㌤' => 'ダース', '㌥' => 'デシ', '㌦' => 'ドル', '㌧' => 'トン', '㌨' => 'ナノ', '㌩' => 'ノット', '㌪' => 'ハイツ', '㌫' => 'パーセント', '㌬' => 'パーツ', '㌭' => 'バーレル', '㌮' => 'ピアストル', '㌯' => 'ピクル', '㌰' => 'ピコ', '㌱' => 'ビル', '㌲' => 'ファラッド', '㌳' => 'フィート', '㌴' => 'ブッシェル', '㌵' => 'フラン', '㌶' => 'ヘクタール', '㌷' => 'ペソ', '㌸' => 'ペニヒ', '㌹' => 'ヘルツ', '㌺' => 'ペンス', '㌻' => 'ページ', '㌼' => 'ベータ', '㌽' => 'ポイント', '㌾' => 'ボルト', '㌿' => 'ホン', '㍀' => 'ポンド', '㍁' => 'ホール', '㍂' => 'ホーン', '㍃' => 'マイクロ', '㍄' => 'マイル', '㍅' => 'マッハ', '㍆' => 'マルク', '㍇' => 'マンション', '㍈' => 'ミクロン', '㍉' => 'ミリ', '㍊' => 'ミリバール', '㍋' => 'メガ', '㍌' => 'メガトン', '㍍' => 'メートル', '㍎' => 'ヤード', '㍏' => 'ヤール', '㍐' => 'ユアン', '㍑' => 'リットル', '㍒' => 'リラ', '㍓' => 'ルピー', '㍔' => 'ルーブル', '㍕' => 'レム', '㍖' => 'レントゲン', '㍗' => 'ワット', '㍘' => '0点', '㍙' => '1点', '㍚' => '2点', '㍛' => '3点', '㍜' => '4点', '㍝' => '5点', '㍞' => '6点', '㍟' => '7点', '㍠' => '8点', '㍡' => '9点', '㍢' => '10点', '㍣' => '11点', '㍤' => '12点', '㍥' => '13点', '㍦' => '14点', '㍧' => '15点', '㍨' => '16点', '㍩' => '17点', '㍪' => '18点', '㍫' => '19点', '㍬' => '20点', '㍭' => '21点', '㍮' => '22点', '㍯' => '23点', '㍰' => '24点', '㍱' => 'hPa', '㍲' => 'da', '㍳' => 'AU', '㍴' => 'bar', '㍵' => 'oV', '㍶' => 'pc', '㍷' => 'dm', '㍸' => 'dm2', '㍹' => 'dm3', '㍺' => 'IU', '㍻' => '平成', '㍼' => '昭和', '㍽' => '大正', '㍾' => '明治', '㍿' => '株式会社', '㎀' => 'pA', '㎁' => 'nA', '㎂' => 'μA', '㎃' => 'mA', '㎄' => 'kA', '㎅' => 'KB', '㎆' => 'MB', '㎇' => 'GB', '㎈' => 'cal', '㎉' => 'kcal', '㎊' => 'pF', '㎋' => 'nF', '㎌' => 'μF', '㎍' => 'μg', '㎎' => 'mg', '㎏' => 'kg', '㎐' => 'Hz', '㎑' => 'kHz', '㎒' => 'MHz', '㎓' => 'GHz', '㎔' => 'THz', '㎕' => 'μl', '㎖' => 'ml', '㎗' => 'dl', '㎘' => 'kl', '㎙' => 'fm', '㎚' => 'nm', '㎛' => 'μm', '㎜' => 'mm', '㎝' => 'cm', '㎞' => 'km', '㎟' => 'mm2', '㎠' => 'cm2', '㎡' => 'm2', '㎢' => 'km2', '㎣' => 'mm3', '㎤' => 'cm3', '㎥' => 'm3', '㎦' => 'km3', '㎧' => 'm∕s', '㎨' => 'm∕s2', '㎩' => 'Pa', '㎪' => 'kPa', '㎫' => 'MPa', '㎬' => 'GPa', '㎭' => 'rad', '㎮' => 'rad∕s', '㎯' => 'rad∕s2', '㎰' => 'ps', '㎱' => 'ns', '㎲' => 'μs', '㎳' => 'ms', '㎴' => 'pV', '㎵' => 'nV', '㎶' => 'μV', '㎷' => 'mV', '㎸' => 'kV', '㎹' => 'MV', '㎺' => 'pW', '㎻' => 'nW', '㎼' => 'μW', '㎽' => 'mW', '㎾' => 'kW', '㎿' => 'MW', '㏀' => 'kΩ', '㏁' => 'MΩ', '㏂' => 'a.m.', '㏃' => 'Bq', '㏄' => 'cc', '㏅' => 'cd', '㏆' => 'C∕kg', '㏇' => 'Co.', '㏈' => 'dB', '㏉' => 'Gy', '㏊' => 'ha', '㏋' => 'HP', '㏌' => 'in', '㏍' => 'KK', '㏎' => 'KM', '㏏' => 'kt', '㏐' => 'lm', '㏑' => 'ln', '㏒' => 'log', '㏓' => 'lx', '㏔' => 'mb', '㏕' => 'mil', '㏖' => 'mol', '㏗' => 'PH', '㏘' => 'p.m.', '㏙' => 'PPM', '㏚' => 'PR', '㏛' => 'sr', '㏜' => 'Sv', '㏝' => 'Wb', '㏞' => 'V∕m', '㏟' => 'A∕m', '㏠' => '1日', '㏡' => '2日', '㏢' => '3日', '㏣' => '4日', '㏤' => '5日', '㏥' => '6日', '㏦' => '7日', '㏧' => '8日', '㏨' => '9日', '㏩' => '10日', '㏪' => '11日', '㏫' => '12日', '㏬' => '13日', '㏭' => '14日', '㏮' => '15日', '㏯' => '16日', '㏰' => '17日', '㏱' => '18日', '㏲' => '19日', '㏳' => '20日', '㏴' => '21日', '㏵' => '22日', '㏶' => '23日', '㏷' => '24日', '㏸' => '25日', '㏹' => '26日', '㏺' => '27日', '㏻' => '28日', '㏼' => '29日', '㏽' => '30日', '㏾' => '31日', '㏿' => 'gal', 'ꚜ' => 'ъ', 'ꚝ' => 'ь', 'ꝰ' => 'ꝯ', 'ꟸ' => 'Ħ', 'ꟹ' => 'œ', 'ꭜ' => 'ꜧ', 'ꭝ' => 'ꬷ', 'ꭞ' => 'ɫ', 'ꭟ' => 'ꭒ', 'ꭩ' => 'ʍ', 'ff' => 'ff', 'fi' => 'fi', 'fl' => 'fl', 'ffi' => 'ffi', 'ffl' => 'ffl', 'ſt' => 'st', 'st' => 'st', 'ﬓ' => 'մն', 'ﬔ' => 'մե', 'ﬕ' => 'մի', 'ﬖ' => 'վն', 'ﬗ' => 'մխ', 'ﬠ' => 'ע', 'ﬡ' => 'א', 'ﬢ' => 'ד', 'ﬣ' => 'ה', 'ﬤ' => 'כ', 'ﬥ' => 'ל', 'ﬦ' => 'ם', 'ﬧ' => 'ר', 'ﬨ' => 'ת', '﬩' => '+', 'ﭏ' => 'אל', 'ﭐ' => 'ٱ', 'ﭑ' => 'ٱ', 'ﭒ' => 'ٻ', 'ﭓ' => 'ٻ', 'ﭔ' => 'ٻ', 'ﭕ' => 'ٻ', 'ﭖ' => 'پ', 'ﭗ' => 'پ', 'ﭘ' => 'پ', 'ﭙ' => 'پ', 'ﭚ' => 'ڀ', 'ﭛ' => 'ڀ', 'ﭜ' => 'ڀ', 'ﭝ' => 'ڀ', 'ﭞ' => 'ٺ', 'ﭟ' => 'ٺ', 'ﭠ' => 'ٺ', 'ﭡ' => 'ٺ', 'ﭢ' => 'ٿ', 'ﭣ' => 'ٿ', 'ﭤ' => 'ٿ', 'ﭥ' => 'ٿ', 'ﭦ' => 'ٹ', 'ﭧ' => 'ٹ', 'ﭨ' => 'ٹ', 'ﭩ' => 'ٹ', 'ﭪ' => 'ڤ', 'ﭫ' => 'ڤ', 'ﭬ' => 'ڤ', 'ﭭ' => 'ڤ', 'ﭮ' => 'ڦ', 'ﭯ' => 'ڦ', 'ﭰ' => 'ڦ', 'ﭱ' => 'ڦ', 'ﭲ' => 'ڄ', 'ﭳ' => 'ڄ', 'ﭴ' => 'ڄ', 'ﭵ' => 'ڄ', 'ﭶ' => 'ڃ', 'ﭷ' => 'ڃ', 'ﭸ' => 'ڃ', 'ﭹ' => 'ڃ', 'ﭺ' => 'چ', 'ﭻ' => 'چ', 'ﭼ' => 'چ', 'ﭽ' => 'چ', 'ﭾ' => 'ڇ', 'ﭿ' => 'ڇ', 'ﮀ' => 'ڇ', 'ﮁ' => 'ڇ', 'ﮂ' => 'ڍ', 'ﮃ' => 'ڍ', 'ﮄ' => 'ڌ', 'ﮅ' => 'ڌ', 'ﮆ' => 'ڎ', 'ﮇ' => 'ڎ', 'ﮈ' => 'ڈ', 'ﮉ' => 'ڈ', 'ﮊ' => 'ژ', 'ﮋ' => 'ژ', 'ﮌ' => 'ڑ', 'ﮍ' => 'ڑ', 'ﮎ' => 'ک', 'ﮏ' => 'ک', 'ﮐ' => 'ک', 'ﮑ' => 'ک', 'ﮒ' => 'گ', 'ﮓ' => 'گ', 'ﮔ' => 'گ', 'ﮕ' => 'گ', 'ﮖ' => 'ڳ', 'ﮗ' => 'ڳ', 'ﮘ' => 'ڳ', 'ﮙ' => 'ڳ', 'ﮚ' => 'ڱ', 'ﮛ' => 'ڱ', 'ﮜ' => 'ڱ', 'ﮝ' => 'ڱ', 'ﮞ' => 'ں', 'ﮟ' => 'ں', 'ﮠ' => 'ڻ', 'ﮡ' => 'ڻ', 'ﮢ' => 'ڻ', 'ﮣ' => 'ڻ', 'ﮤ' => 'ۀ', 'ﮥ' => 'ۀ', 'ﮦ' => 'ہ', 'ﮧ' => 'ہ', 'ﮨ' => 'ہ', 'ﮩ' => 'ہ', 'ﮪ' => 'ھ', 'ﮫ' => 'ھ', 'ﮬ' => 'ھ', 'ﮭ' => 'ھ', 'ﮮ' => 'ے', 'ﮯ' => 'ے', 'ﮰ' => 'ۓ', 'ﮱ' => 'ۓ', 'ﯓ' => 'ڭ', 'ﯔ' => 'ڭ', 'ﯕ' => 'ڭ', 'ﯖ' => 'ڭ', 'ﯗ' => 'ۇ', 'ﯘ' => 'ۇ', 'ﯙ' => 'ۆ', 'ﯚ' => 'ۆ', 'ﯛ' => 'ۈ', 'ﯜ' => 'ۈ', 'ﯝ' => 'ۇٴ', 'ﯞ' => 'ۋ', 'ﯟ' => 'ۋ', 'ﯠ' => 'ۅ', 'ﯡ' => 'ۅ', 'ﯢ' => 'ۉ', 'ﯣ' => 'ۉ', 'ﯤ' => 'ې', 'ﯥ' => 'ې', 'ﯦ' => 'ې', 'ﯧ' => 'ې', 'ﯨ' => 'ى', 'ﯩ' => 'ى', 'ﯪ' => 'ئا', 'ﯫ' => 'ئا', 'ﯬ' => 'ئە', 'ﯭ' => 'ئە', 'ﯮ' => 'ئو', 'ﯯ' => 'ئو', 'ﯰ' => 'ئۇ', 'ﯱ' => 'ئۇ', 'ﯲ' => 'ئۆ', 'ﯳ' => 'ئۆ', 'ﯴ' => 'ئۈ', 'ﯵ' => 'ئۈ', 'ﯶ' => 'ئې', 'ﯷ' => 'ئې', 'ﯸ' => 'ئې', 'ﯹ' => 'ئى', 'ﯺ' => 'ئى', 'ﯻ' => 'ئى', 'ﯼ' => 'ی', 'ﯽ' => 'ی', 'ﯾ' => 'ی', 'ﯿ' => 'ی', 'ﰀ' => 'ئج', 'ﰁ' => 'ئح', 'ﰂ' => 'ئم', 'ﰃ' => 'ئى', 'ﰄ' => 'ئي', 'ﰅ' => 'بج', 'ﰆ' => 'بح', 'ﰇ' => 'بخ', 'ﰈ' => 'بم', 'ﰉ' => 'بى', 'ﰊ' => 'بي', 'ﰋ' => 'تج', 'ﰌ' => 'تح', 'ﰍ' => 'تخ', 'ﰎ' => 'تم', 'ﰏ' => 'تى', 'ﰐ' => 'تي', 'ﰑ' => 'ثج', 'ﰒ' => 'ثم', 'ﰓ' => 'ثى', 'ﰔ' => 'ثي', 'ﰕ' => 'جح', 'ﰖ' => 'جم', 'ﰗ' => 'حج', 'ﰘ' => 'حم', 'ﰙ' => 'خج', 'ﰚ' => 'خح', 'ﰛ' => 'خم', 'ﰜ' => 'سج', 'ﰝ' => 'سح', 'ﰞ' => 'سخ', 'ﰟ' => 'سم', 'ﰠ' => 'صح', 'ﰡ' => 'صم', 'ﰢ' => 'ضج', 'ﰣ' => 'ضح', 'ﰤ' => 'ضخ', 'ﰥ' => 'ضم', 'ﰦ' => 'طح', 'ﰧ' => 'طم', 'ﰨ' => 'ظم', 'ﰩ' => 'عج', 'ﰪ' => 'عم', 'ﰫ' => 'غج', 'ﰬ' => 'غم', 'ﰭ' => 'فج', 'ﰮ' => 'فح', 'ﰯ' => 'فخ', 'ﰰ' => 'فم', 'ﰱ' => 'فى', 'ﰲ' => 'في', 'ﰳ' => 'قح', 'ﰴ' => 'قم', 'ﰵ' => 'قى', 'ﰶ' => 'قي', 'ﰷ' => 'كا', 'ﰸ' => 'كج', 'ﰹ' => 'كح', 'ﰺ' => 'كخ', 'ﰻ' => 'كل', 'ﰼ' => 'كم', 'ﰽ' => 'كى', 'ﰾ' => 'كي', 'ﰿ' => 'لج', 'ﱀ' => 'لح', 'ﱁ' => 'لخ', 'ﱂ' => 'لم', 'ﱃ' => 'لى', 'ﱄ' => 'لي', 'ﱅ' => 'مج', 'ﱆ' => 'مح', 'ﱇ' => 'مخ', 'ﱈ' => 'مم', 'ﱉ' => 'مى', 'ﱊ' => 'مي', 'ﱋ' => 'نج', 'ﱌ' => 'نح', 'ﱍ' => 'نخ', 'ﱎ' => 'نم', 'ﱏ' => 'نى', 'ﱐ' => 'ني', 'ﱑ' => 'هج', 'ﱒ' => 'هم', 'ﱓ' => 'هى', 'ﱔ' => 'هي', 'ﱕ' => 'يج', 'ﱖ' => 'يح', 'ﱗ' => 'يخ', 'ﱘ' => 'يم', 'ﱙ' => 'يى', 'ﱚ' => 'يي', 'ﱛ' => 'ذٰ', 'ﱜ' => 'رٰ', 'ﱝ' => 'ىٰ', 'ﱞ' => ' ٌّ', 'ﱟ' => ' ٍّ', 'ﱠ' => ' َّ', 'ﱡ' => ' ُّ', 'ﱢ' => ' ِّ', 'ﱣ' => ' ّٰ', 'ﱤ' => 'ئر', 'ﱥ' => 'ئز', 'ﱦ' => 'ئم', 'ﱧ' => 'ئن', 'ﱨ' => 'ئى', 'ﱩ' => 'ئي', 'ﱪ' => 'بر', 'ﱫ' => 'بز', 'ﱬ' => 'بم', 'ﱭ' => 'بن', 'ﱮ' => 'بى', 'ﱯ' => 'بي', 'ﱰ' => 'تر', 'ﱱ' => 'تز', 'ﱲ' => 'تم', 'ﱳ' => 'تن', 'ﱴ' => 'تى', 'ﱵ' => 'تي', 'ﱶ' => 'ثر', 'ﱷ' => 'ثز', 'ﱸ' => 'ثم', 'ﱹ' => 'ثن', 'ﱺ' => 'ثى', 'ﱻ' => 'ثي', 'ﱼ' => 'فى', 'ﱽ' => 'في', 'ﱾ' => 'قى', 'ﱿ' => 'قي', 'ﲀ' => 'كا', 'ﲁ' => 'كل', 'ﲂ' => 'كم', 'ﲃ' => 'كى', 'ﲄ' => 'كي', 'ﲅ' => 'لم', 'ﲆ' => 'لى', 'ﲇ' => 'لي', 'ﲈ' => 'ما', 'ﲉ' => 'مم', 'ﲊ' => 'نر', 'ﲋ' => 'نز', 'ﲌ' => 'نم', 'ﲍ' => 'نن', 'ﲎ' => 'نى', 'ﲏ' => 'ني', 'ﲐ' => 'ىٰ', 'ﲑ' => 'ير', 'ﲒ' => 'يز', 'ﲓ' => 'يم', 'ﲔ' => 'ين', 'ﲕ' => 'يى', 'ﲖ' => 'يي', 'ﲗ' => 'ئج', 'ﲘ' => 'ئح', 'ﲙ' => 'ئخ', 'ﲚ' => 'ئم', 'ﲛ' => 'ئه', 'ﲜ' => 'بج', 'ﲝ' => 'بح', 'ﲞ' => 'بخ', 'ﲟ' => 'بم', 'ﲠ' => 'به', 'ﲡ' => 'تج', 'ﲢ' => 'تح', 'ﲣ' => 'تخ', 'ﲤ' => 'تم', 'ﲥ' => 'ته', 'ﲦ' => 'ثم', 'ﲧ' => 'جح', 'ﲨ' => 'جم', 'ﲩ' => 'حج', 'ﲪ' => 'حم', 'ﲫ' => 'خج', 'ﲬ' => 'خم', 'ﲭ' => 'سج', 'ﲮ' => 'سح', 'ﲯ' => 'سخ', 'ﲰ' => 'سم', 'ﲱ' => 'صح', 'ﲲ' => 'صخ', 'ﲳ' => 'صم', 'ﲴ' => 'ضج', 'ﲵ' => 'ضح', 'ﲶ' => 'ضخ', 'ﲷ' => 'ضم', 'ﲸ' => 'طح', 'ﲹ' => 'ظم', 'ﲺ' => 'عج', 'ﲻ' => 'عم', 'ﲼ' => 'غج', 'ﲽ' => 'غم', 'ﲾ' => 'فج', 'ﲿ' => 'فح', 'ﳀ' => 'فخ', 'ﳁ' => 'فم', 'ﳂ' => 'قح', 'ﳃ' => 'قم', 'ﳄ' => 'كج', 'ﳅ' => 'كح', 'ﳆ' => 'كخ', 'ﳇ' => 'كل', 'ﳈ' => 'كم', 'ﳉ' => 'لج', 'ﳊ' => 'لح', 'ﳋ' => 'لخ', 'ﳌ' => 'لم', 'ﳍ' => 'له', 'ﳎ' => 'مج', 'ﳏ' => 'مح', 'ﳐ' => 'مخ', 'ﳑ' => 'مم', 'ﳒ' => 'نج', 'ﳓ' => 'نح', 'ﳔ' => 'نخ', 'ﳕ' => 'نم', 'ﳖ' => 'نه', 'ﳗ' => 'هج', 'ﳘ' => 'هم', 'ﳙ' => 'هٰ', 'ﳚ' => 'يج', 'ﳛ' => 'يح', 'ﳜ' => 'يخ', 'ﳝ' => 'يم', 'ﳞ' => 'يه', 'ﳟ' => 'ئم', 'ﳠ' => 'ئه', 'ﳡ' => 'بم', 'ﳢ' => 'به', 'ﳣ' => 'تم', 'ﳤ' => 'ته', 'ﳥ' => 'ثم', 'ﳦ' => 'ثه', 'ﳧ' => 'سم', 'ﳨ' => 'سه', 'ﳩ' => 'شم', 'ﳪ' => 'شه', 'ﳫ' => 'كل', 'ﳬ' => 'كم', 'ﳭ' => 'لم', 'ﳮ' => 'نم', 'ﳯ' => 'نه', 'ﳰ' => 'يم', 'ﳱ' => 'يه', 'ﳲ' => 'ـَّ', 'ﳳ' => 'ـُّ', 'ﳴ' => 'ـِّ', 'ﳵ' => 'طى', 'ﳶ' => 'طي', 'ﳷ' => 'عى', 'ﳸ' => 'عي', 'ﳹ' => 'غى', 'ﳺ' => 'غي', 'ﳻ' => 'سى', 'ﳼ' => 'سي', 'ﳽ' => 'شى', 'ﳾ' => 'شي', 'ﳿ' => 'حى', 'ﴀ' => 'حي', 'ﴁ' => 'جى', 'ﴂ' => 'جي', 'ﴃ' => 'خى', 'ﴄ' => 'خي', 'ﴅ' => 'صى', 'ﴆ' => 'صي', 'ﴇ' => 'ضى', 'ﴈ' => 'ضي', 'ﴉ' => 'شج', 'ﴊ' => 'شح', 'ﴋ' => 'شخ', 'ﴌ' => 'شم', 'ﴍ' => 'شر', 'ﴎ' => 'سر', 'ﴏ' => 'صر', 'ﴐ' => 'ضر', 'ﴑ' => 'طى', 'ﴒ' => 'طي', 'ﴓ' => 'عى', 'ﴔ' => 'عي', 'ﴕ' => 'غى', 'ﴖ' => 'غي', 'ﴗ' => 'سى', 'ﴘ' => 'سي', 'ﴙ' => 'شى', 'ﴚ' => 'شي', 'ﴛ' => 'حى', 'ﴜ' => 'حي', 'ﴝ' => 'جى', 'ﴞ' => 'جي', 'ﴟ' => 'خى', 'ﴠ' => 'خي', 'ﴡ' => 'صى', 'ﴢ' => 'صي', 'ﴣ' => 'ضى', 'ﴤ' => 'ضي', 'ﴥ' => 'شج', 'ﴦ' => 'شح', 'ﴧ' => 'شخ', 'ﴨ' => 'شم', 'ﴩ' => 'شر', 'ﴪ' => 'سر', 'ﴫ' => 'صر', 'ﴬ' => 'ضر', 'ﴭ' => 'شج', 'ﴮ' => 'شح', 'ﴯ' => 'شخ', 'ﴰ' => 'شم', 'ﴱ' => 'سه', 'ﴲ' => 'شه', 'ﴳ' => 'طم', 'ﴴ' => 'سج', 'ﴵ' => 'سح', 'ﴶ' => 'سخ', 'ﴷ' => 'شج', 'ﴸ' => 'شح', 'ﴹ' => 'شخ', 'ﴺ' => 'طم', 'ﴻ' => 'ظم', 'ﴼ' => 'اً', 'ﴽ' => 'اً', 'ﵐ' => 'تجم', 'ﵑ' => 'تحج', 'ﵒ' => 'تحج', 'ﵓ' => 'تحم', 'ﵔ' => 'تخم', 'ﵕ' => 'تمج', 'ﵖ' => 'تمح', 'ﵗ' => 'تمخ', 'ﵘ' => 'جمح', 'ﵙ' => 'جمح', 'ﵚ' => 'حمي', 'ﵛ' => 'حمى', 'ﵜ' => 'سحج', 'ﵝ' => 'سجح', 'ﵞ' => 'سجى', 'ﵟ' => 'سمح', 'ﵠ' => 'سمح', 'ﵡ' => 'سمج', 'ﵢ' => 'سمم', 'ﵣ' => 'سمم', 'ﵤ' => 'صحح', 'ﵥ' => 'صحح', 'ﵦ' => 'صمم', 'ﵧ' => 'شحم', 'ﵨ' => 'شحم', 'ﵩ' => 'شجي', 'ﵪ' => 'شمخ', 'ﵫ' => 'شمخ', 'ﵬ' => 'شمم', 'ﵭ' => 'شمم', 'ﵮ' => 'ضحى', 'ﵯ' => 'ضخم', 'ﵰ' => 'ضخم', 'ﵱ' => 'طمح', 'ﵲ' => 'طمح', 'ﵳ' => 'طمم', 'ﵴ' => 'طمي', 'ﵵ' => 'عجم', 'ﵶ' => 'عمم', 'ﵷ' => 'عمم', 'ﵸ' => 'عمى', 'ﵹ' => 'غمم', 'ﵺ' => 'غمي', 'ﵻ' => 'غمى', 'ﵼ' => 'فخم', 'ﵽ' => 'فخم', 'ﵾ' => 'قمح', 'ﵿ' => 'قمم', 'ﶀ' => 'لحم', 'ﶁ' => 'لحي', 'ﶂ' => 'لحى', 'ﶃ' => 'لجج', 'ﶄ' => 'لجج', 'ﶅ' => 'لخم', 'ﶆ' => 'لخم', 'ﶇ' => 'لمح', 'ﶈ' => 'لمح', 'ﶉ' => 'محج', 'ﶊ' => 'محم', 'ﶋ' => 'محي', 'ﶌ' => 'مجح', 'ﶍ' => 'مجم', 'ﶎ' => 'مخج', 'ﶏ' => 'مخم', 'ﶒ' => 'مجخ', 'ﶓ' => 'همج', 'ﶔ' => 'همم', 'ﶕ' => 'نحم', 'ﶖ' => 'نحى', 'ﶗ' => 'نجم', 'ﶘ' => 'نجم', 'ﶙ' => 'نجى', 'ﶚ' => 'نمي', 'ﶛ' => 'نمى', 'ﶜ' => 'يمم', 'ﶝ' => 'يمم', 'ﶞ' => 'بخي', 'ﶟ' => 'تجي', 'ﶠ' => 'تجى', 'ﶡ' => 'تخي', 'ﶢ' => 'تخى', 'ﶣ' => 'تمي', 'ﶤ' => 'تمى', 'ﶥ' => 'جمي', 'ﶦ' => 'جحى', 'ﶧ' => 'جمى', 'ﶨ' => 'سخى', 'ﶩ' => 'صحي', 'ﶪ' => 'شحي', 'ﶫ' => 'ضحي', 'ﶬ' => 'لجي', 'ﶭ' => 'لمي', 'ﶮ' => 'يحي', 'ﶯ' => 'يجي', 'ﶰ' => 'يمي', 'ﶱ' => 'ممي', 'ﶲ' => 'قمي', 'ﶳ' => 'نحي', 'ﶴ' => 'قمح', 'ﶵ' => 'لحم', 'ﶶ' => 'عمي', 'ﶷ' => 'كمي', 'ﶸ' => 'نجح', 'ﶹ' => 'مخي', 'ﶺ' => 'لجم', 'ﶻ' => 'كمم', 'ﶼ' => 'لجم', 'ﶽ' => 'نجح', 'ﶾ' => 'جحي', 'ﶿ' => 'حجي', 'ﷀ' => 'مجي', 'ﷁ' => 'فمي', 'ﷂ' => 'بحي', 'ﷃ' => 'كمم', 'ﷄ' => 'عجم', 'ﷅ' => 'صمم', 'ﷆ' => 'سخي', 'ﷇ' => 'نجي', 'ﷰ' => 'صلے', 'ﷱ' => 'قلے', 'ﷲ' => 'الله', 'ﷳ' => 'اكبر', 'ﷴ' => 'محمد', 'ﷵ' => 'صلعم', 'ﷶ' => 'رسول', 'ﷷ' => 'عليه', 'ﷸ' => 'وسلم', 'ﷹ' => 'صلى', 'ﷺ' => 'صلى الله عليه وسلم', 'ﷻ' => 'جل جلاله', '﷼' => 'ریال', '︐' => ',', '︑' => '、', '︒' => '。', '︓' => ':', '︔' => ';', '︕' => '!', '︖' => '?', '︗' => '〖', '︘' => '〗', '︙' => '...', '︰' => '..', '︱' => '—', '︲' => '–', '︳' => '_', '︴' => '_', '︵' => '(', '︶' => ')', '︷' => '{', '︸' => '}', '︹' => '〔', '︺' => '〕', '︻' => '【', '︼' => '】', '︽' => '《', '︾' => '》', '︿' => '〈', '﹀' => '〉', '﹁' => '「', '﹂' => '」', '﹃' => '『', '﹄' => '』', '﹇' => '[', '﹈' => ']', '﹉' => ' ̅', '﹊' => ' ̅', '﹋' => ' ̅', '﹌' => ' ̅', '﹍' => '_', '﹎' => '_', '﹏' => '_', '﹐' => ',', '﹑' => '、', '﹒' => '.', '﹔' => ';', '﹕' => ':', '﹖' => '?', '﹗' => '!', '﹘' => '—', '﹙' => '(', '﹚' => ')', '﹛' => '{', '﹜' => '}', '﹝' => '〔', '﹞' => '〕', '﹟' => '#', '﹠' => '&', '﹡' => '*', '﹢' => '+', '﹣' => '-', '﹤' => '<', '﹥' => '>', '﹦' => '=', '﹨' => '\\', '﹩' => '$', '﹪' => '%', '﹫' => '@', 'ﹰ' => ' ً', 'ﹱ' => 'ـً', 'ﹲ' => ' ٌ', 'ﹴ' => ' ٍ', 'ﹶ' => ' َ', 'ﹷ' => 'ـَ', 'ﹸ' => ' ُ', 'ﹹ' => 'ـُ', 'ﹺ' => ' ِ', 'ﹻ' => 'ـِ', 'ﹼ' => ' ّ', 'ﹽ' => 'ـّ', 'ﹾ' => ' ْ', 'ﹿ' => 'ـْ', 'ﺀ' => 'ء', 'ﺁ' => 'آ', 'ﺂ' => 'آ', 'ﺃ' => 'أ', 'ﺄ' => 'أ', 'ﺅ' => 'ؤ', 'ﺆ' => 'ؤ', 'ﺇ' => 'إ', 'ﺈ' => 'إ', 'ﺉ' => 'ئ', 'ﺊ' => 'ئ', 'ﺋ' => 'ئ', 'ﺌ' => 'ئ', 'ﺍ' => 'ا', 'ﺎ' => 'ا', 'ﺏ' => 'ب', 'ﺐ' => 'ب', 'ﺑ' => 'ب', 'ﺒ' => 'ب', 'ﺓ' => 'ة', 'ﺔ' => 'ة', 'ﺕ' => 'ت', 'ﺖ' => 'ت', 'ﺗ' => 'ت', 'ﺘ' => 'ت', 'ﺙ' => 'ث', 'ﺚ' => 'ث', 'ﺛ' => 'ث', 'ﺜ' => 'ث', 'ﺝ' => 'ج', 'ﺞ' => 'ج', 'ﺟ' => 'ج', 'ﺠ' => 'ج', 'ﺡ' => 'ح', 'ﺢ' => 'ح', 'ﺣ' => 'ح', 'ﺤ' => 'ح', 'ﺥ' => 'خ', 'ﺦ' => 'خ', 'ﺧ' => 'خ', 'ﺨ' => 'خ', 'ﺩ' => 'د', 'ﺪ' => 'د', 'ﺫ' => 'ذ', 'ﺬ' => 'ذ', 'ﺭ' => 'ر', 'ﺮ' => 'ر', 'ﺯ' => 'ز', 'ﺰ' => 'ز', 'ﺱ' => 'س', 'ﺲ' => 'س', 'ﺳ' => 'س', 'ﺴ' => 'س', 'ﺵ' => 'ش', 'ﺶ' => 'ش', 'ﺷ' => 'ش', 'ﺸ' => 'ش', 'ﺹ' => 'ص', 'ﺺ' => 'ص', 'ﺻ' => 'ص', 'ﺼ' => 'ص', 'ﺽ' => 'ض', 'ﺾ' => 'ض', 'ﺿ' => 'ض', 'ﻀ' => 'ض', 'ﻁ' => 'ط', 'ﻂ' => 'ط', 'ﻃ' => 'ط', 'ﻄ' => 'ط', 'ﻅ' => 'ظ', 'ﻆ' => 'ظ', 'ﻇ' => 'ظ', 'ﻈ' => 'ظ', 'ﻉ' => 'ع', 'ﻊ' => 'ع', 'ﻋ' => 'ع', 'ﻌ' => 'ع', 'ﻍ' => 'غ', 'ﻎ' => 'غ', 'ﻏ' => 'غ', 'ﻐ' => 'غ', 'ﻑ' => 'ف', 'ﻒ' => 'ف', 'ﻓ' => 'ف', 'ﻔ' => 'ف', 'ﻕ' => 'ق', 'ﻖ' => 'ق', 'ﻗ' => 'ق', 'ﻘ' => 'ق', 'ﻙ' => 'ك', 'ﻚ' => 'ك', 'ﻛ' => 'ك', 'ﻜ' => 'ك', 'ﻝ' => 'ل', 'ﻞ' => 'ل', 'ﻟ' => 'ل', 'ﻠ' => 'ل', 'ﻡ' => 'م', 'ﻢ' => 'م', 'ﻣ' => 'م', 'ﻤ' => 'م', 'ﻥ' => 'ن', 'ﻦ' => 'ن', 'ﻧ' => 'ن', 'ﻨ' => 'ن', 'ﻩ' => 'ه', 'ﻪ' => 'ه', 'ﻫ' => 'ه', 'ﻬ' => 'ه', 'ﻭ' => 'و', 'ﻮ' => 'و', 'ﻯ' => 'ى', 'ﻰ' => 'ى', 'ﻱ' => 'ي', 'ﻲ' => 'ي', 'ﻳ' => 'ي', 'ﻴ' => 'ي', 'ﻵ' => 'لآ', 'ﻶ' => 'لآ', 'ﻷ' => 'لأ', 'ﻸ' => 'لأ', 'ﻹ' => 'لإ', 'ﻺ' => 'لإ', 'ﻻ' => 'لا', 'ﻼ' => 'لا', '!' => '!', '"' => '"', '#' => '#', '$' => '$', '%' => '%', '&' => '&', ''' => '\'', '(' => '(', ')' => ')', '*' => '*', '+' => '+', ',' => ',', '-' => '-', '.' => '.', '/' => '/', '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', ':' => ':', ';' => ';', '<' => '<', '=' => '=', '>' => '>', '?' => '?', '@' => '@', 'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E', 'F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J', 'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O', 'P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T', 'U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y', 'Z' => 'Z', '[' => '[', '\' => '\\', ']' => ']', '^' => '^', '_' => '_', '`' => '`', 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd', 'e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i', 'j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n', 'o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's', 't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x', 'y' => 'y', 'z' => 'z', '{' => '{', '|' => '|', '}' => '}', '~' => '~', '⦅' => '⦅', '⦆' => '⦆', '。' => '。', '「' => '「', '」' => '」', '、' => '、', '・' => '・', 'ヲ' => 'ヲ', 'ァ' => 'ァ', 'ィ' => 'ィ', 'ゥ' => 'ゥ', 'ェ' => 'ェ', 'ォ' => 'ォ', 'ャ' => 'ャ', 'ュ' => 'ュ', 'ョ' => 'ョ', 'ッ' => 'ッ', 'ー' => 'ー', 'ア' => 'ア', 'イ' => 'イ', 'ウ' => 'ウ', 'エ' => 'エ', 'オ' => 'オ', 'カ' => 'カ', 'キ' => 'キ', 'ク' => 'ク', 'ケ' => 'ケ', 'コ' => 'コ', 'サ' => 'サ', 'シ' => 'シ', 'ス' => 'ス', 'セ' => 'セ', 'ソ' => 'ソ', 'タ' => 'タ', 'チ' => 'チ', 'ツ' => 'ツ', 'テ' => 'テ', 'ト' => 'ト', 'ナ' => 'ナ', 'ニ' => 'ニ', 'ヌ' => 'ヌ', 'ネ' => 'ネ', 'ノ' => 'ノ', 'ハ' => 'ハ', 'ヒ' => 'ヒ', 'フ' => 'フ', 'ヘ' => 'ヘ', 'ホ' => 'ホ', 'マ' => 'マ', 'ミ' => 'ミ', 'ム' => 'ム', 'メ' => 'メ', 'モ' => 'モ', 'ヤ' => 'ヤ', 'ユ' => 'ユ', 'ヨ' => 'ヨ', 'ラ' => 'ラ', 'リ' => 'リ', 'ル' => 'ル', 'レ' => 'レ', 'ロ' => 'ロ', 'ワ' => 'ワ', 'ン' => 'ン', '゙' => '゙', '゚' => '゚', 'ᅠ' => 'ᅠ', 'ᄀ' => 'ᄀ', 'ᄁ' => 'ᄁ', 'ᆪ' => 'ᆪ', 'ᄂ' => 'ᄂ', 'ᆬ' => 'ᆬ', 'ᆭ' => 'ᆭ', 'ᄃ' => 'ᄃ', 'ᄄ' => 'ᄄ', 'ᄅ' => 'ᄅ', 'ᆰ' => 'ᆰ', 'ᆱ' => 'ᆱ', 'ᆲ' => 'ᆲ', 'ᆳ' => 'ᆳ', 'ᆴ' => 'ᆴ', 'ᆵ' => 'ᆵ', 'ᄚ' => 'ᄚ', 'ᄆ' => 'ᄆ', 'ᄇ' => 'ᄇ', 'ᄈ' => 'ᄈ', 'ᄡ' => 'ᄡ', 'ᄉ' => 'ᄉ', 'ᄊ' => 'ᄊ', 'ᄋ' => 'ᄋ', 'ᄌ' => 'ᄌ', 'ᄍ' => 'ᄍ', 'ᄎ' => 'ᄎ', 'ᄏ' => 'ᄏ', 'ᄐ' => 'ᄐ', 'ᄑ' => 'ᄑ', 'ᄒ' => 'ᄒ', 'ᅡ' => 'ᅡ', 'ᅢ' => 'ᅢ', 'ᅣ' => 'ᅣ', 'ᅤ' => 'ᅤ', 'ᅥ' => 'ᅥ', 'ᅦ' => 'ᅦ', 'ᅧ' => 'ᅧ', 'ᅨ' => 'ᅨ', 'ᅩ' => 'ᅩ', 'ᅪ' => 'ᅪ', 'ᅫ' => 'ᅫ', 'ᅬ' => 'ᅬ', 'ᅭ' => 'ᅭ', 'ᅮ' => 'ᅮ', 'ᅯ' => 'ᅯ', 'ᅰ' => 'ᅰ', 'ᅱ' => 'ᅱ', 'ᅲ' => 'ᅲ', 'ᅳ' => 'ᅳ', 'ᅴ' => 'ᅴ', 'ᅵ' => 'ᅵ', '¢' => '¢', '£' => '£', '¬' => '¬', ' ̄' => ' ̄', '¦' => '¦', '¥' => '¥', '₩' => '₩', '│' => '│', '←' => '←', '↑' => '↑', '→' => '→', '↓' => '↓', '■' => '■', '○' => '○', '𝐀' => 'A', '𝐁' => 'B', '𝐂' => 'C', '𝐃' => 'D', '𝐄' => 'E', '𝐅' => 'F', '𝐆' => 'G', '𝐇' => 'H', '𝐈' => 'I', '𝐉' => 'J', '𝐊' => 'K', '𝐋' => 'L', '𝐌' => 'M', '𝐍' => 'N', '𝐎' => 'O', '𝐏' => 'P', '𝐐' => 'Q', '𝐑' => 'R', '𝐒' => 'S', '𝐓' => 'T', '𝐔' => 'U', '𝐕' => 'V', '𝐖' => 'W', '𝐗' => 'X', '𝐘' => 'Y', '𝐙' => 'Z', '𝐚' => 'a', '𝐛' => 'b', '𝐜' => 'c', '𝐝' => 'd', '𝐞' => 'e', '𝐟' => 'f', '𝐠' => 'g', '𝐡' => 'h', '𝐢' => 'i', '𝐣' => 'j', '𝐤' => 'k', '𝐥' => 'l', '𝐦' => 'm', '𝐧' => 'n', '𝐨' => 'o', '𝐩' => 'p', '𝐪' => 'q', '𝐫' => 'r', '𝐬' => 's', '𝐭' => 't', '𝐮' => 'u', '𝐯' => 'v', '𝐰' => 'w', '𝐱' => 'x', '𝐲' => 'y', '𝐳' => 'z', '𝐴' => 'A', '𝐵' => 'B', '𝐶' => 'C', '𝐷' => 'D', '𝐸' => 'E', '𝐹' => 'F', '𝐺' => 'G', '𝐻' => 'H', '𝐼' => 'I', '𝐽' => 'J', '𝐾' => 'K', '𝐿' => 'L', '𝑀' => 'M', '𝑁' => 'N', '𝑂' => 'O', '𝑃' => 'P', '𝑄' => 'Q', '𝑅' => 'R', '𝑆' => 'S', '𝑇' => 'T', '𝑈' => 'U', '𝑉' => 'V', '𝑊' => 'W', '𝑋' => 'X', '𝑌' => 'Y', '𝑍' => 'Z', '𝑎' => 'a', '𝑏' => 'b', '𝑐' => 'c', '𝑑' => 'd', '𝑒' => 'e', '𝑓' => 'f', '𝑔' => 'g', '𝑖' => 'i', '𝑗' => 'j', '𝑘' => 'k', '𝑙' => 'l', '𝑚' => 'm', '𝑛' => 'n', '𝑜' => 'o', '𝑝' => 'p', '𝑞' => 'q', '𝑟' => 'r', '𝑠' => 's', '𝑡' => 't', '𝑢' => 'u', '𝑣' => 'v', '𝑤' => 'w', '𝑥' => 'x', '𝑦' => 'y', '𝑧' => 'z', '𝑨' => 'A', '𝑩' => 'B', '𝑪' => 'C', '𝑫' => 'D', '𝑬' => 'E', '𝑭' => 'F', '𝑮' => 'G', '𝑯' => 'H', '𝑰' => 'I', '𝑱' => 'J', '𝑲' => 'K', '𝑳' => 'L', '𝑴' => 'M', '𝑵' => 'N', '𝑶' => 'O', '𝑷' => 'P', '𝑸' => 'Q', '𝑹' => 'R', '𝑺' => 'S', '𝑻' => 'T', '𝑼' => 'U', '𝑽' => 'V', '𝑾' => 'W', '𝑿' => 'X', '𝒀' => 'Y', '𝒁' => 'Z', '𝒂' => 'a', '𝒃' => 'b', '𝒄' => 'c', '𝒅' => 'd', '𝒆' => 'e', '𝒇' => 'f', '𝒈' => 'g', '𝒉' => 'h', '𝒊' => 'i', '𝒋' => 'j', '𝒌' => 'k', '𝒍' => 'l', '𝒎' => 'm', '𝒏' => 'n', '𝒐' => 'o', '𝒑' => 'p', '𝒒' => 'q', '𝒓' => 'r', '𝒔' => 's', '𝒕' => 't', '𝒖' => 'u', '𝒗' => 'v', '𝒘' => 'w', '𝒙' => 'x', '𝒚' => 'y', '𝒛' => 'z', '𝒜' => 'A', '𝒞' => 'C', '𝒟' => 'D', '𝒢' => 'G', '𝒥' => 'J', '𝒦' => 'K', '𝒩' => 'N', '𝒪' => 'O', '𝒫' => 'P', '𝒬' => 'Q', '𝒮' => 'S', '𝒯' => 'T', '𝒰' => 'U', '𝒱' => 'V', '𝒲' => 'W', '𝒳' => 'X', '𝒴' => 'Y', '𝒵' => 'Z', '𝒶' => 'a', '𝒷' => 'b', '𝒸' => 'c', '𝒹' => 'd', '𝒻' => 'f', '𝒽' => 'h', '𝒾' => 'i', '𝒿' => 'j', '𝓀' => 'k', '𝓁' => 'l', '𝓂' => 'm', '𝓃' => 'n', '𝓅' => 'p', '𝓆' => 'q', '𝓇' => 'r', '𝓈' => 's', '𝓉' => 't', '𝓊' => 'u', '𝓋' => 'v', '𝓌' => 'w', '𝓍' => 'x', '𝓎' => 'y', '𝓏' => 'z', '𝓐' => 'A', '𝓑' => 'B', '𝓒' => 'C', '𝓓' => 'D', '𝓔' => 'E', '𝓕' => 'F', '𝓖' => 'G', '𝓗' => 'H', '𝓘' => 'I', '𝓙' => 'J', '𝓚' => 'K', '𝓛' => 'L', '𝓜' => 'M', '𝓝' => 'N', '𝓞' => 'O', '𝓟' => 'P', '𝓠' => 'Q', '𝓡' => 'R', '𝓢' => 'S', '𝓣' => 'T', '𝓤' => 'U', '𝓥' => 'V', '𝓦' => 'W', '𝓧' => 'X', '𝓨' => 'Y', '𝓩' => 'Z', '𝓪' => 'a', '𝓫' => 'b', '𝓬' => 'c', '𝓭' => 'd', '𝓮' => 'e', '𝓯' => 'f', '𝓰' => 'g', '𝓱' => 'h', '𝓲' => 'i', '𝓳' => 'j', '𝓴' => 'k', '𝓵' => 'l', '𝓶' => 'm', '𝓷' => 'n', '𝓸' => 'o', '𝓹' => 'p', '𝓺' => 'q', '𝓻' => 'r', '𝓼' => 's', '𝓽' => 't', '𝓾' => 'u', '𝓿' => 'v', '𝔀' => 'w', '𝔁' => 'x', '𝔂' => 'y', '𝔃' => 'z', '𝔄' => 'A', '𝔅' => 'B', '𝔇' => 'D', '𝔈' => 'E', '𝔉' => 'F', '𝔊' => 'G', '𝔍' => 'J', '𝔎' => 'K', '𝔏' => 'L', '𝔐' => 'M', '𝔑' => 'N', '𝔒' => 'O', '𝔓' => 'P', '𝔔' => 'Q', '𝔖' => 'S', '𝔗' => 'T', '𝔘' => 'U', '𝔙' => 'V', '𝔚' => 'W', '𝔛' => 'X', '𝔜' => 'Y', '𝔞' => 'a', '𝔟' => 'b', '𝔠' => 'c', '𝔡' => 'd', '𝔢' => 'e', '𝔣' => 'f', '𝔤' => 'g', '𝔥' => 'h', '𝔦' => 'i', '𝔧' => 'j', '𝔨' => 'k', '𝔩' => 'l', '𝔪' => 'm', '𝔫' => 'n', '𝔬' => 'o', '𝔭' => 'p', '𝔮' => 'q', '𝔯' => 'r', '𝔰' => 's', '𝔱' => 't', '𝔲' => 'u', '𝔳' => 'v', '𝔴' => 'w', '𝔵' => 'x', '𝔶' => 'y', '𝔷' => 'z', '𝔸' => 'A', '𝔹' => 'B', '𝔻' => 'D', '𝔼' => 'E', '𝔽' => 'F', '𝔾' => 'G', '𝕀' => 'I', '𝕁' => 'J', '𝕂' => 'K', '𝕃' => 'L', '𝕄' => 'M', '𝕆' => 'O', '𝕊' => 'S', '𝕋' => 'T', '𝕌' => 'U', '𝕍' => 'V', '𝕎' => 'W', '𝕏' => 'X', '𝕐' => 'Y', '𝕒' => 'a', '𝕓' => 'b', '𝕔' => 'c', '𝕕' => 'd', '𝕖' => 'e', '𝕗' => 'f', '𝕘' => 'g', '𝕙' => 'h', '𝕚' => 'i', '𝕛' => 'j', '𝕜' => 'k', '𝕝' => 'l', '𝕞' => 'm', '𝕟' => 'n', '𝕠' => 'o', '𝕡' => 'p', '𝕢' => 'q', '𝕣' => 'r', '𝕤' => 's', '𝕥' => 't', '𝕦' => 'u', '𝕧' => 'v', '𝕨' => 'w', '𝕩' => 'x', '𝕪' => 'y', '𝕫' => 'z', '𝕬' => 'A', '𝕭' => 'B', '𝕮' => 'C', '𝕯' => 'D', '𝕰' => 'E', '𝕱' => 'F', '𝕲' => 'G', '𝕳' => 'H', '𝕴' => 'I', '𝕵' => 'J', '𝕶' => 'K', '𝕷' => 'L', '𝕸' => 'M', '𝕹' => 'N', '𝕺' => 'O', '𝕻' => 'P', '𝕼' => 'Q', '𝕽' => 'R', '𝕾' => 'S', '𝕿' => 'T', '𝖀' => 'U', '𝖁' => 'V', '𝖂' => 'W', '𝖃' => 'X', '𝖄' => 'Y', '𝖅' => 'Z', '𝖆' => 'a', '𝖇' => 'b', '𝖈' => 'c', '𝖉' => 'd', '𝖊' => 'e', '𝖋' => 'f', '𝖌' => 'g', '𝖍' => 'h', '𝖎' => 'i', '𝖏' => 'j', '𝖐' => 'k', '𝖑' => 'l', '𝖒' => 'm', '𝖓' => 'n', '𝖔' => 'o', '𝖕' => 'p', '𝖖' => 'q', '𝖗' => 'r', '𝖘' => 's', '𝖙' => 't', '𝖚' => 'u', '𝖛' => 'v', '𝖜' => 'w', '𝖝' => 'x', '𝖞' => 'y', '𝖟' => 'z', '𝖠' => 'A', '𝖡' => 'B', '𝖢' => 'C', '𝖣' => 'D', '𝖤' => 'E', '𝖥' => 'F', '𝖦' => 'G', '𝖧' => 'H', '𝖨' => 'I', '𝖩' => 'J', '𝖪' => 'K', '𝖫' => 'L', '𝖬' => 'M', '𝖭' => 'N', '𝖮' => 'O', '𝖯' => 'P', '𝖰' => 'Q', '𝖱' => 'R', '𝖲' => 'S', '𝖳' => 'T', '𝖴' => 'U', '𝖵' => 'V', '𝖶' => 'W', '𝖷' => 'X', '𝖸' => 'Y', '𝖹' => 'Z', '𝖺' => 'a', '𝖻' => 'b', '𝖼' => 'c', '𝖽' => 'd', '𝖾' => 'e', '𝖿' => 'f', '𝗀' => 'g', '𝗁' => 'h', '𝗂' => 'i', '𝗃' => 'j', '𝗄' => 'k', '𝗅' => 'l', '𝗆' => 'm', '𝗇' => 'n', '𝗈' => 'o', '𝗉' => 'p', '𝗊' => 'q', '𝗋' => 'r', '𝗌' => 's', '𝗍' => 't', '𝗎' => 'u', '𝗏' => 'v', '𝗐' => 'w', '𝗑' => 'x', '𝗒' => 'y', '𝗓' => 'z', '𝗔' => 'A', '𝗕' => 'B', '𝗖' => 'C', '𝗗' => 'D', '𝗘' => 'E', '𝗙' => 'F', '𝗚' => 'G', '𝗛' => 'H', '𝗜' => 'I', '𝗝' => 'J', '𝗞' => 'K', '𝗟' => 'L', '𝗠' => 'M', '𝗡' => 'N', '𝗢' => 'O', '𝗣' => 'P', '𝗤' => 'Q', '𝗥' => 'R', '𝗦' => 'S', '𝗧' => 'T', '𝗨' => 'U', '𝗩' => 'V', '𝗪' => 'W', '𝗫' => 'X', '𝗬' => 'Y', '𝗭' => 'Z', '𝗮' => 'a', '𝗯' => 'b', '𝗰' => 'c', '𝗱' => 'd', '𝗲' => 'e', '𝗳' => 'f', '𝗴' => 'g', '𝗵' => 'h', '𝗶' => 'i', '𝗷' => 'j', '𝗸' => 'k', '𝗹' => 'l', '𝗺' => 'm', '𝗻' => 'n', '𝗼' => 'o', '𝗽' => 'p', '𝗾' => 'q', '𝗿' => 'r', '𝘀' => 's', '𝘁' => 't', '𝘂' => 'u', '𝘃' => 'v', '𝘄' => 'w', '𝘅' => 'x', '𝘆' => 'y', '𝘇' => 'z', '𝘈' => 'A', '𝘉' => 'B', '𝘊' => 'C', '𝘋' => 'D', '𝘌' => 'E', '𝘍' => 'F', '𝘎' => 'G', '𝘏' => 'H', '𝘐' => 'I', '𝘑' => 'J', '𝘒' => 'K', '𝘓' => 'L', '𝘔' => 'M', '𝘕' => 'N', '𝘖' => 'O', '𝘗' => 'P', '𝘘' => 'Q', '𝘙' => 'R', '𝘚' => 'S', '𝘛' => 'T', '𝘜' => 'U', '𝘝' => 'V', '𝘞' => 'W', '𝘟' => 'X', '𝘠' => 'Y', '𝘡' => 'Z', '𝘢' => 'a', '𝘣' => 'b', '𝘤' => 'c', '𝘥' => 'd', '𝘦' => 'e', '𝘧' => 'f', '𝘨' => 'g', '𝘩' => 'h', '𝘪' => 'i', '𝘫' => 'j', '𝘬' => 'k', '𝘭' => 'l', '𝘮' => 'm', '𝘯' => 'n', '𝘰' => 'o', '𝘱' => 'p', '𝘲' => 'q', '𝘳' => 'r', '𝘴' => 's', '𝘵' => 't', '𝘶' => 'u', '𝘷' => 'v', '𝘸' => 'w', '𝘹' => 'x', '𝘺' => 'y', '𝘻' => 'z', '𝘼' => 'A', '𝘽' => 'B', '𝘾' => 'C', '𝘿' => 'D', '𝙀' => 'E', '𝙁' => 'F', '𝙂' => 'G', '𝙃' => 'H', '𝙄' => 'I', '𝙅' => 'J', '𝙆' => 'K', '𝙇' => 'L', '𝙈' => 'M', '𝙉' => 'N', '𝙊' => 'O', '𝙋' => 'P', '𝙌' => 'Q', '𝙍' => 'R', '𝙎' => 'S', '𝙏' => 'T', '𝙐' => 'U', '𝙑' => 'V', '𝙒' => 'W', '𝙓' => 'X', '𝙔' => 'Y', '𝙕' => 'Z', '𝙖' => 'a', '𝙗' => 'b', '𝙘' => 'c', '𝙙' => 'd', '𝙚' => 'e', '𝙛' => 'f', '𝙜' => 'g', '𝙝' => 'h', '𝙞' => 'i', '𝙟' => 'j', '𝙠' => 'k', '𝙡' => 'l', '𝙢' => 'm', '𝙣' => 'n', '𝙤' => 'o', '𝙥' => 'p', '𝙦' => 'q', '𝙧' => 'r', '𝙨' => 's', '𝙩' => 't', '𝙪' => 'u', '𝙫' => 'v', '𝙬' => 'w', '𝙭' => 'x', '𝙮' => 'y', '𝙯' => 'z', '𝙰' => 'A', '𝙱' => 'B', '𝙲' => 'C', '𝙳' => 'D', '𝙴' => 'E', '𝙵' => 'F', '𝙶' => 'G', '𝙷' => 'H', '𝙸' => 'I', '𝙹' => 'J', '𝙺' => 'K', '𝙻' => 'L', '𝙼' => 'M', '𝙽' => 'N', '𝙾' => 'O', '𝙿' => 'P', '𝚀' => 'Q', '𝚁' => 'R', '𝚂' => 'S', '𝚃' => 'T', '𝚄' => 'U', '𝚅' => 'V', '𝚆' => 'W', '𝚇' => 'X', '𝚈' => 'Y', '𝚉' => 'Z', '𝚊' => 'a', '𝚋' => 'b', '𝚌' => 'c', '𝚍' => 'd', '𝚎' => 'e', '𝚏' => 'f', '𝚐' => 'g', '𝚑' => 'h', '𝚒' => 'i', '𝚓' => 'j', '𝚔' => 'k', '𝚕' => 'l', '𝚖' => 'm', '𝚗' => 'n', '𝚘' => 'o', '𝚙' => 'p', '𝚚' => 'q', '𝚛' => 'r', '𝚜' => 's', '𝚝' => 't', '𝚞' => 'u', '𝚟' => 'v', '𝚠' => 'w', '𝚡' => 'x', '𝚢' => 'y', '𝚣' => 'z', '𝚤' => 'ı', '𝚥' => 'ȷ', '𝚨' => 'Α', '𝚩' => 'Β', '𝚪' => 'Γ', '𝚫' => 'Δ', '𝚬' => 'Ε', '𝚭' => 'Ζ', '𝚮' => 'Η', '𝚯' => 'Θ', '𝚰' => 'Ι', '𝚱' => 'Κ', '𝚲' => 'Λ', '𝚳' => 'Μ', '𝚴' => 'Ν', '𝚵' => 'Ξ', '𝚶' => 'Ο', '𝚷' => 'Π', '𝚸' => 'Ρ', '𝚹' => 'Θ', '𝚺' => 'Σ', '𝚻' => 'Τ', '𝚼' => 'Υ', '𝚽' => 'Φ', '𝚾' => 'Χ', '𝚿' => 'Ψ', '𝛀' => 'Ω', '𝛁' => '∇', '𝛂' => 'α', '𝛃' => 'β', '𝛄' => 'γ', '𝛅' => 'δ', '𝛆' => 'ε', '𝛇' => 'ζ', '𝛈' => 'η', '𝛉' => 'θ', '𝛊' => 'ι', '𝛋' => 'κ', '𝛌' => 'λ', '𝛍' => 'μ', '𝛎' => 'ν', '𝛏' => 'ξ', '𝛐' => 'ο', '𝛑' => 'π', '𝛒' => 'ρ', '𝛓' => 'ς', '𝛔' => 'σ', '𝛕' => 'τ', '𝛖' => 'υ', '𝛗' => 'φ', '𝛘' => 'χ', '𝛙' => 'ψ', '𝛚' => 'ω', '𝛛' => '∂', '𝛜' => 'ε', '𝛝' => 'θ', '𝛞' => 'κ', '𝛟' => 'φ', '𝛠' => 'ρ', '𝛡' => 'π', '𝛢' => 'Α', '𝛣' => 'Β', '𝛤' => 'Γ', '𝛥' => 'Δ', '𝛦' => 'Ε', '𝛧' => 'Ζ', '𝛨' => 'Η', '𝛩' => 'Θ', '𝛪' => 'Ι', '𝛫' => 'Κ', '𝛬' => 'Λ', '𝛭' => 'Μ', '𝛮' => 'Ν', '𝛯' => 'Ξ', '𝛰' => 'Ο', '𝛱' => 'Π', '𝛲' => 'Ρ', '𝛳' => 'Θ', '𝛴' => 'Σ', '𝛵' => 'Τ', '𝛶' => 'Υ', '𝛷' => 'Φ', '𝛸' => 'Χ', '𝛹' => 'Ψ', '𝛺' => 'Ω', '𝛻' => '∇', '𝛼' => 'α', '𝛽' => 'β', '𝛾' => 'γ', '𝛿' => 'δ', '𝜀' => 'ε', '𝜁' => 'ζ', '𝜂' => 'η', '𝜃' => 'θ', '𝜄' => 'ι', '𝜅' => 'κ', '𝜆' => 'λ', '𝜇' => 'μ', '𝜈' => 'ν', '𝜉' => 'ξ', '𝜊' => 'ο', '𝜋' => 'π', '𝜌' => 'ρ', '𝜍' => 'ς', '𝜎' => 'σ', '𝜏' => 'τ', '𝜐' => 'υ', '𝜑' => 'φ', '𝜒' => 'χ', '𝜓' => 'ψ', '𝜔' => 'ω', '𝜕' => '∂', '𝜖' => 'ε', '𝜗' => 'θ', '𝜘' => 'κ', '𝜙' => 'φ', '𝜚' => 'ρ', '𝜛' => 'π', '𝜜' => 'Α', '𝜝' => 'Β', '𝜞' => 'Γ', '𝜟' => 'Δ', '𝜠' => 'Ε', '𝜡' => 'Ζ', '𝜢' => 'Η', '𝜣' => 'Θ', '𝜤' => 'Ι', '𝜥' => 'Κ', '𝜦' => 'Λ', '𝜧' => 'Μ', '𝜨' => 'Ν', '𝜩' => 'Ξ', '𝜪' => 'Ο', '𝜫' => 'Π', '𝜬' => 'Ρ', '𝜭' => 'Θ', '𝜮' => 'Σ', '𝜯' => 'Τ', '𝜰' => 'Υ', '𝜱' => 'Φ', '𝜲' => 'Χ', '𝜳' => 'Ψ', '𝜴' => 'Ω', '𝜵' => '∇', '𝜶' => 'α', '𝜷' => 'β', '𝜸' => 'γ', '𝜹' => 'δ', '𝜺' => 'ε', '𝜻' => 'ζ', '𝜼' => 'η', '𝜽' => 'θ', '𝜾' => 'ι', '𝜿' => 'κ', '𝝀' => 'λ', '𝝁' => 'μ', '𝝂' => 'ν', '𝝃' => 'ξ', '𝝄' => 'ο', '𝝅' => 'π', '𝝆' => 'ρ', '𝝇' => 'ς', '𝝈' => 'σ', '𝝉' => 'τ', '𝝊' => 'υ', '𝝋' => 'φ', '𝝌' => 'χ', '𝝍' => 'ψ', '𝝎' => 'ω', '𝝏' => '∂', '𝝐' => 'ε', '𝝑' => 'θ', '𝝒' => 'κ', '𝝓' => 'φ', '𝝔' => 'ρ', '𝝕' => 'π', '𝝖' => 'Α', '𝝗' => 'Β', '𝝘' => 'Γ', '𝝙' => 'Δ', '𝝚' => 'Ε', '𝝛' => 'Ζ', '𝝜' => 'Η', '𝝝' => 'Θ', '𝝞' => 'Ι', '𝝟' => 'Κ', '𝝠' => 'Λ', '𝝡' => 'Μ', '𝝢' => 'Ν', '𝝣' => 'Ξ', '𝝤' => 'Ο', '𝝥' => 'Π', '𝝦' => 'Ρ', '𝝧' => 'Θ', '𝝨' => 'Σ', '𝝩' => 'Τ', '𝝪' => 'Υ', '𝝫' => 'Φ', '𝝬' => 'Χ', '𝝭' => 'Ψ', '𝝮' => 'Ω', '𝝯' => '∇', '𝝰' => 'α', '𝝱' => 'β', '𝝲' => 'γ', '𝝳' => 'δ', '𝝴' => 'ε', '𝝵' => 'ζ', '𝝶' => 'η', '𝝷' => 'θ', '𝝸' => 'ι', '𝝹' => 'κ', '𝝺' => 'λ', '𝝻' => 'μ', '𝝼' => 'ν', '𝝽' => 'ξ', '𝝾' => 'ο', '𝝿' => 'π', '𝞀' => 'ρ', '𝞁' => 'ς', '𝞂' => 'σ', '𝞃' => 'τ', '𝞄' => 'υ', '𝞅' => 'φ', '𝞆' => 'χ', '𝞇' => 'ψ', '𝞈' => 'ω', '𝞉' => '∂', '𝞊' => 'ε', '𝞋' => 'θ', '𝞌' => 'κ', '𝞍' => 'φ', '𝞎' => 'ρ', '𝞏' => 'π', '𝞐' => 'Α', '𝞑' => 'Β', '𝞒' => 'Γ', '𝞓' => 'Δ', '𝞔' => 'Ε', '𝞕' => 'Ζ', '𝞖' => 'Η', '𝞗' => 'Θ', '𝞘' => 'Ι', '𝞙' => 'Κ', '𝞚' => 'Λ', '𝞛' => 'Μ', '𝞜' => 'Ν', '𝞝' => 'Ξ', '𝞞' => 'Ο', '𝞟' => 'Π', '𝞠' => 'Ρ', '𝞡' => 'Θ', '𝞢' => 'Σ', '𝞣' => 'Τ', '𝞤' => 'Υ', '𝞥' => 'Φ', '𝞦' => 'Χ', '𝞧' => 'Ψ', '𝞨' => 'Ω', '𝞩' => '∇', '𝞪' => 'α', '𝞫' => 'β', '𝞬' => 'γ', '𝞭' => 'δ', '𝞮' => 'ε', '𝞯' => 'ζ', '𝞰' => 'η', '𝞱' => 'θ', '𝞲' => 'ι', '𝞳' => 'κ', '𝞴' => 'λ', '𝞵' => 'μ', '𝞶' => 'ν', '𝞷' => 'ξ', '𝞸' => 'ο', '𝞹' => 'π', '𝞺' => 'ρ', '𝞻' => 'ς', '𝞼' => 'σ', '𝞽' => 'τ', '𝞾' => 'υ', '𝞿' => 'φ', '𝟀' => 'χ', '𝟁' => 'ψ', '𝟂' => 'ω', '𝟃' => '∂', '𝟄' => 'ε', '𝟅' => 'θ', '𝟆' => 'κ', '𝟇' => 'φ', '𝟈' => 'ρ', '𝟉' => 'π', '𝟊' => 'Ϝ', '𝟋' => 'ϝ', '𝟎' => '0', '𝟏' => '1', '𝟐' => '2', '𝟑' => '3', '𝟒' => '4', '𝟓' => '5', '𝟔' => '6', '𝟕' => '7', '𝟖' => '8', '𝟗' => '9', '𝟘' => '0', '𝟙' => '1', '𝟚' => '2', '𝟛' => '3', '𝟜' => '4', '𝟝' => '5', '𝟞' => '6', '𝟟' => '7', '𝟠' => '8', '𝟡' => '9', '𝟢' => '0', '𝟣' => '1', '𝟤' => '2', '𝟥' => '3', '𝟦' => '4', '𝟧' => '5', '𝟨' => '6', '𝟩' => '7', '𝟪' => '8', '𝟫' => '9', '𝟬' => '0', '𝟭' => '1', '𝟮' => '2', '𝟯' => '3', '𝟰' => '4', '𝟱' => '5', '𝟲' => '6', '𝟳' => '7', '𝟴' => '8', '𝟵' => '9', '𝟶' => '0', '𝟷' => '1', '𝟸' => '2', '𝟹' => '3', '𝟺' => '4', '𝟻' => '5', '𝟼' => '6', '𝟽' => '7', '𝟾' => '8', '𝟿' => '9', '𞸀' => 'ا', '𞸁' => 'ب', '𞸂' => 'ج', '𞸃' => 'د', '𞸅' => 'و', '𞸆' => 'ز', '𞸇' => 'ح', '𞸈' => 'ط', '𞸉' => 'ي', '𞸊' => 'ك', '𞸋' => 'ل', '𞸌' => 'م', '𞸍' => 'ن', '𞸎' => 'س', '𞸏' => 'ع', '𞸐' => 'ف', '𞸑' => 'ص', '𞸒' => 'ق', '𞸓' => 'ر', '𞸔' => 'ش', '𞸕' => 'ت', '𞸖' => 'ث', '𞸗' => 'خ', '𞸘' => 'ذ', '𞸙' => 'ض', '𞸚' => 'ظ', '𞸛' => 'غ', '𞸜' => 'ٮ', '𞸝' => 'ں', '𞸞' => 'ڡ', '𞸟' => 'ٯ', '𞸡' => 'ب', '𞸢' => 'ج', '𞸤' => 'ه', '𞸧' => 'ح', '𞸩' => 'ي', '𞸪' => 'ك', '𞸫' => 'ل', '𞸬' => 'م', '𞸭' => 'ن', '𞸮' => 'س', '𞸯' => 'ع', '𞸰' => 'ف', '𞸱' => 'ص', '𞸲' => 'ق', '𞸴' => 'ش', '𞸵' => 'ت', '𞸶' => 'ث', '𞸷' => 'خ', '𞸹' => 'ض', '𞸻' => 'غ', '𞹂' => 'ج', '𞹇' => 'ح', '𞹉' => 'ي', '𞹋' => 'ل', '𞹍' => 'ن', '𞹎' => 'س', '𞹏' => 'ع', '𞹑' => 'ص', '𞹒' => 'ق', '𞹔' => 'ش', '𞹗' => 'خ', '𞹙' => 'ض', '𞹛' => 'غ', '𞹝' => 'ں', '𞹟' => 'ٯ', '𞹡' => 'ب', '𞹢' => 'ج', '𞹤' => 'ه', '𞹧' => 'ح', '𞹨' => 'ط', '𞹩' => 'ي', '𞹪' => 'ك', '𞹬' => 'م', '𞹭' => 'ن', '𞹮' => 'س', '𞹯' => 'ع', '𞹰' => 'ف', '𞹱' => 'ص', '𞹲' => 'ق', '𞹴' => 'ش', '𞹵' => 'ت', '𞹶' => 'ث', '𞹷' => 'خ', '𞹹' => 'ض', '𞹺' => 'ظ', '𞹻' => 'غ', '𞹼' => 'ٮ', '𞹾' => 'ڡ', '𞺀' => 'ا', '𞺁' => 'ب', '𞺂' => 'ج', '𞺃' => 'د', '𞺄' => 'ه', '𞺅' => 'و', '𞺆' => 'ز', '𞺇' => 'ح', '𞺈' => 'ط', '𞺉' => 'ي', '𞺋' => 'ل', '𞺌' => 'م', '𞺍' => 'ن', '𞺎' => 'س', '𞺏' => 'ع', '𞺐' => 'ف', '𞺑' => 'ص', '𞺒' => 'ق', '𞺓' => 'ر', '𞺔' => 'ش', '𞺕' => 'ت', '𞺖' => 'ث', '𞺗' => 'خ', '𞺘' => 'ذ', '𞺙' => 'ض', '𞺚' => 'ظ', '𞺛' => 'غ', '𞺡' => 'ب', '𞺢' => 'ج', '𞺣' => 'د', '𞺥' => 'و', '𞺦' => 'ز', '𞺧' => 'ح', '𞺨' => 'ط', '𞺩' => 'ي', '𞺫' => 'ل', '𞺬' => 'م', '𞺭' => 'ن', '𞺮' => 'س', '𞺯' => 'ع', '𞺰' => 'ف', '𞺱' => 'ص', '𞺲' => 'ق', '𞺳' => 'ر', '𞺴' => 'ش', '𞺵' => 'ت', '𞺶' => 'ث', '𞺷' => 'خ', '𞺸' => 'ذ', '𞺹' => 'ض', '𞺺' => 'ظ', '𞺻' => 'غ', '🄀' => '0.', '🄁' => '0,', '🄂' => '1,', '🄃' => '2,', '🄄' => '3,', '🄅' => '4,', '🄆' => '5,', '🄇' => '6,', '🄈' => '7,', '🄉' => '8,', '🄊' => '9,', '🄐' => '(A)', '🄑' => '(B)', '🄒' => '(C)', '🄓' => '(D)', '🄔' => '(E)', '🄕' => '(F)', '🄖' => '(G)', '🄗' => '(H)', '🄘' => '(I)', '🄙' => '(J)', '🄚' => '(K)', '🄛' => '(L)', '🄜' => '(M)', '🄝' => '(N)', '🄞' => '(O)', '🄟' => '(P)', '🄠' => '(Q)', '🄡' => '(R)', '🄢' => '(S)', '🄣' => '(T)', '🄤' => '(U)', '🄥' => '(V)', '🄦' => '(W)', '🄧' => '(X)', '🄨' => '(Y)', '🄩' => '(Z)', '🄪' => '〔S〕', '🄫' => 'C', '🄬' => 'R', '🄭' => 'CD', '🄮' => 'WZ', '🄰' => 'A', '🄱' => 'B', '🄲' => 'C', '🄳' => 'D', '🄴' => 'E', '🄵' => 'F', '🄶' => 'G', '🄷' => 'H', '🄸' => 'I', '🄹' => 'J', '🄺' => 'K', '🄻' => 'L', '🄼' => 'M', '🄽' => 'N', '🄾' => 'O', '🄿' => 'P', '🅀' => 'Q', '🅁' => 'R', '🅂' => 'S', '🅃' => 'T', '🅄' => 'U', '🅅' => 'V', '🅆' => 'W', '🅇' => 'X', '🅈' => 'Y', '🅉' => 'Z', '🅊' => 'HV', '🅋' => 'MV', '🅌' => 'SD', '🅍' => 'SS', '🅎' => 'PPV', '🅏' => 'WC', '🅪' => 'MC', '🅫' => 'MD', '🅬' => 'MR', '🆐' => 'DJ', '🈀' => 'ほか', '🈁' => 'ココ', '🈂' => 'サ', '🈐' => '手', '🈑' => '字', '🈒' => '双', '🈓' => 'デ', '🈔' => '二', '🈕' => '多', '🈖' => '解', '🈗' => '天', '🈘' => '交', '🈙' => '映', '🈚' => '無', '🈛' => '料', '🈜' => '前', '🈝' => '後', '🈞' => '再', '🈟' => '新', '🈠' => '初', '🈡' => '終', '🈢' => '生', '🈣' => '販', '🈤' => '声', '🈥' => '吹', '🈦' => '演', '🈧' => '投', '🈨' => '捕', '🈩' => '一', '🈪' => '三', '🈫' => '遊', '🈬' => '左', '🈭' => '中', '🈮' => '右', '🈯' => '指', '🈰' => '走', '🈱' => '打', '🈲' => '禁', '🈳' => '空', '🈴' => '合', '🈵' => '満', '🈶' => '有', '🈷' => '月', '🈸' => '申', '🈹' => '割', '🈺' => '営', '🈻' => '配', '🉀' => '〔本〕', '🉁' => '〔三〕', '🉂' => '〔二〕', '🉃' => '〔安〕', '🉄' => '〔点〕', '🉅' => '〔打〕', '🉆' => '〔盗〕', '🉇' => '〔勝〕', '🉈' => '〔敗〕', '🉐' => '得', '🉑' => '可', '🯰' => '0', '🯱' => '1', '🯲' => '2', '🯳' => '3', '🯴' => '4', '🯵' => '5', '🯶' => '6', '🯷' => '7', '🯸' => '8', '🯹' => '9'); diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap.php new file mode 100644 index 0000000000..3608e5c05d --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/bootstrap.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Normalizer as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('normalizer_is_normalized')) { + function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::isNormalized($string, $form); } +} +if (!function_exists('normalizer_normalize')) { + function normalizer_normalize($string, $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize($string, $form); } +} diff --git a/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php b/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php new file mode 100644 index 0000000000..35b06c0878 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/bootstrap80.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Intl\Normalizer as p; + +if (!function_exists('normalizer_is_normalized')) { + function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C): bool { return p\Normalizer::isNormalized((string) $string, (int) $form); } +} +if (!function_exists('normalizer_normalize')) { + /** + * @return string|false + */ + function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C) { return p\Normalizer::normalize((string) $string, (int) $form); } +} diff --git a/vendor/symfony/polyfill-intl-normalizer/composer.json b/vendor/symfony/polyfill-intl-normalizer/composer.json new file mode 100644 index 0000000000..a9940cb0e7 --- /dev/null +++ b/vendor/symfony/polyfill-intl-normalizer/composer.json @@ -0,0 +1,52 @@ +{ + "name": "symfony\/polyfill-intl-normalizer", + "type": "library", + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "keywords": [ + "polyfill", + "shim", + "compatibility", + "portable", + "intl", + "normalizer" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources\/stubs" + ] + }, + "suggest": { + "ext-intl": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + } +} \ No newline at end of file diff --git a/vendor/symfony/polyfill-mbstring/LICENSE b/vendor/symfony/polyfill-mbstring/LICENSE new file mode 100644 index 0000000000..6e3afce692 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php new file mode 100644 index 0000000000..3b0a3eb27a --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -0,0 +1,753 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace Symfony\Polyfill\Mbstring; + +/** + * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. + * + * Implemented: + * - mb_chr - Returns a specific character from its Unicode code point + * - mb_convert_encoding - Convert character encoding + * - mb_convert_variables - Convert character code in variable(s) + * - mb_decode_mimeheader - Decode string in MIME header field + * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED + * - mb_decode_numericentity - Decode HTML numeric string reference to character + * - mb_encode_numericentity - Encode character to HTML numeric string reference + * - mb_convert_case - Perform case folding on a string + * - mb_detect_encoding - Detect character encoding + * - mb_get_info - Get internal settings of mbstring + * - mb_http_input - Detect HTTP input character encoding + * - mb_http_output - Set/Get HTTP output character encoding + * - mb_internal_encoding - Set/Get internal character encoding + * - mb_list_encodings - Returns an array of all supported encodings + * - mb_ord - Returns the Unicode code point of a character + * - mb_output_handler - Callback function converts character encoding in output buffer + * - mb_scrub - Replaces ill-formed byte sequences with substitute characters + * - mb_strlen - Get string length + * - mb_strpos - Find position of first occurrence of string in a string + * - mb_strrpos - Find position of last occurrence of a string in a string + * - mb_str_split - Convert a string to an array + * - mb_strtolower - Make a string lowercase + * - mb_strtoupper - Make a string uppercase + * - mb_substitute_character - Set/Get substitution character + * - mb_substr - Get part of string + * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive + * - mb_stristr - Finds first occurrence of a string within another, case insensitive + * - mb_strrchr - Finds the last occurrence of a character in a string within another + * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive + * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive + * - mb_strstr - Finds first occurrence of a string within another + * - mb_strwidth - Return width of string + * - mb_substr_count - Count the number of substring occurrences + * + * Not implemented: + * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) + * - mb_ereg_* - Regular expression with multibyte support + * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable + * - mb_preferred_mime_name - Get MIME charset string + * - mb_regex_encoding - Returns current encoding for multibyte regex as string + * - mb_regex_set_options - Set/Get the default options for mbregex functions + * - mb_send_mail - Send encoded mail + * - mb_split - Split multibyte string using regular expression + * - mb_strcut - Get part of string + * - mb_strimwidth - Get truncated string with specified width + * + * @author Nicolas Grekas + * + * @internal + */ +final class Mbstring +{ + public const MB_CASE_FOLD = \PHP_INT_MAX; + private const SIMPLE_CASE_FOLD = [['µ', 'ſ', "ͅ", 'ς', "ϐ", "ϑ", "ϕ", "ϖ", "ϰ", "ϱ", "ϵ", "ẛ", "ι"], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "ṡ", 'ι']]; + private static $encodingList = ['ASCII', 'UTF-8']; + private static $language = 'neutral'; + private static $internalEncoding = 'UTF-8'; + public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) + { + if (\is_array($fromEncoding) || null !== $fromEncoding && \false !== \strpos($fromEncoding, ',')) { + $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); + } else { + $fromEncoding = self::getEncoding($fromEncoding); + } + $toEncoding = self::getEncoding($toEncoding); + if ('BASE64' === $fromEncoding) { + $s = \base64_decode($s); + $fromEncoding = $toEncoding; + } + if ('BASE64' === $toEncoding) { + return \base64_encode($s); + } + if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) { + if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) { + $fromEncoding = 'Windows-1252'; + } + if ('UTF-8' !== $fromEncoding) { + $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s); + } + return \preg_replace_callback('/[\\x80-\\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); + } + if ('HTML-ENTITIES' === $fromEncoding) { + $s = \html_entity_decode($s, \ENT_COMPAT, 'UTF-8'); + $fromEncoding = 'UTF-8'; + } + return \iconv($fromEncoding, $toEncoding . '//IGNORE', $s); + } + public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) + { + $ok = \true; + \array_walk_recursive($vars, function (&$v) use(&$ok, $toEncoding, $fromEncoding) { + if (\false === ($v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding))) { + $ok = \false; + } + }); + return $ok ? $fromEncoding : \false; + } + public static function mb_decode_mimeheader($s) + { + return \iconv_mime_decode($s, 2, self::$internalEncoding); + } + public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) + { + \trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING); + } + public static function mb_decode_numericentity($s, $convmap, $encoding = null) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { + \trigger_error('mb_decode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + } + if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) { + return \false; + } + if (null !== $encoding && !\is_scalar($encoding)) { + \trigger_error('mb_decode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return ''; + // Instead of null (cf. mb_encode_numericentity). + } + $s = (string) $s; + if ('' === $s) { + return ''; + } + $encoding = self::getEncoding($encoding); + if ('UTF-8' === $encoding) { + $encoding = null; + if (!\preg_match('//u', $s)) { + $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + $cnt = \floor(\count($convmap) / 4) * 4; + for ($i = 0; $i < $cnt; $i += 4) { + // collector_decode_htmlnumericentity ignores $convmap[$i + 3] + $convmap[$i] += $convmap[$i + 2]; + $convmap[$i + 1] += $convmap[$i + 2]; + } + $s = \preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use($cnt, $convmap) { + $c = isset($m[2]) ? (int) \hexdec($m[2]) : $m[1]; + for ($i = 0; $i < $cnt; $i += 4) { + if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) { + return self::mb_chr($c - $convmap[$i + 2]); + } + } + return $m[0]; + }, $s); + if (null === $encoding) { + return $s; + } + return \iconv('UTF-8', $encoding . '//IGNORE', $s); + } + public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = \false) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { + \trigger_error('mb_encode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + } + if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) { + return \false; + } + if (null !== $encoding && !\is_scalar($encoding)) { + \trigger_error('mb_encode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + // Instead of '' (cf. mb_decode_numericentity). + } + if (null !== $is_hex && !\is_scalar($is_hex)) { + \trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + } + $s = (string) $s; + if ('' === $s) { + return ''; + } + $encoding = self::getEncoding($encoding); + if ('UTF-8' === $encoding) { + $encoding = null; + if (!\preg_match('//u', $s)) { + $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4]; + $cnt = \floor(\count($convmap) / 4) * 4; + $i = 0; + $len = \strlen($s); + $result = ''; + while ($i < $len) { + $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"]; + $uchr = \substr($s, $i, $ulen); + $i += $ulen; + $c = self::mb_ord($uchr); + for ($j = 0; $j < $cnt; $j += 4) { + if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) { + $cOffset = $c + $convmap[$j + 2] & $convmap[$j + 3]; + $result .= $is_hex ? \sprintf('&#x%X;', $cOffset) : '&#' . $cOffset . ';'; + continue 2; + } + } + $result .= $uchr; + } + if (null === $encoding) { + return $result; + } + return \iconv('UTF-8', $encoding . '//IGNORE', $result); + } + public static function mb_convert_case($s, $mode, $encoding = null) + { + $s = (string) $s; + if ('' === $s) { + return ''; + } + $encoding = self::getEncoding($encoding); + if ('UTF-8' === $encoding) { + $encoding = null; + if (!\preg_match('//u', $s)) { + $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + if (\MB_CASE_TITLE == $mode) { + static $titleRegexp = null; + if (null === $titleRegexp) { + $titleRegexp = self::getData('titleCaseRegexp'); + } + $s = \preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s); + } else { + if (\MB_CASE_UPPER == $mode) { + static $upper = null; + if (null === $upper) { + $upper = self::getData('upperCase'); + } + $map = $upper; + } else { + if (self::MB_CASE_FOLD === $mode) { + static $caseFolding = null; + if (null === $caseFolding) { + $caseFolding = self::getData('caseFolding'); + } + $s = \strtr($s, $caseFolding); + } + static $lower = null; + if (null === $lower) { + $lower = self::getData('lowerCase'); + } + $map = $lower; + } + static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4]; + $i = 0; + $len = \strlen($s); + while ($i < $len) { + $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"]; + $uchr = \substr($s, $i, $ulen); + $i += $ulen; + if (isset($map[$uchr])) { + $uchr = $map[$uchr]; + $nlen = \strlen($uchr); + if ($nlen == $ulen) { + $nlen = $i; + do { + $s[--$nlen] = $uchr[--$ulen]; + } while ($ulen); + } else { + $s = \substr_replace($s, $uchr, $i - $ulen, $ulen); + $len += $nlen - $ulen; + $i += $nlen - $ulen; + } + } + } + } + if (null === $encoding) { + return $s; + } + return \iconv('UTF-8', $encoding . '//IGNORE', $s); + } + public static function mb_internal_encoding($encoding = null) + { + if (null === $encoding) { + return self::$internalEncoding; + } + $normalizedEncoding = self::getEncoding($encoding); + if ('UTF-8' === $normalizedEncoding || \false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) { + self::$internalEncoding = $normalizedEncoding; + return \true; + } + if (80000 > \PHP_VERSION_ID) { + return \false; + } + throw new \ValueError(\sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + public static function mb_language($lang = null) + { + if (null === $lang) { + return self::$language; + } + switch ($normalizedLang = \strtolower($lang)) { + case 'uni': + case 'neutral': + self::$language = $normalizedLang; + return \true; + } + if (80000 > \PHP_VERSION_ID) { + return \false; + } + throw new \ValueError(\sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang)); + } + public static function mb_list_encodings() + { + return ['UTF-8']; + } + public static function mb_encoding_aliases($encoding) + { + switch (\strtoupper($encoding)) { + case 'UTF8': + case 'UTF-8': + return ['utf8']; + } + return \false; + } + public static function mb_check_encoding($var = null, $encoding = null) + { + if (\PHP_VERSION_ID < 70200 && \is_array($var)) { + \trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); + return null; + } + if (null === $encoding) { + if (null === $var) { + return \false; + } + $encoding = self::$internalEncoding; + } + if (!\is_array($var)) { + return self::mb_detect_encoding($var, [$encoding]) || \false !== @\iconv($encoding, $encoding, $var); + } + foreach ($var as $key => $value) { + if (!self::mb_check_encoding($key, $encoding)) { + return \false; + } + if (!self::mb_check_encoding($value, $encoding)) { + return \false; + } + } + return \true; + } + public static function mb_detect_encoding($str, $encodingList = null, $strict = \false) + { + if (null === $encodingList) { + $encodingList = self::$encodingList; + } else { + if (!\is_array($encodingList)) { + $encodingList = \array_map('trim', \explode(',', $encodingList)); + } + $encodingList = \array_map('strtoupper', $encodingList); + } + foreach ($encodingList as $enc) { + switch ($enc) { + case 'ASCII': + if (!\preg_match('/[\\x80-\\xFF]/', $str)) { + return $enc; + } + break; + case 'UTF8': + case 'UTF-8': + if (\preg_match('//u', $str)) { + return 'UTF-8'; + } + break; + default: + if (0 === \strncmp($enc, 'ISO-8859-', 9)) { + return $enc; + } + } + } + return \false; + } + public static function mb_detect_order($encodingList = null) + { + if (null === $encodingList) { + return self::$encodingList; + } + if (!\is_array($encodingList)) { + $encodingList = \array_map('trim', \explode(',', $encodingList)); + } + $encodingList = \array_map('strtoupper', $encodingList); + foreach ($encodingList as $enc) { + switch ($enc) { + default: + if (\strncmp($enc, 'ISO-8859-', 9)) { + return \false; + } + // no break + case 'ASCII': + case 'UTF8': + case 'UTF-8': + } + } + self::$encodingList = $encodingList; + return \true; + } + public static function mb_strlen($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strlen($s); + } + return @\iconv_strlen($s, $encoding); + } + public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strpos($haystack, $needle, $offset); + } + $needle = (string) $needle; + if ('' === $needle) { + if (80000 > \PHP_VERSION_ID) { + \trigger_error(__METHOD__ . ': Empty delimiter', \E_USER_WARNING); + return \false; + } + return 0; + } + return \iconv_strpos($haystack, $needle, $offset, $encoding); + } + public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strrpos($haystack, $needle, $offset); + } + if ($offset != (int) $offset) { + $offset = 0; + } elseif ($offset = (int) $offset) { + if ($offset < 0) { + if (0 > ($offset += self::mb_strlen($needle))) { + $haystack = self::mb_substr($haystack, 0, $offset, $encoding); + } + $offset = 0; + } else { + $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding); + } + } + $pos = '' !== $needle || 80000 > \PHP_VERSION_ID ? \iconv_strrpos($haystack, $needle, $encoding) : self::mb_strlen($haystack, $encoding); + return \false !== $pos ? $offset + $pos : \false; + } + public static function mb_str_split($string, $split_length = 1, $encoding = null) + { + if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) { + \trigger_error('mb_str_split() expects parameter 1 to be string, ' . \gettype($string) . ' given', \E_USER_WARNING); + return null; + } + if (1 > ($split_length = (int) $split_length)) { + if (80000 > \PHP_VERSION_ID) { + \trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); + return \false; + } + throw new \ValueError('Argument #2 ($length) must be greater than 0'); + } + if (null === $encoding) { + $encoding = \mb_internal_encoding(); + } + if ('UTF-8' === ($encoding = self::getEncoding($encoding))) { + $rx = '/('; + while (65535 < $split_length) { + $rx .= '.{65535}'; + $split_length -= 65535; + } + $rx .= '.{' . $split_length . '})/us'; + return \preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); + } + $result = []; + $length = \mb_strlen($string, $encoding); + for ($i = 0; $i < $length; $i += $split_length) { + $result[] = \mb_substr($string, $i, $split_length, $encoding); + } + return $result; + } + public static function mb_strtolower($s, $encoding = null) + { + return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding); + } + public static function mb_strtoupper($s, $encoding = null) + { + return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding); + } + public static function mb_substitute_character($c = null) + { + if (null === $c) { + return 'none'; + } + if (0 === \strcasecmp($c, 'none')) { + return \true; + } + if (80000 > \PHP_VERSION_ID) { + return \false; + } + if (\is_int($c) || 'long' === $c || 'entity' === $c) { + return \false; + } + throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint'); + } + public static function mb_substr($s, $start, $length = null, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return (string) \substr($s, $start, null === $length ? 2147483647 : $length); + } + if ($start < 0) { + $start = \iconv_strlen($s, $encoding) + $start; + if ($start < 0) { + $start = 0; + } + } + if (null === $length) { + $length = 2147483647; + } elseif ($length < 0) { + $length = \iconv_strlen($s, $encoding) + $length - $start; + if ($length < 0) { + return ''; + } + } + return (string) \iconv_substr($s, $start, $length, $encoding); + } + public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) + { + [$haystack, $needle] = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding)]); + return self::mb_strpos($haystack, $needle, $offset, $encoding); + } + public static function mb_stristr($haystack, $needle, $part = \false, $encoding = null) + { + $pos = self::mb_stripos($haystack, $needle, 0, $encoding); + return self::getSubpart($pos, $part, $haystack, $encoding); + } + public static function mb_strrchr($haystack, $needle, $part = \false, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + $pos = \strrpos($haystack, $needle); + } else { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = \iconv_strrpos($haystack, $needle, $encoding); + } + return self::getSubpart($pos, $part, $haystack, $encoding); + } + public static function mb_strrichr($haystack, $needle, $part = \false, $encoding = null) + { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = self::mb_strripos($haystack, $needle, $encoding); + return self::getSubpart($pos, $part, $haystack, $encoding); + } + public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) + { + $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding); + $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding); + $haystack = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack); + $needle = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle); + return self::mb_strrpos($haystack, $needle, $offset, $encoding); + } + public static function mb_strstr($haystack, $needle, $part = \false, $encoding = null) + { + $pos = \strpos($haystack, $needle); + if (\false === $pos) { + return \false; + } + if ($part) { + return \substr($haystack, 0, $pos); + } + return \substr($haystack, $pos); + } + public static function mb_get_info($type = 'all') + { + $info = ['internal_encoding' => self::$internalEncoding, 'http_output' => 'pass', 'http_output_conv_mimetypes' => '^(text/|application/xhtml\\+xml)', 'func_overload' => 0, 'func_overload_list' => 'no overload', 'mail_charset' => 'UTF-8', 'mail_header_encoding' => 'BASE64', 'mail_body_encoding' => 'BASE64', 'illegal_chars' => 0, 'encoding_translation' => 'Off', 'language' => self::$language, 'detect_order' => self::$encodingList, 'substitute_character' => 'none', 'strict_detection' => 'Off']; + if ('all' === $type) { + return $info; + } + if (isset($info[$type])) { + return $info[$type]; + } + return \false; + } + public static function mb_http_input($type = '') + { + return \false; + } + public static function mb_http_output($encoding = null) + { + return null !== $encoding ? 'pass' === $encoding : 'pass'; + } + public static function mb_strwidth($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('UTF-8' !== $encoding) { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + $s = \preg_replace('/[\\x{1100}-\\x{115F}\\x{2329}\\x{232A}\\x{2E80}-\\x{303E}\\x{3040}-\\x{A4CF}\\x{AC00}-\\x{D7A3}\\x{F900}-\\x{FAFF}\\x{FE10}-\\x{FE19}\\x{FE30}-\\x{FE6F}\\x{FF00}-\\x{FF60}\\x{FFE0}-\\x{FFE6}\\x{20000}-\\x{2FFFD}\\x{30000}-\\x{3FFFD}]/u', '', $s, -1, $wide); + return ($wide << 1) + \iconv_strlen($s, 'UTF-8'); + } + public static function mb_substr_count($haystack, $needle, $encoding = null) + { + return \substr_count($haystack, $needle); + } + public static function mb_output_handler($contents, $status) + { + return $contents; + } + public static function mb_chr($code, $encoding = null) + { + if (0x80 > ($code %= 0x200000)) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f); + } elseif (0x10000 > $code) { + $s = \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } else { + $s = \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } + if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) { + $s = \mb_convert_encoding($s, $encoding, 'UTF-8'); + } + return $s; + } + public static function mb_ord($s, $encoding = null) + { + if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) { + $s = \mb_convert_encoding($s, 'UTF-8', $encoding); + } + if (1 === \strlen($s)) { + return \ord($s); + } + $code = ($s = \unpack('C*', \substr($s, 0, 4))) ? $s[1] : 0; + if (0xf0 <= $code) { + return ($code - 0xf0 << 18) + ($s[2] - 0x80 << 12) + ($s[3] - 0x80 << 6) + $s[4] - 0x80; + } + if (0xe0 <= $code) { + return ($code - 0xe0 << 12) + ($s[2] - 0x80 << 6) + $s[3] - 0x80; + } + if (0xc0 <= $code) { + return ($code - 0xc0 << 6) + $s[2] - 0x80; + } + return $code; + } + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null) : string + { + if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], \true)) { + throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); + } + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + if (self::mb_strlen($pad_string, $encoding) <= 0) { + throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); + } + $paddingRequired = $length - self::mb_strlen($string, $encoding); + if ($paddingRequired < 1) { + return $string; + } + switch ($pad_type) { + case \STR_PAD_LEFT: + return self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding) . $string; + case \STR_PAD_RIGHT: + return $string . self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding); + default: + $leftPaddingLength = \floor($paddingRequired / 2); + $rightPaddingLength = $paddingRequired - $leftPaddingLength; + return self::mb_substr(\str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding) . $string . self::mb_substr(\str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding); + } + } + private static function getSubpart($pos, $part, $haystack, $encoding) + { + if (\false === $pos) { + return \false; + } + if ($part) { + return self::mb_substr($haystack, 0, $pos, $encoding); + } + return self::mb_substr($haystack, $pos, null, $encoding); + } + private static function html_encoding_callback(array $m) + { + $i = 1; + $entities = ''; + $m = \unpack('C*', \htmlentities($m[0], \ENT_COMPAT, 'UTF-8')); + while (isset($m[$i])) { + if (0x80 > $m[$i]) { + $entities .= \chr($m[$i++]); + continue; + } + if (0xf0 <= $m[$i]) { + $c = ($m[$i++] - 0xf0 << 18) + ($m[$i++] - 0x80 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80; + } elseif (0xe0 <= $m[$i]) { + $c = ($m[$i++] - 0xe0 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80; + } else { + $c = ($m[$i++] - 0xc0 << 6) + $m[$i++] - 0x80; + } + $entities .= '&#' . $c . ';'; + } + return $entities; + } + private static function title_case(array $s) + { + return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8') . self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8'); + } + private static function getData($file) + { + if (\file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) { + return require $file; + } + return \false; + } + private static function getEncoding($encoding) + { + if (null === $encoding) { + return self::$internalEncoding; + } + if ('UTF-8' === $encoding) { + return 'UTF-8'; + } + $encoding = \strtoupper($encoding); + if ('8BIT' === $encoding || 'BINARY' === $encoding) { + return 'CP850'; + } + if ('UTF8' === $encoding) { + return 'UTF-8'; + } + return $encoding; + } +} diff --git a/vendor/symfony/polyfill-mbstring/README.md b/vendor/symfony/polyfill-mbstring/README.md new file mode 100644 index 0000000000..478b40da25 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/README.md @@ -0,0 +1,13 @@ +Symfony Polyfill / Mbstring +=========================== + +This component provides a partial, native PHP implementation for the +[Mbstring](https://php.net/mbstring) extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php new file mode 100644 index 0000000000..831143e8f2 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php @@ -0,0 +1,5 @@ + 'i̇', 'µ' => 'μ', 'ſ' => 's', 'ͅ' => 'ι', 'ς' => 'σ', 'ϐ' => 'β', 'ϑ' => 'θ', 'ϕ' => 'φ', 'ϖ' => 'π', 'ϰ' => 'κ', 'ϱ' => 'ρ', 'ϵ' => 'ε', 'ẛ' => 'ṡ', 'ι' => 'ι', 'ß' => 'ss', 'ʼn' => 'ʼn', 'ǰ' => 'ǰ', 'ΐ' => 'ΐ', 'ΰ' => 'ΰ', 'և' => 'եւ', 'ẖ' => 'ẖ', 'ẗ' => 'ẗ', 'ẘ' => 'ẘ', 'ẙ' => 'ẙ', 'ẚ' => 'aʾ', 'ẞ' => 'ss', 'ὐ' => 'ὐ', 'ὒ' => 'ὒ', 'ὔ' => 'ὔ', 'ὖ' => 'ὖ', 'ᾀ' => 'ἀι', 'ᾁ' => 'ἁι', 'ᾂ' => 'ἂι', 'ᾃ' => 'ἃι', 'ᾄ' => 'ἄι', 'ᾅ' => 'ἅι', 'ᾆ' => 'ἆι', 'ᾇ' => 'ἇι', 'ᾈ' => 'ἀι', 'ᾉ' => 'ἁι', 'ᾊ' => 'ἂι', 'ᾋ' => 'ἃι', 'ᾌ' => 'ἄι', 'ᾍ' => 'ἅι', 'ᾎ' => 'ἆι', 'ᾏ' => 'ἇι', 'ᾐ' => 'ἠι', 'ᾑ' => 'ἡι', 'ᾒ' => 'ἢι', 'ᾓ' => 'ἣι', 'ᾔ' => 'ἤι', 'ᾕ' => 'ἥι', 'ᾖ' => 'ἦι', 'ᾗ' => 'ἧι', 'ᾘ' => 'ἠι', 'ᾙ' => 'ἡι', 'ᾚ' => 'ἢι', 'ᾛ' => 'ἣι', 'ᾜ' => 'ἤι', 'ᾝ' => 'ἥι', 'ᾞ' => 'ἦι', 'ᾟ' => 'ἧι', 'ᾠ' => 'ὠι', 'ᾡ' => 'ὡι', 'ᾢ' => 'ὢι', 'ᾣ' => 'ὣι', 'ᾤ' => 'ὤι', 'ᾥ' => 'ὥι', 'ᾦ' => 'ὦι', 'ᾧ' => 'ὧι', 'ᾨ' => 'ὠι', 'ᾩ' => 'ὡι', 'ᾪ' => 'ὢι', 'ᾫ' => 'ὣι', 'ᾬ' => 'ὤι', 'ᾭ' => 'ὥι', 'ᾮ' => 'ὦι', 'ᾯ' => 'ὧι', 'ᾲ' => 'ὰι', 'ᾳ' => 'αι', 'ᾴ' => 'άι', 'ᾶ' => 'ᾶ', 'ᾷ' => 'ᾶι', 'ᾼ' => 'αι', 'ῂ' => 'ὴι', 'ῃ' => 'ηι', 'ῄ' => 'ήι', 'ῆ' => 'ῆ', 'ῇ' => 'ῆι', 'ῌ' => 'ηι', 'ῒ' => 'ῒ', 'ῖ' => 'ῖ', 'ῗ' => 'ῗ', 'ῢ' => 'ῢ', 'ῤ' => 'ῤ', 'ῦ' => 'ῦ', 'ῧ' => 'ῧ', 'ῲ' => 'ὼι', 'ῳ' => 'ωι', 'ῴ' => 'ώι', 'ῶ' => 'ῶ', 'ῷ' => 'ῶι', 'ῼ' => 'ωι', 'ff' => 'ff', 'fi' => 'fi', 'fl' => 'fl', 'ffi' => 'ffi', 'ffl' => 'ffl', 'ſt' => 'st', 'st' => 'st', 'ﬓ' => 'մն', 'ﬔ' => 'մե', 'ﬕ' => 'մի', 'ﬖ' => 'վն', 'ﬗ' => 'մխ']; diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php new file mode 100644 index 0000000000..e4724979af --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php @@ -0,0 +1,5 @@ + 'a', 'B' => 'b', 'C' => 'c', 'D' => 'd', 'E' => 'e', 'F' => 'f', 'G' => 'g', 'H' => 'h', 'I' => 'i', 'J' => 'j', 'K' => 'k', 'L' => 'l', 'M' => 'm', 'N' => 'n', 'O' => 'o', 'P' => 'p', 'Q' => 'q', 'R' => 'r', 'S' => 's', 'T' => 't', 'U' => 'u', 'V' => 'v', 'W' => 'w', 'X' => 'x', 'Y' => 'y', 'Z' => 'z', 'À' => 'à', 'Á' => 'á', 'Â' => 'â', 'Ã' => 'ã', 'Ä' => 'ä', 'Å' => 'å', 'Æ' => 'æ', 'Ç' => 'ç', 'È' => 'è', 'É' => 'é', 'Ê' => 'ê', 'Ë' => 'ë', 'Ì' => 'ì', 'Í' => 'í', 'Î' => 'î', 'Ï' => 'ï', 'Ð' => 'ð', 'Ñ' => 'ñ', 'Ò' => 'ò', 'Ó' => 'ó', 'Ô' => 'ô', 'Õ' => 'õ', 'Ö' => 'ö', 'Ø' => 'ø', 'Ù' => 'ù', 'Ú' => 'ú', 'Û' => 'û', 'Ü' => 'ü', 'Ý' => 'ý', 'Þ' => 'þ', 'Ā' => 'ā', 'Ă' => 'ă', 'Ą' => 'ą', 'Ć' => 'ć', 'Ĉ' => 'ĉ', 'Ċ' => 'ċ', 'Č' => 'č', 'Ď' => 'ď', 'Đ' => 'đ', 'Ē' => 'ē', 'Ĕ' => 'ĕ', 'Ė' => 'ė', 'Ę' => 'ę', 'Ě' => 'ě', 'Ĝ' => 'ĝ', 'Ğ' => 'ğ', 'Ġ' => 'ġ', 'Ģ' => 'ģ', 'Ĥ' => 'ĥ', 'Ħ' => 'ħ', 'Ĩ' => 'ĩ', 'Ī' => 'ī', 'Ĭ' => 'ĭ', 'Į' => 'į', 'İ' => 'i̇', 'IJ' => 'ij', 'Ĵ' => 'ĵ', 'Ķ' => 'ķ', 'Ĺ' => 'ĺ', 'Ļ' => 'ļ', 'Ľ' => 'ľ', 'Ŀ' => 'ŀ', 'Ł' => 'ł', 'Ń' => 'ń', 'Ņ' => 'ņ', 'Ň' => 'ň', 'Ŋ' => 'ŋ', 'Ō' => 'ō', 'Ŏ' => 'ŏ', 'Ő' => 'ő', 'Œ' => 'œ', 'Ŕ' => 'ŕ', 'Ŗ' => 'ŗ', 'Ř' => 'ř', 'Ś' => 'ś', 'Ŝ' => 'ŝ', 'Ş' => 'ş', 'Š' => 'š', 'Ţ' => 'ţ', 'Ť' => 'ť', 'Ŧ' => 'ŧ', 'Ũ' => 'ũ', 'Ū' => 'ū', 'Ŭ' => 'ŭ', 'Ů' => 'ů', 'Ű' => 'ű', 'Ų' => 'ų', 'Ŵ' => 'ŵ', 'Ŷ' => 'ŷ', 'Ÿ' => 'ÿ', 'Ź' => 'ź', 'Ż' => 'ż', 'Ž' => 'ž', 'Ɓ' => 'ɓ', 'Ƃ' => 'ƃ', 'Ƅ' => 'ƅ', 'Ɔ' => 'ɔ', 'Ƈ' => 'ƈ', 'Ɖ' => 'ɖ', 'Ɗ' => 'ɗ', 'Ƌ' => 'ƌ', 'Ǝ' => 'ǝ', 'Ə' => 'ə', 'Ɛ' => 'ɛ', 'Ƒ' => 'ƒ', 'Ɠ' => 'ɠ', 'Ɣ' => 'ɣ', 'Ɩ' => 'ɩ', 'Ɨ' => 'ɨ', 'Ƙ' => 'ƙ', 'Ɯ' => 'ɯ', 'Ɲ' => 'ɲ', 'Ɵ' => 'ɵ', 'Ơ' => 'ơ', 'Ƣ' => 'ƣ', 'Ƥ' => 'ƥ', 'Ʀ' => 'ʀ', 'Ƨ' => 'ƨ', 'Ʃ' => 'ʃ', 'Ƭ' => 'ƭ', 'Ʈ' => 'ʈ', 'Ư' => 'ư', 'Ʊ' => 'ʊ', 'Ʋ' => 'ʋ', 'Ƴ' => 'ƴ', 'Ƶ' => 'ƶ', 'Ʒ' => 'ʒ', 'Ƹ' => 'ƹ', 'Ƽ' => 'ƽ', 'DŽ' => 'dž', 'Dž' => 'dž', 'LJ' => 'lj', 'Lj' => 'lj', 'NJ' => 'nj', 'Nj' => 'nj', 'Ǎ' => 'ǎ', 'Ǐ' => 'ǐ', 'Ǒ' => 'ǒ', 'Ǔ' => 'ǔ', 'Ǖ' => 'ǖ', 'Ǘ' => 'ǘ', 'Ǚ' => 'ǚ', 'Ǜ' => 'ǜ', 'Ǟ' => 'ǟ', 'Ǡ' => 'ǡ', 'Ǣ' => 'ǣ', 'Ǥ' => 'ǥ', 'Ǧ' => 'ǧ', 'Ǩ' => 'ǩ', 'Ǫ' => 'ǫ', 'Ǭ' => 'ǭ', 'Ǯ' => 'ǯ', 'DZ' => 'dz', 'Dz' => 'dz', 'Ǵ' => 'ǵ', 'Ƕ' => 'ƕ', 'Ƿ' => 'ƿ', 'Ǹ' => 'ǹ', 'Ǻ' => 'ǻ', 'Ǽ' => 'ǽ', 'Ǿ' => 'ǿ', 'Ȁ' => 'ȁ', 'Ȃ' => 'ȃ', 'Ȅ' => 'ȅ', 'Ȇ' => 'ȇ', 'Ȉ' => 'ȉ', 'Ȋ' => 'ȋ', 'Ȍ' => 'ȍ', 'Ȏ' => 'ȏ', 'Ȑ' => 'ȑ', 'Ȓ' => 'ȓ', 'Ȕ' => 'ȕ', 'Ȗ' => 'ȗ', 'Ș' => 'ș', 'Ț' => 'ț', 'Ȝ' => 'ȝ', 'Ȟ' => 'ȟ', 'Ƞ' => 'ƞ', 'Ȣ' => 'ȣ', 'Ȥ' => 'ȥ', 'Ȧ' => 'ȧ', 'Ȩ' => 'ȩ', 'Ȫ' => 'ȫ', 'Ȭ' => 'ȭ', 'Ȯ' => 'ȯ', 'Ȱ' => 'ȱ', 'Ȳ' => 'ȳ', 'Ⱥ' => 'ⱥ', 'Ȼ' => 'ȼ', 'Ƚ' => 'ƚ', 'Ⱦ' => 'ⱦ', 'Ɂ' => 'ɂ', 'Ƀ' => 'ƀ', 'Ʉ' => 'ʉ', 'Ʌ' => 'ʌ', 'Ɇ' => 'ɇ', 'Ɉ' => 'ɉ', 'Ɋ' => 'ɋ', 'Ɍ' => 'ɍ', 'Ɏ' => 'ɏ', 'Ͱ' => 'ͱ', 'Ͳ' => 'ͳ', 'Ͷ' => 'ͷ', 'Ϳ' => 'ϳ', 'Ά' => 'ά', 'Έ' => 'έ', 'Ή' => 'ή', 'Ί' => 'ί', 'Ό' => 'ό', 'Ύ' => 'ύ', 'Ώ' => 'ώ', 'Α' => 'α', 'Β' => 'β', 'Γ' => 'γ', 'Δ' => 'δ', 'Ε' => 'ε', 'Ζ' => 'ζ', 'Η' => 'η', 'Θ' => 'θ', 'Ι' => 'ι', 'Κ' => 'κ', 'Λ' => 'λ', 'Μ' => 'μ', 'Ν' => 'ν', 'Ξ' => 'ξ', 'Ο' => 'ο', 'Π' => 'π', 'Ρ' => 'ρ', 'Σ' => 'σ', 'Τ' => 'τ', 'Υ' => 'υ', 'Φ' => 'φ', 'Χ' => 'χ', 'Ψ' => 'ψ', 'Ω' => 'ω', 'Ϊ' => 'ϊ', 'Ϋ' => 'ϋ', 'Ϗ' => 'ϗ', 'Ϙ' => 'ϙ', 'Ϛ' => 'ϛ', 'Ϝ' => 'ϝ', 'Ϟ' => 'ϟ', 'Ϡ' => 'ϡ', 'Ϣ' => 'ϣ', 'Ϥ' => 'ϥ', 'Ϧ' => 'ϧ', 'Ϩ' => 'ϩ', 'Ϫ' => 'ϫ', 'Ϭ' => 'ϭ', 'Ϯ' => 'ϯ', 'ϴ' => 'θ', 'Ϸ' => 'ϸ', 'Ϲ' => 'ϲ', 'Ϻ' => 'ϻ', 'Ͻ' => 'ͻ', 'Ͼ' => 'ͼ', 'Ͽ' => 'ͽ', 'Ѐ' => 'ѐ', 'Ё' => 'ё', 'Ђ' => 'ђ', 'Ѓ' => 'ѓ', 'Є' => 'є', 'Ѕ' => 'ѕ', 'І' => 'і', 'Ї' => 'ї', 'Ј' => 'ј', 'Љ' => 'љ', 'Њ' => 'њ', 'Ћ' => 'ћ', 'Ќ' => 'ќ', 'Ѝ' => 'ѝ', 'Ў' => 'ў', 'Џ' => 'џ', 'А' => 'а', 'Б' => 'б', 'В' => 'в', 'Г' => 'г', 'Д' => 'д', 'Е' => 'е', 'Ж' => 'ж', 'З' => 'з', 'И' => 'и', 'Й' => 'й', 'К' => 'к', 'Л' => 'л', 'М' => 'м', 'Н' => 'н', 'О' => 'о', 'П' => 'п', 'Р' => 'р', 'С' => 'с', 'Т' => 'т', 'У' => 'у', 'Ф' => 'ф', 'Х' => 'х', 'Ц' => 'ц', 'Ч' => 'ч', 'Ш' => 'ш', 'Щ' => 'щ', 'Ъ' => 'ъ', 'Ы' => 'ы', 'Ь' => 'ь', 'Э' => 'э', 'Ю' => 'ю', 'Я' => 'я', 'Ѡ' => 'ѡ', 'Ѣ' => 'ѣ', 'Ѥ' => 'ѥ', 'Ѧ' => 'ѧ', 'Ѩ' => 'ѩ', 'Ѫ' => 'ѫ', 'Ѭ' => 'ѭ', 'Ѯ' => 'ѯ', 'Ѱ' => 'ѱ', 'Ѳ' => 'ѳ', 'Ѵ' => 'ѵ', 'Ѷ' => 'ѷ', 'Ѹ' => 'ѹ', 'Ѻ' => 'ѻ', 'Ѽ' => 'ѽ', 'Ѿ' => 'ѿ', 'Ҁ' => 'ҁ', 'Ҋ' => 'ҋ', 'Ҍ' => 'ҍ', 'Ҏ' => 'ҏ', 'Ґ' => 'ґ', 'Ғ' => 'ғ', 'Ҕ' => 'ҕ', 'Җ' => 'җ', 'Ҙ' => 'ҙ', 'Қ' => 'қ', 'Ҝ' => 'ҝ', 'Ҟ' => 'ҟ', 'Ҡ' => 'ҡ', 'Ң' => 'ң', 'Ҥ' => 'ҥ', 'Ҧ' => 'ҧ', 'Ҩ' => 'ҩ', 'Ҫ' => 'ҫ', 'Ҭ' => 'ҭ', 'Ү' => 'ү', 'Ұ' => 'ұ', 'Ҳ' => 'ҳ', 'Ҵ' => 'ҵ', 'Ҷ' => 'ҷ', 'Ҹ' => 'ҹ', 'Һ' => 'һ', 'Ҽ' => 'ҽ', 'Ҿ' => 'ҿ', 'Ӏ' => 'ӏ', 'Ӂ' => 'ӂ', 'Ӄ' => 'ӄ', 'Ӆ' => 'ӆ', 'Ӈ' => 'ӈ', 'Ӊ' => 'ӊ', 'Ӌ' => 'ӌ', 'Ӎ' => 'ӎ', 'Ӑ' => 'ӑ', 'Ӓ' => 'ӓ', 'Ӕ' => 'ӕ', 'Ӗ' => 'ӗ', 'Ә' => 'ә', 'Ӛ' => 'ӛ', 'Ӝ' => 'ӝ', 'Ӟ' => 'ӟ', 'Ӡ' => 'ӡ', 'Ӣ' => 'ӣ', 'Ӥ' => 'ӥ', 'Ӧ' => 'ӧ', 'Ө' => 'ө', 'Ӫ' => 'ӫ', 'Ӭ' => 'ӭ', 'Ӯ' => 'ӯ', 'Ӱ' => 'ӱ', 'Ӳ' => 'ӳ', 'Ӵ' => 'ӵ', 'Ӷ' => 'ӷ', 'Ӹ' => 'ӹ', 'Ӻ' => 'ӻ', 'Ӽ' => 'ӽ', 'Ӿ' => 'ӿ', 'Ԁ' => 'ԁ', 'Ԃ' => 'ԃ', 'Ԅ' => 'ԅ', 'Ԇ' => 'ԇ', 'Ԉ' => 'ԉ', 'Ԋ' => 'ԋ', 'Ԍ' => 'ԍ', 'Ԏ' => 'ԏ', 'Ԑ' => 'ԑ', 'Ԓ' => 'ԓ', 'Ԕ' => 'ԕ', 'Ԗ' => 'ԗ', 'Ԙ' => 'ԙ', 'Ԛ' => 'ԛ', 'Ԝ' => 'ԝ', 'Ԟ' => 'ԟ', 'Ԡ' => 'ԡ', 'Ԣ' => 'ԣ', 'Ԥ' => 'ԥ', 'Ԧ' => 'ԧ', 'Ԩ' => 'ԩ', 'Ԫ' => 'ԫ', 'Ԭ' => 'ԭ', 'Ԯ' => 'ԯ', 'Ա' => 'ա', 'Բ' => 'բ', 'Գ' => 'գ', 'Դ' => 'դ', 'Ե' => 'ե', 'Զ' => 'զ', 'Է' => 'է', 'Ը' => 'ը', 'Թ' => 'թ', 'Ժ' => 'ժ', 'Ի' => 'ի', 'Լ' => 'լ', 'Խ' => 'խ', 'Ծ' => 'ծ', 'Կ' => 'կ', 'Հ' => 'հ', 'Ձ' => 'ձ', 'Ղ' => 'ղ', 'Ճ' => 'ճ', 'Մ' => 'մ', 'Յ' => 'յ', 'Ն' => 'ն', 'Շ' => 'շ', 'Ո' => 'ո', 'Չ' => 'չ', 'Պ' => 'պ', 'Ջ' => 'ջ', 'Ռ' => 'ռ', 'Ս' => 'ս', 'Վ' => 'վ', 'Տ' => 'տ', 'Ր' => 'ր', 'Ց' => 'ց', 'Ւ' => 'ւ', 'Փ' => 'փ', 'Ք' => 'ք', 'Օ' => 'օ', 'Ֆ' => 'ֆ', 'Ⴀ' => 'ⴀ', 'Ⴁ' => 'ⴁ', 'Ⴂ' => 'ⴂ', 'Ⴃ' => 'ⴃ', 'Ⴄ' => 'ⴄ', 'Ⴅ' => 'ⴅ', 'Ⴆ' => 'ⴆ', 'Ⴇ' => 'ⴇ', 'Ⴈ' => 'ⴈ', 'Ⴉ' => 'ⴉ', 'Ⴊ' => 'ⴊ', 'Ⴋ' => 'ⴋ', 'Ⴌ' => 'ⴌ', 'Ⴍ' => 'ⴍ', 'Ⴎ' => 'ⴎ', 'Ⴏ' => 'ⴏ', 'Ⴐ' => 'ⴐ', 'Ⴑ' => 'ⴑ', 'Ⴒ' => 'ⴒ', 'Ⴓ' => 'ⴓ', 'Ⴔ' => 'ⴔ', 'Ⴕ' => 'ⴕ', 'Ⴖ' => 'ⴖ', 'Ⴗ' => 'ⴗ', 'Ⴘ' => 'ⴘ', 'Ⴙ' => 'ⴙ', 'Ⴚ' => 'ⴚ', 'Ⴛ' => 'ⴛ', 'Ⴜ' => 'ⴜ', 'Ⴝ' => 'ⴝ', 'Ⴞ' => 'ⴞ', 'Ⴟ' => 'ⴟ', 'Ⴠ' => 'ⴠ', 'Ⴡ' => 'ⴡ', 'Ⴢ' => 'ⴢ', 'Ⴣ' => 'ⴣ', 'Ⴤ' => 'ⴤ', 'Ⴥ' => 'ⴥ', 'Ⴧ' => 'ⴧ', 'Ⴭ' => 'ⴭ', 'Ꭰ' => 'ꭰ', 'Ꭱ' => 'ꭱ', 'Ꭲ' => 'ꭲ', 'Ꭳ' => 'ꭳ', 'Ꭴ' => 'ꭴ', 'Ꭵ' => 'ꭵ', 'Ꭶ' => 'ꭶ', 'Ꭷ' => 'ꭷ', 'Ꭸ' => 'ꭸ', 'Ꭹ' => 'ꭹ', 'Ꭺ' => 'ꭺ', 'Ꭻ' => 'ꭻ', 'Ꭼ' => 'ꭼ', 'Ꭽ' => 'ꭽ', 'Ꭾ' => 'ꭾ', 'Ꭿ' => 'ꭿ', 'Ꮀ' => 'ꮀ', 'Ꮁ' => 'ꮁ', 'Ꮂ' => 'ꮂ', 'Ꮃ' => 'ꮃ', 'Ꮄ' => 'ꮄ', 'Ꮅ' => 'ꮅ', 'Ꮆ' => 'ꮆ', 'Ꮇ' => 'ꮇ', 'Ꮈ' => 'ꮈ', 'Ꮉ' => 'ꮉ', 'Ꮊ' => 'ꮊ', 'Ꮋ' => 'ꮋ', 'Ꮌ' => 'ꮌ', 'Ꮍ' => 'ꮍ', 'Ꮎ' => 'ꮎ', 'Ꮏ' => 'ꮏ', 'Ꮐ' => 'ꮐ', 'Ꮑ' => 'ꮑ', 'Ꮒ' => 'ꮒ', 'Ꮓ' => 'ꮓ', 'Ꮔ' => 'ꮔ', 'Ꮕ' => 'ꮕ', 'Ꮖ' => 'ꮖ', 'Ꮗ' => 'ꮗ', 'Ꮘ' => 'ꮘ', 'Ꮙ' => 'ꮙ', 'Ꮚ' => 'ꮚ', 'Ꮛ' => 'ꮛ', 'Ꮜ' => 'ꮜ', 'Ꮝ' => 'ꮝ', 'Ꮞ' => 'ꮞ', 'Ꮟ' => 'ꮟ', 'Ꮠ' => 'ꮠ', 'Ꮡ' => 'ꮡ', 'Ꮢ' => 'ꮢ', 'Ꮣ' => 'ꮣ', 'Ꮤ' => 'ꮤ', 'Ꮥ' => 'ꮥ', 'Ꮦ' => 'ꮦ', 'Ꮧ' => 'ꮧ', 'Ꮨ' => 'ꮨ', 'Ꮩ' => 'ꮩ', 'Ꮪ' => 'ꮪ', 'Ꮫ' => 'ꮫ', 'Ꮬ' => 'ꮬ', 'Ꮭ' => 'ꮭ', 'Ꮮ' => 'ꮮ', 'Ꮯ' => 'ꮯ', 'Ꮰ' => 'ꮰ', 'Ꮱ' => 'ꮱ', 'Ꮲ' => 'ꮲ', 'Ꮳ' => 'ꮳ', 'Ꮴ' => 'ꮴ', 'Ꮵ' => 'ꮵ', 'Ꮶ' => 'ꮶ', 'Ꮷ' => 'ꮷ', 'Ꮸ' => 'ꮸ', 'Ꮹ' => 'ꮹ', 'Ꮺ' => 'ꮺ', 'Ꮻ' => 'ꮻ', 'Ꮼ' => 'ꮼ', 'Ꮽ' => 'ꮽ', 'Ꮾ' => 'ꮾ', 'Ꮿ' => 'ꮿ', 'Ᏸ' => 'ᏸ', 'Ᏹ' => 'ᏹ', 'Ᏺ' => 'ᏺ', 'Ᏻ' => 'ᏻ', 'Ᏼ' => 'ᏼ', 'Ᏽ' => 'ᏽ', 'Ა' => 'ა', 'Ბ' => 'ბ', 'Გ' => 'გ', 'Დ' => 'დ', 'Ე' => 'ე', 'Ვ' => 'ვ', 'Ზ' => 'ზ', 'Თ' => 'თ', 'Ი' => 'ი', 'Კ' => 'კ', 'Ლ' => 'ლ', 'Მ' => 'მ', 'Ნ' => 'ნ', 'Ო' => 'ო', 'Პ' => 'პ', 'Ჟ' => 'ჟ', 'Რ' => 'რ', 'Ს' => 'ს', 'Ტ' => 'ტ', 'Უ' => 'უ', 'Ფ' => 'ფ', 'Ქ' => 'ქ', 'Ღ' => 'ღ', 'Ყ' => 'ყ', 'Შ' => 'შ', 'Ჩ' => 'ჩ', 'Ც' => 'ც', 'Ძ' => 'ძ', 'Წ' => 'წ', 'Ჭ' => 'ჭ', 'Ხ' => 'ხ', 'Ჯ' => 'ჯ', 'Ჰ' => 'ჰ', 'Ჱ' => 'ჱ', 'Ჲ' => 'ჲ', 'Ჳ' => 'ჳ', 'Ჴ' => 'ჴ', 'Ჵ' => 'ჵ', 'Ჶ' => 'ჶ', 'Ჷ' => 'ჷ', 'Ჸ' => 'ჸ', 'Ჹ' => 'ჹ', 'Ჺ' => 'ჺ', 'Ჽ' => 'ჽ', 'Ჾ' => 'ჾ', 'Ჿ' => 'ჿ', 'Ḁ' => 'ḁ', 'Ḃ' => 'ḃ', 'Ḅ' => 'ḅ', 'Ḇ' => 'ḇ', 'Ḉ' => 'ḉ', 'Ḋ' => 'ḋ', 'Ḍ' => 'ḍ', 'Ḏ' => 'ḏ', 'Ḑ' => 'ḑ', 'Ḓ' => 'ḓ', 'Ḕ' => 'ḕ', 'Ḗ' => 'ḗ', 'Ḙ' => 'ḙ', 'Ḛ' => 'ḛ', 'Ḝ' => 'ḝ', 'Ḟ' => 'ḟ', 'Ḡ' => 'ḡ', 'Ḣ' => 'ḣ', 'Ḥ' => 'ḥ', 'Ḧ' => 'ḧ', 'Ḩ' => 'ḩ', 'Ḫ' => 'ḫ', 'Ḭ' => 'ḭ', 'Ḯ' => 'ḯ', 'Ḱ' => 'ḱ', 'Ḳ' => 'ḳ', 'Ḵ' => 'ḵ', 'Ḷ' => 'ḷ', 'Ḹ' => 'ḹ', 'Ḻ' => 'ḻ', 'Ḽ' => 'ḽ', 'Ḿ' => 'ḿ', 'Ṁ' => 'ṁ', 'Ṃ' => 'ṃ', 'Ṅ' => 'ṅ', 'Ṇ' => 'ṇ', 'Ṉ' => 'ṉ', 'Ṋ' => 'ṋ', 'Ṍ' => 'ṍ', 'Ṏ' => 'ṏ', 'Ṑ' => 'ṑ', 'Ṓ' => 'ṓ', 'Ṕ' => 'ṕ', 'Ṗ' => 'ṗ', 'Ṙ' => 'ṙ', 'Ṛ' => 'ṛ', 'Ṝ' => 'ṝ', 'Ṟ' => 'ṟ', 'Ṡ' => 'ṡ', 'Ṣ' => 'ṣ', 'Ṥ' => 'ṥ', 'Ṧ' => 'ṧ', 'Ṩ' => 'ṩ', 'Ṫ' => 'ṫ', 'Ṭ' => 'ṭ', 'Ṯ' => 'ṯ', 'Ṱ' => 'ṱ', 'Ṳ' => 'ṳ', 'Ṵ' => 'ṵ', 'Ṷ' => 'ṷ', 'Ṹ' => 'ṹ', 'Ṻ' => 'ṻ', 'Ṽ' => 'ṽ', 'Ṿ' => 'ṿ', 'Ẁ' => 'ẁ', 'Ẃ' => 'ẃ', 'Ẅ' => 'ẅ', 'Ẇ' => 'ẇ', 'Ẉ' => 'ẉ', 'Ẋ' => 'ẋ', 'Ẍ' => 'ẍ', 'Ẏ' => 'ẏ', 'Ẑ' => 'ẑ', 'Ẓ' => 'ẓ', 'Ẕ' => 'ẕ', 'ẞ' => 'ß', 'Ạ' => 'ạ', 'Ả' => 'ả', 'Ấ' => 'ấ', 'Ầ' => 'ầ', 'Ẩ' => 'ẩ', 'Ẫ' => 'ẫ', 'Ậ' => 'ậ', 'Ắ' => 'ắ', 'Ằ' => 'ằ', 'Ẳ' => 'ẳ', 'Ẵ' => 'ẵ', 'Ặ' => 'ặ', 'Ẹ' => 'ẹ', 'Ẻ' => 'ẻ', 'Ẽ' => 'ẽ', 'Ế' => 'ế', 'Ề' => 'ề', 'Ể' => 'ể', 'Ễ' => 'ễ', 'Ệ' => 'ệ', 'Ỉ' => 'ỉ', 'Ị' => 'ị', 'Ọ' => 'ọ', 'Ỏ' => 'ỏ', 'Ố' => 'ố', 'Ồ' => 'ồ', 'Ổ' => 'ổ', 'Ỗ' => 'ỗ', 'Ộ' => 'ộ', 'Ớ' => 'ớ', 'Ờ' => 'ờ', 'Ở' => 'ở', 'Ỡ' => 'ỡ', 'Ợ' => 'ợ', 'Ụ' => 'ụ', 'Ủ' => 'ủ', 'Ứ' => 'ứ', 'Ừ' => 'ừ', 'Ử' => 'ử', 'Ữ' => 'ữ', 'Ự' => 'ự', 'Ỳ' => 'ỳ', 'Ỵ' => 'ỵ', 'Ỷ' => 'ỷ', 'Ỹ' => 'ỹ', 'Ỻ' => 'ỻ', 'Ỽ' => 'ỽ', 'Ỿ' => 'ỿ', 'Ἀ' => 'ἀ', 'Ἁ' => 'ἁ', 'Ἂ' => 'ἂ', 'Ἃ' => 'ἃ', 'Ἄ' => 'ἄ', 'Ἅ' => 'ἅ', 'Ἆ' => 'ἆ', 'Ἇ' => 'ἇ', 'Ἐ' => 'ἐ', 'Ἑ' => 'ἑ', 'Ἒ' => 'ἒ', 'Ἓ' => 'ἓ', 'Ἔ' => 'ἔ', 'Ἕ' => 'ἕ', 'Ἠ' => 'ἠ', 'Ἡ' => 'ἡ', 'Ἢ' => 'ἢ', 'Ἣ' => 'ἣ', 'Ἤ' => 'ἤ', 'Ἥ' => 'ἥ', 'Ἦ' => 'ἦ', 'Ἧ' => 'ἧ', 'Ἰ' => 'ἰ', 'Ἱ' => 'ἱ', 'Ἲ' => 'ἲ', 'Ἳ' => 'ἳ', 'Ἴ' => 'ἴ', 'Ἵ' => 'ἵ', 'Ἶ' => 'ἶ', 'Ἷ' => 'ἷ', 'Ὀ' => 'ὀ', 'Ὁ' => 'ὁ', 'Ὂ' => 'ὂ', 'Ὃ' => 'ὃ', 'Ὄ' => 'ὄ', 'Ὅ' => 'ὅ', 'Ὑ' => 'ὑ', 'Ὓ' => 'ὓ', 'Ὕ' => 'ὕ', 'Ὗ' => 'ὗ', 'Ὠ' => 'ὠ', 'Ὡ' => 'ὡ', 'Ὢ' => 'ὢ', 'Ὣ' => 'ὣ', 'Ὤ' => 'ὤ', 'Ὥ' => 'ὥ', 'Ὦ' => 'ὦ', 'Ὧ' => 'ὧ', 'ᾈ' => 'ᾀ', 'ᾉ' => 'ᾁ', 'ᾊ' => 'ᾂ', 'ᾋ' => 'ᾃ', 'ᾌ' => 'ᾄ', 'ᾍ' => 'ᾅ', 'ᾎ' => 'ᾆ', 'ᾏ' => 'ᾇ', 'ᾘ' => 'ᾐ', 'ᾙ' => 'ᾑ', 'ᾚ' => 'ᾒ', 'ᾛ' => 'ᾓ', 'ᾜ' => 'ᾔ', 'ᾝ' => 'ᾕ', 'ᾞ' => 'ᾖ', 'ᾟ' => 'ᾗ', 'ᾨ' => 'ᾠ', 'ᾩ' => 'ᾡ', 'ᾪ' => 'ᾢ', 'ᾫ' => 'ᾣ', 'ᾬ' => 'ᾤ', 'ᾭ' => 'ᾥ', 'ᾮ' => 'ᾦ', 'ᾯ' => 'ᾧ', 'Ᾰ' => 'ᾰ', 'Ᾱ' => 'ᾱ', 'Ὰ' => 'ὰ', 'Ά' => 'ά', 'ᾼ' => 'ᾳ', 'Ὲ' => 'ὲ', 'Έ' => 'έ', 'Ὴ' => 'ὴ', 'Ή' => 'ή', 'ῌ' => 'ῃ', 'Ῐ' => 'ῐ', 'Ῑ' => 'ῑ', 'Ὶ' => 'ὶ', 'Ί' => 'ί', 'Ῠ' => 'ῠ', 'Ῡ' => 'ῡ', 'Ὺ' => 'ὺ', 'Ύ' => 'ύ', 'Ῥ' => 'ῥ', 'Ὸ' => 'ὸ', 'Ό' => 'ό', 'Ὼ' => 'ὼ', 'Ώ' => 'ώ', 'ῼ' => 'ῳ', 'Ω' => 'ω', 'K' => 'k', 'Å' => 'å', 'Ⅎ' => 'ⅎ', 'Ⅰ' => 'ⅰ', 'Ⅱ' => 'ⅱ', 'Ⅲ' => 'ⅲ', 'Ⅳ' => 'ⅳ', 'Ⅴ' => 'ⅴ', 'Ⅵ' => 'ⅵ', 'Ⅶ' => 'ⅶ', 'Ⅷ' => 'ⅷ', 'Ⅸ' => 'ⅸ', 'Ⅹ' => 'ⅹ', 'Ⅺ' => 'ⅺ', 'Ⅻ' => 'ⅻ', 'Ⅼ' => 'ⅼ', 'Ⅽ' => 'ⅽ', 'Ⅾ' => 'ⅾ', 'Ⅿ' => 'ⅿ', 'Ↄ' => 'ↄ', 'Ⓐ' => 'ⓐ', 'Ⓑ' => 'ⓑ', 'Ⓒ' => 'ⓒ', 'Ⓓ' => 'ⓓ', 'Ⓔ' => 'ⓔ', 'Ⓕ' => 'ⓕ', 'Ⓖ' => 'ⓖ', 'Ⓗ' => 'ⓗ', 'Ⓘ' => 'ⓘ', 'Ⓙ' => 'ⓙ', 'Ⓚ' => 'ⓚ', 'Ⓛ' => 'ⓛ', 'Ⓜ' => 'ⓜ', 'Ⓝ' => 'ⓝ', 'Ⓞ' => 'ⓞ', 'Ⓟ' => 'ⓟ', 'Ⓠ' => 'ⓠ', 'Ⓡ' => 'ⓡ', 'Ⓢ' => 'ⓢ', 'Ⓣ' => 'ⓣ', 'Ⓤ' => 'ⓤ', 'Ⓥ' => 'ⓥ', 'Ⓦ' => 'ⓦ', 'Ⓧ' => 'ⓧ', 'Ⓨ' => 'ⓨ', 'Ⓩ' => 'ⓩ', 'Ⰰ' => 'ⰰ', 'Ⰱ' => 'ⰱ', 'Ⰲ' => 'ⰲ', 'Ⰳ' => 'ⰳ', 'Ⰴ' => 'ⰴ', 'Ⰵ' => 'ⰵ', 'Ⰶ' => 'ⰶ', 'Ⰷ' => 'ⰷ', 'Ⰸ' => 'ⰸ', 'Ⰹ' => 'ⰹ', 'Ⰺ' => 'ⰺ', 'Ⰻ' => 'ⰻ', 'Ⰼ' => 'ⰼ', 'Ⰽ' => 'ⰽ', 'Ⰾ' => 'ⰾ', 'Ⰿ' => 'ⰿ', 'Ⱀ' => 'ⱀ', 'Ⱁ' => 'ⱁ', 'Ⱂ' => 'ⱂ', 'Ⱃ' => 'ⱃ', 'Ⱄ' => 'ⱄ', 'Ⱅ' => 'ⱅ', 'Ⱆ' => 'ⱆ', 'Ⱇ' => 'ⱇ', 'Ⱈ' => 'ⱈ', 'Ⱉ' => 'ⱉ', 'Ⱊ' => 'ⱊ', 'Ⱋ' => 'ⱋ', 'Ⱌ' => 'ⱌ', 'Ⱍ' => 'ⱍ', 'Ⱎ' => 'ⱎ', 'Ⱏ' => 'ⱏ', 'Ⱐ' => 'ⱐ', 'Ⱑ' => 'ⱑ', 'Ⱒ' => 'ⱒ', 'Ⱓ' => 'ⱓ', 'Ⱔ' => 'ⱔ', 'Ⱕ' => 'ⱕ', 'Ⱖ' => 'ⱖ', 'Ⱗ' => 'ⱗ', 'Ⱘ' => 'ⱘ', 'Ⱙ' => 'ⱙ', 'Ⱚ' => 'ⱚ', 'Ⱛ' => 'ⱛ', 'Ⱜ' => 'ⱜ', 'Ⱝ' => 'ⱝ', 'Ⱞ' => 'ⱞ', 'Ⱡ' => 'ⱡ', 'Ɫ' => 'ɫ', 'Ᵽ' => 'ᵽ', 'Ɽ' => 'ɽ', 'Ⱨ' => 'ⱨ', 'Ⱪ' => 'ⱪ', 'Ⱬ' => 'ⱬ', 'Ɑ' => 'ɑ', 'Ɱ' => 'ɱ', 'Ɐ' => 'ɐ', 'Ɒ' => 'ɒ', 'Ⱳ' => 'ⱳ', 'Ⱶ' => 'ⱶ', 'Ȿ' => 'ȿ', 'Ɀ' => 'ɀ', 'Ⲁ' => 'ⲁ', 'Ⲃ' => 'ⲃ', 'Ⲅ' => 'ⲅ', 'Ⲇ' => 'ⲇ', 'Ⲉ' => 'ⲉ', 'Ⲋ' => 'ⲋ', 'Ⲍ' => 'ⲍ', 'Ⲏ' => 'ⲏ', 'Ⲑ' => 'ⲑ', 'Ⲓ' => 'ⲓ', 'Ⲕ' => 'ⲕ', 'Ⲗ' => 'ⲗ', 'Ⲙ' => 'ⲙ', 'Ⲛ' => 'ⲛ', 'Ⲝ' => 'ⲝ', 'Ⲟ' => 'ⲟ', 'Ⲡ' => 'ⲡ', 'Ⲣ' => 'ⲣ', 'Ⲥ' => 'ⲥ', 'Ⲧ' => 'ⲧ', 'Ⲩ' => 'ⲩ', 'Ⲫ' => 'ⲫ', 'Ⲭ' => 'ⲭ', 'Ⲯ' => 'ⲯ', 'Ⲱ' => 'ⲱ', 'Ⲳ' => 'ⲳ', 'Ⲵ' => 'ⲵ', 'Ⲷ' => 'ⲷ', 'Ⲹ' => 'ⲹ', 'Ⲻ' => 'ⲻ', 'Ⲽ' => 'ⲽ', 'Ⲿ' => 'ⲿ', 'Ⳁ' => 'ⳁ', 'Ⳃ' => 'ⳃ', 'Ⳅ' => 'ⳅ', 'Ⳇ' => 'ⳇ', 'Ⳉ' => 'ⳉ', 'Ⳋ' => 'ⳋ', 'Ⳍ' => 'ⳍ', 'Ⳏ' => 'ⳏ', 'Ⳑ' => 'ⳑ', 'Ⳓ' => 'ⳓ', 'Ⳕ' => 'ⳕ', 'Ⳗ' => 'ⳗ', 'Ⳙ' => 'ⳙ', 'Ⳛ' => 'ⳛ', 'Ⳝ' => 'ⳝ', 'Ⳟ' => 'ⳟ', 'Ⳡ' => 'ⳡ', 'Ⳣ' => 'ⳣ', 'Ⳬ' => 'ⳬ', 'Ⳮ' => 'ⳮ', 'Ⳳ' => 'ⳳ', 'Ꙁ' => 'ꙁ', 'Ꙃ' => 'ꙃ', 'Ꙅ' => 'ꙅ', 'Ꙇ' => 'ꙇ', 'Ꙉ' => 'ꙉ', 'Ꙋ' => 'ꙋ', 'Ꙍ' => 'ꙍ', 'Ꙏ' => 'ꙏ', 'Ꙑ' => 'ꙑ', 'Ꙓ' => 'ꙓ', 'Ꙕ' => 'ꙕ', 'Ꙗ' => 'ꙗ', 'Ꙙ' => 'ꙙ', 'Ꙛ' => 'ꙛ', 'Ꙝ' => 'ꙝ', 'Ꙟ' => 'ꙟ', 'Ꙡ' => 'ꙡ', 'Ꙣ' => 'ꙣ', 'Ꙥ' => 'ꙥ', 'Ꙧ' => 'ꙧ', 'Ꙩ' => 'ꙩ', 'Ꙫ' => 'ꙫ', 'Ꙭ' => 'ꙭ', 'Ꚁ' => 'ꚁ', 'Ꚃ' => 'ꚃ', 'Ꚅ' => 'ꚅ', 'Ꚇ' => 'ꚇ', 'Ꚉ' => 'ꚉ', 'Ꚋ' => 'ꚋ', 'Ꚍ' => 'ꚍ', 'Ꚏ' => 'ꚏ', 'Ꚑ' => 'ꚑ', 'Ꚓ' => 'ꚓ', 'Ꚕ' => 'ꚕ', 'Ꚗ' => 'ꚗ', 'Ꚙ' => 'ꚙ', 'Ꚛ' => 'ꚛ', 'Ꜣ' => 'ꜣ', 'Ꜥ' => 'ꜥ', 'Ꜧ' => 'ꜧ', 'Ꜩ' => 'ꜩ', 'Ꜫ' => 'ꜫ', 'Ꜭ' => 'ꜭ', 'Ꜯ' => 'ꜯ', 'Ꜳ' => 'ꜳ', 'Ꜵ' => 'ꜵ', 'Ꜷ' => 'ꜷ', 'Ꜹ' => 'ꜹ', 'Ꜻ' => 'ꜻ', 'Ꜽ' => 'ꜽ', 'Ꜿ' => 'ꜿ', 'Ꝁ' => 'ꝁ', 'Ꝃ' => 'ꝃ', 'Ꝅ' => 'ꝅ', 'Ꝇ' => 'ꝇ', 'Ꝉ' => 'ꝉ', 'Ꝋ' => 'ꝋ', 'Ꝍ' => 'ꝍ', 'Ꝏ' => 'ꝏ', 'Ꝑ' => 'ꝑ', 'Ꝓ' => 'ꝓ', 'Ꝕ' => 'ꝕ', 'Ꝗ' => 'ꝗ', 'Ꝙ' => 'ꝙ', 'Ꝛ' => 'ꝛ', 'Ꝝ' => 'ꝝ', 'Ꝟ' => 'ꝟ', 'Ꝡ' => 'ꝡ', 'Ꝣ' => 'ꝣ', 'Ꝥ' => 'ꝥ', 'Ꝧ' => 'ꝧ', 'Ꝩ' => 'ꝩ', 'Ꝫ' => 'ꝫ', 'Ꝭ' => 'ꝭ', 'Ꝯ' => 'ꝯ', 'Ꝺ' => 'ꝺ', 'Ꝼ' => 'ꝼ', 'Ᵹ' => 'ᵹ', 'Ꝿ' => 'ꝿ', 'Ꞁ' => 'ꞁ', 'Ꞃ' => 'ꞃ', 'Ꞅ' => 'ꞅ', 'Ꞇ' => 'ꞇ', 'Ꞌ' => 'ꞌ', 'Ɥ' => 'ɥ', 'Ꞑ' => 'ꞑ', 'Ꞓ' => 'ꞓ', 'Ꞗ' => 'ꞗ', 'Ꞙ' => 'ꞙ', 'Ꞛ' => 'ꞛ', 'Ꞝ' => 'ꞝ', 'Ꞟ' => 'ꞟ', 'Ꞡ' => 'ꞡ', 'Ꞣ' => 'ꞣ', 'Ꞥ' => 'ꞥ', 'Ꞧ' => 'ꞧ', 'Ꞩ' => 'ꞩ', 'Ɦ' => 'ɦ', 'Ɜ' => 'ɜ', 'Ɡ' => 'ɡ', 'Ɬ' => 'ɬ', 'Ɪ' => 'ɪ', 'Ʞ' => 'ʞ', 'Ʇ' => 'ʇ', 'Ʝ' => 'ʝ', 'Ꭓ' => 'ꭓ', 'Ꞵ' => 'ꞵ', 'Ꞷ' => 'ꞷ', 'Ꞹ' => 'ꞹ', 'Ꞻ' => 'ꞻ', 'Ꞽ' => 'ꞽ', 'Ꞿ' => 'ꞿ', 'Ꟃ' => 'ꟃ', 'Ꞔ' => 'ꞔ', 'Ʂ' => 'ʂ', 'Ᶎ' => 'ᶎ', 'Ꟈ' => 'ꟈ', 'Ꟊ' => 'ꟊ', 'Ꟶ' => 'ꟶ', 'A' => 'a', 'B' => 'b', 'C' => 'c', 'D' => 'd', 'E' => 'e', 'F' => 'f', 'G' => 'g', 'H' => 'h', 'I' => 'i', 'J' => 'j', 'K' => 'k', 'L' => 'l', 'M' => 'm', 'N' => 'n', 'O' => 'o', 'P' => 'p', 'Q' => 'q', 'R' => 'r', 'S' => 's', 'T' => 't', 'U' => 'u', 'V' => 'v', 'W' => 'w', 'X' => 'x', 'Y' => 'y', 'Z' => 'z', '𐐀' => '𐐨', '𐐁' => '𐐩', '𐐂' => '𐐪', '𐐃' => '𐐫', '𐐄' => '𐐬', '𐐅' => '𐐭', '𐐆' => '𐐮', '𐐇' => '𐐯', '𐐈' => '𐐰', '𐐉' => '𐐱', '𐐊' => '𐐲', '𐐋' => '𐐳', '𐐌' => '𐐴', '𐐍' => '𐐵', '𐐎' => '𐐶', '𐐏' => '𐐷', '𐐐' => '𐐸', '𐐑' => '𐐹', '𐐒' => '𐐺', '𐐓' => '𐐻', '𐐔' => '𐐼', '𐐕' => '𐐽', '𐐖' => '𐐾', '𐐗' => '𐐿', '𐐘' => '𐑀', '𐐙' => '𐑁', '𐐚' => '𐑂', '𐐛' => '𐑃', '𐐜' => '𐑄', '𐐝' => '𐑅', '𐐞' => '𐑆', '𐐟' => '𐑇', '𐐠' => '𐑈', '𐐡' => '𐑉', '𐐢' => '𐑊', '𐐣' => '𐑋', '𐐤' => '𐑌', '𐐥' => '𐑍', '𐐦' => '𐑎', '𐐧' => '𐑏', '𐒰' => '𐓘', '𐒱' => '𐓙', '𐒲' => '𐓚', '𐒳' => '𐓛', '𐒴' => '𐓜', '𐒵' => '𐓝', '𐒶' => '𐓞', '𐒷' => '𐓟', '𐒸' => '𐓠', '𐒹' => '𐓡', '𐒺' => '𐓢', '𐒻' => '𐓣', '𐒼' => '𐓤', '𐒽' => '𐓥', '𐒾' => '𐓦', '𐒿' => '𐓧', '𐓀' => '𐓨', '𐓁' => '𐓩', '𐓂' => '𐓪', '𐓃' => '𐓫', '𐓄' => '𐓬', '𐓅' => '𐓭', '𐓆' => '𐓮', '𐓇' => '𐓯', '𐓈' => '𐓰', '𐓉' => '𐓱', '𐓊' => '𐓲', '𐓋' => '𐓳', '𐓌' => '𐓴', '𐓍' => '𐓵', '𐓎' => '𐓶', '𐓏' => '𐓷', '𐓐' => '𐓸', '𐓑' => '𐓹', '𐓒' => '𐓺', '𐓓' => '𐓻', '𐲀' => '𐳀', '𐲁' => '𐳁', '𐲂' => '𐳂', '𐲃' => '𐳃', '𐲄' => '𐳄', '𐲅' => '𐳅', '𐲆' => '𐳆', '𐲇' => '𐳇', '𐲈' => '𐳈', '𐲉' => '𐳉', '𐲊' => '𐳊', '𐲋' => '𐳋', '𐲌' => '𐳌', '𐲍' => '𐳍', '𐲎' => '𐳎', '𐲏' => '𐳏', '𐲐' => '𐳐', '𐲑' => '𐳑', '𐲒' => '𐳒', '𐲓' => '𐳓', '𐲔' => '𐳔', '𐲕' => '𐳕', '𐲖' => '𐳖', '𐲗' => '𐳗', '𐲘' => '𐳘', '𐲙' => '𐳙', '𐲚' => '𐳚', '𐲛' => '𐳛', '𐲜' => '𐳜', '𐲝' => '𐳝', '𐲞' => '𐳞', '𐲟' => '𐳟', '𐲠' => '𐳠', '𐲡' => '𐳡', '𐲢' => '𐳢', '𐲣' => '𐳣', '𐲤' => '𐳤', '𐲥' => '𐳥', '𐲦' => '𐳦', '𐲧' => '𐳧', '𐲨' => '𐳨', '𐲩' => '𐳩', '𐲪' => '𐳪', '𐲫' => '𐳫', '𐲬' => '𐳬', '𐲭' => '𐳭', '𐲮' => '𐳮', '𐲯' => '𐳯', '𐲰' => '𐳰', '𐲱' => '𐳱', '𐲲' => '𐳲', '𑢠' => '𑣀', '𑢡' => '𑣁', '𑢢' => '𑣂', '𑢣' => '𑣃', '𑢤' => '𑣄', '𑢥' => '𑣅', '𑢦' => '𑣆', '𑢧' => '𑣇', '𑢨' => '𑣈', '𑢩' => '𑣉', '𑢪' => '𑣊', '𑢫' => '𑣋', '𑢬' => '𑣌', '𑢭' => '𑣍', '𑢮' => '𑣎', '𑢯' => '𑣏', '𑢰' => '𑣐', '𑢱' => '𑣑', '𑢲' => '𑣒', '𑢳' => '𑣓', '𑢴' => '𑣔', '𑢵' => '𑣕', '𑢶' => '𑣖', '𑢷' => '𑣗', '𑢸' => '𑣘', '𑢹' => '𑣙', '𑢺' => '𑣚', '𑢻' => '𑣛', '𑢼' => '𑣜', '𑢽' => '𑣝', '𑢾' => '𑣞', '𑢿' => '𑣟', '𖹀' => '𖹠', '𖹁' => '𖹡', '𖹂' => '𖹢', '𖹃' => '𖹣', '𖹄' => '𖹤', '𖹅' => '𖹥', '𖹆' => '𖹦', '𖹇' => '𖹧', '𖹈' => '𖹨', '𖹉' => '𖹩', '𖹊' => '𖹪', '𖹋' => '𖹫', '𖹌' => '𖹬', '𖹍' => '𖹭', '𖹎' => '𖹮', '𖹏' => '𖹯', '𖹐' => '𖹰', '𖹑' => '𖹱', '𖹒' => '𖹲', '𖹓' => '𖹳', '𖹔' => '𖹴', '𖹕' => '𖹵', '𖹖' => '𖹶', '𖹗' => '𖹷', '𖹘' => '𖹸', '𖹙' => '𖹹', '𖹚' => '𖹺', '𖹛' => '𖹻', '𖹜' => '𖹼', '𖹝' => '𖹽', '𖹞' => '𖹾', '𖹟' => '𖹿', '𞤀' => '𞤢', '𞤁' => '𞤣', '𞤂' => '𞤤', '𞤃' => '𞤥', '𞤄' => '𞤦', '𞤅' => '𞤧', '𞤆' => '𞤨', '𞤇' => '𞤩', '𞤈' => '𞤪', '𞤉' => '𞤫', '𞤊' => '𞤬', '𞤋' => '𞤭', '𞤌' => '𞤮', '𞤍' => '𞤯', '𞤎' => '𞤰', '𞤏' => '𞤱', '𞤐' => '𞤲', '𞤑' => '𞤳', '𞤒' => '𞤴', '𞤓' => '𞤵', '𞤔' => '𞤶', '𞤕' => '𞤷', '𞤖' => '𞤸', '𞤗' => '𞤹', '𞤘' => '𞤺', '𞤙' => '𞤻', '𞤚' => '𞤼', '𞤛' => '𞤽', '𞤜' => '𞤾', '𞤝' => '𞤿', '𞤞' => '𞥀', '𞤟' => '𞥁', '𞤠' => '𞥂', '𞤡' => '𞥃'); diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php new file mode 100644 index 0000000000..369965fb0e --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php @@ -0,0 +1,6 @@ + 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D', 'e' => 'E', 'f' => 'F', 'g' => 'G', 'h' => 'H', 'i' => 'I', 'j' => 'J', 'k' => 'K', 'l' => 'L', 'm' => 'M', 'n' => 'N', 'o' => 'O', 'p' => 'P', 'q' => 'Q', 'r' => 'R', 's' => 'S', 't' => 'T', 'u' => 'U', 'v' => 'V', 'w' => 'W', 'x' => 'X', 'y' => 'Y', 'z' => 'Z', 'µ' => 'Μ', 'à' => 'À', 'á' => 'Á', 'â' => 'Â', 'ã' => 'Ã', 'ä' => 'Ä', 'å' => 'Å', 'æ' => 'Æ', 'ç' => 'Ç', 'è' => 'È', 'é' => 'É', 'ê' => 'Ê', 'ë' => 'Ë', 'ì' => 'Ì', 'í' => 'Í', 'î' => 'Î', 'ï' => 'Ï', 'ð' => 'Ð', 'ñ' => 'Ñ', 'ò' => 'Ò', 'ó' => 'Ó', 'ô' => 'Ô', 'õ' => 'Õ', 'ö' => 'Ö', 'ø' => 'Ø', 'ù' => 'Ù', 'ú' => 'Ú', 'û' => 'Û', 'ü' => 'Ü', 'ý' => 'Ý', 'þ' => 'Þ', 'ÿ' => 'Ÿ', 'ā' => 'Ā', 'ă' => 'Ă', 'ą' => 'Ą', 'ć' => 'Ć', 'ĉ' => 'Ĉ', 'ċ' => 'Ċ', 'č' => 'Č', 'ď' => 'Ď', 'đ' => 'Đ', 'ē' => 'Ē', 'ĕ' => 'Ĕ', 'ė' => 'Ė', 'ę' => 'Ę', 'ě' => 'Ě', 'ĝ' => 'Ĝ', 'ğ' => 'Ğ', 'ġ' => 'Ġ', 'ģ' => 'Ģ', 'ĥ' => 'Ĥ', 'ħ' => 'Ħ', 'ĩ' => 'Ĩ', 'ī' => 'Ī', 'ĭ' => 'Ĭ', 'į' => 'Į', 'ı' => 'I', 'ij' => 'IJ', 'ĵ' => 'Ĵ', 'ķ' => 'Ķ', 'ĺ' => 'Ĺ', 'ļ' => 'Ļ', 'ľ' => 'Ľ', 'ŀ' => 'Ŀ', 'ł' => 'Ł', 'ń' => 'Ń', 'ņ' => 'Ņ', 'ň' => 'Ň', 'ŋ' => 'Ŋ', 'ō' => 'Ō', 'ŏ' => 'Ŏ', 'ő' => 'Ő', 'œ' => 'Œ', 'ŕ' => 'Ŕ', 'ŗ' => 'Ŗ', 'ř' => 'Ř', 'ś' => 'Ś', 'ŝ' => 'Ŝ', 'ş' => 'Ş', 'š' => 'Š', 'ţ' => 'Ţ', 'ť' => 'Ť', 'ŧ' => 'Ŧ', 'ũ' => 'Ũ', 'ū' => 'Ū', 'ŭ' => 'Ŭ', 'ů' => 'Ů', 'ű' => 'Ű', 'ų' => 'Ų', 'ŵ' => 'Ŵ', 'ŷ' => 'Ŷ', 'ź' => 'Ź', 'ż' => 'Ż', 'ž' => 'Ž', 'ſ' => 'S', 'ƀ' => 'Ƀ', 'ƃ' => 'Ƃ', 'ƅ' => 'Ƅ', 'ƈ' => 'Ƈ', 'ƌ' => 'Ƌ', 'ƒ' => 'Ƒ', 'ƕ' => 'Ƕ', 'ƙ' => 'Ƙ', 'ƚ' => 'Ƚ', 'ƞ' => 'Ƞ', 'ơ' => 'Ơ', 'ƣ' => 'Ƣ', 'ƥ' => 'Ƥ', 'ƨ' => 'Ƨ', 'ƭ' => 'Ƭ', 'ư' => 'Ư', 'ƴ' => 'Ƴ', 'ƶ' => 'Ƶ', 'ƹ' => 'Ƹ', 'ƽ' => 'Ƽ', 'ƿ' => 'Ƿ', 'Dž' => 'DŽ', 'dž' => 'DŽ', 'Lj' => 'LJ', 'lj' => 'LJ', 'Nj' => 'NJ', 'nj' => 'NJ', 'ǎ' => 'Ǎ', 'ǐ' => 'Ǐ', 'ǒ' => 'Ǒ', 'ǔ' => 'Ǔ', 'ǖ' => 'Ǖ', 'ǘ' => 'Ǘ', 'ǚ' => 'Ǚ', 'ǜ' => 'Ǜ', 'ǝ' => 'Ǝ', 'ǟ' => 'Ǟ', 'ǡ' => 'Ǡ', 'ǣ' => 'Ǣ', 'ǥ' => 'Ǥ', 'ǧ' => 'Ǧ', 'ǩ' => 'Ǩ', 'ǫ' => 'Ǫ', 'ǭ' => 'Ǭ', 'ǯ' => 'Ǯ', 'Dz' => 'DZ', 'dz' => 'DZ', 'ǵ' => 'Ǵ', 'ǹ' => 'Ǹ', 'ǻ' => 'Ǻ', 'ǽ' => 'Ǽ', 'ǿ' => 'Ǿ', 'ȁ' => 'Ȁ', 'ȃ' => 'Ȃ', 'ȅ' => 'Ȅ', 'ȇ' => 'Ȇ', 'ȉ' => 'Ȉ', 'ȋ' => 'Ȋ', 'ȍ' => 'Ȍ', 'ȏ' => 'Ȏ', 'ȑ' => 'Ȑ', 'ȓ' => 'Ȓ', 'ȕ' => 'Ȕ', 'ȗ' => 'Ȗ', 'ș' => 'Ș', 'ț' => 'Ț', 'ȝ' => 'Ȝ', 'ȟ' => 'Ȟ', 'ȣ' => 'Ȣ', 'ȥ' => 'Ȥ', 'ȧ' => 'Ȧ', 'ȩ' => 'Ȩ', 'ȫ' => 'Ȫ', 'ȭ' => 'Ȭ', 'ȯ' => 'Ȯ', 'ȱ' => 'Ȱ', 'ȳ' => 'Ȳ', 'ȼ' => 'Ȼ', 'ȿ' => 'Ȿ', 'ɀ' => 'Ɀ', 'ɂ' => 'Ɂ', 'ɇ' => 'Ɇ', 'ɉ' => 'Ɉ', 'ɋ' => 'Ɋ', 'ɍ' => 'Ɍ', 'ɏ' => 'Ɏ', 'ɐ' => 'Ɐ', 'ɑ' => 'Ɑ', 'ɒ' => 'Ɒ', 'ɓ' => 'Ɓ', 'ɔ' => 'Ɔ', 'ɖ' => 'Ɖ', 'ɗ' => 'Ɗ', 'ə' => 'Ə', 'ɛ' => 'Ɛ', 'ɜ' => 'Ɜ', 'ɠ' => 'Ɠ', 'ɡ' => 'Ɡ', 'ɣ' => 'Ɣ', 'ɥ' => 'Ɥ', 'ɦ' => 'Ɦ', 'ɨ' => 'Ɨ', 'ɩ' => 'Ɩ', 'ɪ' => 'Ɪ', 'ɫ' => 'Ɫ', 'ɬ' => 'Ɬ', 'ɯ' => 'Ɯ', 'ɱ' => 'Ɱ', 'ɲ' => 'Ɲ', 'ɵ' => 'Ɵ', 'ɽ' => 'Ɽ', 'ʀ' => 'Ʀ', 'ʂ' => 'Ʂ', 'ʃ' => 'Ʃ', 'ʇ' => 'Ʇ', 'ʈ' => 'Ʈ', 'ʉ' => 'Ʉ', 'ʊ' => 'Ʊ', 'ʋ' => 'Ʋ', 'ʌ' => 'Ʌ', 'ʒ' => 'Ʒ', 'ʝ' => 'Ʝ', 'ʞ' => 'Ʞ', 'ͅ' => 'Ι', 'ͱ' => 'Ͱ', 'ͳ' => 'Ͳ', 'ͷ' => 'Ͷ', 'ͻ' => 'Ͻ', 'ͼ' => 'Ͼ', 'ͽ' => 'Ͽ', 'ά' => 'Ά', 'έ' => 'Έ', 'ή' => 'Ή', 'ί' => 'Ί', 'α' => 'Α', 'β' => 'Β', 'γ' => 'Γ', 'δ' => 'Δ', 'ε' => 'Ε', 'ζ' => 'Ζ', 'η' => 'Η', 'θ' => 'Θ', 'ι' => 'Ι', 'κ' => 'Κ', 'λ' => 'Λ', 'μ' => 'Μ', 'ν' => 'Ν', 'ξ' => 'Ξ', 'ο' => 'Ο', 'π' => 'Π', 'ρ' => 'Ρ', 'ς' => 'Σ', 'σ' => 'Σ', 'τ' => 'Τ', 'υ' => 'Υ', 'φ' => 'Φ', 'χ' => 'Χ', 'ψ' => 'Ψ', 'ω' => 'Ω', 'ϊ' => 'Ϊ', 'ϋ' => 'Ϋ', 'ό' => 'Ό', 'ύ' => 'Ύ', 'ώ' => 'Ώ', 'ϐ' => 'Β', 'ϑ' => 'Θ', 'ϕ' => 'Φ', 'ϖ' => 'Π', 'ϗ' => 'Ϗ', 'ϙ' => 'Ϙ', 'ϛ' => 'Ϛ', 'ϝ' => 'Ϝ', 'ϟ' => 'Ϟ', 'ϡ' => 'Ϡ', 'ϣ' => 'Ϣ', 'ϥ' => 'Ϥ', 'ϧ' => 'Ϧ', 'ϩ' => 'Ϩ', 'ϫ' => 'Ϫ', 'ϭ' => 'Ϭ', 'ϯ' => 'Ϯ', 'ϰ' => 'Κ', 'ϱ' => 'Ρ', 'ϲ' => 'Ϲ', 'ϳ' => 'Ϳ', 'ϵ' => 'Ε', 'ϸ' => 'Ϸ', 'ϻ' => 'Ϻ', 'а' => 'А', 'б' => 'Б', 'в' => 'В', 'г' => 'Г', 'д' => 'Д', 'е' => 'Е', 'ж' => 'Ж', 'з' => 'З', 'и' => 'И', 'й' => 'Й', 'к' => 'К', 'л' => 'Л', 'м' => 'М', 'н' => 'Н', 'о' => 'О', 'п' => 'П', 'р' => 'Р', 'с' => 'С', 'т' => 'Т', 'у' => 'У', 'ф' => 'Ф', 'х' => 'Х', 'ц' => 'Ц', 'ч' => 'Ч', 'ш' => 'Ш', 'щ' => 'Щ', 'ъ' => 'Ъ', 'ы' => 'Ы', 'ь' => 'Ь', 'э' => 'Э', 'ю' => 'Ю', 'я' => 'Я', 'ѐ' => 'Ѐ', 'ё' => 'Ё', 'ђ' => 'Ђ', 'ѓ' => 'Ѓ', 'є' => 'Є', 'ѕ' => 'Ѕ', 'і' => 'І', 'ї' => 'Ї', 'ј' => 'Ј', 'љ' => 'Љ', 'њ' => 'Њ', 'ћ' => 'Ћ', 'ќ' => 'Ќ', 'ѝ' => 'Ѝ', 'ў' => 'Ў', 'џ' => 'Џ', 'ѡ' => 'Ѡ', 'ѣ' => 'Ѣ', 'ѥ' => 'Ѥ', 'ѧ' => 'Ѧ', 'ѩ' => 'Ѩ', 'ѫ' => 'Ѫ', 'ѭ' => 'Ѭ', 'ѯ' => 'Ѯ', 'ѱ' => 'Ѱ', 'ѳ' => 'Ѳ', 'ѵ' => 'Ѵ', 'ѷ' => 'Ѷ', 'ѹ' => 'Ѹ', 'ѻ' => 'Ѻ', 'ѽ' => 'Ѽ', 'ѿ' => 'Ѿ', 'ҁ' => 'Ҁ', 'ҋ' => 'Ҋ', 'ҍ' => 'Ҍ', 'ҏ' => 'Ҏ', 'ґ' => 'Ґ', 'ғ' => 'Ғ', 'ҕ' => 'Ҕ', 'җ' => 'Җ', 'ҙ' => 'Ҙ', 'қ' => 'Қ', 'ҝ' => 'Ҝ', 'ҟ' => 'Ҟ', 'ҡ' => 'Ҡ', 'ң' => 'Ң', 'ҥ' => 'Ҥ', 'ҧ' => 'Ҧ', 'ҩ' => 'Ҩ', 'ҫ' => 'Ҫ', 'ҭ' => 'Ҭ', 'ү' => 'Ү', 'ұ' => 'Ұ', 'ҳ' => 'Ҳ', 'ҵ' => 'Ҵ', 'ҷ' => 'Ҷ', 'ҹ' => 'Ҹ', 'һ' => 'Һ', 'ҽ' => 'Ҽ', 'ҿ' => 'Ҿ', 'ӂ' => 'Ӂ', 'ӄ' => 'Ӄ', 'ӆ' => 'Ӆ', 'ӈ' => 'Ӈ', 'ӊ' => 'Ӊ', 'ӌ' => 'Ӌ', 'ӎ' => 'Ӎ', 'ӏ' => 'Ӏ', 'ӑ' => 'Ӑ', 'ӓ' => 'Ӓ', 'ӕ' => 'Ӕ', 'ӗ' => 'Ӗ', 'ә' => 'Ә', 'ӛ' => 'Ӛ', 'ӝ' => 'Ӝ', 'ӟ' => 'Ӟ', 'ӡ' => 'Ӡ', 'ӣ' => 'Ӣ', 'ӥ' => 'Ӥ', 'ӧ' => 'Ӧ', 'ө' => 'Ө', 'ӫ' => 'Ӫ', 'ӭ' => 'Ӭ', 'ӯ' => 'Ӯ', 'ӱ' => 'Ӱ', 'ӳ' => 'Ӳ', 'ӵ' => 'Ӵ', 'ӷ' => 'Ӷ', 'ӹ' => 'Ӹ', 'ӻ' => 'Ӻ', 'ӽ' => 'Ӽ', 'ӿ' => 'Ӿ', 'ԁ' => 'Ԁ', 'ԃ' => 'Ԃ', 'ԅ' => 'Ԅ', 'ԇ' => 'Ԇ', 'ԉ' => 'Ԉ', 'ԋ' => 'Ԋ', 'ԍ' => 'Ԍ', 'ԏ' => 'Ԏ', 'ԑ' => 'Ԑ', 'ԓ' => 'Ԓ', 'ԕ' => 'Ԕ', 'ԗ' => 'Ԗ', 'ԙ' => 'Ԙ', 'ԛ' => 'Ԛ', 'ԝ' => 'Ԝ', 'ԟ' => 'Ԟ', 'ԡ' => 'Ԡ', 'ԣ' => 'Ԣ', 'ԥ' => 'Ԥ', 'ԧ' => 'Ԧ', 'ԩ' => 'Ԩ', 'ԫ' => 'Ԫ', 'ԭ' => 'Ԭ', 'ԯ' => 'Ԯ', 'ա' => 'Ա', 'բ' => 'Բ', 'գ' => 'Գ', 'դ' => 'Դ', 'ե' => 'Ե', 'զ' => 'Զ', 'է' => 'Է', 'ը' => 'Ը', 'թ' => 'Թ', 'ժ' => 'Ժ', 'ի' => 'Ի', 'լ' => 'Լ', 'խ' => 'Խ', 'ծ' => 'Ծ', 'կ' => 'Կ', 'հ' => 'Հ', 'ձ' => 'Ձ', 'ղ' => 'Ղ', 'ճ' => 'Ճ', 'մ' => 'Մ', 'յ' => 'Յ', 'ն' => 'Ն', 'շ' => 'Շ', 'ո' => 'Ո', 'չ' => 'Չ', 'պ' => 'Պ', 'ջ' => 'Ջ', 'ռ' => 'Ռ', 'ս' => 'Ս', 'վ' => 'Վ', 'տ' => 'Տ', 'ր' => 'Ր', 'ց' => 'Ց', 'ւ' => 'Ւ', 'փ' => 'Փ', 'ք' => 'Ք', 'օ' => 'Օ', 'ֆ' => 'Ֆ', 'ა' => 'Ა', 'ბ' => 'Ბ', 'გ' => 'Გ', 'დ' => 'Დ', 'ე' => 'Ე', 'ვ' => 'Ვ', 'ზ' => 'Ზ', 'თ' => 'Თ', 'ი' => 'Ი', 'კ' => 'Კ', 'ლ' => 'Ლ', 'მ' => 'Მ', 'ნ' => 'Ნ', 'ო' => 'Ო', 'პ' => 'Პ', 'ჟ' => 'Ჟ', 'რ' => 'Რ', 'ს' => 'Ს', 'ტ' => 'Ტ', 'უ' => 'Უ', 'ფ' => 'Ფ', 'ქ' => 'Ქ', 'ღ' => 'Ღ', 'ყ' => 'Ყ', 'შ' => 'Შ', 'ჩ' => 'Ჩ', 'ც' => 'Ც', 'ძ' => 'Ძ', 'წ' => 'Წ', 'ჭ' => 'Ჭ', 'ხ' => 'Ხ', 'ჯ' => 'Ჯ', 'ჰ' => 'Ჰ', 'ჱ' => 'Ჱ', 'ჲ' => 'Ჲ', 'ჳ' => 'Ჳ', 'ჴ' => 'Ჴ', 'ჵ' => 'Ჵ', 'ჶ' => 'Ჶ', 'ჷ' => 'Ჷ', 'ჸ' => 'Ჸ', 'ჹ' => 'Ჹ', 'ჺ' => 'Ჺ', 'ჽ' => 'Ჽ', 'ჾ' => 'Ჾ', 'ჿ' => 'Ჿ', 'ᏸ' => 'Ᏸ', 'ᏹ' => 'Ᏹ', 'ᏺ' => 'Ᏺ', 'ᏻ' => 'Ᏻ', 'ᏼ' => 'Ᏼ', 'ᏽ' => 'Ᏽ', 'ᲀ' => 'В', 'ᲁ' => 'Д', 'ᲂ' => 'О', 'ᲃ' => 'С', 'ᲄ' => 'Т', 'ᲅ' => 'Т', 'ᲆ' => 'Ъ', 'ᲇ' => 'Ѣ', 'ᲈ' => 'Ꙋ', 'ᵹ' => 'Ᵹ', 'ᵽ' => 'Ᵽ', 'ᶎ' => 'Ᶎ', 'ḁ' => 'Ḁ', 'ḃ' => 'Ḃ', 'ḅ' => 'Ḅ', 'ḇ' => 'Ḇ', 'ḉ' => 'Ḉ', 'ḋ' => 'Ḋ', 'ḍ' => 'Ḍ', 'ḏ' => 'Ḏ', 'ḑ' => 'Ḑ', 'ḓ' => 'Ḓ', 'ḕ' => 'Ḕ', 'ḗ' => 'Ḗ', 'ḙ' => 'Ḙ', 'ḛ' => 'Ḛ', 'ḝ' => 'Ḝ', 'ḟ' => 'Ḟ', 'ḡ' => 'Ḡ', 'ḣ' => 'Ḣ', 'ḥ' => 'Ḥ', 'ḧ' => 'Ḧ', 'ḩ' => 'Ḩ', 'ḫ' => 'Ḫ', 'ḭ' => 'Ḭ', 'ḯ' => 'Ḯ', 'ḱ' => 'Ḱ', 'ḳ' => 'Ḳ', 'ḵ' => 'Ḵ', 'ḷ' => 'Ḷ', 'ḹ' => 'Ḹ', 'ḻ' => 'Ḻ', 'ḽ' => 'Ḽ', 'ḿ' => 'Ḿ', 'ṁ' => 'Ṁ', 'ṃ' => 'Ṃ', 'ṅ' => 'Ṅ', 'ṇ' => 'Ṇ', 'ṉ' => 'Ṉ', 'ṋ' => 'Ṋ', 'ṍ' => 'Ṍ', 'ṏ' => 'Ṏ', 'ṑ' => 'Ṑ', 'ṓ' => 'Ṓ', 'ṕ' => 'Ṕ', 'ṗ' => 'Ṗ', 'ṙ' => 'Ṙ', 'ṛ' => 'Ṛ', 'ṝ' => 'Ṝ', 'ṟ' => 'Ṟ', 'ṡ' => 'Ṡ', 'ṣ' => 'Ṣ', 'ṥ' => 'Ṥ', 'ṧ' => 'Ṧ', 'ṩ' => 'Ṩ', 'ṫ' => 'Ṫ', 'ṭ' => 'Ṭ', 'ṯ' => 'Ṯ', 'ṱ' => 'Ṱ', 'ṳ' => 'Ṳ', 'ṵ' => 'Ṵ', 'ṷ' => 'Ṷ', 'ṹ' => 'Ṹ', 'ṻ' => 'Ṻ', 'ṽ' => 'Ṽ', 'ṿ' => 'Ṿ', 'ẁ' => 'Ẁ', 'ẃ' => 'Ẃ', 'ẅ' => 'Ẅ', 'ẇ' => 'Ẇ', 'ẉ' => 'Ẉ', 'ẋ' => 'Ẋ', 'ẍ' => 'Ẍ', 'ẏ' => 'Ẏ', 'ẑ' => 'Ẑ', 'ẓ' => 'Ẓ', 'ẕ' => 'Ẕ', 'ẛ' => 'Ṡ', 'ạ' => 'Ạ', 'ả' => 'Ả', 'ấ' => 'Ấ', 'ầ' => 'Ầ', 'ẩ' => 'Ẩ', 'ẫ' => 'Ẫ', 'ậ' => 'Ậ', 'ắ' => 'Ắ', 'ằ' => 'Ằ', 'ẳ' => 'Ẳ', 'ẵ' => 'Ẵ', 'ặ' => 'Ặ', 'ẹ' => 'Ẹ', 'ẻ' => 'Ẻ', 'ẽ' => 'Ẽ', 'ế' => 'Ế', 'ề' => 'Ề', 'ể' => 'Ể', 'ễ' => 'Ễ', 'ệ' => 'Ệ', 'ỉ' => 'Ỉ', 'ị' => 'Ị', 'ọ' => 'Ọ', 'ỏ' => 'Ỏ', 'ố' => 'Ố', 'ồ' => 'Ồ', 'ổ' => 'Ổ', 'ỗ' => 'Ỗ', 'ộ' => 'Ộ', 'ớ' => 'Ớ', 'ờ' => 'Ờ', 'ở' => 'Ở', 'ỡ' => 'Ỡ', 'ợ' => 'Ợ', 'ụ' => 'Ụ', 'ủ' => 'Ủ', 'ứ' => 'Ứ', 'ừ' => 'Ừ', 'ử' => 'Ử', 'ữ' => 'Ữ', 'ự' => 'Ự', 'ỳ' => 'Ỳ', 'ỵ' => 'Ỵ', 'ỷ' => 'Ỷ', 'ỹ' => 'Ỹ', 'ỻ' => 'Ỻ', 'ỽ' => 'Ỽ', 'ỿ' => 'Ỿ', 'ἀ' => 'Ἀ', 'ἁ' => 'Ἁ', 'ἂ' => 'Ἂ', 'ἃ' => 'Ἃ', 'ἄ' => 'Ἄ', 'ἅ' => 'Ἅ', 'ἆ' => 'Ἆ', 'ἇ' => 'Ἇ', 'ἐ' => 'Ἐ', 'ἑ' => 'Ἑ', 'ἒ' => 'Ἒ', 'ἓ' => 'Ἓ', 'ἔ' => 'Ἔ', 'ἕ' => 'Ἕ', 'ἠ' => 'Ἠ', 'ἡ' => 'Ἡ', 'ἢ' => 'Ἢ', 'ἣ' => 'Ἣ', 'ἤ' => 'Ἤ', 'ἥ' => 'Ἥ', 'ἦ' => 'Ἦ', 'ἧ' => 'Ἧ', 'ἰ' => 'Ἰ', 'ἱ' => 'Ἱ', 'ἲ' => 'Ἲ', 'ἳ' => 'Ἳ', 'ἴ' => 'Ἴ', 'ἵ' => 'Ἵ', 'ἶ' => 'Ἶ', 'ἷ' => 'Ἷ', 'ὀ' => 'Ὀ', 'ὁ' => 'Ὁ', 'ὂ' => 'Ὂ', 'ὃ' => 'Ὃ', 'ὄ' => 'Ὄ', 'ὅ' => 'Ὅ', 'ὑ' => 'Ὑ', 'ὓ' => 'Ὓ', 'ὕ' => 'Ὕ', 'ὗ' => 'Ὗ', 'ὠ' => 'Ὠ', 'ὡ' => 'Ὡ', 'ὢ' => 'Ὢ', 'ὣ' => 'Ὣ', 'ὤ' => 'Ὤ', 'ὥ' => 'Ὥ', 'ὦ' => 'Ὦ', 'ὧ' => 'Ὧ', 'ὰ' => 'Ὰ', 'ά' => 'Ά', 'ὲ' => 'Ὲ', 'έ' => 'Έ', 'ὴ' => 'Ὴ', 'ή' => 'Ή', 'ὶ' => 'Ὶ', 'ί' => 'Ί', 'ὸ' => 'Ὸ', 'ό' => 'Ό', 'ὺ' => 'Ὺ', 'ύ' => 'Ύ', 'ὼ' => 'Ὼ', 'ώ' => 'Ώ', 'ᾀ' => 'ἈΙ', 'ᾁ' => 'ἉΙ', 'ᾂ' => 'ἊΙ', 'ᾃ' => 'ἋΙ', 'ᾄ' => 'ἌΙ', 'ᾅ' => 'ἍΙ', 'ᾆ' => 'ἎΙ', 'ᾇ' => 'ἏΙ', 'ᾐ' => 'ἨΙ', 'ᾑ' => 'ἩΙ', 'ᾒ' => 'ἪΙ', 'ᾓ' => 'ἫΙ', 'ᾔ' => 'ἬΙ', 'ᾕ' => 'ἭΙ', 'ᾖ' => 'ἮΙ', 'ᾗ' => 'ἯΙ', 'ᾠ' => 'ὨΙ', 'ᾡ' => 'ὩΙ', 'ᾢ' => 'ὪΙ', 'ᾣ' => 'ὫΙ', 'ᾤ' => 'ὬΙ', 'ᾥ' => 'ὭΙ', 'ᾦ' => 'ὮΙ', 'ᾧ' => 'ὯΙ', 'ᾰ' => 'Ᾰ', 'ᾱ' => 'Ᾱ', 'ᾳ' => 'ΑΙ', 'ι' => 'Ι', 'ῃ' => 'ΗΙ', 'ῐ' => 'Ῐ', 'ῑ' => 'Ῑ', 'ῠ' => 'Ῠ', 'ῡ' => 'Ῡ', 'ῥ' => 'Ῥ', 'ῳ' => 'ΩΙ', 'ⅎ' => 'Ⅎ', 'ⅰ' => 'Ⅰ', 'ⅱ' => 'Ⅱ', 'ⅲ' => 'Ⅲ', 'ⅳ' => 'Ⅳ', 'ⅴ' => 'Ⅴ', 'ⅵ' => 'Ⅵ', 'ⅶ' => 'Ⅶ', 'ⅷ' => 'Ⅷ', 'ⅸ' => 'Ⅸ', 'ⅹ' => 'Ⅹ', 'ⅺ' => 'Ⅺ', 'ⅻ' => 'Ⅻ', 'ⅼ' => 'Ⅼ', 'ⅽ' => 'Ⅽ', 'ⅾ' => 'Ⅾ', 'ⅿ' => 'Ⅿ', 'ↄ' => 'Ↄ', 'ⓐ' => 'Ⓐ', 'ⓑ' => 'Ⓑ', 'ⓒ' => 'Ⓒ', 'ⓓ' => 'Ⓓ', 'ⓔ' => 'Ⓔ', 'ⓕ' => 'Ⓕ', 'ⓖ' => 'Ⓖ', 'ⓗ' => 'Ⓗ', 'ⓘ' => 'Ⓘ', 'ⓙ' => 'Ⓙ', 'ⓚ' => 'Ⓚ', 'ⓛ' => 'Ⓛ', 'ⓜ' => 'Ⓜ', 'ⓝ' => 'Ⓝ', 'ⓞ' => 'Ⓞ', 'ⓟ' => 'Ⓟ', 'ⓠ' => 'Ⓠ', 'ⓡ' => 'Ⓡ', 'ⓢ' => 'Ⓢ', 'ⓣ' => 'Ⓣ', 'ⓤ' => 'Ⓤ', 'ⓥ' => 'Ⓥ', 'ⓦ' => 'Ⓦ', 'ⓧ' => 'Ⓧ', 'ⓨ' => 'Ⓨ', 'ⓩ' => 'Ⓩ', 'ⰰ' => 'Ⰰ', 'ⰱ' => 'Ⰱ', 'ⰲ' => 'Ⰲ', 'ⰳ' => 'Ⰳ', 'ⰴ' => 'Ⰴ', 'ⰵ' => 'Ⰵ', 'ⰶ' => 'Ⰶ', 'ⰷ' => 'Ⰷ', 'ⰸ' => 'Ⰸ', 'ⰹ' => 'Ⰹ', 'ⰺ' => 'Ⰺ', 'ⰻ' => 'Ⰻ', 'ⰼ' => 'Ⰼ', 'ⰽ' => 'Ⰽ', 'ⰾ' => 'Ⰾ', 'ⰿ' => 'Ⰿ', 'ⱀ' => 'Ⱀ', 'ⱁ' => 'Ⱁ', 'ⱂ' => 'Ⱂ', 'ⱃ' => 'Ⱃ', 'ⱄ' => 'Ⱄ', 'ⱅ' => 'Ⱅ', 'ⱆ' => 'Ⱆ', 'ⱇ' => 'Ⱇ', 'ⱈ' => 'Ⱈ', 'ⱉ' => 'Ⱉ', 'ⱊ' => 'Ⱊ', 'ⱋ' => 'Ⱋ', 'ⱌ' => 'Ⱌ', 'ⱍ' => 'Ⱍ', 'ⱎ' => 'Ⱎ', 'ⱏ' => 'Ⱏ', 'ⱐ' => 'Ⱐ', 'ⱑ' => 'Ⱑ', 'ⱒ' => 'Ⱒ', 'ⱓ' => 'Ⱓ', 'ⱔ' => 'Ⱔ', 'ⱕ' => 'Ⱕ', 'ⱖ' => 'Ⱖ', 'ⱗ' => 'Ⱗ', 'ⱘ' => 'Ⱘ', 'ⱙ' => 'Ⱙ', 'ⱚ' => 'Ⱚ', 'ⱛ' => 'Ⱛ', 'ⱜ' => 'Ⱜ', 'ⱝ' => 'Ⱝ', 'ⱞ' => 'Ⱞ', 'ⱡ' => 'Ⱡ', 'ⱥ' => 'Ⱥ', 'ⱦ' => 'Ⱦ', 'ⱨ' => 'Ⱨ', 'ⱪ' => 'Ⱪ', 'ⱬ' => 'Ⱬ', 'ⱳ' => 'Ⱳ', 'ⱶ' => 'Ⱶ', 'ⲁ' => 'Ⲁ', 'ⲃ' => 'Ⲃ', 'ⲅ' => 'Ⲅ', 'ⲇ' => 'Ⲇ', 'ⲉ' => 'Ⲉ', 'ⲋ' => 'Ⲋ', 'ⲍ' => 'Ⲍ', 'ⲏ' => 'Ⲏ', 'ⲑ' => 'Ⲑ', 'ⲓ' => 'Ⲓ', 'ⲕ' => 'Ⲕ', 'ⲗ' => 'Ⲗ', 'ⲙ' => 'Ⲙ', 'ⲛ' => 'Ⲛ', 'ⲝ' => 'Ⲝ', 'ⲟ' => 'Ⲟ', 'ⲡ' => 'Ⲡ', 'ⲣ' => 'Ⲣ', 'ⲥ' => 'Ⲥ', 'ⲧ' => 'Ⲧ', 'ⲩ' => 'Ⲩ', 'ⲫ' => 'Ⲫ', 'ⲭ' => 'Ⲭ', 'ⲯ' => 'Ⲯ', 'ⲱ' => 'Ⲱ', 'ⲳ' => 'Ⲳ', 'ⲵ' => 'Ⲵ', 'ⲷ' => 'Ⲷ', 'ⲹ' => 'Ⲹ', 'ⲻ' => 'Ⲻ', 'ⲽ' => 'Ⲽ', 'ⲿ' => 'Ⲿ', 'ⳁ' => 'Ⳁ', 'ⳃ' => 'Ⳃ', 'ⳅ' => 'Ⳅ', 'ⳇ' => 'Ⳇ', 'ⳉ' => 'Ⳉ', 'ⳋ' => 'Ⳋ', 'ⳍ' => 'Ⳍ', 'ⳏ' => 'Ⳏ', 'ⳑ' => 'Ⳑ', 'ⳓ' => 'Ⳓ', 'ⳕ' => 'Ⳕ', 'ⳗ' => 'Ⳗ', 'ⳙ' => 'Ⳙ', 'ⳛ' => 'Ⳛ', 'ⳝ' => 'Ⳝ', 'ⳟ' => 'Ⳟ', 'ⳡ' => 'Ⳡ', 'ⳣ' => 'Ⳣ', 'ⳬ' => 'Ⳬ', 'ⳮ' => 'Ⳮ', 'ⳳ' => 'Ⳳ', 'ⴀ' => 'Ⴀ', 'ⴁ' => 'Ⴁ', 'ⴂ' => 'Ⴂ', 'ⴃ' => 'Ⴃ', 'ⴄ' => 'Ⴄ', 'ⴅ' => 'Ⴅ', 'ⴆ' => 'Ⴆ', 'ⴇ' => 'Ⴇ', 'ⴈ' => 'Ⴈ', 'ⴉ' => 'Ⴉ', 'ⴊ' => 'Ⴊ', 'ⴋ' => 'Ⴋ', 'ⴌ' => 'Ⴌ', 'ⴍ' => 'Ⴍ', 'ⴎ' => 'Ⴎ', 'ⴏ' => 'Ⴏ', 'ⴐ' => 'Ⴐ', 'ⴑ' => 'Ⴑ', 'ⴒ' => 'Ⴒ', 'ⴓ' => 'Ⴓ', 'ⴔ' => 'Ⴔ', 'ⴕ' => 'Ⴕ', 'ⴖ' => 'Ⴖ', 'ⴗ' => 'Ⴗ', 'ⴘ' => 'Ⴘ', 'ⴙ' => 'Ⴙ', 'ⴚ' => 'Ⴚ', 'ⴛ' => 'Ⴛ', 'ⴜ' => 'Ⴜ', 'ⴝ' => 'Ⴝ', 'ⴞ' => 'Ⴞ', 'ⴟ' => 'Ⴟ', 'ⴠ' => 'Ⴠ', 'ⴡ' => 'Ⴡ', 'ⴢ' => 'Ⴢ', 'ⴣ' => 'Ⴣ', 'ⴤ' => 'Ⴤ', 'ⴥ' => 'Ⴥ', 'ⴧ' => 'Ⴧ', 'ⴭ' => 'Ⴭ', 'ꙁ' => 'Ꙁ', 'ꙃ' => 'Ꙃ', 'ꙅ' => 'Ꙅ', 'ꙇ' => 'Ꙇ', 'ꙉ' => 'Ꙉ', 'ꙋ' => 'Ꙋ', 'ꙍ' => 'Ꙍ', 'ꙏ' => 'Ꙏ', 'ꙑ' => 'Ꙑ', 'ꙓ' => 'Ꙓ', 'ꙕ' => 'Ꙕ', 'ꙗ' => 'Ꙗ', 'ꙙ' => 'Ꙙ', 'ꙛ' => 'Ꙛ', 'ꙝ' => 'Ꙝ', 'ꙟ' => 'Ꙟ', 'ꙡ' => 'Ꙡ', 'ꙣ' => 'Ꙣ', 'ꙥ' => 'Ꙥ', 'ꙧ' => 'Ꙧ', 'ꙩ' => 'Ꙩ', 'ꙫ' => 'Ꙫ', 'ꙭ' => 'Ꙭ', 'ꚁ' => 'Ꚁ', 'ꚃ' => 'Ꚃ', 'ꚅ' => 'Ꚅ', 'ꚇ' => 'Ꚇ', 'ꚉ' => 'Ꚉ', 'ꚋ' => 'Ꚋ', 'ꚍ' => 'Ꚍ', 'ꚏ' => 'Ꚏ', 'ꚑ' => 'Ꚑ', 'ꚓ' => 'Ꚓ', 'ꚕ' => 'Ꚕ', 'ꚗ' => 'Ꚗ', 'ꚙ' => 'Ꚙ', 'ꚛ' => 'Ꚛ', 'ꜣ' => 'Ꜣ', 'ꜥ' => 'Ꜥ', 'ꜧ' => 'Ꜧ', 'ꜩ' => 'Ꜩ', 'ꜫ' => 'Ꜫ', 'ꜭ' => 'Ꜭ', 'ꜯ' => 'Ꜯ', 'ꜳ' => 'Ꜳ', 'ꜵ' => 'Ꜵ', 'ꜷ' => 'Ꜷ', 'ꜹ' => 'Ꜹ', 'ꜻ' => 'Ꜻ', 'ꜽ' => 'Ꜽ', 'ꜿ' => 'Ꜿ', 'ꝁ' => 'Ꝁ', 'ꝃ' => 'Ꝃ', 'ꝅ' => 'Ꝅ', 'ꝇ' => 'Ꝇ', 'ꝉ' => 'Ꝉ', 'ꝋ' => 'Ꝋ', 'ꝍ' => 'Ꝍ', 'ꝏ' => 'Ꝏ', 'ꝑ' => 'Ꝑ', 'ꝓ' => 'Ꝓ', 'ꝕ' => 'Ꝕ', 'ꝗ' => 'Ꝗ', 'ꝙ' => 'Ꝙ', 'ꝛ' => 'Ꝛ', 'ꝝ' => 'Ꝝ', 'ꝟ' => 'Ꝟ', 'ꝡ' => 'Ꝡ', 'ꝣ' => 'Ꝣ', 'ꝥ' => 'Ꝥ', 'ꝧ' => 'Ꝧ', 'ꝩ' => 'Ꝩ', 'ꝫ' => 'Ꝫ', 'ꝭ' => 'Ꝭ', 'ꝯ' => 'Ꝯ', 'ꝺ' => 'Ꝺ', 'ꝼ' => 'Ꝼ', 'ꝿ' => 'Ꝿ', 'ꞁ' => 'Ꞁ', 'ꞃ' => 'Ꞃ', 'ꞅ' => 'Ꞅ', 'ꞇ' => 'Ꞇ', 'ꞌ' => 'Ꞌ', 'ꞑ' => 'Ꞑ', 'ꞓ' => 'Ꞓ', 'ꞔ' => 'Ꞔ', 'ꞗ' => 'Ꞗ', 'ꞙ' => 'Ꞙ', 'ꞛ' => 'Ꞛ', 'ꞝ' => 'Ꞝ', 'ꞟ' => 'Ꞟ', 'ꞡ' => 'Ꞡ', 'ꞣ' => 'Ꞣ', 'ꞥ' => 'Ꞥ', 'ꞧ' => 'Ꞧ', 'ꞩ' => 'Ꞩ', 'ꞵ' => 'Ꞵ', 'ꞷ' => 'Ꞷ', 'ꞹ' => 'Ꞹ', 'ꞻ' => 'Ꞻ', 'ꞽ' => 'Ꞽ', 'ꞿ' => 'Ꞿ', 'ꟃ' => 'Ꟃ', 'ꟈ' => 'Ꟈ', 'ꟊ' => 'Ꟊ', 'ꟶ' => 'Ꟶ', 'ꭓ' => 'Ꭓ', 'ꭰ' => 'Ꭰ', 'ꭱ' => 'Ꭱ', 'ꭲ' => 'Ꭲ', 'ꭳ' => 'Ꭳ', 'ꭴ' => 'Ꭴ', 'ꭵ' => 'Ꭵ', 'ꭶ' => 'Ꭶ', 'ꭷ' => 'Ꭷ', 'ꭸ' => 'Ꭸ', 'ꭹ' => 'Ꭹ', 'ꭺ' => 'Ꭺ', 'ꭻ' => 'Ꭻ', 'ꭼ' => 'Ꭼ', 'ꭽ' => 'Ꭽ', 'ꭾ' => 'Ꭾ', 'ꭿ' => 'Ꭿ', 'ꮀ' => 'Ꮀ', 'ꮁ' => 'Ꮁ', 'ꮂ' => 'Ꮂ', 'ꮃ' => 'Ꮃ', 'ꮄ' => 'Ꮄ', 'ꮅ' => 'Ꮅ', 'ꮆ' => 'Ꮆ', 'ꮇ' => 'Ꮇ', 'ꮈ' => 'Ꮈ', 'ꮉ' => 'Ꮉ', 'ꮊ' => 'Ꮊ', 'ꮋ' => 'Ꮋ', 'ꮌ' => 'Ꮌ', 'ꮍ' => 'Ꮍ', 'ꮎ' => 'Ꮎ', 'ꮏ' => 'Ꮏ', 'ꮐ' => 'Ꮐ', 'ꮑ' => 'Ꮑ', 'ꮒ' => 'Ꮒ', 'ꮓ' => 'Ꮓ', 'ꮔ' => 'Ꮔ', 'ꮕ' => 'Ꮕ', 'ꮖ' => 'Ꮖ', 'ꮗ' => 'Ꮗ', 'ꮘ' => 'Ꮘ', 'ꮙ' => 'Ꮙ', 'ꮚ' => 'Ꮚ', 'ꮛ' => 'Ꮛ', 'ꮜ' => 'Ꮜ', 'ꮝ' => 'Ꮝ', 'ꮞ' => 'Ꮞ', 'ꮟ' => 'Ꮟ', 'ꮠ' => 'Ꮠ', 'ꮡ' => 'Ꮡ', 'ꮢ' => 'Ꮢ', 'ꮣ' => 'Ꮣ', 'ꮤ' => 'Ꮤ', 'ꮥ' => 'Ꮥ', 'ꮦ' => 'Ꮦ', 'ꮧ' => 'Ꮧ', 'ꮨ' => 'Ꮨ', 'ꮩ' => 'Ꮩ', 'ꮪ' => 'Ꮪ', 'ꮫ' => 'Ꮫ', 'ꮬ' => 'Ꮬ', 'ꮭ' => 'Ꮭ', 'ꮮ' => 'Ꮮ', 'ꮯ' => 'Ꮯ', 'ꮰ' => 'Ꮰ', 'ꮱ' => 'Ꮱ', 'ꮲ' => 'Ꮲ', 'ꮳ' => 'Ꮳ', 'ꮴ' => 'Ꮴ', 'ꮵ' => 'Ꮵ', 'ꮶ' => 'Ꮶ', 'ꮷ' => 'Ꮷ', 'ꮸ' => 'Ꮸ', 'ꮹ' => 'Ꮹ', 'ꮺ' => 'Ꮺ', 'ꮻ' => 'Ꮻ', 'ꮼ' => 'Ꮼ', 'ꮽ' => 'Ꮽ', 'ꮾ' => 'Ꮾ', 'ꮿ' => 'Ꮿ', 'a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D', 'e' => 'E', 'f' => 'F', 'g' => 'G', 'h' => 'H', 'i' => 'I', 'j' => 'J', 'k' => 'K', 'l' => 'L', 'm' => 'M', 'n' => 'N', 'o' => 'O', 'p' => 'P', 'q' => 'Q', 'r' => 'R', 's' => 'S', 't' => 'T', 'u' => 'U', 'v' => 'V', 'w' => 'W', 'x' => 'X', 'y' => 'Y', 'z' => 'Z', '𐐨' => '𐐀', '𐐩' => '𐐁', '𐐪' => '𐐂', '𐐫' => '𐐃', '𐐬' => '𐐄', '𐐭' => '𐐅', '𐐮' => '𐐆', '𐐯' => '𐐇', '𐐰' => '𐐈', '𐐱' => '𐐉', '𐐲' => '𐐊', '𐐳' => '𐐋', '𐐴' => '𐐌', '𐐵' => '𐐍', '𐐶' => '𐐎', '𐐷' => '𐐏', '𐐸' => '𐐐', '𐐹' => '𐐑', '𐐺' => '𐐒', '𐐻' => '𐐓', '𐐼' => '𐐔', '𐐽' => '𐐕', '𐐾' => '𐐖', '𐐿' => '𐐗', '𐑀' => '𐐘', '𐑁' => '𐐙', '𐑂' => '𐐚', '𐑃' => '𐐛', '𐑄' => '𐐜', '𐑅' => '𐐝', '𐑆' => '𐐞', '𐑇' => '𐐟', '𐑈' => '𐐠', '𐑉' => '𐐡', '𐑊' => '𐐢', '𐑋' => '𐐣', '𐑌' => '𐐤', '𐑍' => '𐐥', '𐑎' => '𐐦', '𐑏' => '𐐧', '𐓘' => '𐒰', '𐓙' => '𐒱', '𐓚' => '𐒲', '𐓛' => '𐒳', '𐓜' => '𐒴', '𐓝' => '𐒵', '𐓞' => '𐒶', '𐓟' => '𐒷', '𐓠' => '𐒸', '𐓡' => '𐒹', '𐓢' => '𐒺', '𐓣' => '𐒻', '𐓤' => '𐒼', '𐓥' => '𐒽', '𐓦' => '𐒾', '𐓧' => '𐒿', '𐓨' => '𐓀', '𐓩' => '𐓁', '𐓪' => '𐓂', '𐓫' => '𐓃', '𐓬' => '𐓄', '𐓭' => '𐓅', '𐓮' => '𐓆', '𐓯' => '𐓇', '𐓰' => '𐓈', '𐓱' => '𐓉', '𐓲' => '𐓊', '𐓳' => '𐓋', '𐓴' => '𐓌', '𐓵' => '𐓍', '𐓶' => '𐓎', '𐓷' => '𐓏', '𐓸' => '𐓐', '𐓹' => '𐓑', '𐓺' => '𐓒', '𐓻' => '𐓓', '𐳀' => '𐲀', '𐳁' => '𐲁', '𐳂' => '𐲂', '𐳃' => '𐲃', '𐳄' => '𐲄', '𐳅' => '𐲅', '𐳆' => '𐲆', '𐳇' => '𐲇', '𐳈' => '𐲈', '𐳉' => '𐲉', '𐳊' => '𐲊', '𐳋' => '𐲋', '𐳌' => '𐲌', '𐳍' => '𐲍', '𐳎' => '𐲎', '𐳏' => '𐲏', '𐳐' => '𐲐', '𐳑' => '𐲑', '𐳒' => '𐲒', '𐳓' => '𐲓', '𐳔' => '𐲔', '𐳕' => '𐲕', '𐳖' => '𐲖', '𐳗' => '𐲗', '𐳘' => '𐲘', '𐳙' => '𐲙', '𐳚' => '𐲚', '𐳛' => '𐲛', '𐳜' => '𐲜', '𐳝' => '𐲝', '𐳞' => '𐲞', '𐳟' => '𐲟', '𐳠' => '𐲠', '𐳡' => '𐲡', '𐳢' => '𐲢', '𐳣' => '𐲣', '𐳤' => '𐲤', '𐳥' => '𐲥', '𐳦' => '𐲦', '𐳧' => '𐲧', '𐳨' => '𐲨', '𐳩' => '𐲩', '𐳪' => '𐲪', '𐳫' => '𐲫', '𐳬' => '𐲬', '𐳭' => '𐲭', '𐳮' => '𐲮', '𐳯' => '𐲯', '𐳰' => '𐲰', '𐳱' => '𐲱', '𐳲' => '𐲲', '𑣀' => '𑢠', '𑣁' => '𑢡', '𑣂' => '𑢢', '𑣃' => '𑢣', '𑣄' => '𑢤', '𑣅' => '𑢥', '𑣆' => '𑢦', '𑣇' => '𑢧', '𑣈' => '𑢨', '𑣉' => '𑢩', '𑣊' => '𑢪', '𑣋' => '𑢫', '𑣌' => '𑢬', '𑣍' => '𑢭', '𑣎' => '𑢮', '𑣏' => '𑢯', '𑣐' => '𑢰', '𑣑' => '𑢱', '𑣒' => '𑢲', '𑣓' => '𑢳', '𑣔' => '𑢴', '𑣕' => '𑢵', '𑣖' => '𑢶', '𑣗' => '𑢷', '𑣘' => '𑢸', '𑣙' => '𑢹', '𑣚' => '𑢺', '𑣛' => '𑢻', '𑣜' => '𑢼', '𑣝' => '𑢽', '𑣞' => '𑢾', '𑣟' => '𑢿', '𖹠' => '𖹀', '𖹡' => '𖹁', '𖹢' => '𖹂', '𖹣' => '𖹃', '𖹤' => '𖹄', '𖹥' => '𖹅', '𖹦' => '𖹆', '𖹧' => '𖹇', '𖹨' => '𖹈', '𖹩' => '𖹉', '𖹪' => '𖹊', '𖹫' => '𖹋', '𖹬' => '𖹌', '𖹭' => '𖹍', '𖹮' => '𖹎', '𖹯' => '𖹏', '𖹰' => '𖹐', '𖹱' => '𖹑', '𖹲' => '𖹒', '𖹳' => '𖹓', '𖹴' => '𖹔', '𖹵' => '𖹕', '𖹶' => '𖹖', '𖹷' => '𖹗', '𖹸' => '𖹘', '𖹹' => '𖹙', '𖹺' => '𖹚', '𖹻' => '𖹛', '𖹼' => '𖹜', '𖹽' => '𖹝', '𖹾' => '𖹞', '𖹿' => '𖹟', '𞤢' => '𞤀', '𞤣' => '𞤁', '𞤤' => '𞤂', '𞤥' => '𞤃', '𞤦' => '𞤄', '𞤧' => '𞤅', '𞤨' => '𞤆', '𞤩' => '𞤇', '𞤪' => '𞤈', '𞤫' => '𞤉', '𞤬' => '𞤊', '𞤭' => '𞤋', '𞤮' => '𞤌', '𞤯' => '𞤍', '𞤰' => '𞤎', '𞤱' => '𞤏', '𞤲' => '𞤐', '𞤳' => '𞤑', '𞤴' => '𞤒', '𞤵' => '𞤓', '𞤶' => '𞤔', '𞤷' => '𞤕', '𞤸' => '𞤖', '𞤹' => '𞤗', '𞤺' => '𞤘', '𞤻' => '𞤙', '𞤼' => '𞤚', '𞤽' => '𞤛', '𞤾' => '𞤜', '𞤿' => '𞤝', '𞥀' => '𞤞', '𞥁' => '𞤟', '𞥂' => '𞤠', '𞥃' => '𞤡', 'ß' => 'SS', 'ff' => 'FF', 'fi' => 'FI', 'fl' => 'FL', 'ffi' => 'FFI', 'ffl' => 'FFL', 'ſt' => 'ST', 'st' => 'ST', 'և' => 'ԵՒ', 'ﬓ' => 'ՄՆ', 'ﬔ' => 'ՄԵ', 'ﬕ' => 'ՄԻ', 'ﬖ' => 'ՎՆ', 'ﬗ' => 'ՄԽ', 'ʼn' => 'ʼN', 'ΐ' => 'Ϊ́', 'ΰ' => 'Ϋ́', 'ǰ' => 'J̌', 'ẖ' => 'H̱', 'ẗ' => 'T̈', 'ẘ' => 'W̊', 'ẙ' => 'Y̊', 'ẚ' => 'Aʾ', 'ὐ' => 'Υ̓', 'ὒ' => 'Υ̓̀', 'ὔ' => 'Υ̓́', 'ὖ' => 'Υ̓͂', 'ᾶ' => 'Α͂', 'ῆ' => 'Η͂', 'ῒ' => 'Ϊ̀', 'ΐ' => 'Ϊ́', 'ῖ' => 'Ι͂', 'ῗ' => 'Ϊ͂', 'ῢ' => 'Ϋ̀', 'ΰ' => 'Ϋ́', 'ῤ' => 'Ρ̓', 'ῦ' => 'Υ͂', 'ῧ' => 'Ϋ͂', 'ῶ' => 'Ω͂', 'ᾈ' => 'ἈΙ', 'ᾉ' => 'ἉΙ', 'ᾊ' => 'ἊΙ', 'ᾋ' => 'ἋΙ', 'ᾌ' => 'ἌΙ', 'ᾍ' => 'ἍΙ', 'ᾎ' => 'ἎΙ', 'ᾏ' => 'ἏΙ', 'ᾘ' => 'ἨΙ', 'ᾙ' => 'ἩΙ', 'ᾚ' => 'ἪΙ', 'ᾛ' => 'ἫΙ', 'ᾜ' => 'ἬΙ', 'ᾝ' => 'ἭΙ', 'ᾞ' => 'ἮΙ', 'ᾟ' => 'ἯΙ', 'ᾨ' => 'ὨΙ', 'ᾩ' => 'ὩΙ', 'ᾪ' => 'ὪΙ', 'ᾫ' => 'ὫΙ', 'ᾬ' => 'ὬΙ', 'ᾭ' => 'ὭΙ', 'ᾮ' => 'ὮΙ', 'ᾯ' => 'ὯΙ', 'ᾼ' => 'ΑΙ', 'ῌ' => 'ΗΙ', 'ῼ' => 'ΩΙ', 'ᾲ' => 'ᾺΙ', 'ᾴ' => 'ΆΙ', 'ῂ' => 'ῊΙ', 'ῄ' => 'ΉΙ', 'ῲ' => 'ῺΙ', 'ῴ' => 'ΏΙ', 'ᾷ' => 'Α͂Ι', 'ῇ' => 'Η͂Ι', 'ῷ' => 'Ω͂Ι'); diff --git a/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php new file mode 100644 index 0000000000..ecf1a03522 --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Mbstring as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('mb_convert_encoding')) { + function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + function mb_language($language = null) { return p\Mbstring::mb_language($language); } +} +if (!function_exists('mb_list_encodings')) { + function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } +} +if (!function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } +} +if (!function_exists('mb_check_encoding')) { + function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } +} +if (!function_exists('mb_detect_order')) { + function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } +} +if (!function_exists('mb_strpos')) { + function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_get_info')) { + function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } +} +if (!function_exists('mb_http_output')) { + function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } +} +if (!function_exists('mb_http_input')) { + function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } +} + +if (!function_exists('mb_ord')) { + function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (extension_loaded('mbstring')) { + return; +} + +if (!defined('MB_CASE_UPPER')) { + define('MB_CASE_UPPER', 0); +} +if (!defined('MB_CASE_LOWER')) { + define('MB_CASE_LOWER', 1); +} +if (!defined('MB_CASE_TITLE')) { + define('MB_CASE_TITLE', 2); +} diff --git a/vendor/symfony/polyfill-mbstring/bootstrap80.php b/vendor/symfony/polyfill-mbstring/bootstrap80.php new file mode 100644 index 0000000000..08db438c9c --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/bootstrap80.php @@ -0,0 +1,218 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Mbstring as p; + +if (!function_exists('mb_convert_encoding')) { + /** + * @param mixed[]|string|null $string + * @param mixed[]|string|null $from_encoding + * @return mixed[]|string|false + */ + function mb_convert_encoding($string, ?string $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + /** + * @return string|bool + */ + function mb_internal_encoding(?string $encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + /** + * @return string|bool + */ + function mb_language(?string $language = null) { return p\Mbstring::mb_language($language); } +} +if (!function_exists('mb_list_encodings')) { + function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); } +} +if (!function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); } +} +if (!function_exists('mb_check_encoding')) { + /** + * @param mixed[]|string|null $value + */ + function mb_check_encoding($value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + /** + * @param mixed[]|string|null $encodings + * @return string|false + */ + function mb_detect_encoding(?string $string, $encodings = null, ?bool $strict = false) { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); } +} +if (!function_exists('mb_detect_order')) { + /** + * @param mixed[]|string|null $encoding + * @return mixed[]|bool + */ + function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); } +} +if (!function_exists('mb_strpos')) { + /** + * @return int|false + */ + function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + /** + * @param string|int|null $substitute_character + * @return string|int|bool + */ + function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + /** + * @return int|false + */ + function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + /** + * @return string|false + */ + function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null) { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + /** + * @return string|false + */ + function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null) { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + /** + * @return string|false + */ + function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null) { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + /** + * @return int|false + */ + function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + /** + * @return int|false + */ + function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + /** + * @return string|false + */ + function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null) { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_get_info')) { + /** + * @return mixed[]|string|int|false + */ + function mb_get_info(?string $type = 'all') { return p\Mbstring::mb_get_info((string) $type); } +} +if (!function_exists('mb_http_output')) { + /** + * @return string|bool + */ + function mb_http_output(?string $encoding = null) { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); } +} +if (!function_exists('mb_http_input')) { + /** + * @return mixed[]|string|false + */ + function mb_http_input(?string $type = null) { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + /** + * @param mixed[]|string|null $from_encoding + * @return string|false + * @param mixed $var + * @param mixed ...$vars + */ + function mb_convert_variables(?string $to_encoding, $from_encoding, &$var, &...$vars) { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); } +} + +if (!function_exists('mb_ord')) { + /** + * @return int|false + */ + function mb_ord(?string $string, ?string $encoding = null) { return p\Mbstring::mb_ord((string) $string, $encoding); } +} +if (!function_exists('mb_chr')) { + /** + * @return string|false + */ + function mb_chr(?int $codepoint, ?string $encoding = null) { return p\Mbstring::mb_chr((int) $codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub(?string $string, ?string $encoding = null): string { $encoding = $encoding ?? mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (extension_loaded('mbstring')) { + return; +} + +if (!defined('MB_CASE_UPPER')) { + define('MB_CASE_UPPER', 0); +} +if (!defined('MB_CASE_LOWER')) { + define('MB_CASE_LOWER', 1); +} +if (!defined('MB_CASE_TITLE')) { + define('MB_CASE_TITLE', 2); +} diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json new file mode 100644 index 0000000000..18d803a37b --- /dev/null +++ b/vendor/symfony/polyfill-mbstring/composer.json @@ -0,0 +1,51 @@ +{ + "name": "symfony\/polyfill-mbstring", + "type": "library", + "description": "Symfony polyfill for the Mbstring extension", + "keywords": [ + "polyfill", + "shim", + "compatibility", + "portable", + "mbstring" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony\/polyfill", + "url": "https:\/\/github.com\/symfony\/polyfill" + } + } +} \ No newline at end of file diff --git a/vendor/symfony/process/CHANGELOG.md b/vendor/symfony/process/CHANGELOG.md new file mode 100644 index 0000000000..31b9ee6a25 --- /dev/null +++ b/vendor/symfony/process/CHANGELOG.md @@ -0,0 +1,116 @@ +CHANGELOG +========= + +5.2.0 +----- + + * added `Process::setOptions()` to set `Process` specific options + * added option `create_new_console` to allow a subprocess to continue + to run after the main script exited, both on Linux and on Windows + +5.1.0 +----- + + * added `Process::getStartTime()` to retrieve the start time of the process as float + +5.0.0 +----- + + * removed `Process::inheritEnvironmentVariables()` + * removed `PhpProcess::setPhpBinary()` + * `Process` must be instantiated with a command array, use `Process::fromShellCommandline()` when the command should be parsed by the shell + * removed `Process::setCommandLine()` + +4.4.0 +----- + + * deprecated `Process::inheritEnvironmentVariables()`: env variables are always inherited. + * added `Process::getLastOutputTime()` method + +4.2.0 +----- + + * added the `Process::fromShellCommandline()` to run commands in a shell wrapper + * deprecated passing a command as string when creating a `Process` instance + * deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods + * added the `Process::waitUntil()` method to wait for the process only for a + specific output, then continue the normal execution of your application + +4.1.0 +----- + + * added the `Process::isTtySupported()` method that allows to check for TTY support + * made `PhpExecutableFinder` look for the `PHP_BINARY` env var when searching the php binary + * added the `ProcessSignaledException` class to properly catch signaled process errors + +4.0.0 +----- + + * environment variables will always be inherited + * added a second `array $env = []` argument to the `start()`, `run()`, + `mustRun()`, and `restart()` methods of the `Process` class + * added a second `array $env = []` argument to the `start()` method of the + `PhpProcess` class + * the `ProcessUtils::escapeArgument()` method has been removed + * the `areEnvironmentVariablesInherited()`, `getOptions()`, and `setOptions()` + methods of the `Process` class have been removed + * support for passing `proc_open()` options has been removed + * removed the `ProcessBuilder` class, use the `Process` class instead + * removed the `getEnhanceWindowsCompatibility()` and `setEnhanceWindowsCompatibility()` methods of the `Process` class + * passing a not existing working directory to the constructor of the `Symfony\Component\Process\Process` class is not + supported anymore + +3.4.0 +----- + + * deprecated the ProcessBuilder class + * deprecated calling `Process::start()` without setting a valid working directory beforehand (via `setWorkingDirectory()` or constructor) + +3.3.0 +----- + + * added command line arrays in the `Process` class + * added `$env` argument to `Process::start()`, `run()`, `mustRun()` and `restart()` methods + * deprecated the `ProcessUtils::escapeArgument()` method + * deprecated not inheriting environment variables + * deprecated configuring `proc_open()` options + * deprecated configuring enhanced Windows compatibility + * deprecated configuring enhanced sigchild compatibility + +2.5.0 +----- + + * added support for PTY mode + * added the convenience method "mustRun" + * deprecation: Process::setStdin() is deprecated in favor of Process::setInput() + * deprecation: Process::getStdin() is deprecated in favor of Process::getInput() + * deprecation: Process::setInput() and ProcessBuilder::setInput() do not accept non-scalar types + +2.4.0 +----- + + * added the ability to define an idle timeout + +2.3.0 +----- + + * added ProcessUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows + * added Process::signal() + * added Process::getPid() + * added support for a TTY mode + +2.2.0 +----- + + * added ProcessBuilder::setArguments() to reset the arguments on a builder + * added a way to retrieve the standard and error output incrementally + * added Process:restart() + +2.1.0 +----- + + * added support for non-blocking processes (start(), wait(), isRunning(), stop()) + * enhanced Windows compatibility + * added Process::getExitCodeText() that returns a string representation for + the exit code returned by the process + * added ProcessBuilder diff --git a/vendor/symfony/process/Exception/ExceptionInterface.php b/vendor/symfony/process/Exception/ExceptionInterface.php new file mode 100644 index 0000000000..937505972c --- /dev/null +++ b/vendor/symfony/process/Exception/ExceptionInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception; + +/** + * Marker Interface for the Process Component. + * + * @author Johannes M. Schmitt + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/process/Exception/InvalidArgumentException.php b/vendor/symfony/process/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000..41197ba3db --- /dev/null +++ b/vendor/symfony/process/Exception/InvalidArgumentException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception; + +/** + * InvalidArgumentException for the Process Component. + * + * @author Romain Neutron + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/process/Exception/LogicException.php b/vendor/symfony/process/Exception/LogicException.php new file mode 100644 index 0000000000..902d8b88c5 --- /dev/null +++ b/vendor/symfony/process/Exception/LogicException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception; + +/** + * LogicException for the Process Component. + * + * @author Romain Neutron + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/process/Exception/ProcessFailedException.php b/vendor/symfony/process/Exception/ProcessFailedException.php new file mode 100644 index 0000000000..c4be534015 --- /dev/null +++ b/vendor/symfony/process/Exception/ProcessFailedException.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Process; +/** + * Exception for failed processes. + * + * @author Johannes M. Schmitt + */ +class ProcessFailedException extends RuntimeException +{ + private $process; + public function __construct(Process $process) + { + if ($process->isSuccessful()) { + throw new InvalidArgumentException('Expected a failed process, but the given process was successful.'); + } + $error = \sprintf('The command "%s" failed.' . "\n\nExit Code: %s(%s)\n\nWorking directory: %s", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText(), $process->getWorkingDirectory()); + if (!$process->isOutputDisabled()) { + $error .= \sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", $process->getOutput(), $process->getErrorOutput()); + } + parent::__construct($error); + $this->process = $process; + } + /** + * @return Process + */ + public function getProcess() + { + return $this->process; + } +} diff --git a/vendor/symfony/process/Exception/ProcessSignaledException.php b/vendor/symfony/process/Exception/ProcessSignaledException.php new file mode 100644 index 0000000000..35900f7517 --- /dev/null +++ b/vendor/symfony/process/Exception/ProcessSignaledException.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Process; +/** + * Exception that is thrown when a process has been signaled. + * + * @author Sullivan Senechal + */ +final class ProcessSignaledException extends RuntimeException +{ + private $process; + public function __construct(Process $process) + { + $this->process = $process; + parent::__construct(\sprintf('The process has been signaled with signal "%s".', $process->getTermSignal())); + } + public function getProcess() : Process + { + return $this->process; + } + public function getSignal() : int + { + return $this->getProcess()->getTermSignal(); + } +} diff --git a/vendor/symfony/process/Exception/ProcessTimedOutException.php b/vendor/symfony/process/Exception/ProcessTimedOutException.php new file mode 100644 index 0000000000..d3b5a4ed01 --- /dev/null +++ b/vendor/symfony/process/Exception/ProcessTimedOutException.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Process; +/** + * Exception that is thrown when a process times out. + * + * @author Johannes M. Schmitt + */ +class ProcessTimedOutException extends RuntimeException +{ + public const TYPE_GENERAL = 1; + public const TYPE_IDLE = 2; + private $process; + private $timeoutType; + public function __construct(Process $process, int $timeoutType) + { + $this->process = $process; + $this->timeoutType = $timeoutType; + parent::__construct(\sprintf('The process "%s" exceeded the timeout of %s seconds.', $process->getCommandLine(), $this->getExceededTimeout())); + } + /** + * @return Process + */ + public function getProcess() + { + return $this->process; + } + /** + * @return bool + */ + public function isGeneralTimeout() + { + return self::TYPE_GENERAL === $this->timeoutType; + } + /** + * @return bool + */ + public function isIdleTimeout() + { + return self::TYPE_IDLE === $this->timeoutType; + } + public function getExceededTimeout() : ?float + { + switch ($this->timeoutType) { + case self::TYPE_GENERAL: + return $this->process->getTimeout(); + case self::TYPE_IDLE: + return $this->process->getIdleTimeout(); + default: + throw new \LogicException(\sprintf('Unknown timeout type "%d".', $this->timeoutType)); + } + } +} diff --git a/vendor/symfony/process/Exception/RuntimeException.php b/vendor/symfony/process/Exception/RuntimeException.php new file mode 100644 index 0000000000..7ab7bd0e11 --- /dev/null +++ b/vendor/symfony/process/Exception/RuntimeException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception; + +/** + * RuntimeException for the Process Component. + * + * @author Johannes M. Schmitt + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/process/ExecutableFinder.php b/vendor/symfony/process/ExecutableFinder.php new file mode 100644 index 0000000000..a3d97d92d4 --- /dev/null +++ b/vendor/symfony/process/ExecutableFinder.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process; + +/** + * Generic executable finder. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class ExecutableFinder +{ + private $suffixes = ['.exe', '.bat', '.cmd', '.com']; + /** + * Replaces default suffixes of executable. + * + * @return void + */ + public function setSuffixes(array $suffixes) + { + $this->suffixes = $suffixes; + } + /** + * Adds new possible suffix to check for executable. + * + * @return void + */ + public function addSuffix(string $suffix) + { + $this->suffixes[] = $suffix; + } + /** + * Finds an executable by name. + * + * @param string $name The executable name (without the extension) + * @param string|null $default The default to return if no executable is found + * @param array $extraDirs Additional dirs to check into + */ + public function find(string $name, string $default = null, array $extraDirs = []) : ?string + { + if (\ini_get('open_basedir')) { + $searchPath = \array_merge(\explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs); + $dirs = []; + foreach ($searchPath as $path) { + // Silencing against https://bugs.php.net/69240 + if (@\is_dir($path)) { + $dirs[] = $path; + } else { + if (\basename($path) == $name && @\is_executable($path)) { + return $path; + } + } + } + } else { + $dirs = \array_merge(\explode(\PATH_SEPARATOR, \getenv('PATH') ?: \getenv('Path')), $extraDirs); + } + $suffixes = ['']; + if ('\\' === \DIRECTORY_SEPARATOR) { + $pathExt = \getenv('PATHEXT'); + $suffixes = \array_merge($pathExt ? \explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes); + } + foreach ($suffixes as $suffix) { + foreach ($dirs as $dir) { + if (@\is_file($file = $dir . \DIRECTORY_SEPARATOR . $name . $suffix) && ('\\' === \DIRECTORY_SEPARATOR || @\is_executable($file))) { + return $file; + } + } + } + return $default; + } +} diff --git a/vendor/symfony/process/InputStream.php b/vendor/symfony/process/InputStream.php new file mode 100644 index 0000000000..177354878b --- /dev/null +++ b/vendor/symfony/process/InputStream.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\RuntimeException; +/** + * Provides a way to continuously write to the input of a Process until the InputStream is closed. + * + * @author Nicolas Grekas + * + * @implements \IteratorAggregate + */ +class InputStream implements \IteratorAggregate +{ + /** @var callable|null */ + private $onEmpty; + private $input = []; + private $open = \true; + /** + * Sets a callback that is called when the write buffer becomes empty. + * + * @return void + */ + public function onEmpty(callable $onEmpty = null) + { + $this->onEmpty = $onEmpty; + } + /** + * Appends an input to the write buffer. + * + * @param mixed $input The input to append as scalar, + stream resource or \Traversable + * + * @return void + */ + public function write($input) + { + if (null === $input) { + return; + } + if ($this->isClosed()) { + throw new RuntimeException(\sprintf('"%s" is closed.', static::class)); + } + $this->input[] = ProcessUtils::validateInput(__METHOD__, $input); + } + /** + * Closes the write buffer. + * + * @return void + */ + public function close() + { + $this->open = \false; + } + /** + * Tells whether the write buffer is closed or not. + * + * @return bool + */ + public function isClosed() + { + return !$this->open; + } + public function getIterator() : \Traversable + { + $this->open = \true; + while ($this->open || $this->input) { + if (!$this->input) { + (yield ''); + continue; + } + $current = \array_shift($this->input); + if ($current instanceof \Iterator) { + yield from $current; + } else { + (yield $current); + } + if (!$this->input && $this->open && null !== ($onEmpty = $this->onEmpty)) { + $this->write($onEmpty($this)); + } + } + } +} diff --git a/vendor/symfony/process/LICENSE b/vendor/symfony/process/LICENSE new file mode 100644 index 0000000000..0138f8f071 --- /dev/null +++ b/vendor/symfony/process/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/process/PhpExecutableFinder.php b/vendor/symfony/process/PhpExecutableFinder.php new file mode 100644 index 0000000000..f8a67bcba3 --- /dev/null +++ b/vendor/symfony/process/PhpExecutableFinder.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process; + +/** + * An executable finder specifically designed for the PHP executable. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class PhpExecutableFinder +{ + private $executableFinder; + public function __construct() + { + $this->executableFinder = new ExecutableFinder(); + } + /** + * Finds The PHP executable. + * @return string|false + */ + public function find(bool $includeArgs = \true) + { + if ($php = \getenv('PHP_BINARY')) { + if (!\is_executable($php)) { + $command = '\\' === \DIRECTORY_SEPARATOR ? 'where' : 'command -v'; + if ($php = \strtok(\exec($command . ' ' . \escapeshellarg($php)), \PHP_EOL)) { + if (!\is_executable($php)) { + return \false; + } + } else { + return \false; + } + } + if (@\is_dir($php)) { + return \false; + } + return $php; + } + $args = $this->findArguments(); + $args = $includeArgs && $args ? ' ' . \implode(' ', $args) : ''; + // PHP_BINARY return the current sapi executable + if (\PHP_BINARY && \in_array(\PHP_SAPI, ['cli', 'cli-server', 'phpdbg'], \true)) { + return \PHP_BINARY . $args; + } + if ($php = \getenv('PHP_PATH')) { + if (!@\is_executable($php) || @\is_dir($php)) { + return \false; + } + return $php; + } + if ($php = \getenv('PHP_PEAR_PHP_BIN')) { + if (@\is_executable($php) && !@\is_dir($php)) { + return $php; + } + } + if (@\is_executable($php = \PHP_BINDIR . ('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php')) && !@\is_dir($php)) { + return $php; + } + $dirs = [\PHP_BINDIR]; + if ('\\' === \DIRECTORY_SEPARATOR) { + $dirs[] = 'C:\\xampp\\php\\'; + } + return $this->executableFinder->find('php', \false, $dirs); + } + /** + * Finds the PHP executable arguments. + */ + public function findArguments() : array + { + $arguments = []; + if ('phpdbg' === \PHP_SAPI) { + $arguments[] = '-qrr'; + } + return $arguments; + } +} diff --git a/vendor/symfony/process/PhpProcess.php b/vendor/symfony/process/PhpProcess.php new file mode 100644 index 0000000000..445c2d9a80 --- /dev/null +++ b/vendor/symfony/process/PhpProcess.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\RuntimeException; +/** + * PhpProcess runs a PHP script in an independent process. + * + * $p = new PhpProcess(''); + * $p->run(); + * print $p->getOutput()."\n"; + * + * @author Fabien Potencier + */ +class PhpProcess extends Process +{ + /** + * @param string $script The PHP script to run (as a string) + * @param string|null $cwd The working directory or null to use the working dir of the current PHP process + * @param array|null $env The environment variables or null to use the same environment as the current PHP process + * @param int $timeout The timeout in seconds + * @param array|null $php Path to the PHP binary to use with any additional arguments + */ + public function __construct(string $script, string $cwd = null, array $env = null, int $timeout = 60, array $php = null) + { + if (null === $php) { + $executableFinder = new PhpExecutableFinder(); + $php = $executableFinder->find(\false); + $php = \false === $php ? null : \array_merge([$php], $executableFinder->findArguments()); + } + if ('phpdbg' === \PHP_SAPI) { + $file = \tempnam(\sys_get_temp_dir(), 'dbg'); + \file_put_contents($file, $script); + \register_shutdown_function('unlink', $file); + $php[] = $file; + $script = null; + } + parent::__construct($php, $cwd, $env, $script, $timeout); + } + /** + * @param mixed $input + * @return static + */ + public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + { + throw new LogicException(\sprintf('The "%s()" method cannot be called when using "%s".', __METHOD__, self::class)); + } + /** + * @return void + */ + public function start(callable $callback = null, array $env = []) + { + if (null === $this->getCommandLine()) { + throw new RuntimeException('Unable to find the PHP executable.'); + } + parent::start($callback, $env); + } +} diff --git a/vendor/symfony/process/Pipes/AbstractPipes.php b/vendor/symfony/process/Pipes/AbstractPipes.php new file mode 100644 index 0000000000..e6e14811a9 --- /dev/null +++ b/vendor/symfony/process/Pipes/AbstractPipes.php @@ -0,0 +1,160 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Pipes; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\InvalidArgumentException; +/** + * @author Romain Neutron + * + * @internal + */ +abstract class AbstractPipes implements PipesInterface +{ + /** + * @var mixed[] + */ + public $pipes = []; + private $inputBuffer = ''; + private $input; + private $blocked = \true; + private $lastError; + /** + * @param mixed $input + */ + public function __construct($input) + { + if (\is_resource($input) || $input instanceof \Iterator) { + $this->input = $input; + } elseif (\is_string($input)) { + $this->inputBuffer = $input; + } else { + $this->inputBuffer = (string) $input; + } + } + public function close() : void + { + foreach ($this->pipes as $pipe) { + if (\is_resource($pipe)) { + \fclose($pipe); + } + } + $this->pipes = []; + } + /** + * Returns true if a system call has been interrupted. + */ + protected function hasSystemCallBeenInterrupted() : bool + { + $lastError = $this->lastError; + $this->lastError = null; + // stream_select returns false when the `select` system call is interrupted by an incoming signal + return null !== $lastError && \false !== \stripos($lastError, 'interrupted system call'); + } + /** + * Unblocks streams. + */ + protected function unblock() : void + { + if (!$this->blocked) { + return; + } + foreach ($this->pipes as $pipe) { + \stream_set_blocking($pipe, 0); + } + if (\is_resource($this->input)) { + \stream_set_blocking($this->input, 0); + } + $this->blocked = \false; + } + /** + * Writes input to stdin. + * + * @throws InvalidArgumentException When an input iterator yields a non supported value + */ + protected function write() : ?array + { + if (!isset($this->pipes[0])) { + return null; + } + $input = $this->input; + if ($input instanceof \Iterator) { + if (!$input->valid()) { + $input = null; + } elseif (\is_resource($input = $input->current())) { + \stream_set_blocking($input, 0); + } elseif (!isset($this->inputBuffer[0])) { + if (!\is_string($input)) { + if (!\is_scalar($input)) { + throw new InvalidArgumentException(\sprintf('"%s" yielded a value of type "%s", but only scalars and stream resources are supported.', \get_debug_type($this->input), \get_debug_type($input))); + } + $input = (string) $input; + } + $this->inputBuffer = $input; + $this->input->next(); + $input = null; + } else { + $input = null; + } + } + $r = $e = []; + $w = [$this->pipes[0]]; + // let's have a look if something changed in streams + if (\false === @\stream_select($r, $w, $e, 0, 0)) { + return null; + } + foreach ($w as $stdin) { + if (isset($this->inputBuffer[0])) { + $written = \fwrite($stdin, $this->inputBuffer); + $this->inputBuffer = \substr($this->inputBuffer, $written); + if (isset($this->inputBuffer[0])) { + return [$this->pipes[0]]; + } + } + if ($input) { + while (\true) { + $data = \fread($input, self::CHUNK_SIZE); + if (!isset($data[0])) { + break; + } + $written = \fwrite($stdin, $data); + $data = \substr($data, $written); + if (isset($data[0])) { + $this->inputBuffer = $data; + return [$this->pipes[0]]; + } + } + if (\feof($input)) { + if ($this->input instanceof \Iterator) { + $this->input->next(); + } else { + $this->input = null; + } + } + } + } + // no input to read on resource, buffer is empty + if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) { + $this->input = null; + \fclose($this->pipes[0]); + unset($this->pipes[0]); + } elseif (!$w) { + return [$this->pipes[0]]; + } + return null; + } + /** + * @internal + */ + public function handleError(int $type, string $msg) : void + { + $this->lastError = $msg; + } +} diff --git a/vendor/symfony/process/Pipes/PipesInterface.php b/vendor/symfony/process/Pipes/PipesInterface.php new file mode 100644 index 0000000000..03586db497 --- /dev/null +++ b/vendor/symfony/process/Pipes/PipesInterface.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Pipes; + +/** + * PipesInterface manages descriptors and pipes for the use of proc_open. + * + * @author Romain Neutron + * + * @internal + */ +interface PipesInterface +{ + public const CHUNK_SIZE = 16384; + /** + * Returns an array of descriptors for the use of proc_open. + */ + public function getDescriptors() : array; + /** + * Returns an array of filenames indexed by their related stream in case these pipes use temporary files. + * + * @return string[] + */ + public function getFiles() : array; + /** + * Reads data in file handles and pipes. + * + * @param bool $blocking Whether to use blocking calls or not + * @param bool $close Whether to close pipes if they've reached EOF + * + * @return string[] An array of read data indexed by their fd + */ + public function readAndWrite(bool $blocking, bool $close = \false) : array; + /** + * Returns if the current state has open file handles or pipes. + */ + public function areOpen() : bool; + /** + * Returns if pipes are able to read output. + */ + public function haveReadSupport() : bool; + /** + * Closes file handles and pipes. + */ + public function close() : void; +} diff --git a/vendor/symfony/process/Pipes/UnixPipes.php b/vendor/symfony/process/Pipes/UnixPipes.php new file mode 100644 index 0000000000..8ff57a2855 --- /dev/null +++ b/vendor/symfony/process/Pipes/UnixPipes.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Pipes; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Process; +/** + * UnixPipes implementation uses unix pipes as handles. + * + * @author Romain Neutron + * + * @internal + */ +class UnixPipes extends AbstractPipes +{ + private $ttyMode; + private $ptyMode; + private $haveReadSupport; + /** + * @param mixed $input + */ + public function __construct(?bool $ttyMode, bool $ptyMode, $input, bool $haveReadSupport) + { + $this->ttyMode = $ttyMode; + $this->ptyMode = $ptyMode; + $this->haveReadSupport = $haveReadSupport; + parent::__construct($input); + } + public function __sleep() : array + { + throw new \BadMethodCallException('Cannot serialize ' . __CLASS__); + } + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__); + } + public function __destruct() + { + $this->close(); + } + public function getDescriptors() : array + { + if (!$this->haveReadSupport) { + $nullstream = \fopen('/dev/null', 'c'); + return [['pipe', 'r'], $nullstream, $nullstream]; + } + if ($this->ttyMode) { + return [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']]; + } + if ($this->ptyMode && Process::isPtySupported()) { + return [['pty'], ['pty'], ['pty']]; + } + return [ + ['pipe', 'r'], + ['pipe', 'w'], + // stdout + ['pipe', 'w'], + ]; + } + public function getFiles() : array + { + return []; + } + public function readAndWrite(bool $blocking, bool $close = \false) : array + { + $this->unblock(); + $w = $this->write(); + $read = $e = []; + $r = $this->pipes; + unset($r[0]); + // let's have a look if something changed in streams + \set_error_handler(\Closure::fromCallable([$this, 'handleError'])); + if (($r || $w) && \false === \stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1000000.0 : 0)) { + \restore_error_handler(); + // if a system call has been interrupted, forget about it, let's try again + // otherwise, an error occurred, let's reset pipes + if (!$this->hasSystemCallBeenInterrupted()) { + $this->pipes = []; + } + return $read; + } + \restore_error_handler(); + foreach ($r as $pipe) { + // prior PHP 5.4 the array passed to stream_select is modified and + // lose key association, we have to find back the key + $read[$type = \array_search($pipe, $this->pipes, \true)] = ''; + do { + $data = @\fread($pipe, self::CHUNK_SIZE); + $read[$type] .= $data; + } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1]))); + if (!isset($read[$type][0])) { + unset($read[$type]); + } + if ($close && \feof($pipe)) { + \fclose($pipe); + unset($this->pipes[$type]); + } + } + return $read; + } + public function haveReadSupport() : bool + { + return $this->haveReadSupport; + } + public function areOpen() : bool + { + return (bool) $this->pipes; + } +} diff --git a/vendor/symfony/process/Pipes/WindowsPipes.php b/vendor/symfony/process/Pipes/WindowsPipes.php new file mode 100644 index 0000000000..5c7d124ab1 --- /dev/null +++ b/vendor/symfony/process/Pipes/WindowsPipes.php @@ -0,0 +1,156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process\Pipes; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Process; +/** + * WindowsPipes implementation uses temporary files as handles. + * + * @see https://bugs.php.net/51800 + * @see https://bugs.php.net/65650 + * + * @author Romain Neutron + * + * @internal + */ +class WindowsPipes extends AbstractPipes +{ + private $files = []; + private $fileHandles = []; + private $lockHandles = []; + private $readBytes = [Process::STDOUT => 0, Process::STDERR => 0]; + private $haveReadSupport; + /** + * @param mixed $input + */ + public function __construct($input, bool $haveReadSupport) + { + $this->haveReadSupport = $haveReadSupport; + if ($this->haveReadSupport) { + // Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. + // Workaround for this problem is to use temporary files instead of pipes on Windows platform. + // + // @see https://bugs.php.net/51800 + $pipes = [Process::STDOUT => Process::OUT, Process::STDERR => Process::ERR]; + $tmpDir = \sys_get_temp_dir(); + $lastError = 'unknown reason'; + \set_error_handler(function ($type, $msg) use(&$lastError) { + $lastError = $msg; + }); + for ($i = 0;; ++$i) { + foreach ($pipes as $pipe => $name) { + $file = \sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name); + if (!($h = \fopen($file . '.lock', 'w'))) { + if (\file_exists($file . '.lock')) { + continue 2; + } + \restore_error_handler(); + throw new RuntimeException('A temporary file could not be opened to write the process output: ' . $lastError); + } + if (!\flock($h, \LOCK_EX | \LOCK_NB)) { + continue 2; + } + if (isset($this->lockHandles[$pipe])) { + \flock($this->lockHandles[$pipe], \LOCK_UN); + \fclose($this->lockHandles[$pipe]); + } + $this->lockHandles[$pipe] = $h; + if (!($h = \fopen($file, 'w')) || !\fclose($h) || !($h = \fopen($file, 'r'))) { + \flock($this->lockHandles[$pipe], \LOCK_UN); + \fclose($this->lockHandles[$pipe]); + unset($this->lockHandles[$pipe]); + continue 2; + } + $this->fileHandles[$pipe] = $h; + $this->files[$pipe] = $file; + } + break; + } + \restore_error_handler(); + } + parent::__construct($input); + } + public function __sleep() : array + { + throw new \BadMethodCallException('Cannot serialize ' . __CLASS__); + } + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__); + } + public function __destruct() + { + $this->close(); + } + public function getDescriptors() : array + { + if (!$this->haveReadSupport) { + $nullstream = \fopen('NUL', 'c'); + return [['pipe', 'r'], $nullstream, $nullstream]; + } + // We're not using pipe on Windows platform as it hangs (https://bugs.php.net/51800) + // We're not using file handles as it can produce corrupted output https://bugs.php.net/65650 + // So we redirect output within the commandline and pass the nul device to the process + return [['pipe', 'r'], ['file', 'NUL', 'w'], ['file', 'NUL', 'w']]; + } + public function getFiles() : array + { + return $this->files; + } + public function readAndWrite(bool $blocking, bool $close = \false) : array + { + $this->unblock(); + $w = $this->write(); + $read = $r = $e = []; + if ($blocking) { + if ($w) { + @\stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1000000.0); + } elseif ($this->fileHandles) { + \usleep(Process::TIMEOUT_PRECISION * 1000000.0); + } + } + foreach ($this->fileHandles as $type => $fileHandle) { + $data = \stream_get_contents($fileHandle, -1, $this->readBytes[$type]); + if (isset($data[0])) { + $this->readBytes[$type] += \strlen($data); + $read[$type] = $data; + } + if ($close) { + \ftruncate($fileHandle, 0); + \fclose($fileHandle); + \flock($this->lockHandles[$type], \LOCK_UN); + \fclose($this->lockHandles[$type]); + unset($this->fileHandles[$type], $this->lockHandles[$type]); + } + } + return $read; + } + public function haveReadSupport() : bool + { + return $this->haveReadSupport; + } + public function areOpen() : bool + { + return $this->pipes && $this->fileHandles; + } + public function close() : void + { + parent::close(); + foreach ($this->fileHandles as $type => $handle) { + \ftruncate($handle, 0); + \fclose($handle); + \flock($this->lockHandles[$type], \LOCK_UN); + \fclose($this->lockHandles[$type]); + } + $this->fileHandles = $this->lockHandles = []; + } +} diff --git a/vendor/symfony/process/Process.php b/vendor/symfony/process/Process.php new file mode 100644 index 0000000000..cfa89815c2 --- /dev/null +++ b/vendor/symfony/process/Process.php @@ -0,0 +1,1382 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\LogicException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\ProcessFailedException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\ProcessSignaledException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\ProcessTimedOutException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\RuntimeException; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Pipes\PipesInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Pipes\UnixPipes; +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Pipes\WindowsPipes; +/** + * Process is a thin wrapper around proc_* functions to easily + * start independent PHP processes. + * + * @author Fabien Potencier + * @author Romain Neutron + * + * @implements \IteratorAggregate + */ +class Process implements \IteratorAggregate +{ + public const ERR = 'err'; + public const OUT = 'out'; + public const STATUS_READY = 'ready'; + public const STATUS_STARTED = 'started'; + public const STATUS_TERMINATED = 'terminated'; + public const STDIN = 0; + public const STDOUT = 1; + public const STDERR = 2; + // Timeout Precision in seconds. + public const TIMEOUT_PRECISION = 0.2; + public const ITER_NON_BLOCKING = 1; + // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking + public const ITER_KEEP_OUTPUT = 2; + // By default, outputs are cleared while iterating, use this flag to keep them in memory + public const ITER_SKIP_OUT = 4; + // Use this flag to skip STDOUT while iterating + public const ITER_SKIP_ERR = 8; + // Use this flag to skip STDERR while iterating + private $callback; + private $hasCallback = \false; + private $commandline; + private $cwd; + private $env = []; + private $input; + private $starttime; + private $lastOutputTime; + private $timeout; + private $idleTimeout; + private $exitcode; + private $fallbackStatus = []; + private $processInformation; + private $outputDisabled = \false; + private $stdout; + private $stderr; + private $process; + private $status = self::STATUS_READY; + private $incrementalOutputOffset = 0; + private $incrementalErrorOutputOffset = 0; + private $tty = \false; + private $pty; + private $options = ['suppress_errors' => \true, 'bypass_shell' => \true]; + private $useFileHandles = \false; + /** @var PipesInterface */ + private $processPipes; + private $latestSignal; + private static $sigchild; + /** + * Exit codes translation table. + * + * User-defined errors must use exit codes in the 64-113 range. + */ + public static $exitCodes = [ + 0 => 'OK', + 1 => 'General error', + 2 => 'Misuse of shell builtins', + 126 => 'Invoked command cannot execute', + 127 => 'Command not found', + 128 => 'Invalid exit argument', + // signals + 129 => 'Hangup', + 130 => 'Interrupt', + 131 => 'Quit and dump core', + 132 => 'Illegal instruction', + 133 => 'Trace/breakpoint trap', + 134 => 'Process aborted', + 135 => 'Bus error: "access to undefined portion of memory object"', + 136 => 'Floating point exception: "erroneous arithmetic operation"', + 137 => 'Kill (terminate immediately)', + 138 => 'User-defined 1', + 139 => 'Segmentation violation', + 140 => 'User-defined 2', + 141 => 'Write to pipe with no one reading', + 142 => 'Signal raised by alarm', + 143 => 'Termination (request to terminate)', + // 144 - not defined + 145 => 'Child process terminated, stopped (or continued*)', + 146 => 'Continue if stopped', + 147 => 'Stop executing temporarily', + 148 => 'Terminal stop signal', + 149 => 'Background process attempting to read from tty ("in")', + 150 => 'Background process attempting to write to tty ("out")', + 151 => 'Urgent data available on socket', + 152 => 'CPU time limit exceeded', + 153 => 'File size limit exceeded', + 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"', + 155 => 'Profiling timer expired', + // 156 - not defined + 157 => 'Pollable event', + // 158 - not defined + 159 => 'Bad syscall', + ]; + /** + * @param array $command The command to run and its arguments listed as separate entries + * @param string|null $cwd The working directory or null to use the working dir of the current PHP process + * @param array|null $env The environment variables or null to use the same environment as the current PHP process + * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input + * @param int|float|null $timeout The timeout in seconds or null to disable + * + * @throws LogicException When proc_open is not installed + */ + public function __construct(array $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + { + if (!\function_exists('proc_open')) { + throw new LogicException('The Process class relies on proc_open, which is not available on your PHP installation.'); + } + $this->commandline = $command; + $this->cwd = $cwd; + // on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started + // on Gnu/Linux, PHP builds with --enable-maintainer-zts are also affected + // @see : https://bugs.php.net/51800 + // @see : https://bugs.php.net/50524 + if (null === $this->cwd && (\defined('ZEND_THREAD_SAFE') || '\\' === \DIRECTORY_SEPARATOR)) { + $this->cwd = \getcwd(); + } + if (null !== $env) { + $this->setEnv($env); + } + $this->setInput($input); + $this->setTimeout($timeout); + $this->useFileHandles = '\\' === \DIRECTORY_SEPARATOR; + $this->pty = \false; + } + /** + * Creates a Process instance as a command-line to be run in a shell wrapper. + * + * Command-lines are parsed by the shell of your OS (/bin/sh on Unix-like, cmd.exe on Windows.) + * This allows using e.g. pipes or conditional execution. In this mode, signals are sent to the + * shell wrapper and not to your commands. + * + * In order to inject dynamic values into command-lines, we strongly recommend using placeholders. + * This will save escaping values, which is not portable nor secure anyway: + * + * $process = Process::fromShellCommandline('my_command "${:MY_VAR}"'); + * $process->run(null, ['MY_VAR' => $theValue]); + * + * @param string $command The command line to pass to the shell of the OS + * @param string|null $cwd The working directory or null to use the working dir of the current PHP process + * @param array|null $env The environment variables or null to use the same environment as the current PHP process + * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input + * @param int|float|null $timeout The timeout in seconds or null to disable + * + * @throws LogicException When proc_open is not installed + * @return static + */ + public static function fromShellCommandline(string $command, string $cwd = null, array $env = null, $input = null, ?float $timeout = 60) + { + $process = new static([], $cwd, $env, $input, $timeout); + $process->commandline = $command; + return $process; + } + public function __sleep() : array + { + throw new \BadMethodCallException('Cannot serialize ' . __CLASS__); + } + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__); + } + public function __destruct() + { + if ($this->options['create_new_console'] ?? \false) { + $this->processPipes->close(); + } else { + $this->stop(0); + } + } + public function __clone() + { + $this->resetProcessData(); + } + /** + * Runs the process. + * + * The callback receives the type of output (out or err) and + * some bytes from the output in real-time. It allows to have feedback + * from the independent process during execution. + * + * The STDOUT and STDERR are also available after the process is finished + * via the getOutput() and getErrorOutput() methods. + * + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @return int The exit status code + * + * @throws RuntimeException When process can't be launched + * @throws RuntimeException When process is already running + * @throws ProcessTimedOutException When process timed out + * @throws ProcessSignaledException When process stopped after receiving signal + * @throws LogicException In case a callback is provided and output has been disabled + * + * @final + */ + public function run(callable $callback = null, array $env = []) : int + { + $this->start($callback, $env); + return $this->wait(); + } + /** + * Runs the process. + * + * This is identical to run() except that an exception is thrown if the process + * exits with a non-zero exit code. + * + * @return $this + * + * @throws ProcessFailedException if the process didn't terminate successfully + * + * @final + */ + public function mustRun(callable $callback = null, array $env = []) + { + if (0 !== $this->run($callback, $env)) { + throw new ProcessFailedException($this); + } + return $this; + } + /** + * Starts the process and returns after writing the input to STDIN. + * + * This method blocks until all STDIN data is sent to the process then it + * returns while the process runs in the background. + * + * The termination of the process can be awaited with wait(). + * + * The callback receives the type of output (out or err) and some bytes from + * the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @return void + * + * @throws RuntimeException When process can't be launched + * @throws RuntimeException When process is already running + * @throws LogicException In case a callback is provided and output has been disabled + */ + public function start(callable $callback = null, array $env = []) + { + if ($this->isRunning()) { + throw new RuntimeException('Process is already running.'); + } + $this->resetProcessData(); + $this->starttime = $this->lastOutputTime = \microtime(\true); + $this->callback = $this->buildCallback($callback); + $this->hasCallback = null !== $callback; + $descriptors = $this->getDescriptors(); + if ($this->env) { + $env += '\\' === \DIRECTORY_SEPARATOR ? \array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env; + } + $env += '\\' === \DIRECTORY_SEPARATOR ? \array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv(); + if (\is_array($commandline = $this->commandline)) { + $commandline = \implode(' ', \array_map(\Closure::fromCallable([$this, 'escapeArgument']), $commandline)); + if ('\\' !== \DIRECTORY_SEPARATOR) { + // exec is mandatory to deal with sending a signal to the process + $commandline = 'exec ' . $commandline; + } + } else { + $commandline = $this->replacePlaceholders($commandline, $env); + } + if ('\\' === \DIRECTORY_SEPARATOR) { + $commandline = $this->prepareWindowsCommandLine($commandline, $env); + } elseif (!$this->useFileHandles && $this->isSigchildEnabled()) { + // last exit code is output on the fourth pipe and caught to work around --enable-sigchild + $descriptors[3] = ['pipe', 'w']; + // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input + $commandline = '{ (' . $commandline . ') <&3 3<&- 3>/dev/null & } 3<&0;'; + $commandline .= 'pid=$!; echo $pid >&3; wait $pid 2>/dev/null; code=$?; echo $code >&3; exit $code'; + // Workaround for the bug, when PTS functionality is enabled. + // @see : https://bugs.php.net/69442 + $ptsWorkaround = \fopen(__FILE__, 'r'); + } + $envPairs = []; + foreach ($env as $k => $v) { + if (\false !== $v && \false === \in_array($k, ['argc', 'argv', 'ARGC', 'ARGV'], \true)) { + $envPairs[] = $k . '=' . $v; + } + } + if (!\is_dir($this->cwd)) { + throw new RuntimeException(\sprintf('The provided cwd "%s" does not exist.', $this->cwd)); + } + $this->process = @\proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $envPairs, $this->options); + if (!\is_resource($this->process)) { + throw new RuntimeException('Unable to launch a new process.'); + } + $this->status = self::STATUS_STARTED; + if (isset($descriptors[3])) { + $this->fallbackStatus['pid'] = (int) \fgets($this->processPipes->pipes[3]); + } + if ($this->tty) { + return; + } + $this->updateStatus(\false); + $this->checkTimeout(); + } + /** + * Restarts the process. + * + * Be warned that the process is cloned before being started. + * + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @throws RuntimeException When process can't be launched + * @throws RuntimeException When process is already running + * + * @see start() + * + * @final + * @return static + */ + public function restart(callable $callback = null, array $env = []) + { + if ($this->isRunning()) { + throw new RuntimeException('Process is already running.'); + } + $process = clone $this; + $process->start($callback, $env); + return $process; + } + /** + * Waits for the process to terminate. + * + * The callback receives the type of output (out or err) and some bytes + * from the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * + * @param callable|null $callback A valid PHP callback + * + * @return int The exitcode of the process + * + * @throws ProcessTimedOutException When process timed out + * @throws ProcessSignaledException When process stopped after receiving signal + * @throws LogicException When process is not yet started + */ + public function wait(callable $callback = null) : int + { + $this->requireProcessIsStarted(__FUNCTION__); + $this->updateStatus(\false); + if (null !== $callback) { + if (!$this->processPipes->haveReadSupport()) { + $this->stop(0); + throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::wait".'); + } + $this->callback = $this->buildCallback($callback); + } + do { + $this->checkTimeout(); + $running = $this->isRunning() && ('\\' === \DIRECTORY_SEPARATOR || $this->processPipes->areOpen()); + $this->readPipes($running, '\\' !== \DIRECTORY_SEPARATOR || !$running); + } while ($running); + while ($this->isRunning()) { + $this->checkTimeout(); + \usleep(1000); + } + if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) { + throw new ProcessSignaledException($this); + } + return $this->exitcode; + } + /** + * Waits until the callback returns true. + * + * The callback receives the type of output (out or err) and some bytes + * from the output in real-time while writing the standard input to the process. + * It allows to have feedback from the independent process during execution. + * + * @throws RuntimeException When process timed out + * @throws LogicException When process is not yet started + * @throws ProcessTimedOutException In case the timeout was reached + */ + public function waitUntil(callable $callback) : bool + { + $this->requireProcessIsStarted(__FUNCTION__); + $this->updateStatus(\false); + if (!$this->processPipes->haveReadSupport()) { + $this->stop(0); + throw new LogicException('Pass the callback to the "Process::start" method or call enableOutput to use a callback with "Process::waitUntil".'); + } + $callback = $this->buildCallback($callback); + $ready = \false; + while (\true) { + $this->checkTimeout(); + $running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen(); + $output = $this->processPipes->readAndWrite($running, '\\' !== \DIRECTORY_SEPARATOR || !$running); + foreach ($output as $type => $data) { + if (3 !== $type) { + $ready = $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data) || $ready; + } elseif (!isset($this->fallbackStatus['signaled'])) { + $this->fallbackStatus['exitcode'] = (int) $data; + } + } + if ($ready) { + return \true; + } + if (!$running) { + return \false; + } + \usleep(1000); + } + } + /** + * Returns the Pid (process identifier), if applicable. + * + * @return int|null The process id if running, null otherwise + */ + public function getPid() : ?int + { + return $this->isRunning() ? $this->processInformation['pid'] : null; + } + /** + * Sends a POSIX signal to the process. + * + * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants) + * + * @return $this + * + * @throws LogicException In case the process is not running + * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed + * @throws RuntimeException In case of failure + */ + public function signal(int $signal) + { + $this->doSignal($signal, \true); + return $this; + } + /** + * Disables fetching output and error output from the underlying process. + * + * @return $this + * + * @throws RuntimeException In case the process is already running + * @throws LogicException if an idle timeout is set + */ + public function disableOutput() + { + if ($this->isRunning()) { + throw new RuntimeException('Disabling output while the process is running is not possible.'); + } + if (null !== $this->idleTimeout) { + throw new LogicException('Output cannot be disabled while an idle timeout is set.'); + } + $this->outputDisabled = \true; + return $this; + } + /** + * Enables fetching output and error output from the underlying process. + * + * @return $this + * + * @throws RuntimeException In case the process is already running + */ + public function enableOutput() + { + if ($this->isRunning()) { + throw new RuntimeException('Enabling output while the process is running is not possible.'); + } + $this->outputDisabled = \false; + return $this; + } + /** + * Returns true in case the output is disabled, false otherwise. + */ + public function isOutputDisabled() : bool + { + return $this->outputDisabled; + } + /** + * Returns the current output of the process (STDOUT). + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getOutput() : string + { + $this->readPipesForOutput(__FUNCTION__); + if (\false === ($ret = \stream_get_contents($this->stdout, -1, 0))) { + return ''; + } + return $ret; + } + /** + * Returns the output incrementally. + * + * In comparison with the getOutput method which always return the whole + * output, this one returns the new output since the last call. + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getIncrementalOutput() : string + { + $this->readPipesForOutput(__FUNCTION__); + $latest = \stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); + $this->incrementalOutputOffset = \ftell($this->stdout); + if (\false === $latest) { + return ''; + } + return $latest; + } + /** + * Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR). + * + * @param int $flags A bit field of Process::ITER_* flags + * + * @return \Generator + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getIterator(int $flags = 0) : \Generator + { + $this->readPipesForOutput(__FUNCTION__, \false); + $clearOutput = !(self::ITER_KEEP_OUTPUT & $flags); + $blocking = !(self::ITER_NON_BLOCKING & $flags); + $yieldOut = !(self::ITER_SKIP_OUT & $flags); + $yieldErr = !(self::ITER_SKIP_ERR & $flags); + while (null !== $this->callback || $yieldOut && !\feof($this->stdout) || $yieldErr && !\feof($this->stderr)) { + if ($yieldOut) { + $out = \stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset); + if (isset($out[0])) { + if ($clearOutput) { + $this->clearOutput(); + } else { + $this->incrementalOutputOffset = \ftell($this->stdout); + } + (yield self::OUT => $out); + } + } + if ($yieldErr) { + $err = \stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); + if (isset($err[0])) { + if ($clearOutput) { + $this->clearErrorOutput(); + } else { + $this->incrementalErrorOutputOffset = \ftell($this->stderr); + } + (yield self::ERR => $err); + } + } + if (!$blocking && !isset($out[0]) && !isset($err[0])) { + (yield self::OUT => ''); + } + $this->checkTimeout(); + $this->readPipesForOutput(__FUNCTION__, $blocking); + } + } + /** + * Clears the process output. + * + * @return $this + */ + public function clearOutput() + { + \ftruncate($this->stdout, 0); + \fseek($this->stdout, 0); + $this->incrementalOutputOffset = 0; + return $this; + } + /** + * Returns the current error output of the process (STDERR). + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getErrorOutput() : string + { + $this->readPipesForOutput(__FUNCTION__); + if (\false === ($ret = \stream_get_contents($this->stderr, -1, 0))) { + return ''; + } + return $ret; + } + /** + * Returns the errorOutput incrementally. + * + * In comparison with the getErrorOutput method which always return the + * whole error output, this one returns the new error output since the last + * call. + * + * @throws LogicException in case the output has been disabled + * @throws LogicException In case the process is not started + */ + public function getIncrementalErrorOutput() : string + { + $this->readPipesForOutput(__FUNCTION__); + $latest = \stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset); + $this->incrementalErrorOutputOffset = \ftell($this->stderr); + if (\false === $latest) { + return ''; + } + return $latest; + } + /** + * Clears the process output. + * + * @return $this + */ + public function clearErrorOutput() + { + \ftruncate($this->stderr, 0); + \fseek($this->stderr, 0); + $this->incrementalErrorOutputOffset = 0; + return $this; + } + /** + * Returns the exit code returned by the process. + * + * @return int|null The exit status code, null if the Process is not terminated + */ + public function getExitCode() : ?int + { + $this->updateStatus(\false); + return $this->exitcode; + } + /** + * Returns a string representation for the exit code returned by the process. + * + * This method relies on the Unix exit code status standardization + * and might not be relevant for other operating systems. + * + * @return string|null A string representation for the exit status code, null if the Process is not terminated + * + * @see http://tldp.org/LDP/abs/html/exitcodes.html + * @see http://en.wikipedia.org/wiki/Unix_signal + */ + public function getExitCodeText() : ?string + { + if (null === ($exitcode = $this->getExitCode())) { + return null; + } + return self::$exitCodes[$exitcode] ?? 'Unknown error'; + } + /** + * Checks if the process ended successfully. + */ + public function isSuccessful() : bool + { + return 0 === $this->getExitCode(); + } + /** + * Returns true if the child process has been terminated by an uncaught signal. + * + * It always returns false on Windows. + * + * @throws LogicException In case the process is not terminated + */ + public function hasBeenSignaled() : bool + { + $this->requireProcessIsTerminated(__FUNCTION__); + return $this->processInformation['signaled']; + } + /** + * Returns the number of the signal that caused the child process to terminate its execution. + * + * It is only meaningful if hasBeenSignaled() returns true. + * + * @throws RuntimeException In case --enable-sigchild is activated + * @throws LogicException In case the process is not terminated + */ + public function getTermSignal() : int + { + $this->requireProcessIsTerminated(__FUNCTION__); + if ($this->isSigchildEnabled() && -1 === $this->processInformation['termsig']) { + throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal cannot be retrieved.'); + } + return $this->processInformation['termsig']; + } + /** + * Returns true if the child process has been stopped by a signal. + * + * It always returns false on Windows. + * + * @throws LogicException In case the process is not terminated + */ + public function hasBeenStopped() : bool + { + $this->requireProcessIsTerminated(__FUNCTION__); + return $this->processInformation['stopped']; + } + /** + * Returns the number of the signal that caused the child process to stop its execution. + * + * It is only meaningful if hasBeenStopped() returns true. + * + * @throws LogicException In case the process is not terminated + */ + public function getStopSignal() : int + { + $this->requireProcessIsTerminated(__FUNCTION__); + return $this->processInformation['stopsig']; + } + /** + * Checks if the process is currently running. + */ + public function isRunning() : bool + { + if (self::STATUS_STARTED !== $this->status) { + return \false; + } + $this->updateStatus(\false); + return $this->processInformation['running']; + } + /** + * Checks if the process has been started with no regard to the current state. + */ + public function isStarted() : bool + { + return self::STATUS_READY != $this->status; + } + /** + * Checks if the process is terminated. + */ + public function isTerminated() : bool + { + $this->updateStatus(\false); + return self::STATUS_TERMINATED == $this->status; + } + /** + * Gets the process status. + * + * The status is one of: ready, started, terminated. + */ + public function getStatus() : string + { + $this->updateStatus(\false); + return $this->status; + } + /** + * Stops the process. + * + * @param int|float $timeout The timeout in seconds + * @param int|null $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9) + * + * @return int|null The exit-code of the process or null if it's not running + */ + public function stop(float $timeout = 10, int $signal = null) : ?int + { + $timeoutMicro = \microtime(\true) + $timeout; + if ($this->isRunning()) { + // given SIGTERM may not be defined and that "proc_terminate" uses the constant value and not the constant itself, we use the same here + $this->doSignal(15, \false); + do { + \usleep(1000); + } while ($this->isRunning() && \microtime(\true) < $timeoutMicro); + if ($this->isRunning()) { + // Avoid exception here: process is supposed to be running, but it might have stopped just + // after this line. In any case, let's silently discard the error, we cannot do anything. + $this->doSignal($signal ?: 9, \false); + } + } + if ($this->isRunning()) { + if (isset($this->fallbackStatus['pid'])) { + unset($this->fallbackStatus['pid']); + return $this->stop(0, $signal); + } + $this->close(); + } + return $this->exitcode; + } + /** + * Adds a line to the STDOUT stream. + * + * @internal + */ + public function addOutput(string $line) : void + { + $this->lastOutputTime = \microtime(\true); + \fseek($this->stdout, 0, \SEEK_END); + \fwrite($this->stdout, $line); + \fseek($this->stdout, $this->incrementalOutputOffset); + } + /** + * Adds a line to the STDERR stream. + * + * @internal + */ + public function addErrorOutput(string $line) : void + { + $this->lastOutputTime = \microtime(\true); + \fseek($this->stderr, 0, \SEEK_END); + \fwrite($this->stderr, $line); + \fseek($this->stderr, $this->incrementalErrorOutputOffset); + } + /** + * Gets the last output time in seconds. + */ + public function getLastOutputTime() : ?float + { + return $this->lastOutputTime; + } + /** + * Gets the command line to be executed. + */ + public function getCommandLine() : string + { + return \is_array($this->commandline) ? \implode(' ', \array_map(\Closure::fromCallable([$this, 'escapeArgument']), $this->commandline)) : $this->commandline; + } + /** + * Gets the process timeout in seconds (max. runtime). + */ + public function getTimeout() : ?float + { + return $this->timeout; + } + /** + * Gets the process idle timeout in seconds (max. time since last output). + */ + public function getIdleTimeout() : ?float + { + return $this->idleTimeout; + } + /** + * Sets the process timeout (max. runtime) in seconds. + * + * To disable the timeout, set this value to null. + * + * @return $this + * + * @throws InvalidArgumentException if the timeout is negative + */ + public function setTimeout(?float $timeout) + { + $this->timeout = $this->validateTimeout($timeout); + return $this; + } + /** + * Sets the process idle timeout (max. time since last output) in seconds. + * + * To disable the timeout, set this value to null. + * + * @return $this + * + * @throws LogicException if the output is disabled + * @throws InvalidArgumentException if the timeout is negative + */ + public function setIdleTimeout(?float $timeout) + { + if (null !== $timeout && $this->outputDisabled) { + throw new LogicException('Idle timeout cannot be set while the output is disabled.'); + } + $this->idleTimeout = $this->validateTimeout($timeout); + return $this; + } + /** + * Enables or disables the TTY mode. + * + * @return $this + * + * @throws RuntimeException In case the TTY mode is not supported + */ + public function setTty(bool $tty) + { + if ('\\' === \DIRECTORY_SEPARATOR && $tty) { + throw new RuntimeException('TTY mode is not supported on Windows platform.'); + } + if ($tty && !self::isTtySupported()) { + throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.'); + } + $this->tty = $tty; + return $this; + } + /** + * Checks if the TTY mode is enabled. + */ + public function isTty() : bool + { + return $this->tty; + } + /** + * Sets PTY mode. + * + * @return $this + */ + public function setPty(bool $bool) + { + $this->pty = $bool; + return $this; + } + /** + * Returns PTY state. + */ + public function isPty() : bool + { + return $this->pty; + } + /** + * Gets the working directory. + */ + public function getWorkingDirectory() : ?string + { + if (null === $this->cwd) { + // getcwd() will return false if any one of the parent directories does not have + // the readable or search mode set, even if the current directory does + return \getcwd() ?: null; + } + return $this->cwd; + } + /** + * Sets the current working directory. + * + * @return $this + */ + public function setWorkingDirectory(string $cwd) + { + $this->cwd = $cwd; + return $this; + } + /** + * Gets the environment variables. + */ + public function getEnv() : array + { + return $this->env; + } + /** + * Sets the environment variables. + * + * @param array $env The new environment variables + * + * @return $this + */ + public function setEnv(array $env) + { + $this->env = $env; + return $this; + } + /** + * Gets the Process input. + * + * @return resource|string|\Iterator|null + */ + public function getInput() + { + return $this->input; + } + /** + * Sets the input. + * + * This content will be passed to the underlying process standard input. + * + * @param mixed $input The content + * + * @return $this + * + * @throws LogicException In case the process is running + */ + public function setInput($input) + { + if ($this->isRunning()) { + throw new LogicException('Input cannot be set while the process is running.'); + } + $this->input = ProcessUtils::validateInput(__METHOD__, $input); + return $this; + } + /** + * Performs a check between the timeout definition and the time the process started. + * + * In case you run a background process (with the start method), you should + * trigger this method regularly to ensure the process timeout + * + * @return void + * + * @throws ProcessTimedOutException In case the timeout was reached + */ + public function checkTimeout() + { + if (self::STATUS_STARTED !== $this->status) { + return; + } + if (null !== $this->timeout && $this->timeout < \microtime(\true) - $this->starttime) { + $this->stop(0); + throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL); + } + if (null !== $this->idleTimeout && $this->idleTimeout < \microtime(\true) - $this->lastOutputTime) { + $this->stop(0); + throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE); + } + } + /** + * @throws LogicException in case process is not started + */ + public function getStartTime() : float + { + if (!$this->isStarted()) { + throw new LogicException('Start time is only available after process start.'); + } + return $this->starttime; + } + /** + * Defines options to pass to the underlying proc_open(). + * + * @see https://php.net/proc_open for the options supported by PHP. + * + * Enabling the "create_new_console" option allows a subprocess to continue + * to run after the main process exited, on both Windows and *nix + * + * @return void + */ + public function setOptions(array $options) + { + if ($this->isRunning()) { + throw new RuntimeException('Setting options while the process is running is not possible.'); + } + $defaultOptions = $this->options; + $existingOptions = ['blocking_pipes', 'create_process_group', 'create_new_console']; + foreach ($options as $key => $value) { + if (!\in_array($key, $existingOptions)) { + $this->options = $defaultOptions; + throw new LogicException(\sprintf('Invalid option "%s" passed to "%s()". Supported options are "%s".', $key, __METHOD__, \implode('", "', $existingOptions))); + } + $this->options[$key] = $value; + } + } + /** + * Returns whether TTY is supported on the current operating system. + */ + public static function isTtySupported() : bool + { + static $isTtySupported; + return $isTtySupported = $isTtySupported ?? '/' === \DIRECTORY_SEPARATOR && \stream_isatty(\STDOUT); + } + /** + * Returns whether PTY is supported on the current operating system. + */ + public static function isPtySupported() : bool + { + static $result; + if (null !== $result) { + return $result; + } + if ('\\' === \DIRECTORY_SEPARATOR) { + return $result = \false; + } + return $result = (bool) @\proc_open('echo 1 >/dev/null', [['pty'], ['pty'], ['pty']], $pipes); + } + /** + * Creates the descriptors needed by the proc_open. + */ + private function getDescriptors() : array + { + if ($this->input instanceof \Iterator) { + $this->input->rewind(); + } + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback); + } else { + $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback); + } + return $this->processPipes->getDescriptors(); + } + /** + * Builds up the callback used by wait(). + * + * The callbacks adds all occurred output to the specific buffer and calls + * the user callback (if present) with the received output. + * + * @param callable|null $callback The user defined PHP callback + */ + protected function buildCallback(callable $callback = null) : \Closure + { + if ($this->outputDisabled) { + return function ($type, $data) use($callback) : bool { + return null !== $callback && $callback($type, $data); + }; + } + $out = self::OUT; + return function ($type, $data) use($callback, $out) : bool { + if ($out == $type) { + $this->addOutput($data); + } else { + $this->addErrorOutput($data); + } + return null !== $callback && $callback($type, $data); + }; + } + /** + * Updates the status of the process, reads pipes. + * + * @param bool $blocking Whether to use a blocking read call + * + * @return void + */ + protected function updateStatus(bool $blocking) + { + if (self::STATUS_STARTED !== $this->status) { + return; + } + $this->processInformation = \proc_get_status($this->process); + $running = $this->processInformation['running']; + $this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running); + if ($this->fallbackStatus && $this->isSigchildEnabled()) { + $this->processInformation = $this->fallbackStatus + $this->processInformation; + } + if (!$running) { + $this->close(); + } + } + /** + * Returns whether PHP has been compiled with the '--enable-sigchild' option or not. + */ + protected function isSigchildEnabled() : bool + { + if (null !== self::$sigchild) { + return self::$sigchild; + } + if (!\function_exists('phpinfo')) { + return self::$sigchild = \false; + } + \ob_start(); + \phpinfo(\INFO_GENERAL); + return self::$sigchild = \strpos(\ob_get_clean(), '--enable-sigchild') !== \false; + } + /** + * Reads pipes for the freshest output. + * + * @param string $caller The name of the method that needs fresh outputs + * @param bool $blocking Whether to use blocking calls or not + * + * @throws LogicException in case output has been disabled or process is not started + */ + private function readPipesForOutput(string $caller, bool $blocking = \false) : void + { + if ($this->outputDisabled) { + throw new LogicException('Output has been disabled.'); + } + $this->requireProcessIsStarted($caller); + $this->updateStatus($blocking); + } + /** + * Validates and returns the filtered timeout. + * + * @throws InvalidArgumentException if the given timeout is a negative number + */ + private function validateTimeout(?float $timeout) : ?float + { + $timeout = (float) $timeout; + if (0.0 === $timeout) { + $timeout = null; + } elseif ($timeout < 0) { + throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); + } + return $timeout; + } + /** + * Reads pipes, executes callback. + * + * @param bool $blocking Whether to use blocking calls or not + * @param bool $close Whether to close file handles or not + */ + private function readPipes(bool $blocking, bool $close) : void + { + $result = $this->processPipes->readAndWrite($blocking, $close); + $callback = $this->callback; + foreach ($result as $type => $data) { + if (3 !== $type) { + $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data); + } elseif (!isset($this->fallbackStatus['signaled'])) { + $this->fallbackStatus['exitcode'] = (int) $data; + } + } + } + /** + * Closes process resource, closes file handles, sets the exitcode. + * + * @return int The exitcode + */ + private function close() : int + { + $this->processPipes->close(); + if (\is_resource($this->process)) { + \proc_close($this->process); + } + $this->exitcode = $this->processInformation['exitcode']; + $this->status = self::STATUS_TERMINATED; + if (-1 === $this->exitcode) { + if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) { + // if process has been signaled, no exitcode but a valid termsig, apply Unix convention + $this->exitcode = 128 + $this->processInformation['termsig']; + } elseif ($this->isSigchildEnabled()) { + $this->processInformation['signaled'] = \true; + $this->processInformation['termsig'] = -1; + } + } + // Free memory from self-reference callback created by buildCallback + // Doing so in other contexts like __destruct or by garbage collector is ineffective + // Now pipes are closed, so the callback is no longer necessary + $this->callback = null; + return $this->exitcode; + } + /** + * Resets data related to the latest run of the process. + */ + private function resetProcessData() : void + { + $this->starttime = null; + $this->callback = null; + $this->exitcode = null; + $this->fallbackStatus = []; + $this->processInformation = null; + $this->stdout = \fopen('php://temp/maxmemory:' . 1024 * 1024, 'w+'); + $this->stderr = \fopen('php://temp/maxmemory:' . 1024 * 1024, 'w+'); + $this->process = null; + $this->latestSignal = null; + $this->status = self::STATUS_READY; + $this->incrementalOutputOffset = 0; + $this->incrementalErrorOutputOffset = 0; + } + /** + * Sends a POSIX signal to the process. + * + * @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants) + * @param bool $throwException Whether to throw exception in case signal failed + * + * @throws LogicException In case the process is not running + * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed + * @throws RuntimeException In case of failure + */ + private function doSignal(int $signal, bool $throwException) : bool + { + if (null === ($pid = $this->getPid())) { + if ($throwException) { + throw new LogicException('Cannot send signal on a non running process.'); + } + return \false; + } + if ('\\' === \DIRECTORY_SEPARATOR) { + \exec(\sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode); + if ($exitCode && $this->isRunning()) { + if ($throwException) { + throw new RuntimeException(\sprintf('Unable to kill the process (%s).', \implode(' ', $output))); + } + return \false; + } + } else { + if (!$this->isSigchildEnabled()) { + $ok = @\proc_terminate($this->process, $signal); + } elseif (\function_exists('posix_kill')) { + $ok = @\posix_kill($pid, $signal); + } elseif ($ok = \proc_open(\sprintf('kill -%d %d', $signal, $pid), [2 => ['pipe', 'w']], $pipes)) { + $ok = \false === \fgets($pipes[2]); + } + if (!$ok) { + if ($throwException) { + throw new RuntimeException(\sprintf('Error while sending signal "%s".', $signal)); + } + return \false; + } + } + $this->latestSignal = $signal; + $this->fallbackStatus['signaled'] = \true; + $this->fallbackStatus['exitcode'] = -1; + $this->fallbackStatus['termsig'] = $this->latestSignal; + return \true; + } + private function prepareWindowsCommandLine(string $cmd, array &$env) : string + { + $uid = \uniqid('', \true); + $cmd = \preg_replace_callback('/"(?:( + [^"%!^]*+ + (?: + (?: !LF! | "(?:\\^[%!^])?+" ) + [^"%!^]*+ + )++ + ) | [^"]*+ )"/x', function ($m) use(&$env, $uid) { + static $varCount = 0; + static $varCache = []; + if (!isset($m[1])) { + return $m[0]; + } + if (isset($varCache[$m[0]])) { + return $varCache[$m[0]]; + } + if (\strpos($value = $m[1], "\x00") !== \false) { + $value = \str_replace("\x00", '?', $value); + } + if (\false === \strpbrk($value, "\"%!\n")) { + return '"' . $value . '"'; + } + $value = \str_replace(['!LF!', '"^!"', '"^%"', '"^^"', '""'], ["\n", '!', '%', '^', '"'], $value); + $value = '"' . \preg_replace('/(\\\\*)"/', '$1$1\\"', $value) . '"'; + $var = $uid . ++$varCount; + $env[$var] = $value; + return $varCache[$m[0]] = '!' . $var . '!'; + }, $cmd); + $cmd = 'cmd /V:ON /E:ON /D /C (' . \str_replace("\n", ' ', $cmd) . ')'; + foreach ($this->processPipes->getFiles() as $offset => $filename) { + $cmd .= ' ' . $offset . '>"' . $filename . '"'; + } + return $cmd; + } + /** + * Ensures the process is running or terminated, throws a LogicException if the process has a not started. + * + * @throws LogicException if the process has not run + */ + private function requireProcessIsStarted(string $functionName) : void + { + if (!$this->isStarted()) { + throw new LogicException(\sprintf('Process must be started before calling "%s()".', $functionName)); + } + } + /** + * Ensures the process is terminated, throws a LogicException if the process has a status different than "terminated". + * + * @throws LogicException if the process is not yet terminated + */ + private function requireProcessIsTerminated(string $functionName) : void + { + if (!$this->isTerminated()) { + throw new LogicException(\sprintf('Process must be terminated before calling "%s()".', $functionName)); + } + } + /** + * Escapes a string to be used as a shell argument. + */ + private function escapeArgument(?string $argument) : string + { + if ('' === $argument || null === $argument) { + return '""'; + } + if ('\\' !== \DIRECTORY_SEPARATOR) { + return "'" . \str_replace("'", "'\\''", $argument) . "'"; + } + if (\strpos($argument, "\x00") !== \false) { + $argument = \str_replace("\x00", '?', $argument); + } + if (!\preg_match('/[\\/()%!^"<>&|\\s]/', $argument)) { + return $argument; + } + $argument = \preg_replace('/(\\\\+)$/', '$1$1', $argument); + return '"' . \str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument) . '"'; + } + private function replacePlaceholders(string $commandline, array $env) : string + { + return \preg_replace_callback('/"\\$\\{:([_a-zA-Z]++[_a-zA-Z0-9]*+)\\}"/', function ($matches) use($commandline, $env) { + if (!isset($env[$matches[1]]) || \false === $env[$matches[1]]) { + throw new InvalidArgumentException(\sprintf('Command line is missing a value for parameter "%s": ', $matches[1]) . $commandline); + } + return $this->escapeArgument($env[$matches[1]]); + }, $commandline); + } + private function getDefaultEnv() : array + { + $env = \getenv(); + $env = ('\\' === \DIRECTORY_SEPARATOR ? \array_intersect_ukey($env, $_SERVER, 'strcasecmp') : \array_intersect_key($env, $_SERVER)) ?: $env; + return $_ENV + ('\\' === \DIRECTORY_SEPARATOR ? \array_diff_ukey($env, $_ENV, 'strcasecmp') : $env); + } +} diff --git a/vendor/symfony/process/ProcessUtils.php b/vendor/symfony/process/ProcessUtils.php new file mode 100644 index 0000000000..90988f25f8 --- /dev/null +++ b/vendor/symfony/process/ProcessUtils.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\Process; + +use MonorepoBuilderPrefix202310\Symfony\Component\Process\Exception\InvalidArgumentException; +/** + * ProcessUtils is a bunch of utility methods. + * + * This class contains static methods only and is not meant to be instantiated. + * + * @author Martin Hasoň + */ +class ProcessUtils +{ + /** + * This class should not be instantiated. + */ + private function __construct() + { + } + /** + * Validates and normalizes a Process input. + * + * @param string $caller The name of method call that validates the input + * @param mixed $input The input to validate + * + * @throws InvalidArgumentException In case the input is not valid + * @return mixed + */ + public static function validateInput(string $caller, $input) + { + if (null !== $input) { + if (\is_resource($input)) { + return $input; + } + if (\is_string($input)) { + return $input; + } + if (\is_scalar($input)) { + return (string) $input; + } + if ($input instanceof Process) { + return $input->getIterator($input::ITER_SKIP_ERR); + } + if ($input instanceof \Iterator) { + return $input; + } + if ($input instanceof \Traversable) { + return new \IteratorIterator($input); + } + throw new InvalidArgumentException(\sprintf('"%s" only accepts strings, Traversable objects or stream resources.', $caller)); + } + return $input; + } +} diff --git a/vendor/symfony/process/README.md b/vendor/symfony/process/README.md new file mode 100644 index 0000000000..afce5e45ee --- /dev/null +++ b/vendor/symfony/process/README.md @@ -0,0 +1,13 @@ +Process Component +================= + +The Process component executes commands in sub-processes. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/process.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/process/composer.json b/vendor/symfony/process/composer.json new file mode 100644 index 0000000000..dcecfb7cbc --- /dev/null +++ b/vendor/symfony/process/composer.json @@ -0,0 +1,30 @@ +{ + "name": "symfony\/process", + "type": "library", + "description": "Executes commands in sub-processes", + "keywords": [], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/vendor/symfony/service-contracts/Attribute/Required.php b/vendor/symfony/service-contracts/Attribute/Required.php new file mode 100644 index 0000000000..9d362c3798 --- /dev/null +++ b/vendor/symfony/service-contracts/Attribute/Required.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Attribute; + +/** + * A required dependency. + * + * This attribute indicates that a property holds a required dependency. The annotated property or method should be + * considered during the instantiation process of the containing class. + * + * @author Alexander M. Turek + */ +#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)] +final class Required +{ +} diff --git a/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/vendor/symfony/service-contracts/Attribute/SubscribedService.php new file mode 100644 index 0000000000..a120d244ca --- /dev/null +++ b/vendor/symfony/service-contracts/Attribute/SubscribedService.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Attribute; + +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceSubscriberInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceSubscriberTrait; +/** + * For use as the return value for {@see ServiceSubscriberInterface}. + * + * @example new SubscribedService('http_client', HttpClientInterface::class, false, new Target('githubApi')) + * + * Use with {@see ServiceSubscriberTrait} to mark a method's return type + * as a subscribed service. + * + * @author Kevin Bond + */ +#[\Attribute(\Attribute::TARGET_METHOD)] +final class SubscribedService +{ + /** + * @var string|null + */ + public $key; + /** + * @var class-string|null + */ + public $type; + /** + * @var bool + */ + public $nullable = \false; + /** @var object[] */ + public $attributes; + /** + * @param string|null $key The key to use for the service + * @param class-string|null $type The service class + * @param bool $nullable Whether the service is optional + * @param object|object[] $attributes One or more dependency injection attributes to use + */ + public function __construct(?string $key = null, ?string $type = null, bool $nullable = \false, $attributes = []) + { + $this->key = $key; + $this->type = $type; + $this->nullable = $nullable; + $this->attributes = \is_array($attributes) ? $attributes : [$attributes]; + } +} diff --git a/vendor/symfony/service-contracts/CHANGELOG.md b/vendor/symfony/service-contracts/CHANGELOG.md new file mode 100644 index 0000000000..7932e26132 --- /dev/null +++ b/vendor/symfony/service-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/vendor/symfony/service-contracts/LICENSE b/vendor/symfony/service-contracts/LICENSE new file mode 100644 index 0000000000..7536caeae8 --- /dev/null +++ b/vendor/symfony/service-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/service-contracts/README.md b/vendor/symfony/service-contracts/README.md new file mode 100644 index 0000000000..42841a57d0 --- /dev/null +++ b/vendor/symfony/service-contracts/README.md @@ -0,0 +1,9 @@ +Symfony Service Contracts +========================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/main/README.md for more information. diff --git a/vendor/symfony/service-contracts/ResetInterface.php b/vendor/symfony/service-contracts/ResetInterface.php new file mode 100644 index 0000000000..fb98da4b0a --- /dev/null +++ b/vendor/symfony/service-contracts/ResetInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service; + +/** + * Provides a way to reset an object to its initial state. + * + * When calling the "reset()" method on an object, it should be put back to its + * initial state. This usually means clearing any internal buffers and forwarding + * the call to internal dependencies. All properties of the object should be put + * back to the same state it had when it was first ready to use. + * + * This method could be called, for example, to recycle objects that are used as + * services, so that they can be used to handle several requests in the same + * process loop (note that we advise making your services stateless instead of + * implementing this interface when possible.) + */ +interface ResetInterface +{ + /** + * @return void + */ + public function reset(); +} diff --git a/vendor/symfony/service-contracts/ServiceLocatorTrait.php b/vendor/symfony/service-contracts/ServiceLocatorTrait.php new file mode 100644 index 0000000000..60d1fdf30c --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceLocatorTrait.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerExceptionInterface; +use MonorepoBuilderPrefix202310\Psr\Container\NotFoundExceptionInterface; +// Help opcache.preload discover always-needed symbols +\class_exists(ContainerExceptionInterface::class); +\class_exists(NotFoundExceptionInterface::class); +/** + * A trait to help implement ServiceProviderInterface. + * + * @author Robin Chalas + * @author Nicolas Grekas + */ +trait ServiceLocatorTrait +{ + /** + * @var mixed[] + */ + private $factories; + /** + * @var mixed[] + */ + private $loading = []; + /** + * @var mixed[] + */ + private $providedTypes; + /** + * @param callable[] $factories + */ + public function __construct(array $factories) + { + $this->factories = $factories; + } + public function has(string $id) : bool + { + return isset($this->factories[$id]); + } + /** + * @return mixed + */ + public function get(string $id) + { + if (!isset($this->factories[$id])) { + throw $this->createNotFoundException($id); + } + if (isset($this->loading[$id])) { + $ids = \array_values($this->loading); + $ids = \array_slice($this->loading, \array_search($id, $ids)); + $ids[] = $id; + throw $this->createCircularReferenceException($id, $ids); + } + $this->loading[$id] = $id; + try { + return $this->factories[$id]($this); + } finally { + unset($this->loading[$id]); + } + } + public function getProvidedServices() : array + { + if (!isset($this->providedTypes)) { + $this->providedTypes = []; + foreach ($this->factories as $name => $factory) { + if (!\is_callable($factory)) { + $this->providedTypes[$name] = '?'; + } else { + $type = (new \ReflectionFunction($factory))->getReturnType(); + $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '') . ($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?'; + } + } + } + return $this->providedTypes; + } + private function createNotFoundException(string $id) : NotFoundExceptionInterface + { + if (!($alternatives = \array_keys($this->factories))) { + $message = 'is empty...'; + } else { + $last = \array_pop($alternatives); + if ($alternatives) { + $message = \sprintf('only knows about the "%s" and "%s" services.', \implode('", "', $alternatives), $last); + } else { + $message = \sprintf('only knows about the "%s" service.', $last); + } + } + if ($this->loading) { + $message = \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', \end($this->loading), $id, $message); + } else { + $message = \sprintf('Service "%s" not found: the current service locator %s', $id, $message); + } + return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface + { + }; + } + private function createCircularReferenceException(string $id, array $path) : ContainerExceptionInterface + { + return new class(\sprintf('Circular reference detected for service "%s", path: "%s".', $id, \implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface + { + }; + } +} diff --git a/vendor/symfony/service-contracts/ServiceProviderInterface.php b/vendor/symfony/service-contracts/ServiceProviderInterface.php new file mode 100644 index 0000000000..1aa0316b10 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceProviderInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface; +/** + * A ServiceProviderInterface exposes the identifiers and the types of services provided by a container. + * + * @author Nicolas Grekas + * @author Mateusz Sip + * + * @template-covariant T of mixed + */ +interface ServiceProviderInterface extends ContainerInterface +{ + /** + * @return T + */ + public function get(string $id); + public function has(string $id) : bool; + /** + * Returns an associative array of service types keyed by the identifiers provided by the current container. + * + * Examples: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface + * * ['foo' => '?'] means the container provides service name "foo" of unspecified type + * * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null + * + * @return string[] The provided service types, keyed by service names + */ + public function getProvidedServices() : array; +} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberInterface.php b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php new file mode 100644 index 0000000000..02ee36abfd --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service; + +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Attribute\SubscribedService; +/** + * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method. + * + * The getSubscribedServices method returns an array of service types required by such instances, + * optionally keyed by the service names used internally. Service types that start with an interrogation + * mark "?" are optional, while the other ones are mandatory service dependencies. + * + * The injected service locators SHOULD NOT allow access to any other services not specified by the method. + * + * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally. + * This interface does not dictate any injection method for these service locators, although constructor + * injection is recommended. + * + * @author Nicolas Grekas + */ +interface ServiceSubscriberInterface +{ + /** + * Returns an array of service types (or {@see SubscribedService} objects) required + * by such instances, optionally keyed by the service names used internally. + * + * For mandatory dependencies: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name + * internally to fetch a service which must implement Psr\Log\LoggerInterface. + * * ['loggers' => 'Psr\Log\LoggerInterface[]'] means the objects use the "loggers" name + * internally to fetch an iterable of Psr\Log\LoggerInterface instances. + * * ['Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface'] + * + * otherwise: + * + * * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency + * * ['loggers' => '?Psr\Log\LoggerInterface[]'] denotes an optional iterable dependency + * * ['?Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface'] + * + * additionally, an array of {@see SubscribedService}'s can be returned: + * + * * [new SubscribedService('logger', Psr\Log\LoggerInterface::class)] + * * [new SubscribedService(type: Psr\Log\LoggerInterface::class, nullable: true)] + * * [new SubscribedService('http_client', HttpClientInterface::class, attributes: new Target('githubApi'))] + * + * @return string[]|SubscribedService[] The required service types, optionally keyed by service names + */ + public static function getSubscribedServices() : array; +} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php new file mode 100644 index 0000000000..4426a3896b --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service; + +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Attribute\Required; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Attribute\SubscribedService; +/** + * Implementation of ServiceSubscriberInterface that determines subscribed services from + * method return types. Service ids are available as "ClassName::methodName". + * + * @author Kevin Bond + */ +trait ServiceSubscriberTrait +{ + /** @var ContainerInterface */ + protected $container; + public static function getSubscribedServices() : array + { + $services = \method_exists(\get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + if (!($attribute = (\method_exists($method, 'getAttributes') ? $method->getAttributes(SubscribedService::class) : [])[0] ?? null)) { + continue; + } + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + throw new \LogicException(\sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); + } + if (!($returnType = $method->getReturnType())) { + throw new \LogicException(\sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); + } + /* @var SubscribedService $attribute */ + $attribute = $attribute->newInstance(); + $attribute->key = $attribute->key ?? self::class . '::' . $method->name; + $attribute->type = $attribute->type ?? ($returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType); + $attribute->nullable = $returnType->allowsNull(); + if ($attribute->attributes) { + $services[] = $attribute; + } else { + $services[$attribute->key] = ($attribute->nullable ? '?' : '') . $attribute->type; + } + } + return $services; + } + /** + * @required + */ + public function setContainer(ContainerInterface $container) : ?ContainerInterface + { + $ret = null; + if (\method_exists(\get_parent_class(self::class) ?: '', __FUNCTION__)) { + $ret = parent::setContainer($container); + } + $this->container = $container; + return $ret; + } +} diff --git a/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php new file mode 100644 index 0000000000..ccb8801cb4 --- /dev/null +++ b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Test; + +\class_alias(ServiceLocatorTestCase::class, ServiceLocatorTest::class); +if (\false) { + /** + * @deprecated since PHPUnit 9.6 + */ + class ServiceLocatorTest + { + } +} diff --git a/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php b/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php new file mode 100644 index 0000000000..51992fd446 --- /dev/null +++ b/vendor/symfony/service-contracts/Test/ServiceLocatorTestCase.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Contracts\Service\Test; + +use MonorepoBuilderPrefix202310\PHPUnit\Framework\TestCase; +use MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Service\ServiceLocatorTrait; +abstract class ServiceLocatorTestCase extends TestCase +{ + protected function getServiceLocator(array $factories) : ContainerInterface + { + return new class($factories) implements ContainerInterface + { + use ServiceLocatorTrait; + }; + } + public function testHas() + { + $locator = $this->getServiceLocator(['foo' => function () { + return 'bar'; + }, 'bar' => function () { + return 'baz'; + }, function () { + return 'dummy'; + }]); + $this->assertTrue($locator->has('foo')); + $this->assertTrue($locator->has('bar')); + $this->assertFalse($locator->has('dummy')); + } + public function testGet() + { + $locator = $this->getServiceLocator(['foo' => function () { + return 'bar'; + }, 'bar' => function () { + return 'baz'; + }]); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('baz', $locator->get('bar')); + } + public function testGetDoesNotMemoize() + { + $i = 0; + $locator = $this->getServiceLocator(['foo' => function () use(&$i) { + ++$i; + return 'bar'; + }]); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame(2, $i); + } + public function testThrowsOnUndefinedInternalService() + { + if (!$this->getExpectedException()) { + $this->expectException(\MonorepoBuilderPrefix202310\Psr\Container\NotFoundExceptionInterface::class); + $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.'); + } + $locator = $this->getServiceLocator(['foo' => function () use(&$locator) { + return $locator->get('bar'); + }]); + $locator->get('foo'); + } + public function testThrowsOnCircularReference() + { + $this->expectException(\MonorepoBuilderPrefix202310\Psr\Container\ContainerExceptionInterface::class); + $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".'); + $locator = $this->getServiceLocator(['foo' => function () use(&$locator) { + return $locator->get('bar'); + }, 'bar' => function () use(&$locator) { + return $locator->get('baz'); + }, 'baz' => function () use(&$locator) { + return $locator->get('bar'); + }]); + $locator->get('foo'); + } +} diff --git a/vendor/symfony/service-contracts/composer.json b/vendor/symfony/service-contracts/composer.json new file mode 100644 index 0000000000..3bdef8264b --- /dev/null +++ b/vendor/symfony/service-contracts/composer.json @@ -0,0 +1,50 @@ +{ + "name": "symfony\/service-contracts", + "type": "library", + "description": "Generic abstractions related to writing services", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1", + "psr\/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "\/Test\/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony\/contracts", + "url": "https:\/\/github.com\/symfony\/contracts" + } + } +} \ No newline at end of file diff --git a/vendor/symfony/string/AbstractString.php b/vendor/symfony/string/AbstractString.php new file mode 100644 index 0000000000..2f5f20f26d --- /dev/null +++ b/vendor/symfony/string/AbstractString.php @@ -0,0 +1,646 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String; + +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\RuntimeException; +/** + * Represents a string of abstract characters. + * + * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters). + * This class is the abstract type to use as a type-hint when the logic you want to + * implement doesn't care about the exact variant it deals with. + * + * @author Nicolas Grekas + * @author Hugo Hamon + * + * @throws ExceptionInterface + */ +abstract class AbstractString implements \JsonSerializable +{ + public const PREG_PATTERN_ORDER = \PREG_PATTERN_ORDER; + public const PREG_SET_ORDER = \PREG_SET_ORDER; + public const PREG_OFFSET_CAPTURE = \PREG_OFFSET_CAPTURE; + public const PREG_UNMATCHED_AS_NULL = \PREG_UNMATCHED_AS_NULL; + public const PREG_SPLIT = 0; + public const PREG_SPLIT_NO_EMPTY = \PREG_SPLIT_NO_EMPTY; + public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE; + public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE; + protected $string = ''; + protected $ignoreCase = \false; + public abstract function __construct(string $string = ''); + /** + * Unwraps instances of AbstractString back to strings. + * + * @return string[]|array + */ + public static function unwrap(array $values) : array + { + foreach ($values as $k => $v) { + if ($v instanceof self) { + $values[$k] = $v->__toString(); + } elseif (\is_array($v) && $values[$k] !== ($v = static::unwrap($v))) { + $values[$k] = $v; + } + } + return $values; + } + /** + * Wraps (and normalizes) strings in instances of AbstractString. + * + * @return static[]|array + */ + public static function wrap(array $values) : array + { + $i = 0; + $keys = null; + foreach ($values as $k => $v) { + if (\is_string($k) && '' !== $k && $k !== ($j = (string) new static($k))) { + $keys = $keys ?? \array_keys($values); + $keys[$i] = $j; + } + if (\is_string($v)) { + $values[$k] = new static($v); + } elseif (\is_array($v) && $values[$k] !== ($v = static::wrap($v))) { + $values[$k] = $v; + } + ++$i; + } + return null !== $keys ? \array_combine($keys, $values) : $values; + } + /** + * @param string|string[] $needle + * @return static + */ + public function after($needle, bool $includeNeedle = \false, int $offset = 0) + { + $str = clone $this; + $i = \PHP_INT_MAX; + if (\is_string($needle)) { + $needle = [$needle]; + } + foreach ($needle as $n) { + $n = (string) $n; + $j = $this->indexOf($n, $offset); + if (null !== $j && $j < $i) { + $i = $j; + $str->string = $n; + } + } + if (\PHP_INT_MAX === $i) { + return $str; + } + if (!$includeNeedle) { + $i += $str->length(); + } + return $this->slice($i); + } + /** + * @param string|string[] $needle + * @return static + */ + public function afterLast($needle, bool $includeNeedle = \false, int $offset = 0) + { + $str = clone $this; + $i = null; + if (\is_string($needle)) { + $needle = [$needle]; + } + foreach ($needle as $n) { + $n = (string) $n; + $j = $this->indexOfLast($n, $offset); + if (null !== $j && $j >= $i) { + $i = $offset = $j; + $str->string = $n; + } + } + if (null === $i) { + return $str; + } + if (!$includeNeedle) { + $i += $str->length(); + } + return $this->slice($i); + } + /** + * @return static + */ + public abstract function append(string ...$suffix); + /** + * @param string|string[] $needle + * @return static + */ + public function before($needle, bool $includeNeedle = \false, int $offset = 0) + { + $str = clone $this; + $i = \PHP_INT_MAX; + if (\is_string($needle)) { + $needle = [$needle]; + } + foreach ($needle as $n) { + $n = (string) $n; + $j = $this->indexOf($n, $offset); + if (null !== $j && $j < $i) { + $i = $j; + $str->string = $n; + } + } + if (\PHP_INT_MAX === $i) { + return $str; + } + if ($includeNeedle) { + $i += $str->length(); + } + return $this->slice(0, $i); + } + /** + * @param string|string[] $needle + * @return static + */ + public function beforeLast($needle, bool $includeNeedle = \false, int $offset = 0) + { + $str = clone $this; + $i = null; + if (\is_string($needle)) { + $needle = [$needle]; + } + foreach ($needle as $n) { + $n = (string) $n; + $j = $this->indexOfLast($n, $offset); + if (null !== $j && $j >= $i) { + $i = $offset = $j; + $str->string = $n; + } + } + if (null === $i) { + return $str; + } + if ($includeNeedle) { + $i += $str->length(); + } + return $this->slice(0, $i); + } + /** + * @return int[] + */ + public function bytesAt(int $offset) : array + { + $str = $this->slice($offset, 1); + return '' === $str->string ? [] : \array_values(\unpack('C*', $str->string)); + } + /** + * @return static + */ + public abstract function camel(); + /** + * @return static[] + */ + public abstract function chunk(int $length = 1) : array; + /** + * @return static + */ + public function collapseWhitespace() + { + $str = clone $this; + $str->string = \trim(\preg_replace("/(?:[ \n\r\t\f]{2,}+|[\n\r\t\f])/", ' ', $str->string), " \n\r\t\f"); + return $str; + } + /** + * @param string|string[] $needle + */ + public function containsAny($needle) : bool + { + return null !== $this->indexOf($needle); + } + /** + * @param string|string[] $suffix + */ + public function endsWith($suffix) : bool + { + if (\is_string($suffix)) { + throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); + } + foreach ($suffix as $s) { + if ($this->endsWith((string) $s)) { + return \true; + } + } + return \false; + } + /** + * @return static + */ + public function ensureEnd(string $suffix) + { + if (!$this->endsWith($suffix)) { + return $this->append($suffix); + } + $suffix = \preg_quote($suffix); + $regex = '{(' . $suffix . ')(?:' . $suffix . ')++$}D'; + return $this->replaceMatches($regex . ($this->ignoreCase ? 'i' : ''), '$1'); + } + /** + * @return static + */ + public function ensureStart(string $prefix) + { + $prefix = new static($prefix); + if (!$this->startsWith($prefix)) { + return $this->prepend($prefix); + } + $str = clone $this; + $i = $prefixLen = $prefix->length(); + while ($this->indexOf($prefix, $i) === $i) { + $str = $str->slice($prefixLen); + $i += $prefixLen; + } + return $str; + } + /** + * @param string|string[] $string + */ + public function equalsTo($string) : bool + { + if (\is_string($string)) { + throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); + } + foreach ($string as $s) { + if ($this->equalsTo((string) $s)) { + return \true; + } + } + return \false; + } + /** + * @return static + */ + public abstract function folded(); + /** + * @return static + */ + public function ignoreCase() + { + $str = clone $this; + $str->ignoreCase = \true; + return $str; + } + /** + * @param string|string[] $needle + */ + public function indexOf($needle, int $offset = 0) : ?int + { + if (\is_string($needle)) { + throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); + } + $i = \PHP_INT_MAX; + foreach ($needle as $n) { + $j = $this->indexOf((string) $n, $offset); + if (null !== $j && $j < $i) { + $i = $j; + } + } + return \PHP_INT_MAX === $i ? null : $i; + } + /** + * @param string|string[] $needle + */ + public function indexOfLast($needle, int $offset = 0) : ?int + { + if (\is_string($needle)) { + throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); + } + $i = null; + foreach ($needle as $n) { + $j = $this->indexOfLast((string) $n, $offset); + if (null !== $j && $j >= $i) { + $i = $offset = $j; + } + } + return $i; + } + public function isEmpty() : bool + { + return '' === $this->string; + } + /** + * @return static + */ + public abstract function join(array $strings, string $lastGlue = null); + public function jsonSerialize() : string + { + return $this->string; + } + public abstract function length() : int; + /** + * @return static + */ + public abstract function lower(); + /** + * Matches the string using a regular expression. + * + * Pass PREG_PATTERN_ORDER or PREG_SET_ORDER as $flags to get all occurrences matching the regular expression. + * + * @return array All matches in a multi-dimensional array ordered according to flags + */ + public abstract function match(string $regexp, int $flags = 0, int $offset = 0) : array; + /** + * @return static + */ + public abstract function padBoth(int $length, string $padStr = ' '); + /** + * @return static + */ + public abstract function padEnd(int $length, string $padStr = ' '); + /** + * @return static + */ + public abstract function padStart(int $length, string $padStr = ' '); + /** + * @return static + */ + public abstract function prepend(string ...$prefix); + /** + * @return static + */ + public function repeat(int $multiplier) + { + if (0 > $multiplier) { + throw new InvalidArgumentException(\sprintf('Multiplier must be positive, %d given.', $multiplier)); + } + $str = clone $this; + $str->string = \str_repeat($str->string, $multiplier); + return $str; + } + /** + * @return static + */ + public abstract function replace(string $from, string $to); + /** + * @param string|callable $to + * @return static + */ + public abstract function replaceMatches(string $fromRegexp, $to); + /** + * @return static + */ + public abstract function reverse(); + /** + * @return static + */ + public abstract function slice(int $start = 0, int $length = null); + /** + * @return static + */ + public abstract function snake(); + /** + * @return static + */ + public abstract function splice(string $replacement, int $start = 0, int $length = null); + /** + * @return static[] + */ + public function split(string $delimiter, int $limit = null, int $flags = null) : array + { + if (null === $flags) { + throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.'); + } + if ($this->ignoreCase) { + $delimiter .= 'i'; + } + \set_error_handler(static function ($t, $m) { + throw new InvalidArgumentException($m); + }); + try { + if (\false === ($chunks = \preg_split($delimiter, $this->string, $limit, $flags))) { + throw new RuntimeException('Splitting failed with error: ' . \preg_last_error_msg()); + } + } finally { + \restore_error_handler(); + } + $str = clone $this; + if (self::PREG_SPLIT_OFFSET_CAPTURE & $flags) { + foreach ($chunks as &$chunk) { + $str->string = $chunk[0]; + $chunk[0] = clone $str; + } + } else { + foreach ($chunks as &$chunk) { + $str->string = $chunk; + $chunk = clone $str; + } + } + return $chunks; + } + /** + * @param string|string[] $prefix + */ + public function startsWith($prefix) : bool + { + if (\is_string($prefix)) { + throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class)); + } + foreach ($prefix as $prefix) { + if ($this->startsWith((string) $prefix)) { + return \true; + } + } + return \false; + } + /** + * @return static + */ + public abstract function title(bool $allWords = \false); + public function toByteString(string $toEncoding = null) : ByteString + { + $b = new ByteString(); + $toEncoding = \in_array($toEncoding, ['utf8', 'utf-8', 'UTF8'], \true) ? 'UTF-8' : $toEncoding; + if (null === $toEncoding || $toEncoding === ($fromEncoding = $this instanceof AbstractUnicodeString || \preg_match('//u', $b->string) ? 'UTF-8' : 'Windows-1252')) { + $b->string = $this->string; + return $b; + } + \set_error_handler(static function ($t, $m) { + throw new InvalidArgumentException($m); + }); + try { + try { + $b->string = \mb_convert_encoding($this->string, $toEncoding, 'UTF-8'); + } catch (InvalidArgumentException $e) { + if (!\function_exists('iconv')) { + throw $e; + } + $b->string = \iconv('UTF-8', $toEncoding, $this->string); + } + } finally { + \restore_error_handler(); + } + return $b; + } + public function toCodePointString() : CodePointString + { + return new CodePointString($this->string); + } + public function toString() : string + { + return $this->string; + } + public function toUnicodeString() : UnicodeString + { + return new UnicodeString($this->string); + } + /** + * @return static + */ + public abstract function trim(string $chars = " \t\n\r\x00\v\f "); + /** + * @return static + */ + public abstract function trimEnd(string $chars = " \t\n\r\x00\v\f "); + /** + * @param string|string[] $prefix + * @return static + */ + public function trimPrefix($prefix) + { + if (\is_array($prefix) || $prefix instanceof \Traversable) { + // don't use is_iterable(), it's slow + foreach ($prefix as $s) { + $t = $this->trimPrefix($s); + if ($t->string !== $this->string) { + return $t; + } + } + return clone $this; + } + $str = clone $this; + if ($prefix instanceof self) { + $prefix = $prefix->string; + } else { + $prefix = (string) $prefix; + } + if ('' !== $prefix && \strlen($this->string) >= \strlen($prefix) && 0 === \substr_compare($this->string, $prefix, 0, \strlen($prefix), $this->ignoreCase)) { + $str->string = \substr($this->string, \strlen($prefix)); + } + return $str; + } + /** + * @return static + */ + public abstract function trimStart(string $chars = " \t\n\r\x00\v\f "); + /** + * @param string|string[] $suffix + * @return static + */ + public function trimSuffix($suffix) + { + if (\is_array($suffix) || $suffix instanceof \Traversable) { + // don't use is_iterable(), it's slow + foreach ($suffix as $s) { + $t = $this->trimSuffix($s); + if ($t->string !== $this->string) { + return $t; + } + } + return clone $this; + } + $str = clone $this; + if ($suffix instanceof self) { + $suffix = $suffix->string; + } else { + $suffix = (string) $suffix; + } + if ('' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase)) { + $str->string = \substr($this->string, 0, -\strlen($suffix)); + } + return $str; + } + /** + * @return static + */ + public function truncate(int $length, string $ellipsis = '', bool $cut = \true) + { + $stringLength = $this->length(); + if ($stringLength <= $length) { + return clone $this; + } + $ellipsisLength = '' !== $ellipsis ? (new static($ellipsis))->length() : 0; + if ($length < $ellipsisLength) { + $ellipsisLength = 0; + } + if (!$cut) { + if (null === ($length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1))) { + return clone $this; + } + $length += $ellipsisLength; + } + $str = $this->slice(0, $length - $ellipsisLength); + return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str; + } + /** + * @return static + */ + public abstract function upper(); + /** + * Returns the printable length on a terminal. + */ + public abstract function width(bool $ignoreAnsiDecoration = \true) : int; + /** + * @return static + */ + public function wordwrap(int $width = 75, string $break = "\n", bool $cut = \false) + { + $lines = '' !== $break ? $this->split($break) : [clone $this]; + $chars = []; + $mask = ''; + if (1 === \count($lines) && '' === $lines[0]->string) { + return $lines[0]; + } + foreach ($lines as $i => $line) { + if ($i) { + $chars[] = $break; + $mask .= '#'; + } + foreach ($line->chunk() as $char) { + $chars[] = $char->string; + $mask .= ' ' === $char->string ? ' ' : '?'; + } + } + $string = ''; + $j = 0; + $b = $i = -1; + $mask = \wordwrap($mask, $width, '#', $cut); + while (\false !== ($b = \strpos($mask, '#', $b + 1))) { + for (++$i; $i < $b; ++$i) { + $string .= $chars[$j]; + unset($chars[$j++]); + } + if ($break === $chars[$j] || ' ' === $chars[$j]) { + unset($chars[$j++]); + } + $string .= $break; + } + $str = clone $this; + $str->string = $string . \implode('', $chars); + return $str; + } + public function __sleep() : array + { + return ['string']; + } + public function __clone() + { + $this->ignoreCase = \false; + } + public function __toString() : string + { + return $this->string; + } +} diff --git a/vendor/symfony/string/AbstractUnicodeString.php b/vendor/symfony/string/AbstractUnicodeString.php new file mode 100644 index 0000000000..d6ebfbca67 --- /dev/null +++ b/vendor/symfony/string/AbstractUnicodeString.php @@ -0,0 +1,523 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String; + +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\RuntimeException; +/** + * Represents a string of abstract Unicode characters. + * + * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters). + * This class is the abstract type to use as a type-hint when the logic you want to + * implement is Unicode-aware but doesn't care about code points vs grapheme clusters. + * + * @author Nicolas Grekas + * + * @throws ExceptionInterface + */ +abstract class AbstractUnicodeString extends AbstractString +{ + public const NFC = \Normalizer::NFC; + public const NFD = \Normalizer::NFD; + public const NFKC = \Normalizer::NFKC; + public const NFKD = \Normalizer::NFKD; + // all ASCII letters sorted by typical frequency of occurrence + private const ASCII = " eiasntrolud][cmp'\ng|hv.fb,:=-q10C2*yx)(L9AS/P\"EjMIk3>5T>', '<', '>', '-', '-', '-', '-', '-', '-', '-', '-', '-', '||', '/', '[', ']', '*', ',', '.', '<', '>', '<<', '>>', '[', ']', '[', ']', '[', ']', ',', '.', '[', ']', '<<', '>>', '<', '>', ',', '[', ']', '((', '))', '.', ',', '*', '/', '-', '/', '\\', '|', '||', '<<', '>>', '((', '))']; + private static $transliterators = []; + private static $tableZero; + private static $tableWide; + /** + * @return static + */ + public static function fromCodePoints(int ...$codes) + { + $string = ''; + foreach ($codes as $code) { + if (0x80 > ($code %= 0x200000)) { + $string .= \chr($code); + } elseif (0x800 > $code) { + $string .= \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f); + } elseif (0x10000 > $code) { + $string .= \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } else { + $string .= \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } + } + return new static($string); + } + /** + * Generic UTF-8 to ASCII transliteration. + * + * Install the intl extension for best results. + * + * @param string[]|\Transliterator[]|\Closure[] $rules See "*-Latin" rules from Transliterator::listIDs() + */ + public function ascii(array $rules = []) : self + { + $str = clone $this; + $s = $str->string; + $str->string = ''; + \array_unshift($rules, 'nfd'); + $rules[] = 'latin-ascii'; + if (\function_exists('transliterator_transliterate')) { + $rules[] = 'any-latin/bgn'; + } + $rules[] = 'nfkd'; + $rules[] = '[:nonspacing mark:] remove'; + while (\strlen($s) - 1 > ($i = \strspn($s, self::ASCII))) { + if (0 < --$i) { + $str->string .= \substr($s, 0, $i); + $s = \substr($s, $i); + } + if (!($rule = \array_shift($rules))) { + $rules = []; + // An empty rule interrupts the next ones + } + if ($rule instanceof \Transliterator) { + $s = $rule->transliterate($s); + } elseif ($rule instanceof \Closure) { + $s = $rule($s); + } elseif ($rule) { + if ('nfd' === ($rule = \strtolower($rule))) { + \normalizer_is_normalized($s, self::NFD) ?: ($s = \normalizer_normalize($s, self::NFD)); + } elseif ('nfkd' === $rule) { + \normalizer_is_normalized($s, self::NFKD) ?: ($s = \normalizer_normalize($s, self::NFKD)); + } elseif ('[:nonspacing mark:] remove' === $rule) { + $s = \preg_replace('/\\p{Mn}++/u', '', $s); + } elseif ('latin-ascii' === $rule) { + $s = \str_replace(self::TRANSLIT_FROM, self::TRANSLIT_TO, $s); + } elseif ('de-ascii' === $rule) { + $s = \preg_replace("/([AUO])̈(?=\\p{Ll})/u", '$1e', $s); + $s = \str_replace(["ä", "ö", "ü", "Ä", "Ö", "Ü"], ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'], $s); + } elseif (\function_exists('transliterator_transliterate')) { + if (null === ($transliterator = self::$transliterators[$rule] = self::$transliterators[$rule] ?? \Transliterator::create($rule))) { + if ('any-latin/bgn' === $rule) { + $rule = 'any-latin'; + $transliterator = self::$transliterators[$rule] = self::$transliterators[$rule] ?? \Transliterator::create($rule); + } + if (null === $transliterator) { + throw new InvalidArgumentException(\sprintf('Unknown transliteration rule "%s".', $rule)); + } + self::$transliterators['any-latin/bgn'] = $transliterator; + } + $s = $transliterator->transliterate($s); + } + } elseif (!\function_exists('iconv')) { + $s = \preg_replace('/[^\\x00-\\x7F]/u', '?', $s); + } else { + $s = @\preg_replace_callback('/[^\\x00-\\x7F]/u', static function ($c) { + $c = (string) \iconv('UTF-8', 'ASCII//TRANSLIT', $c[0]); + if ('' === $c && '' === \iconv('UTF-8', 'ASCII//TRANSLIT', '²')) { + throw new \LogicException(\sprintf('"%s" requires a translit-able iconv implementation, try installing "gnu-libiconv" if you\'re using Alpine Linux.', static::class)); + } + return 1 < \strlen($c) ? \ltrim($c, '\'`"^~') : ('' !== $c ? $c : '?'); + }, $s); + } + } + $str->string .= $s; + return $str; + } + /** + * @return static + */ + public function camel() + { + $str = clone $this; + $str->string = \str_replace(' ', '', \preg_replace_callback('/\\b.(?![A-Z]{2,})/u', static function ($m) { + static $i = 0; + return 1 === ++$i ? 'İ' === $m[0] ? 'i̇' : \mb_strtolower($m[0], 'UTF-8') : \mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'); + }, \preg_replace('/[^\\pL0-9]++/u', ' ', $this->string))); + return $str; + } + /** + * @return int[] + */ + public function codePointsAt(int $offset) : array + { + $str = $this->slice($offset, 1); + if ('' === $str->string) { + return []; + } + $codePoints = []; + foreach (\preg_split('//u', $str->string, -1, \PREG_SPLIT_NO_EMPTY) as $c) { + $codePoints[] = \mb_ord($c, 'UTF-8'); + } + return $codePoints; + } + /** + * @return static + */ + public function folded(bool $compat = \true) + { + $str = clone $this; + if (!$compat || !\defined('Normalizer::NFKC_CF')) { + $str->string = \normalizer_normalize($str->string, $compat ? \Normalizer::NFKC : \Normalizer::NFC); + $str->string = \mb_strtolower(\str_replace(self::FOLD_FROM, self::FOLD_TO, $this->string), 'UTF-8'); + } else { + $str->string = \normalizer_normalize($str->string, \Normalizer::NFKC_CF); + } + return $str; + } + /** + * @return static + */ + public function join(array $strings, string $lastGlue = null) + { + $str = clone $this; + $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue . \array_pop($strings) : ''; + $str->string = \implode($this->string, $strings) . $tail; + if (!\preg_match('//u', $str->string)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + return $str; + } + /** + * @return static + */ + public function lower() + { + $str = clone $this; + $str->string = \mb_strtolower(\str_replace('İ', 'i̇', $str->string), 'UTF-8'); + return $str; + } + public function match(string $regexp, int $flags = 0, int $offset = 0) : array + { + $match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match'; + if ($this->ignoreCase) { + $regexp .= 'i'; + } + \set_error_handler(static function ($t, $m) { + throw new InvalidArgumentException($m); + }); + try { + if (\false === $match($regexp . 'u', $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) { + throw new RuntimeException('Matching failed with error: ' . \preg_last_error_msg()); + } + } finally { + \restore_error_handler(); + } + return $matches; + } + /** + * @return static + */ + public function normalize(int $form = self::NFC) + { + if (!\in_array($form, [self::NFC, self::NFD, self::NFKC, self::NFKD])) { + throw new InvalidArgumentException('Unsupported normalization form.'); + } + $str = clone $this; + \normalizer_is_normalized($str->string, $form) ?: ($str->string = \normalizer_normalize($str->string, $form)); + return $str; + } + /** + * @return static + */ + public function padBoth(int $length, string $padStr = ' ') + { + if ('' === $padStr || !\preg_match('//u', $padStr)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + $pad = clone $this; + $pad->string = $padStr; + return $this->pad($length, $pad, \STR_PAD_BOTH); + } + /** + * @return static + */ + public function padEnd(int $length, string $padStr = ' ') + { + if ('' === $padStr || !\preg_match('//u', $padStr)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + $pad = clone $this; + $pad->string = $padStr; + return $this->pad($length, $pad, \STR_PAD_RIGHT); + } + /** + * @return static + */ + public function padStart(int $length, string $padStr = ' ') + { + if ('' === $padStr || !\preg_match('//u', $padStr)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + $pad = clone $this; + $pad->string = $padStr; + return $this->pad($length, $pad, \STR_PAD_LEFT); + } + /** + * @param string|callable $to + * @return static + */ + public function replaceMatches(string $fromRegexp, $to) + { + if ($this->ignoreCase) { + $fromRegexp .= 'i'; + } + if (\is_array($to) || $to instanceof \Closure) { + $replace = 'preg_replace_callback'; + $to = static function (array $m) use($to) : string { + $to = $to($m); + if ('' !== $to && (!\is_string($to) || !\preg_match('//u', $to))) { + throw new InvalidArgumentException('Replace callback must return a valid UTF-8 string.'); + } + return $to; + }; + } elseif ('' !== $to && !\preg_match('//u', $to)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } else { + $replace = 'preg_replace'; + } + \set_error_handler(static function ($t, $m) { + throw new InvalidArgumentException($m); + }); + try { + if (null === ($string = $replace($fromRegexp . 'u', $to, $this->string))) { + $lastError = \preg_last_error(); + foreach (\get_defined_constants(\true)['pcre'] as $k => $v) { + if ($lastError === $v && \substr_compare($k, '_ERROR', -\strlen('_ERROR')) === 0) { + throw new RuntimeException('Matching failed with ' . $k . '.'); + } + } + throw new RuntimeException('Matching failed with unknown error code.'); + } + } finally { + \restore_error_handler(); + } + $str = clone $this; + $str->string = $string; + return $str; + } + /** + * @return static + */ + public function reverse() + { + $str = clone $this; + $str->string = \implode('', \array_reverse(\preg_split('/(\\X)/u', $str->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY))); + return $str; + } + /** + * @return static + */ + public function snake() + { + $str = $this->camel(); + $str->string = \mb_strtolower(\preg_replace(['/(\\p{Lu}+)(\\p{Lu}\\p{Ll})/u', '/([\\p{Ll}0-9])(\\p{Lu})/u'], 'MonorepoBuilderPrefix202310\\1_\\2', $str->string), 'UTF-8'); + return $str; + } + /** + * @return static + */ + public function title(bool $allWords = \false) + { + $str = clone $this; + $limit = $allWords ? -1 : 1; + $str->string = \preg_replace_callback('/\\b./u', static function (array $m) : string { + return \mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8'); + }, $str->string, $limit); + return $str; + } + /** + * @return static + */ + public function trim(string $chars = " \t\n\r\x00\v\f ") + { + if (" \t\n\r\x00\v\f " !== $chars && !\preg_match('//u', $chars)) { + throw new InvalidArgumentException('Invalid UTF-8 chars.'); + } + $chars = \preg_quote($chars); + $str = clone $this; + $str->string = \preg_replace("{^[{$chars}]++|[{$chars}]++\$}uD", '', $str->string); + return $str; + } + /** + * @return static + */ + public function trimEnd(string $chars = " \t\n\r\x00\v\f ") + { + if (" \t\n\r\x00\v\f " !== $chars && !\preg_match('//u', $chars)) { + throw new InvalidArgumentException('Invalid UTF-8 chars.'); + } + $chars = \preg_quote($chars); + $str = clone $this; + $str->string = \preg_replace("{[{$chars}]++\$}uD", '', $str->string); + return $str; + } + /** + * @return static + */ + public function trimPrefix($prefix) + { + if (!$this->ignoreCase) { + return parent::trimPrefix($prefix); + } + $str = clone $this; + if ($prefix instanceof \Traversable) { + $prefix = \iterator_to_array($prefix, \false); + } elseif ($prefix instanceof parent) { + $prefix = $prefix->string; + } + $prefix = \implode('|', \array_map('preg_quote', (array) $prefix)); + $str->string = \preg_replace("{^(?:{$prefix})}iuD", '', $this->string); + return $str; + } + /** + * @return static + */ + public function trimStart(string $chars = " \t\n\r\x00\v\f ") + { + if (" \t\n\r\x00\v\f " !== $chars && !\preg_match('//u', $chars)) { + throw new InvalidArgumentException('Invalid UTF-8 chars.'); + } + $chars = \preg_quote($chars); + $str = clone $this; + $str->string = \preg_replace("{^[{$chars}]++}uD", '', $str->string); + return $str; + } + /** + * @return static + */ + public function trimSuffix($suffix) + { + if (!$this->ignoreCase) { + return parent::trimSuffix($suffix); + } + $str = clone $this; + if ($suffix instanceof \Traversable) { + $suffix = \iterator_to_array($suffix, \false); + } elseif ($suffix instanceof parent) { + $suffix = $suffix->string; + } + $suffix = \implode('|', \array_map('preg_quote', (array) $suffix)); + $str->string = \preg_replace("{(?:{$suffix})\$}iuD", '', $this->string); + return $str; + } + /** + * @return static + */ + public function upper() + { + $str = clone $this; + $str->string = \mb_strtoupper($str->string, 'UTF-8'); + return $str; + } + public function width(bool $ignoreAnsiDecoration = \true) : int + { + $width = 0; + $s = \str_replace(["\x00", "\x05", "\x07"], '', $this->string); + if (\strpos($s, "\r") !== \false) { + $s = \str_replace(["\r\n", "\r"], "\n", $s); + } + if (!$ignoreAnsiDecoration) { + $s = \preg_replace('/[\\p{Cc}\\x7F]++/u', '', $s); + } + foreach (\explode("\n", $s) as $s) { + if ($ignoreAnsiDecoration) { + $s = \preg_replace('/(?:\\x1B(?: + \\[ [\\x30-\\x3F]*+ [\\x20-\\x2F]*+ [\\x40-\\x7E] + | [P\\]X^_] .*? \\x1B\\\\ + | [\\x41-\\x7E] + )|[\\p{Cc}\\x7F]++)/xu', '', $s); + } + $lineWidth = $this->wcswidth($s); + if ($lineWidth > $width) { + $width = $lineWidth; + } + } + return $width; + } + /** + * @return static + */ + private function pad(int $len, self $pad, int $type) + { + $sLen = $this->length(); + if ($len <= $sLen) { + return clone $this; + } + $padLen = $pad->length(); + $freeLen = $len - $sLen; + $len = $freeLen % $padLen; + switch ($type) { + case \STR_PAD_RIGHT: + return $this->append(\str_repeat($pad->string, \intdiv($freeLen, $padLen)) . ($len ? $pad->slice(0, $len) : '')); + case \STR_PAD_LEFT: + return $this->prepend(\str_repeat($pad->string, \intdiv($freeLen, $padLen)) . ($len ? $pad->slice(0, $len) : '')); + case \STR_PAD_BOTH: + $freeLen /= 2; + $rightLen = \ceil($freeLen); + $len = $rightLen % $padLen; + $str = $this->append(\str_repeat($pad->string, \intdiv($rightLen, $padLen)) . ($len ? $pad->slice(0, $len) : '')); + $leftLen = \floor($freeLen); + $len = $leftLen % $padLen; + return $str->prepend(\str_repeat($pad->string, \intdiv($leftLen, $padLen)) . ($len ? $pad->slice(0, $len) : '')); + default: + throw new InvalidArgumentException('Invalid padding type.'); + } + } + /** + * Based on https://github.com/jquast/wcwidth, a Python implementation of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c. + */ + private function wcswidth(string $string) : int + { + $width = 0; + foreach (\preg_split('//u', $string, -1, \PREG_SPLIT_NO_EMPTY) as $c) { + $codePoint = \mb_ord($c, 'UTF-8'); + if (0 === $codePoint || 0x34f === $codePoint || 0x200b <= $codePoint && 0x200f >= $codePoint || 0x2028 === $codePoint || 0x2029 === $codePoint || 0x202a <= $codePoint && 0x202e >= $codePoint || 0x2060 <= $codePoint && 0x2063 >= $codePoint) { + continue; + } + // Non printable characters + if (32 > $codePoint || 0x7f <= $codePoint && 0xa0 > $codePoint) { + return -1; + } + self::$tableZero = self::$tableZero ?? (require __DIR__ . '/Resources/data/wcswidth_table_zero.php'); + if ($codePoint >= self::$tableZero[0][0] && $codePoint <= self::$tableZero[$ubound = \count(self::$tableZero) - 1][1]) { + $lbound = 0; + while ($ubound >= $lbound) { + $mid = \floor(($lbound + $ubound) / 2); + if ($codePoint > self::$tableZero[$mid][1]) { + $lbound = $mid + 1; + } elseif ($codePoint < self::$tableZero[$mid][0]) { + $ubound = $mid - 1; + } else { + continue 2; + } + } + } + self::$tableWide = self::$tableWide ?? (require __DIR__ . '/Resources/data/wcswidth_table_wide.php'); + if ($codePoint >= self::$tableWide[0][0] && $codePoint <= self::$tableWide[$ubound = \count(self::$tableWide) - 1][1]) { + $lbound = 0; + while ($ubound >= $lbound) { + $mid = \floor(($lbound + $ubound) / 2); + if ($codePoint > self::$tableWide[$mid][1]) { + $lbound = $mid + 1; + } elseif ($codePoint < self::$tableWide[$mid][0]) { + $ubound = $mid - 1; + } else { + $width += 2; + continue 2; + } + } + } + ++$width; + } + return $width; + } +} diff --git a/vendor/symfony/string/ByteString.php b/vendor/symfony/string/ByteString.php new file mode 100644 index 0000000000..38f9e01ab9 --- /dev/null +++ b/vendor/symfony/string/ByteString.php @@ -0,0 +1,459 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String; + +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\InvalidArgumentException; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\RuntimeException; +/** + * Represents a binary-safe string of bytes. + * + * @author Nicolas Grekas + * @author Hugo Hamon + * + * @throws ExceptionInterface + */ +class ByteString extends AbstractString +{ + private const ALPHABET_ALPHANUMERIC = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; + public function __construct(string $string = '') + { + $this->string = $string; + } + /* + * The following method was derived from code of the Hack Standard Library (v4.40 - 2020-05-03) + * + * https://github.com/hhvm/hsl/blob/80a42c02f036f72a42f0415e80d6b847f4bf62d5/src/random/private.php#L16 + * + * Code subject to the MIT license (https://github.com/hhvm/hsl/blob/master/LICENSE). + * + * Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/) + */ + public static function fromRandom(int $length = 16, string $alphabet = null) : self + { + if ($length <= 0) { + throw new InvalidArgumentException(\sprintf('A strictly positive length is expected, "%d" given.', $length)); + } + $alphabet = $alphabet ?? self::ALPHABET_ALPHANUMERIC; + $alphabetSize = \strlen($alphabet); + $bits = (int) \ceil(\log($alphabetSize, 2.0)); + if ($bits <= 0 || $bits > 56) { + throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.'); + } + $ret = ''; + while ($length > 0) { + $urandomLength = (int) \ceil(2 * $length * $bits / 8.0); + $data = \random_bytes($urandomLength); + $unpackedData = 0; + $unpackedBits = 0; + for ($i = 0; $i < $urandomLength && $length > 0; ++$i) { + // Unpack 8 bits + $unpackedData = $unpackedData << 8 | \ord($data[$i]); + $unpackedBits += 8; + // While we have enough bits to select a character from the alphabet, keep + // consuming the random data + for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) { + $index = $unpackedData & (1 << $bits) - 1; + $unpackedData >>= $bits; + // Unfortunately, the alphabet size is not necessarily a power of two. + // Worst case, it is 2^k + 1, which means we need (k+1) bits and we + // have around a 50% chance of missing as k gets larger + if ($index < $alphabetSize) { + $ret .= $alphabet[$index]; + --$length; + } + } + } + } + return new static($ret); + } + public function bytesAt(int $offset) : array + { + $str = $this->string[$offset] ?? ''; + return '' === $str ? [] : [\ord($str)]; + } + /** + * @return static + */ + public function append(string ...$suffix) + { + $str = clone $this; + $str->string .= 1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix); + return $str; + } + /** + * @return static + */ + public function camel() + { + $str = clone $this; + $parts = \explode(' ', \trim(\ucwords(\preg_replace('/[^a-zA-Z0-9\\x7f-\\xff]++/', ' ', $this->string)))); + $parts[0] = 1 !== \strlen($parts[0]) && \ctype_upper($parts[0]) ? $parts[0] : \lcfirst($parts[0]); + $str->string = \implode('', $parts); + return $str; + } + public function chunk(int $length = 1) : array + { + if (1 > $length) { + throw new InvalidArgumentException('The chunk length must be greater than zero.'); + } + if ('' === $this->string) { + return []; + } + $str = clone $this; + $chunks = []; + foreach (\str_split($this->string, $length) as $chunk) { + $str->string = $chunk; + $chunks[] = clone $str; + } + return $chunks; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $suffix + */ + public function endsWith($suffix) : bool + { + if ($suffix instanceof AbstractString) { + $suffix = $suffix->string; + } elseif (!\is_string($suffix)) { + return parent::endsWith($suffix); + } + return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase); + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $string + */ + public function equalsTo($string) : bool + { + if ($string instanceof AbstractString) { + $string = $string->string; + } elseif (!\is_string($string)) { + return parent::equalsTo($string); + } + if ('' !== $string && $this->ignoreCase) { + return 0 === \strcasecmp($string, $this->string); + } + return $string === $this->string; + } + /** + * @return static + */ + public function folded() + { + $str = clone $this; + $str->string = \strtolower($str->string); + return $str; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $needle + */ + public function indexOf($needle, int $offset = 0) : ?int + { + if ($needle instanceof AbstractString) { + $needle = $needle->string; + } elseif (!\is_string($needle)) { + return parent::indexOf($needle, $offset); + } + if ('' === $needle) { + return null; + } + $i = $this->ignoreCase ? \stripos($this->string, $needle, $offset) : \strpos($this->string, $needle, $offset); + return \false === $i ? null : $i; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $needle + */ + public function indexOfLast($needle, int $offset = 0) : ?int + { + if ($needle instanceof AbstractString) { + $needle = $needle->string; + } elseif (!\is_string($needle)) { + return parent::indexOfLast($needle, $offset); + } + if ('' === $needle) { + return null; + } + $i = $this->ignoreCase ? \strripos($this->string, $needle, $offset) : \strrpos($this->string, $needle, $offset); + return \false === $i ? null : $i; + } + public function isUtf8() : bool + { + return '' === $this->string || \preg_match('//u', $this->string); + } + /** + * @return static + */ + public function join(array $strings, string $lastGlue = null) + { + $str = clone $this; + $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue . \array_pop($strings) : ''; + $str->string = \implode($this->string, $strings) . $tail; + return $str; + } + public function length() : int + { + return \strlen($this->string); + } + /** + * @return static + */ + public function lower() + { + $str = clone $this; + $str->string = \strtolower($str->string); + return $str; + } + public function match(string $regexp, int $flags = 0, int $offset = 0) : array + { + $match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match'; + if ($this->ignoreCase) { + $regexp .= 'i'; + } + \set_error_handler(static function ($t, $m) { + throw new InvalidArgumentException($m); + }); + try { + if (\false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) { + throw new RuntimeException('Matching failed with error: ' . \preg_last_error_msg()); + } + } finally { + \restore_error_handler(); + } + return $matches; + } + /** + * @return static + */ + public function padBoth(int $length, string $padStr = ' ') + { + $str = clone $this; + $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_BOTH); + return $str; + } + /** + * @return static + */ + public function padEnd(int $length, string $padStr = ' ') + { + $str = clone $this; + $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_RIGHT); + return $str; + } + /** + * @return static + */ + public function padStart(int $length, string $padStr = ' ') + { + $str = clone $this; + $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_LEFT); + return $str; + } + /** + * @return static + */ + public function prepend(string ...$prefix) + { + $str = clone $this; + $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $str->string; + return $str; + } + /** + * @return static + */ + public function replace(string $from, string $to) + { + $str = clone $this; + if ('' !== $from) { + $str->string = $this->ignoreCase ? \str_ireplace($from, $to, $this->string) : \str_replace($from, $to, $this->string); + } + return $str; + } + /** + * @param string|callable $to + * @return static + */ + public function replaceMatches(string $fromRegexp, $to) + { + if ($this->ignoreCase) { + $fromRegexp .= 'i'; + } + $replace = \is_array($to) || $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace'; + \set_error_handler(static function ($t, $m) { + throw new InvalidArgumentException($m); + }); + try { + if (null === ($string = $replace($fromRegexp, $to, $this->string))) { + $lastError = \preg_last_error(); + foreach (\get_defined_constants(\true)['pcre'] as $k => $v) { + if ($lastError === $v && \substr_compare($k, '_ERROR', -\strlen('_ERROR')) === 0) { + throw new RuntimeException('Matching failed with ' . $k . '.'); + } + } + throw new RuntimeException('Matching failed with unknown error code.'); + } + } finally { + \restore_error_handler(); + } + $str = clone $this; + $str->string = $string; + return $str; + } + /** + * @return static + */ + public function reverse() + { + $str = clone $this; + $str->string = \strrev($str->string); + return $str; + } + /** + * @return static + */ + public function slice(int $start = 0, int $length = null) + { + $str = clone $this; + $str->string = (string) \substr($this->string, $start, $length ?? \PHP_INT_MAX); + return $str; + } + /** + * @return static + */ + public function snake() + { + $str = $this->camel(); + $str->string = \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], 'MonorepoBuilderPrefix202310\\1_\\2', $str->string)); + return $str; + } + /** + * @return static + */ + public function splice(string $replacement, int $start = 0, int $length = null) + { + $str = clone $this; + $str->string = \substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX); + return $str; + } + public function split(string $delimiter, int $limit = null, int $flags = null) : array + { + if (1 > ($limit = $limit ?? \PHP_INT_MAX)) { + throw new InvalidArgumentException('Split limit must be a positive integer.'); + } + if ('' === $delimiter) { + throw new InvalidArgumentException('Split delimiter is empty.'); + } + if (null !== $flags) { + return parent::split($delimiter, $limit, $flags); + } + $str = clone $this; + $chunks = $this->ignoreCase ? \preg_split('{' . \preg_quote($delimiter) . '}iD', $this->string, $limit) : \explode($delimiter, $this->string, $limit); + foreach ($chunks as &$chunk) { + $str->string = $chunk; + $chunk = clone $str; + } + return $chunks; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $prefix + */ + public function startsWith($prefix) : bool + { + if ($prefix instanceof AbstractString) { + $prefix = $prefix->string; + } elseif (!\is_string($prefix)) { + return parent::startsWith($prefix); + } + return '' !== $prefix && 0 === ($this->ignoreCase ? \strncasecmp($this->string, $prefix, \strlen($prefix)) : \strncmp($this->string, $prefix, \strlen($prefix))); + } + /** + * @return static + */ + public function title(bool $allWords = \false) + { + $str = clone $this; + $str->string = $allWords ? \ucwords($str->string) : \ucfirst($str->string); + return $str; + } + public function toUnicodeString(string $fromEncoding = null) : UnicodeString + { + return new UnicodeString($this->toCodePointString($fromEncoding)->string); + } + public function toCodePointString(string $fromEncoding = null) : CodePointString + { + $u = new CodePointString(); + if (\in_array($fromEncoding, [null, 'utf8', 'utf-8', 'UTF8', 'UTF-8'], \true) && \preg_match('//u', $this->string)) { + $u->string = $this->string; + return $u; + } + \set_error_handler(static function ($t, $m) { + throw new InvalidArgumentException($m); + }); + try { + try { + $validEncoding = \false !== \mb_detect_encoding($this->string, $fromEncoding ?? 'Windows-1252', \true); + } catch (InvalidArgumentException $e) { + if (!\function_exists('iconv')) { + throw $e; + } + $u->string = \iconv($fromEncoding ?? 'Windows-1252', 'UTF-8', $this->string); + return $u; + } + } finally { + \restore_error_handler(); + } + if (!$validEncoding) { + throw new InvalidArgumentException(\sprintf('Invalid "%s" string.', $fromEncoding ?? 'Windows-1252')); + } + $u->string = \mb_convert_encoding($this->string, 'UTF-8', $fromEncoding ?? 'Windows-1252'); + return $u; + } + /** + * @return static + */ + public function trim(string $chars = " \t\n\r\x00\v\f") + { + $str = clone $this; + $str->string = \trim($str->string, $chars); + return $str; + } + /** + * @return static + */ + public function trimEnd(string $chars = " \t\n\r\x00\v\f") + { + $str = clone $this; + $str->string = \rtrim($str->string, $chars); + return $str; + } + /** + * @return static + */ + public function trimStart(string $chars = " \t\n\r\x00\v\f") + { + $str = clone $this; + $str->string = \ltrim($str->string, $chars); + return $str; + } + /** + * @return static + */ + public function upper() + { + $str = clone $this; + $str->string = \strtoupper($str->string); + return $str; + } + public function width(bool $ignoreAnsiDecoration = \true) : int + { + $string = \preg_match('//u', $this->string) ? $this->string : \preg_replace('/[\\x80-\\xFF]/', '?', $this->string); + return (new CodePointString($string))->width($ignoreAnsiDecoration); + } +} diff --git a/vendor/symfony/string/CHANGELOG.md b/vendor/symfony/string/CHANGELOG.md new file mode 100644 index 0000000000..31a3b54dbf --- /dev/null +++ b/vendor/symfony/string/CHANGELOG.md @@ -0,0 +1,40 @@ +CHANGELOG +========= + +6.2 +--- + + * Add support for emoji in `AsciiSlugger` + +5.4 +--- + + * Add `trimSuffix()` and `trimPrefix()` methods + +5.3 +--- + + * Made `AsciiSlugger` fallback to parent locale's symbolsMap + +5.2.0 +----- + + * added a `FrenchInflector` class + +5.1.0 +----- + + * added the `AbstractString::reverse()` method + * made `AbstractString::width()` follow POSIX.1-2001 + * added `LazyString` which provides memoizing stringable objects + * The component is not marked as `@experimental` anymore + * added the `s()` helper method to get either an `UnicodeString` or `ByteString` instance, + depending of the input string UTF-8 compliancy + * added `$cut` parameter to `Symfony\Component\String\AbstractString::truncate()` + * added `AbstractString::containsAny()` + * allow passing a string of custom characters to `ByteString::fromRandom()` + +5.0.0 +----- + + * added the component as experimental diff --git a/vendor/symfony/string/CodePointString.php b/vendor/symfony/string/CodePointString.php new file mode 100644 index 0000000000..200ff569ef --- /dev/null +++ b/vendor/symfony/string/CodePointString.php @@ -0,0 +1,234 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String; + +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\InvalidArgumentException; +/** + * Represents a string of Unicode code points encoded as UTF-8. + * + * @author Nicolas Grekas + * @author Hugo Hamon + * + * @throws ExceptionInterface + */ +class CodePointString extends AbstractUnicodeString +{ + public function __construct(string $string = '') + { + if ('' !== $string && !\preg_match('//u', $string)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + $this->string = $string; + } + /** + * @return static + */ + public function append(string ...$suffix) + { + $str = clone $this; + $str->string .= 1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix); + if (!\preg_match('//u', $str->string)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + return $str; + } + public function chunk(int $length = 1) : array + { + if (1 > $length) { + throw new InvalidArgumentException('The chunk length must be greater than zero.'); + } + if ('' === $this->string) { + return []; + } + $rx = '/('; + while (65535 < $length) { + $rx .= '.{65535}'; + $length -= 65535; + } + $rx .= '.{' . $length . '})/us'; + $str = clone $this; + $chunks = []; + foreach (\preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) { + $str->string = $chunk; + $chunks[] = clone $str; + } + return $chunks; + } + public function codePointsAt(int $offset) : array + { + $str = $offset ? $this->slice($offset, 1) : $this; + return '' === $str->string ? [] : [\mb_ord($str->string, 'UTF-8')]; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $suffix + */ + public function endsWith($suffix) : bool + { + if ($suffix instanceof AbstractString) { + $suffix = $suffix->string; + } elseif (!\is_string($suffix)) { + return parent::endsWith($suffix); + } + if ('' === $suffix || !\preg_match('//u', $suffix)) { + return \false; + } + if ($this->ignoreCase) { + return \preg_match('{' . \preg_quote($suffix) . '$}iuD', $this->string); + } + return \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix)); + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $string + */ + public function equalsTo($string) : bool + { + if ($string instanceof AbstractString) { + $string = $string->string; + } elseif (!\is_string($string)) { + return parent::equalsTo($string); + } + if ('' !== $string && $this->ignoreCase) { + return \strlen($string) === \strlen($this->string) && 0 === \mb_stripos($this->string, $string, 0, 'UTF-8'); + } + return $string === $this->string; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $needle + */ + public function indexOf($needle, int $offset = 0) : ?int + { + if ($needle instanceof AbstractString) { + $needle = $needle->string; + } elseif (!\is_string($needle)) { + return parent::indexOf($needle, $offset); + } + if ('' === $needle) { + return null; + } + $i = $this->ignoreCase ? \mb_stripos($this->string, $needle, $offset, 'UTF-8') : \mb_strpos($this->string, $needle, $offset, 'UTF-8'); + return \false === $i ? null : $i; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $needle + */ + public function indexOfLast($needle, int $offset = 0) : ?int + { + if ($needle instanceof AbstractString) { + $needle = $needle->string; + } elseif (!\is_string($needle)) { + return parent::indexOfLast($needle, $offset); + } + if ('' === $needle) { + return null; + } + $i = $this->ignoreCase ? \mb_strripos($this->string, $needle, $offset, 'UTF-8') : \mb_strrpos($this->string, $needle, $offset, 'UTF-8'); + return \false === $i ? null : $i; + } + public function length() : int + { + return \mb_strlen($this->string, 'UTF-8'); + } + /** + * @return static + */ + public function prepend(string ...$prefix) + { + $str = clone $this; + $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $this->string; + if (!\preg_match('//u', $str->string)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + return $str; + } + /** + * @return static + */ + public function replace(string $from, string $to) + { + $str = clone $this; + if ('' === $from || !\preg_match('//u', $from)) { + return $str; + } + if ('' !== $to && !\preg_match('//u', $to)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + if ($this->ignoreCase) { + $str->string = \implode($to, \preg_split('{' . \preg_quote($from) . '}iuD', $this->string)); + } else { + $str->string = \str_replace($from, $to, $this->string); + } + return $str; + } + /** + * @return static + */ + public function slice(int $start = 0, int $length = null) + { + $str = clone $this; + $str->string = \mb_substr($this->string, $start, $length, 'UTF-8'); + return $str; + } + /** + * @return static + */ + public function splice(string $replacement, int $start = 0, int $length = null) + { + if (!\preg_match('//u', $replacement)) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + $str = clone $this; + $start = $start ? \strlen(\mb_substr($this->string, 0, $start, 'UTF-8')) : 0; + $length = $length ? \strlen(\mb_substr($this->string, $start, $length, 'UTF-8')) : $length; + $str->string = \substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX); + return $str; + } + public function split(string $delimiter, int $limit = null, int $flags = null) : array + { + if (1 > ($limit = $limit ?? \PHP_INT_MAX)) { + throw new InvalidArgumentException('Split limit must be a positive integer.'); + } + if ('' === $delimiter) { + throw new InvalidArgumentException('Split delimiter is empty.'); + } + if (null !== $flags) { + return parent::split($delimiter . 'u', $limit, $flags); + } + if (!\preg_match('//u', $delimiter)) { + throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.'); + } + $str = clone $this; + $chunks = $this->ignoreCase ? \preg_split('{' . \preg_quote($delimiter) . '}iuD', $this->string, $limit) : \explode($delimiter, $this->string, $limit); + foreach ($chunks as &$chunk) { + $str->string = $chunk; + $chunk = clone $str; + } + return $chunks; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $prefix + */ + public function startsWith($prefix) : bool + { + if ($prefix instanceof AbstractString) { + $prefix = $prefix->string; + } elseif (!\is_string($prefix)) { + return parent::startsWith($prefix); + } + if ('' === $prefix || !\preg_match('//u', $prefix)) { + return \false; + } + if ($this->ignoreCase) { + return 0 === \mb_stripos($this->string, $prefix, 0, 'UTF-8'); + } + return 0 === \strncmp($this->string, $prefix, \strlen($prefix)); + } +} diff --git a/vendor/symfony/string/Exception/ExceptionInterface.php b/vendor/symfony/string/Exception/ExceptionInterface.php new file mode 100644 index 0000000000..8aefba156f --- /dev/null +++ b/vendor/symfony/string/Exception/ExceptionInterface.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Exception; + +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/string/Exception/InvalidArgumentException.php b/vendor/symfony/string/Exception/InvalidArgumentException.php new file mode 100644 index 0000000000..0be498aceb --- /dev/null +++ b/vendor/symfony/string/Exception/InvalidArgumentException.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Exception; + +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/string/Exception/RuntimeException.php b/vendor/symfony/string/Exception/RuntimeException.php new file mode 100644 index 0000000000..0ec2172e60 --- /dev/null +++ b/vendor/symfony/string/Exception/RuntimeException.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Exception; + +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/string/Inflector/EnglishInflector.php b/vendor/symfony/string/Inflector/EnglishInflector.php new file mode 100644 index 0000000000..1c1acbc6e9 --- /dev/null +++ b/vendor/symfony/string/Inflector/EnglishInflector.php @@ -0,0 +1,382 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Inflector; + +final class EnglishInflector implements InflectorInterface +{ + /** + * Map English plural to singular suffixes. + * + * @see http://english-zone.com/spelling/plurals.html + */ + private const PLURAL_MAP = [ + // First entry: plural suffix, reversed + // Second entry: length of plural suffix + // Third entry: Whether the suffix may succeed a vocal + // Fourth entry: Whether the suffix may succeed a consonant + // Fifth entry: singular suffix, normal + // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) + ['a', 1, \true, \true, ['on', 'um']], + // nebulae (nebula) + ['ea', 2, \true, \true, 'a'], + // services (service) + ['secivres', 8, \true, \true, 'service'], + // mice (mouse), lice (louse) + ['eci', 3, \false, \true, 'ouse'], + // geese (goose) + ['esee', 4, \false, \true, 'oose'], + // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius) + ['i', 1, \true, \true, 'us'], + // men (man), women (woman) + ['nem', 3, \true, \true, 'man'], + // children (child) + ['nerdlihc', 8, \true, \true, 'child'], + // oxen (ox) + ['nexo', 4, \false, \false, 'ox'], + // indices (index), appendices (appendix), prices (price) + ['seci', 4, \false, \true, ['ex', 'ix', 'ice']], + // codes (code) + ['sedoc', 5, \false, \true, 'code'], + // selfies (selfie) + ['seifles', 7, \true, \true, 'selfie'], + // zombies (zombie) + ['seibmoz', 7, \true, \true, 'zombie'], + // movies (movie) + ['seivom', 6, \true, \true, 'movie'], + // names (name) + ['seman', 5, \true, \false, 'name'], + // conspectuses (conspectus), prospectuses (prospectus) + ['sesutcep', 8, \true, \true, 'pectus'], + // feet (foot) + ['teef', 4, \true, \true, 'foot'], + // geese (goose) + ['eseeg', 5, \true, \true, 'goose'], + // teeth (tooth) + ['hteet', 5, \true, \true, 'tooth'], + // news (news) + ['swen', 4, \true, \true, 'news'], + // series (series) + ['seires', 6, \true, \true, 'series'], + // babies (baby) + ['sei', 3, \false, \true, 'y'], + // accesses (access), addresses (address), kisses (kiss) + ['sess', 4, \true, \false, 'ss'], + // statuses (status) + ['sesutats', 8, \true, \true, 'status'], + // analyses (analysis), ellipses (ellipsis), fungi (fungus), + // neuroses (neurosis), theses (thesis), emphases (emphasis), + // oases (oasis), crises (crisis), houses (house), bases (base), + // atlases (atlas) + ['ses', 3, \true, \true, ['s', 'se', 'sis']], + // objectives (objective), alternative (alternatives) + ['sevit', 5, \true, \true, 'tive'], + // drives (drive) + ['sevird', 6, \false, \true, 'drive'], + // lives (life), wives (wife) + ['sevi', 4, \false, \true, 'ife'], + // moves (move) + ['sevom', 5, \true, \true, 'move'], + // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf), caves (cave), staves (staff) + ['sev', 3, \true, \true, ['f', 've', 'ff']], + // axes (axis), axes (ax), axes (axe) + ['sexa', 4, \false, \false, ['ax', 'axe', 'axis']], + // indexes (index), matrixes (matrix) + ['sex', 3, \true, \false, 'x'], + // quizzes (quiz) + ['sezz', 4, \true, \false, 'z'], + // bureaus (bureau) + ['suae', 4, \false, \true, 'eau'], + // fees (fee), trees (tree), employees (employee) + ['see', 3, \true, \true, 'ee'], + // edges (edge) + ['segd', 4, \true, \true, 'dge'], + // roses (rose), garages (garage), cassettes (cassette), + // waltzes (waltz), heroes (hero), bushes (bush), arches (arch), + // shoes (shoe) + ['se', 2, \true, \true, ['', 'e']], + // status (status) + ['sutats', 6, \true, \true, 'status'], + // tags (tag) + ['s', 1, \true, \true, ''], + // chateaux (chateau) + ['xuae', 4, \false, \true, 'eau'], + // people (person) + ['elpoep', 6, \true, \true, 'person'], + ]; + /** + * Map English singular to plural suffixes. + * + * @see http://english-zone.com/spelling/plurals.html + */ + private const SINGULAR_MAP = [ + // First entry: singular suffix, reversed + // Second entry: length of singular suffix + // Third entry: Whether the suffix may succeed a vocal + // Fourth entry: Whether the suffix may succeed a consonant + // Fifth entry: plural suffix, normal + // criterion (criteria) + ['airetirc', 8, \false, \false, 'criterion'], + // nebulae (nebula) + ['aluben', 6, \false, \false, 'nebulae'], + // children (child) + ['dlihc', 5, \true, \true, 'children'], + // prices (price) + ['eci', 3, \false, \true, 'ices'], + // services (service) + ['ecivres', 7, \true, \true, 'services'], + // lives (life), wives (wife) + ['efi', 3, \false, \true, 'ives'], + // selfies (selfie) + ['eifles', 6, \true, \true, 'selfies'], + // movies (movie) + ['eivom', 5, \true, \true, 'movies'], + // lice (louse) + ['esuol', 5, \false, \true, 'lice'], + // mice (mouse) + ['esuom', 5, \false, \true, 'mice'], + // geese (goose) + ['esoo', 4, \false, \true, 'eese'], + // houses (house), bases (base) + ['es', 2, \true, \true, 'ses'], + // geese (goose) + ['esoog', 5, \true, \true, 'geese'], + // caves (cave) + ['ev', 2, \true, \true, 'ves'], + // drives (drive) + ['evird', 5, \false, \true, 'drives'], + // objectives (objective), alternative (alternatives) + ['evit', 4, \true, \true, 'tives'], + // moves (move) + ['evom', 4, \true, \true, 'moves'], + // staves (staff) + ['ffats', 5, \true, \true, 'staves'], + // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf) + ['ff', 2, \true, \true, 'ffs'], + // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf) + ['f', 1, \true, \true, ['fs', 'ves']], + // arches (arch) + ['hc', 2, \true, \true, 'ches'], + // bushes (bush) + ['hs', 2, \true, \true, 'shes'], + // teeth (tooth) + ['htoot', 5, \true, \true, 'teeth'], + // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) + ['mu', 2, \true, \true, 'a'], + // men (man), women (woman) + ['nam', 3, \true, \true, 'men'], + // people (person) + ['nosrep', 6, \true, \true, ['persons', 'people']], + // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) + ['noi', 3, \true, \true, 'ions'], + // coupon (coupons) + ['nop', 3, \true, \true, 'pons'], + // seasons (season), treasons (treason), poisons (poison), lessons (lesson) + ['nos', 3, \true, \true, 'sons'], + // bacteria (bacterium), criteria (criterion), phenomena (phenomenon) + ['no', 2, \true, \true, 'a'], + // echoes (echo) + ['ohce', 4, \true, \true, 'echoes'], + // heroes (hero) + ['oreh', 4, \true, \true, 'heroes'], + // atlases (atlas) + ['salta', 5, \true, \true, 'atlases'], + // irises (iris) + ['siri', 4, \true, \true, 'irises'], + // analyses (analysis), ellipses (ellipsis), neuroses (neurosis) + // theses (thesis), emphases (emphasis), oases (oasis), + // crises (crisis) + ['sis', 3, \true, \true, 'ses'], + // accesses (access), addresses (address), kisses (kiss) + ['ss', 2, \true, \false, 'sses'], + // syllabi (syllabus) + ['suballys', 8, \true, \true, 'syllabi'], + // buses (bus) + ['sub', 3, \true, \true, 'buses'], + // circuses (circus) + ['suc', 3, \true, \true, 'cuses'], + // status (status) + ['sutats', 6, \true, \true, ['status', 'statuses']], + // conspectuses (conspectus), prospectuses (prospectus) + ['sutcep', 6, \true, \true, 'pectuses'], + // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius) + ['su', 2, \true, \true, 'i'], + // news (news) + ['swen', 4, \true, \true, 'news'], + // feet (foot) + ['toof', 4, \true, \true, 'feet'], + // chateaux (chateau), bureaus (bureau) + ['uae', 3, \false, \true, ['eaus', 'eaux']], + // oxen (ox) + ['xo', 2, \false, \false, 'oxen'], + // hoaxes (hoax) + ['xaoh', 4, \true, \false, 'hoaxes'], + // indices (index) + ['xedni', 5, \false, \true, ['indicies', 'indexes']], + // boxes (box) + ['xo', 2, \false, \true, 'oxes'], + // indexes (index), matrixes (matrix) + ['x', 1, \true, \false, ['cies', 'xes']], + // appendices (appendix) + ['xi', 2, \false, \true, 'ices'], + // babies (baby) + ['y', 1, \false, \true, 'ies'], + // quizzes (quiz) + ['ziuq', 4, \true, \false, 'quizzes'], + // waltzes (waltz) + ['z', 1, \true, \true, 'zes'], + ]; + /** + * A list of words which should not be inflected, reversed. + */ + private const UNINFLECTED = [ + '', + // data + 'atad', + // deer + 'reed', + // feedback + 'kcabdeef', + // fish + 'hsif', + // info + 'ofni', + // moose + 'esoom', + // series + 'seires', + // sheep + 'peehs', + // species + 'seiceps', + ]; + public function singularize(string $plural) : array + { + $pluralRev = \strrev($plural); + $lowerPluralRev = \strtolower($pluralRev); + $pluralLength = \strlen($lowerPluralRev); + // Check if the word is one which is not inflected, return early if so + if (\in_array($lowerPluralRev, self::UNINFLECTED, \true)) { + return [$plural]; + } + // The outer loop iterates over the entries of the plural table + // The inner loop $j iterates over the characters of the plural suffix + // in the plural table to compare them with the characters of the actual + // given plural suffix + foreach (self::PLURAL_MAP as $map) { + $suffix = $map[0]; + $suffixLength = $map[1]; + $j = 0; + // Compare characters in the plural table and of the suffix of the + // given plural one by one + while ($suffix[$j] === $lowerPluralRev[$j]) { + // Let $j point to the next character + ++$j; + // Successfully compared the last character + // Add an entry with the singular suffix to the singular array + if ($j === $suffixLength) { + // Is there any character preceding the suffix in the plural string? + if ($j < $pluralLength) { + $nextIsVocal = \strpos('aeiou', $lowerPluralRev[$j]) !== \false; + if (!$map[2] && $nextIsVocal) { + // suffix may not succeed a vocal but next char is one + break; + } + if (!$map[3] && !$nextIsVocal) { + // suffix may not succeed a consonant but next char is one + break; + } + } + $newBase = \substr($plural, 0, $pluralLength - $suffixLength); + $newSuffix = $map[4]; + // Check whether the first character in the plural suffix + // is uppercased. If yes, uppercase the first character in + // the singular suffix too + $firstUpper = \ctype_upper($pluralRev[$j - 1]); + if (\is_array($newSuffix)) { + $singulars = []; + foreach ($newSuffix as $newSuffixEntry) { + $singulars[] = $newBase . ($firstUpper ? \ucfirst($newSuffixEntry) : $newSuffixEntry); + } + return $singulars; + } + return [$newBase . ($firstUpper ? \ucfirst($newSuffix) : $newSuffix)]; + } + // Suffix is longer than word + if ($j === $pluralLength) { + break; + } + } + } + // Assume that plural and singular is identical + return [$plural]; + } + public function pluralize(string $singular) : array + { + $singularRev = \strrev($singular); + $lowerSingularRev = \strtolower($singularRev); + $singularLength = \strlen($lowerSingularRev); + // Check if the word is one which is not inflected, return early if so + if (\in_array($lowerSingularRev, self::UNINFLECTED, \true)) { + return [$singular]; + } + // The outer loop iterates over the entries of the singular table + // The inner loop $j iterates over the characters of the singular suffix + // in the singular table to compare them with the characters of the actual + // given singular suffix + foreach (self::SINGULAR_MAP as $map) { + $suffix = $map[0]; + $suffixLength = $map[1]; + $j = 0; + // Compare characters in the singular table and of the suffix of the + // given plural one by one + while ($suffix[$j] === $lowerSingularRev[$j]) { + // Let $j point to the next character + ++$j; + // Successfully compared the last character + // Add an entry with the plural suffix to the plural array + if ($j === $suffixLength) { + // Is there any character preceding the suffix in the plural string? + if ($j < $singularLength) { + $nextIsVocal = \strpos('aeiou', $lowerSingularRev[$j]) !== \false; + if (!$map[2] && $nextIsVocal) { + // suffix may not succeed a vocal but next char is one + break; + } + if (!$map[3] && !$nextIsVocal) { + // suffix may not succeed a consonant but next char is one + break; + } + } + $newBase = \substr($singular, 0, $singularLength - $suffixLength); + $newSuffix = $map[4]; + // Check whether the first character in the singular suffix + // is uppercased. If yes, uppercase the first character in + // the singular suffix too + $firstUpper = \ctype_upper($singularRev[$j - 1]); + if (\is_array($newSuffix)) { + $plurals = []; + foreach ($newSuffix as $newSuffixEntry) { + $plurals[] = $newBase . ($firstUpper ? \ucfirst($newSuffixEntry) : $newSuffixEntry); + } + return $plurals; + } + return [$newBase . ($firstUpper ? \ucfirst($newSuffix) : $newSuffix)]; + } + // Suffix is longer than word + if ($j === $singularLength) { + break; + } + } + } + // Assume that plural is singular with a trailing `s` + return [$singular . 's']; + } +} diff --git a/vendor/symfony/string/Inflector/FrenchInflector.php b/vendor/symfony/string/Inflector/FrenchInflector.php new file mode 100644 index 0000000000..6c9572c394 --- /dev/null +++ b/vendor/symfony/string/Inflector/FrenchInflector.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Inflector; + +/** + * French inflector. + * + * This class does only inflect nouns; not adjectives nor composed words like "soixante-dix". + */ +final class FrenchInflector implements InflectorInterface +{ + /** + * A list of all rules for pluralise. + * + * @see https://la-conjugaison.nouvelobs.com/regles/grammaire/le-pluriel-des-noms-121.php + */ + private const PLURALIZE_REGEXP = [ + // First entry: regexp + // Second entry: replacement + // Words finishing with "s", "x" or "z" are invariables + // Les mots finissant par "s", "x" ou "z" sont invariables + ['/(s|x|z)$/i', '\\1'], + // Words finishing with "eau" are pluralized with a "x" + // Les mots finissant par "eau" prennent tous un "x" au pluriel + ['/(eau)$/i', '\\1x'], + // Words finishing with "au" are pluralized with a "x" excepted "landau" + // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau" + ['/^(landau)$/i', '\\1s'], + ['/(au)$/i', '\\1x'], + // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu" + // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu" + ['/^(pneu|bleu|émeu)$/i', '\\1s'], + ['/(eu)$/i', '\\1x'], + // Words finishing with "al" are pluralized with a "aux" excepted + // Les mots finissant en "al" se terminent en "aux" sauf + ['/^(bal|carnaval|caracal|chacal|choral|corral|étal|festival|récital|val)$/i', '\\1s'], + ['/al$/i', '\\1aux'], + // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux + ['/^(aspir|b|cor|ém|ferm|soupir|trav|vant|vitr)ail$/i', '\\1aux'], + // Bijou, caillou, chou, genou, hibou, joujou et pou qui prennent un x au pluriel + ['/^(bij|caill|ch|gen|hib|jouj|p)ou$/i', '\\1oux'], + // Invariable words + ['/^(cinquante|soixante|mille)$/i', '\\1'], + // French titles + ['/^(mon|ma)(sieur|dame|demoiselle|seigneur)$/', 'MonorepoBuilderPrefix202310\\mes\\2s'], + ['/^(Mon|Ma)(sieur|dame|demoiselle|seigneur)$/', 'MonorepoBuilderPrefix202310\\Mes\\2s'], + ]; + /** + * A list of all rules for singularize. + */ + private const SINGULARIZE_REGEXP = [ + // First entry: regexp + // Second entry: replacement + // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux + ['/((aspir|b|cor|ém|ferm|soupir|trav|vant|vitr))aux$/i', '\\1ail'], + // Words finishing with "eau" are pluralized with a "x" + // Les mots finissant par "eau" prennent tous un "x" au pluriel + ['/(eau)x$/i', '\\1'], + // Words finishing with "al" are pluralized with a "aux" expected + // Les mots finissant en "al" se terminent en "aux" sauf + ['/(amir|anim|arsen|boc|can|capit|capor|chev|crist|génér|hopit|hôpit|idé|journ|littor|loc|m|mét|minér|princip|radic|termin)aux$/i', '\\1al'], + // Words finishing with "au" are pluralized with a "x" excepted "landau" + // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau" + ['/(au)x$/i', '\\1'], + // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu" + // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu" + ['/(eu)x$/i', '\\1'], + // Words finishing with "ou" are pluralized with a "s" excepted bijou, caillou, chou, genou, hibou, joujou, pou + // Les mots finissant par "ou" prennent un "s" sauf bijou, caillou, chou, genou, hibou, joujou, pou + ['/(bij|caill|ch|gen|hib|jouj|p)oux$/i', '\\1ou'], + // French titles + ['/^mes(dame|demoiselle)s$/', 'MonorepoBuilderPrefix202310\\ma\\1'], + ['/^Mes(dame|demoiselle)s$/', 'MonorepoBuilderPrefix202310\\Ma\\1'], + ['/^mes(sieur|seigneur)s$/', 'MonorepoBuilderPrefix202310\\mon\\1'], + ['/^Mes(sieur|seigneur)s$/', 'MonorepoBuilderPrefix202310\\Mon\\1'], + // Default rule + ['/s$/i', ''], + ]; + /** + * A list of words which should not be inflected. + * This list is only used by singularize. + */ + private const UNINFLECTED = '/^(abcès|accès|abus|albatros|anchois|anglais|autobus|bois|brebis|carquois|cas|chas|colis|concours|corps|cours|cyprès|décès|devis|discours|dos|embarras|engrais|entrelacs|excès|fils|fois|gâchis|gars|glas|héros|intrus|jars|jus|kermès|lacis|legs|lilas|marais|mars|matelas|mépris|mets|mois|mors|obus|os|palais|paradis|parcours|pardessus|pays|plusieurs|poids|pois|pouls|printemps|processus|progrès|puits|pus|rabais|radis|recors|recours|refus|relais|remords|remous|rictus|rhinocéros|repas|rubis|sans|sas|secours|sens|souris|succès|talus|tapis|tas|taudis|temps|tiers|univers|velours|verglas|vernis|virus)$/i'; + public function singularize(string $plural) : array + { + if ($this->isInflectedWord($plural)) { + return [$plural]; + } + foreach (self::SINGULARIZE_REGEXP as $rule) { + [$regexp, $replace] = $rule; + if (1 === \preg_match($regexp, $plural)) { + return [\preg_replace($regexp, $replace, $plural)]; + } + } + return [$plural]; + } + public function pluralize(string $singular) : array + { + if ($this->isInflectedWord($singular)) { + return [$singular]; + } + foreach (self::PLURALIZE_REGEXP as $rule) { + [$regexp, $replace] = $rule; + if (1 === \preg_match($regexp, $singular)) { + return [\preg_replace($regexp, $replace, $singular)]; + } + } + return [$singular . 's']; + } + private function isInflectedWord(string $word) : bool + { + return 1 === \preg_match(self::UNINFLECTED, $word); + } +} diff --git a/vendor/symfony/string/Inflector/InflectorInterface.php b/vendor/symfony/string/Inflector/InflectorInterface.php new file mode 100644 index 0000000000..c31e46b644 --- /dev/null +++ b/vendor/symfony/string/Inflector/InflectorInterface.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Inflector; + +interface InflectorInterface +{ + /** + * Returns the singular forms of a string. + * + * If the method can't determine the form with certainty, several possible singulars are returned. + * + * @return string[] + */ + public function singularize(string $plural) : array; + /** + * Returns the plural forms of a string. + * + * If the method can't determine the form with certainty, several possible plurals are returned. + * + * @return string[] + */ + public function pluralize(string $singular) : array; +} diff --git a/vendor/symfony/string/LICENSE b/vendor/symfony/string/LICENSE new file mode 100644 index 0000000000..f37c76b591 --- /dev/null +++ b/vendor/symfony/string/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/string/LazyString.php b/vendor/symfony/string/LazyString.php new file mode 100644 index 0000000000..9a093f328b --- /dev/null +++ b/vendor/symfony/string/LazyString.php @@ -0,0 +1,132 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String; + +/** + * A string whose value is computed lazily by a callback. + * + * @author Nicolas Grekas + */ +class LazyString implements \JsonSerializable +{ + /** + * @var \Closure|string + */ + private $value; + /** + * @param callable|array $callback A callable or a [Closure, method] lazy-callable + * @param mixed ...$arguments + * @return static + */ + public static function fromCallable($callback, ...$arguments) + { + if (\is_array($callback) && !\is_callable($callback) && !(($callback[0] ?? null) instanceof \Closure || 2 < \count($callback))) { + throw new \TypeError(\sprintf('Argument 1 passed to "%s()" must be a callable or a [Closure, method] lazy-callable, "%s" given.', __METHOD__, '[' . \implode(', ', \array_map('get_debug_type', $callback)) . ']')); + } + $lazyString = new static(); + $lazyString->value = static function () use(&$callback, &$arguments) : string { + static $value; + if (null !== $arguments) { + if (!\is_callable($callback)) { + $callback[0] = $callback[0](); + $callback[1] = $callback[1] ?? '__invoke'; + } + $value = $callback(...$arguments); + $callback = self::getPrettyName($callback); + $arguments = null; + } + return $value ?? ''; + }; + return $lazyString; + } + /** + * @param string|int|float|bool|\Stringable $value + * @return static + */ + public static function fromStringable($value) + { + if (\is_object($value)) { + return static::fromCallable(\Closure::fromCallable([$value, '__toString'])); + } + $lazyString = new static(); + $lazyString->value = (string) $value; + return $lazyString; + } + /** + * Tells whether the provided value can be cast to string. + * @param mixed $value + */ + public static final function isStringable($value) : bool + { + return \is_string($value) || $value instanceof \Stringable || \is_scalar($value); + } + /** + * Casts scalars and stringable objects to strings. + * + * @throws \TypeError When the provided value is not stringable + * @param \Stringable|string|int|float|bool $value + */ + public static final function resolve($value) : string + { + return $value; + } + public function __toString() : string + { + if (\is_string($this->value)) { + return $this->value; + } + try { + return $this->value = ($this->value)(); + } catch (\Throwable $e) { + if (\TypeError::class === \get_class($e) && __FILE__ === $e->getFile()) { + $type = \explode(', ', $e->getMessage()); + $type = \substr(\array_pop($type), 0, -\strlen(' returned')); + $r = new \ReflectionFunction($this->value); + $callback = $r->getStaticVariables()['callback']; + $e = new \TypeError(\sprintf('Return value of %s() passed to %s::fromCallable() must be of the type string, %s returned.', $callback, static::class, $type)); + } + throw $e; + } + } + public function __sleep() : array + { + $this->__toString(); + return ['value']; + } + public function jsonSerialize() : string + { + return $this->__toString(); + } + private function __construct() + { + } + private static function getPrettyName(callable $callback) : string + { + if (\is_string($callback)) { + return $callback; + } + if (\is_array($callback)) { + $class = \is_object($callback[0]) ? \get_debug_type($callback[0]) : $callback[0]; + $method = $callback[1]; + } elseif ($callback instanceof \Closure) { + $r = new \ReflectionFunction($callback); + if (\strpos($r->name, '{closure}') !== \false || !($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass())) { + return $r->name; + } + $class = $class->name; + $method = $r->name; + } else { + $class = \get_debug_type($callback); + $method = '__invoke'; + } + return $class . '::' . $method; + } +} diff --git a/vendor/symfony/string/README.md b/vendor/symfony/string/README.md new file mode 100644 index 0000000000..9c7e1e190d --- /dev/null +++ b/vendor/symfony/string/README.md @@ -0,0 +1,14 @@ +String Component +================ + +The String component provides an object-oriented API to strings and deals +with bytes, UTF-8 code points and grapheme clusters in a unified way. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/string.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/vendor/symfony/string/Resources/data/wcswidth_table_wide.php b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php new file mode 100644 index 0000000000..5aab9c792e --- /dev/null +++ b/vendor/symfony/string/Resources/data/wcswidth_table_wide.php @@ -0,0 +1,11 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String; + +if (!\function_exists(u::class)) { + function u(?string $string = '') : UnicodeString + { + return new UnicodeString($string ?? ''); + } +} +if (!\function_exists(b::class)) { + function b(?string $string = '') : ByteString + { + return new ByteString($string ?? ''); + } +} +if (!\function_exists(s::class)) { + /** + * @return UnicodeString|ByteString + */ + function s(?string $string = '') : AbstractString + { + $string = $string ?? ''; + return \preg_match('//u', $string) ? new UnicodeString($string) : new ByteString($string); + } +} diff --git a/vendor/symfony/string/Slugger/AsciiSlugger.php b/vendor/symfony/string/Slugger/AsciiSlugger.php new file mode 100644 index 0000000000..2a5bed2244 --- /dev/null +++ b/vendor/symfony/string/Slugger/AsciiSlugger.php @@ -0,0 +1,164 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Slugger; + +use MonorepoBuilderPrefix202310\Symfony\Component\Intl\Transliterator\EmojiTransliterator; +use MonorepoBuilderPrefix202310\Symfony\Component\String\AbstractUnicodeString; +use MonorepoBuilderPrefix202310\Symfony\Component\String\UnicodeString; +use MonorepoBuilderPrefix202310\Symfony\Contracts\Translation\LocaleAwareInterface; +if (!\interface_exists(LocaleAwareInterface::class)) { + throw new \LogicException('You cannot use the "Symfony\\Component\\String\\Slugger\\AsciiSlugger" as the "symfony/translation-contracts" package is not installed. Try running "composer require symfony/translation-contracts".'); +} +/** + * @author Titouan Galopin + */ +class AsciiSlugger implements SluggerInterface, LocaleAwareInterface +{ + private const LOCALE_TO_TRANSLITERATOR_ID = ['am' => 'Amharic-Latin', 'ar' => 'Arabic-Latin', 'az' => 'Azerbaijani-Latin', 'be' => 'Belarusian-Latin', 'bg' => 'Bulgarian-Latin', 'bn' => 'Bengali-Latin', 'de' => 'de-ASCII', 'el' => 'Greek-Latin', 'fa' => 'Persian-Latin', 'he' => 'Hebrew-Latin', 'hy' => 'Armenian-Latin', 'ka' => 'Georgian-Latin', 'kk' => 'Kazakh-Latin', 'ky' => 'Kirghiz-Latin', 'ko' => 'Korean-Latin', 'mk' => 'Macedonian-Latin', 'mn' => 'Mongolian-Latin', 'or' => 'Oriya-Latin', 'ps' => 'Pashto-Latin', 'ru' => 'Russian-Latin', 'sr' => 'Serbian-Latin', 'sr_Cyrl' => 'Serbian-Latin', 'th' => 'Thai-Latin', 'tk' => 'Turkmen-Latin', 'uk' => 'Ukrainian-Latin', 'uz' => 'Uzbek-Latin', 'zh' => 'Han-Latin']; + /** + * @var string|null + */ + private $defaultLocale; + /** + * @var \Closure|mixed[] + */ + private $symbolsMap = ['en' => ['@' => 'at', '&' => 'and']]; + /** + * @var bool|string + */ + private $emoji = \false; + /** + * Cache of transliterators per locale. + * + * @var \Transliterator[] + */ + private $transliterators = []; + /** + * @param mixed[]|\Closure $symbolsMap + */ + public function __construct(string $defaultLocale = null, $symbolsMap = null) + { + $this->defaultLocale = $defaultLocale; + $this->symbolsMap = $symbolsMap ?? $this->symbolsMap; + } + /** + * @return void + */ + public function setLocale(string $locale) + { + $this->defaultLocale = $locale; + } + public function getLocale() : string + { + return $this->defaultLocale; + } + /** + * @param bool|string $emoji true will use the same locale, + * false will disable emoji, + * and a string to use a specific locale + * @return static + */ + public function withEmoji($emoji = \true) + { + if (\false !== $emoji && !\class_exists(EmojiTransliterator::class)) { + throw new \LogicException(\sprintf('You cannot use the "%s()" method as the "symfony/intl" package is not installed. Try running "composer require symfony/intl".', __METHOD__)); + } + $new = clone $this; + $new->emoji = $emoji; + return $new; + } + public function slug(string $string, string $separator = '-', string $locale = null) : AbstractUnicodeString + { + $locale = $locale ?? $this->defaultLocale; + $transliterator = []; + if ($locale && ('de' === $locale || \strncmp($locale, 'de_', \strlen('de_')) === 0)) { + // Use the shortcut for German in UnicodeString::ascii() if possible (faster and no requirement on intl) + $transliterator = ['de-ASCII']; + } elseif (\function_exists('transliterator_transliterate') && $locale) { + $transliterator = (array) $this->createTransliterator($locale); + } + if ($emojiTransliterator = $this->createEmojiTransliterator($locale)) { + $transliterator[] = $emojiTransliterator; + } + if ($this->symbolsMap instanceof \Closure) { + // If the symbols map is passed as a closure, there is no need to fallback to the parent locale + // as the closure can just provide substitutions for all locales of interest. + $symbolsMap = $this->symbolsMap; + \array_unshift($transliterator, static function ($s) use($symbolsMap, $locale) { + return $symbolsMap($s, $locale); + }); + } + $unicodeString = (new UnicodeString($string))->ascii($transliterator); + if (\is_array($this->symbolsMap)) { + $map = null; + if (isset($this->symbolsMap[$locale])) { + $map = $this->symbolsMap[$locale]; + } else { + $parent = self::getParentLocale($locale); + if ($parent && isset($this->symbolsMap[$parent])) { + $map = $this->symbolsMap[$parent]; + } + } + if ($map) { + foreach ($map as $char => $replace) { + $unicodeString = $unicodeString->replace($char, ' ' . $replace . ' '); + } + } + } + return $unicodeString->replaceMatches('/[^A-Za-z0-9]++/', $separator)->trim($separator); + } + private function createTransliterator(string $locale) : ?\Transliterator + { + if (\array_key_exists($locale, $this->transliterators)) { + return $this->transliterators[$locale]; + } + // Exact locale supported, cache and return + if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$locale] ?? null) { + return $this->transliterators[$locale] = \Transliterator::create($id . '/BGN') ?? \Transliterator::create($id); + } + // Locale not supported and no parent, fallback to any-latin + if (!($parent = self::getParentLocale($locale))) { + return $this->transliterators[$locale] = null; + } + // Try to use the parent locale (ie. try "de" for "de_AT") and cache both locales + if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$parent] ?? null) { + $transliterator = \Transliterator::create($id . '/BGN') ?? \Transliterator::create($id); + } + return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null; + } + private function createEmojiTransliterator(?string $locale) : ?EmojiTransliterator + { + if (\is_string($this->emoji)) { + $locale = $this->emoji; + } elseif (!$this->emoji) { + return null; + } + while (null !== $locale) { + try { + return EmojiTransliterator::create("emoji-{$locale}"); + } catch (\IntlException $exception) { + $locale = self::getParentLocale($locale); + } + } + return null; + } + private static function getParentLocale(?string $locale) : ?string + { + if (!$locale) { + return null; + } + if (\false === ($str = \strrchr($locale, '_'))) { + // no parent locale + return null; + } + return \substr($locale, 0, -\strlen($str)); + } +} diff --git a/vendor/symfony/string/Slugger/SluggerInterface.php b/vendor/symfony/string/Slugger/SluggerInterface.php new file mode 100644 index 0000000000..d6a14dcb6c --- /dev/null +++ b/vendor/symfony/string/Slugger/SluggerInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String\Slugger; + +use MonorepoBuilderPrefix202310\Symfony\Component\String\AbstractUnicodeString; +/** + * Creates a URL-friendly slug from a given string. + * + * @author Titouan Galopin + */ +interface SluggerInterface +{ + /** + * Creates a slug for the given string and locale, using appropriate transliteration when needed. + */ + public function slug(string $string, string $separator = '-', string $locale = null) : AbstractUnicodeString; +} diff --git a/vendor/symfony/string/UnicodeString.php b/vendor/symfony/string/UnicodeString.php new file mode 100644 index 0000000000..5fb9b459a3 --- /dev/null +++ b/vendor/symfony/string/UnicodeString.php @@ -0,0 +1,323 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Symfony\Component\String; + +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\ExceptionInterface; +use MonorepoBuilderPrefix202310\Symfony\Component\String\Exception\InvalidArgumentException; +/** + * Represents a string of Unicode grapheme clusters encoded as UTF-8. + * + * A letter followed by combining characters (accents typically) form what Unicode defines + * as a grapheme cluster: a character as humans mean it in written texts. This class knows + * about the concept and won't split a letter apart from its combining accents. It also + * ensures all string comparisons happen on their canonically-composed representation, + * ignoring e.g. the order in which accents are listed when a letter has many of them. + * + * @see https://unicode.org/reports/tr15/ + * + * @author Nicolas Grekas + * @author Hugo Hamon + * + * @throws ExceptionInterface + */ +class UnicodeString extends AbstractUnicodeString +{ + public function __construct(string $string = '') + { + $this->string = \normalizer_is_normalized($string) ? $string : \normalizer_normalize($string); + if (\false === $this->string) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + } + /** + * @return static + */ + public function append(string ...$suffix) + { + $str = clone $this; + $str->string = $this->string . (1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix)); + \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string)); + if (\false === $str->string) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + return $str; + } + public function chunk(int $length = 1) : array + { + if (1 > $length) { + throw new InvalidArgumentException('The chunk length must be greater than zero.'); + } + if ('' === $this->string) { + return []; + } + $rx = '/('; + while (65535 < $length) { + $rx .= '\\X{65535}'; + $length -= 65535; + } + $rx .= '\\X{' . $length . '})/u'; + $str = clone $this; + $chunks = []; + foreach (\preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) { + $str->string = $chunk; + $chunks[] = clone $str; + } + return $chunks; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $suffix + */ + public function endsWith($suffix) : bool + { + if ($suffix instanceof AbstractString) { + $suffix = $suffix->string; + } elseif (!\is_string($suffix)) { + return parent::endsWith($suffix); + } + $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; + \normalizer_is_normalized($suffix, $form) ?: ($suffix = \normalizer_normalize($suffix, $form)); + if ('' === $suffix || \false === $suffix) { + return \false; + } + if ($this->ignoreCase) { + return 0 === \mb_stripos(\grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)), $suffix, 0, 'UTF-8'); + } + return $suffix === \grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)); + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $string + */ + public function equalsTo($string) : bool + { + if ($string instanceof AbstractString) { + $string = $string->string; + } elseif (!\is_string($string)) { + return parent::equalsTo($string); + } + $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; + \normalizer_is_normalized($string, $form) ?: ($string = \normalizer_normalize($string, $form)); + if ('' !== $string && \false !== $string && $this->ignoreCase) { + return \strlen($string) === \strlen($this->string) && 0 === \mb_stripos($this->string, $string, 0, 'UTF-8'); + } + return $string === $this->string; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $needle + */ + public function indexOf($needle, int $offset = 0) : ?int + { + if ($needle instanceof AbstractString) { + $needle = $needle->string; + } elseif (!\is_string($needle)) { + return parent::indexOf($needle, $offset); + } + $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; + \normalizer_is_normalized($needle, $form) ?: ($needle = \normalizer_normalize($needle, $form)); + if ('' === $needle || \false === $needle) { + return null; + } + try { + $i = $this->ignoreCase ? \grapheme_stripos($this->string, $needle, $offset) : \grapheme_strpos($this->string, $needle, $offset); + } catch (\ValueError $exception) { + return null; + } + return \false === $i ? null : $i; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $needle + */ + public function indexOfLast($needle, int $offset = 0) : ?int + { + if ($needle instanceof AbstractString) { + $needle = $needle->string; + } elseif (!\is_string($needle)) { + return parent::indexOfLast($needle, $offset); + } + $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; + \normalizer_is_normalized($needle, $form) ?: ($needle = \normalizer_normalize($needle, $form)); + if ('' === $needle || \false === $needle) { + return null; + } + $string = $this->string; + if (0 > $offset) { + // workaround https://bugs.php.net/74264 + if (0 > ($offset += \grapheme_strlen($needle))) { + $string = \grapheme_substr($string, 0, $offset); + } + $offset = 0; + } + $i = $this->ignoreCase ? \grapheme_strripos($string, $needle, $offset) : \grapheme_strrpos($string, $needle, $offset); + return \false === $i ? null : $i; + } + /** + * @return static + */ + public function join(array $strings, string $lastGlue = null) + { + $str = parent::join($strings, $lastGlue); + \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string)); + return $str; + } + public function length() : int + { + return \grapheme_strlen($this->string); + } + /** + * @return static + */ + public function normalize(int $form = self::NFC) + { + $str = clone $this; + if (\in_array($form, [self::NFC, self::NFKC], \true)) { + \normalizer_is_normalized($str->string, $form) ?: ($str->string = \normalizer_normalize($str->string, $form)); + } elseif (!\in_array($form, [self::NFD, self::NFKD], \true)) { + throw new InvalidArgumentException('Unsupported normalization form.'); + } elseif (!\normalizer_is_normalized($str->string, $form)) { + $str->string = \normalizer_normalize($str->string, $form); + $str->ignoreCase = null; + } + return $str; + } + /** + * @return static + */ + public function prepend(string ...$prefix) + { + $str = clone $this; + $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $this->string; + \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string)); + if (\false === $str->string) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + return $str; + } + /** + * @return static + */ + public function replace(string $from, string $to) + { + $str = clone $this; + \normalizer_is_normalized($from) ?: ($from = \normalizer_normalize($from)); + if ('' !== $from && \false !== $from) { + $tail = $str->string; + $result = ''; + $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos'; + while ('' !== $tail && \false !== ($i = $indexOf($tail, $from))) { + $slice = \grapheme_substr($tail, 0, $i); + $result .= $slice . $to; + $tail = \substr($tail, \strlen($slice) + \strlen($from)); + } + $str->string = $result . $tail; + \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string)); + if (\false === $str->string) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + } + return $str; + } + /** + * @param string|callable $to + * @return static + */ + public function replaceMatches(string $fromRegexp, $to) + { + $str = parent::replaceMatches($fromRegexp, $to); + \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string)); + return $str; + } + /** + * @return static + */ + public function slice(int $start = 0, int $length = null) + { + $str = clone $this; + $str->string = (string) \grapheme_substr($this->string, $start, $length ?? 2147483647); + return $str; + } + /** + * @return static + */ + public function splice(string $replacement, int $start = 0, int $length = null) + { + $str = clone $this; + $start = $start ? \strlen(\grapheme_substr($this->string, 0, $start)) : 0; + $length = $length ? \strlen(\grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length; + $str->string = \substr_replace($this->string, $replacement, $start, $length ?? 2147483647); + \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string)); + if (\false === $str->string) { + throw new InvalidArgumentException('Invalid UTF-8 string.'); + } + return $str; + } + public function split(string $delimiter, int $limit = null, int $flags = null) : array + { + if (1 > ($limit = $limit ?? 2147483647)) { + throw new InvalidArgumentException('Split limit must be a positive integer.'); + } + if ('' === $delimiter) { + throw new InvalidArgumentException('Split delimiter is empty.'); + } + if (null !== $flags) { + return parent::split($delimiter . 'u', $limit, $flags); + } + \normalizer_is_normalized($delimiter) ?: ($delimiter = \normalizer_normalize($delimiter)); + if (\false === $delimiter) { + throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.'); + } + $str = clone $this; + $tail = $this->string; + $chunks = []; + $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos'; + while (1 < $limit && \false !== ($i = $indexOf($tail, $delimiter))) { + $str->string = \grapheme_substr($tail, 0, $i); + $chunks[] = clone $str; + $tail = \substr($tail, \strlen($str->string) + \strlen($delimiter)); + --$limit; + } + $str->string = $tail; + $chunks[] = clone $str; + return $chunks; + } + /** + * @param string|iterable|\Symfony\Component\String\AbstractString $prefix + */ + public function startsWith($prefix) : bool + { + if ($prefix instanceof AbstractString) { + $prefix = $prefix->string; + } elseif (!\is_string($prefix)) { + return parent::startsWith($prefix); + } + $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC; + \normalizer_is_normalized($prefix, $form) ?: ($prefix = \normalizer_normalize($prefix, $form)); + if ('' === $prefix || \false === $prefix) { + return \false; + } + if ($this->ignoreCase) { + return 0 === \mb_stripos(\grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES), $prefix, 0, 'UTF-8'); + } + return $prefix === \grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES); + } + public function __wakeup() + { + if (!\is_string($this->string)) { + throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__); + } + \normalizer_is_normalized($this->string) ?: ($this->string = \normalizer_normalize($this->string)); + } + public function __clone() + { + if (null === $this->ignoreCase) { + \normalizer_is_normalized($this->string) ?: ($this->string = \normalizer_normalize($this->string)); + } + $this->ignoreCase = \false; + } +} diff --git a/vendor/symfony/string/composer.json b/vendor/symfony/string/composer.json new file mode 100644 index 0000000000..f32762f8d0 --- /dev/null +++ b/vendor/symfony/string/composer.json @@ -0,0 +1,54 @@ +{ + "name": "symfony\/string", + "type": "library", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "keywords": [ + "string", + "utf8", + "utf-8", + "grapheme", + "i18n", + "unicode" + ], + "homepage": "https:\/\/symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https:\/\/symfony.com\/contributors" + } + ], + "require": { + "php": ">=8.1", + "symfony\/polyfill-ctype": "~1.8", + "symfony\/polyfill-intl-grapheme": "~1.0", + "symfony\/polyfill-intl-normalizer": "~1.0", + "symfony\/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony\/error-handler": "^5.4|^6.0", + "symfony\/intl": "^6.2", + "symfony\/http-client": "^5.4|^6.0", + "symfony\/translation-contracts": "^2.5|^3.0", + "symfony\/var-exporter": "^5.4|^6.0" + }, + "conflict": { + "symfony\/translation-contracts": "<2.5" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources\/functions.php" + ], + "exclude-from-classmap": [ + "\/Tests\/" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/vendor/symplify/autowire-array-parameter/LICENSE b/vendor/symplify/autowire-array-parameter/LICENSE new file mode 100644 index 0000000000..3fe586ede2 --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/LICENSE @@ -0,0 +1,25 @@ +The MIT License +--------------- + +Copyright (c) 2018 Tomas Votruba (https://tomasvotruba.com) + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/symplify/autowire-array-parameter/composer.json b/vendor/symplify/autowire-array-parameter/composer.json new file mode 100644 index 0000000000..f43f7cd7be --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/composer.json @@ -0,0 +1,54 @@ +{ + "name": "symplify\/autowire-array-parameter", + "description": "Autowire array parameters for your Symfony applications", + "license": "MIT", + "require": { + "php": ">=8.1", + "nette\/utils": "^3.2", + "symfony\/dependency-injection": "6.1.*" + }, + "require-dev": { + "php-parallel-lint\/php-parallel-lint": "^1.3", + "phpstan\/extension-installer": "^1.2", + "phpunit\/phpunit": "^9.5.26", + "rector\/rector": "^0.15.10", + "symplify\/easy-ci": "^11.1", + "symplify\/easy-coding-standard": "^11.1", + "symplify\/package-builder": "^11.2", + "symplify\/phpstan-extensions": "^11.1", + "symplify\/symplify-kernel": "^11.2", + "tomasvotruba\/unused-public": "^0.0.34" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\AutowireArrayParameter\\Tests\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "scripts": { + "check-cs": "vendor\/bin\/ecs check --ansi", + "fix-cs": "vendor\/bin\/ecs check --fix --ansi", + "phpstan": "vendor\/bin\/phpstan analyse --ansi --error-format symplify", + "rector": "vendor\/bin\/rector process --dry-run --ansi", + "release": "vendor\/bin\/monorepo-builder release patch --ansi" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true, + "platform-check": false, + "allow-plugins": { + "cweagans\/composer-patches": true, + "phpstan\/extension-installer": true + } + } +} \ No newline at end of file diff --git a/vendor/symplify/autowire-array-parameter/easy-ci.php b/vendor/symplify/autowire-array-parameter/easy-ci.php new file mode 100644 index 0000000000..692a50d96a --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/easy-ci.php @@ -0,0 +1,10 @@ +typesToSkip([AutowireArrayParameterCompilerPass::class]); +}; diff --git a/vendor/symplify/autowire-array-parameter/ecs.php b/vendor/symplify/autowire-array-parameter/ecs.php new file mode 100644 index 0000000000..9b49fa681d --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/ecs.php @@ -0,0 +1,11 @@ +paths([__DIR__ . '/ecs.php', __DIR__ . '/rector.php', __DIR__ . '/easy-ci.php', __DIR__ . '/src', __DIR__ . '/tests']); + $ecsConfig->sets([SetList::COMMON, SetList::PSR_12]); +}; diff --git a/vendor/symplify/autowire-array-parameter/phpstan.neon b/vendor/symplify/autowire-array-parameter/phpstan.neon new file mode 100644 index 0000000000..7f1fc23444 --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/phpstan.neon @@ -0,0 +1,15 @@ +parameters: + level: 8 + + paths: + - src + - tests + + excludePaths: + - '*/tests/**/Source/*' + - '*/tests/**/Fixture/*' + + unused_public: + methods: true + properties: true + constants: true diff --git a/vendor/symplify/autowire-array-parameter/rector.php b/vendor/symplify/autowire-array-parameter/rector.php new file mode 100644 index 0000000000..5dc4cb63c8 --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/rector.php @@ -0,0 +1,26 @@ +sets([ + SetList::CODE_QUALITY, + SetList::DEAD_CODE, + // @todo bump to PHP 8.1 + LevelSetList::UP_TO_PHP_80, + SetList::CODING_STYLE, + SetList::TYPE_DECLARATION, + SetList::NAMING, + SetList::PRIVATIZATION, + SetList::EARLY_RETURN, + PHPUnitSetList::PHPUNIT_CODE_QUALITY, + ]); + $rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests']); + $rectorConfig->importNames(); + $rectorConfig->skip(['*/Source/*', '*/Fixture/*']); +}; diff --git a/vendor/symplify/autowire-array-parameter/src/DependencyInjection/CompilerPass/AutowireArrayParameterCompilerPass.php b/vendor/symplify/autowire-array-parameter/src/DependencyInjection/CompilerPass/AutowireArrayParameterCompilerPass.php new file mode 100644 index 0000000000..4b1d9cb398 --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/src/DependencyInjection/CompilerPass/AutowireArrayParameterCompilerPass.php @@ -0,0 +1,155 @@ +definitionFinder = new DefinitionFinder(); + $paramTypeDocBlockResolver = new ParamTypeDocBlockResolver(); + $this->parameterTypeResolver = new ParameterTypeResolver($paramTypeDocBlockResolver); + $this->parameterSkipper = new ParameterSkipper($this->parameterTypeResolver, $excludedFatalClasses); + } + public function process(ContainerBuilder $containerBuilder) : void + { + $definitions = $containerBuilder->getDefinitions(); + foreach ($definitions as $definition) { + if ($this->shouldSkipDefinition($containerBuilder, $definition)) { + continue; + } + /** @var ReflectionClass $reflectionClass */ + $reflectionClass = $containerBuilder->getReflectionClass($definition->getClass()); + /** @var ReflectionMethod $constructorReflectionMethod */ + $constructorReflectionMethod = $reflectionClass->getConstructor(); + $this->processParameters($containerBuilder, $constructorReflectionMethod, $definition); + } + } + private function shouldSkipDefinition(ContainerBuilder $containerBuilder, Definition $definition) : bool + { + if ($definition->isAbstract()) { + return \true; + } + if ($definition->getClass() === null) { + return \true; + } + // here class name can be "%parameter.class%" + $parameterBag = $containerBuilder->getParameterBag(); + $resolvedClassName = $parameterBag->resolveValue($definition->getClass()); + // skip 3rd party classes, they're autowired by own config + $excludedNamespacePattern = '#^(' . \implode('|', self::EXCLUDED_NAMESPACES) . ')\\\\#'; + if (Strings::match($resolvedClassName, $excludedNamespacePattern)) { + return \true; + } + if (\in_array($resolvedClassName, self::EXCLUDED_FATAL_CLASSES, \true)) { + return \true; + } + if ($definition->getFactory()) { + return \true; + } + if (!\class_exists($definition->getClass())) { + return \true; + } + $reflectionClass = $containerBuilder->getReflectionClass($definition->getClass()); + if (!$reflectionClass instanceof ReflectionClass) { + return \true; + } + if (!$reflectionClass->hasMethod('__construct')) { + return \true; + } + /** @var ReflectionMethod $constructorReflectionMethod */ + $constructorReflectionMethod = $reflectionClass->getConstructor(); + return !$constructorReflectionMethod->getParameters(); + } + private function processParameters(ContainerBuilder $containerBuilder, ReflectionMethod $reflectionMethod, Definition $definition) : void + { + $reflectionParameters = $reflectionMethod->getParameters(); + foreach ($reflectionParameters as $reflectionParameter) { + if ($this->parameterSkipper->shouldSkipParameter($reflectionMethod, $definition, $reflectionParameter)) { + continue; + } + $parameterType = $this->parameterTypeResolver->resolveParameterType($reflectionParameter->getName(), $reflectionMethod); + if ($parameterType === null) { + continue; + } + $definitionsOfType = $this->definitionFinder->findAllByType($containerBuilder, $parameterType); + $definitionsOfType = $this->filterOutAbstractDefinitions($definitionsOfType); + $argumentName = '$' . $reflectionParameter->getName(); + $definition->setArgument($argumentName, $this->createReferencesFromDefinitions($definitionsOfType)); + } + } + /** + * Abstract definitions cannot be the target of references + * + * @param Definition[] $definitions + * @return Definition[] + */ + private function filterOutAbstractDefinitions(array $definitions) : array + { + foreach ($definitions as $key => $definition) { + if ($definition->isAbstract()) { + unset($definitions[$key]); + } + } + return $definitions; + } + /** + * @param Definition[] $definitions + * @return Reference[] + */ + private function createReferencesFromDefinitions(array $definitions) : array + { + $references = []; + $definitionOfTypeNames = \array_keys($definitions); + foreach ($definitionOfTypeNames as $definitionOfTypeName) { + $references[] = new Reference($definitionOfTypeName); + } + return $references; + } +} diff --git a/vendor/symplify/autowire-array-parameter/src/DependencyInjection/DefinitionFinder.php b/vendor/symplify/autowire-array-parameter/src/DependencyInjection/DefinitionFinder.php new file mode 100644 index 0000000000..528a06351b --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/src/DependencyInjection/DefinitionFinder.php @@ -0,0 +1,64 @@ +getDefinitions(); + foreach ($containerBuilderDefinitions as $name => $definition) { + $class = $definition->getClass() ?: $name; + if (!$this->doesClassExists($class)) { + continue; + } + if (\is_a($class, $type, \true)) { + $definitions[$name] = $definition; + } + } + return $definitions; + } + public function getByType(ContainerBuilder $containerBuilder, string $type) : Definition + { + $definition = $this->getByTypeIfExists($containerBuilder, $type); + if ($definition !== null) { + return $definition; + } + throw new DefinitionForTypeNotFoundException(\sprintf('Definition for type "%s" was not found.', $type)); + } + private function getByTypeIfExists(ContainerBuilder $containerBuilder, string $type) : ?Definition + { + $containerBuilderDefinitions = $containerBuilder->getDefinitions(); + foreach ($containerBuilderDefinitions as $name => $definition) { + $class = $definition->getClass() ?: $name; + if (!$this->doesClassExists($class)) { + continue; + } + if (\is_a($class, $type, \true)) { + return $definition; + } + } + return null; + } + private function doesClassExists(string $class) : bool + { + try { + return \class_exists($class); + } catch (Throwable $exception) { + return \false; + } + } +} diff --git a/vendor/symplify/autowire-array-parameter/src/DocBlock/ParamTypeDocBlockResolver.php b/vendor/symplify/autowire-array-parameter/src/DocBlock/ParamTypeDocBlockResolver.php new file mode 100644 index 0000000000..4c63db4e6c --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/src/DocBlock/ParamTypeDocBlockResolver.php @@ -0,0 +1,48 @@ +[\\w\\\\]+)\\[\\]\\s+\\$' . self::NAME_PLACEHOLDER . '#'; + /** + * @var string + * @see https://regex101.com/r/FZ50hn/2 + */ + private const SHAPE_REGEX = '#@param\\s+(array|iterable)\\<(?<' . self::TYPE_PART . '>[\\w\\\\]+)\\>\\s+\\$' . self::NAME_PLACEHOLDER . '#'; + /** + * @var string + */ + private const NAME_PLACEHOLDER = '__NAME__'; + /** + * @var string[] + */ + private const ARRAY_REGEXES = [self::NORMAL_REGEX, self::SHAPE_REGEX]; + public function resolve(string $docBlock, string $parameterName) : ?string + { + foreach (self::ARRAY_REGEXES as $arrayRegexWithPlaceholder) { + $arrayRegex = \str_replace(self::NAME_PLACEHOLDER, $parameterName, $arrayRegexWithPlaceholder); + $result = Strings::match($docBlock, $arrayRegex); + if (isset($result[self::TYPE_PART])) { + return $result[self::TYPE_PART]; + } + } + return null; + } +} diff --git a/vendor/symplify/autowire-array-parameter/src/Exception/DependencyInjection/DefinitionForTypeNotFoundException.php b/vendor/symplify/autowire-array-parameter/src/Exception/DependencyInjection/DefinitionForTypeNotFoundException.php new file mode 100644 index 0000000000..cf014b27c8 --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/src/Exception/DependencyInjection/DefinitionForTypeNotFoundException.php @@ -0,0 +1,9 @@ +parameterTypeResolver = $parameterTypeResolver; + $this->excludedFatalClasses = \array_merge(self::DEFAULT_EXCLUDED_FATAL_CLASSES, $excludedFatalClasses); + } + public function shouldSkipParameter(ReflectionMethod $reflectionMethod, Definition $definition, ReflectionParameter $reflectionParameter) : bool + { + if (!$this->isArrayType($reflectionParameter)) { + return \true; + } + // already set + $argumentName = '$' . $reflectionParameter->getName(); + if (isset($definition->getArguments()[$argumentName])) { + return \true; + } + $parameterType = $this->parameterTypeResolver->resolveParameterType($reflectionParameter->getName(), $reflectionMethod); + if ($parameterType === null) { + return \true; + } + if (\in_array($parameterType, $this->excludedFatalClasses, \true)) { + return \true; + } + if (!\class_exists($parameterType) && !\interface_exists($parameterType)) { + return \true; + } + // prevent circular dependency + if ($definition->getClass() === null) { + return \false; + } + return \is_a($definition->getClass(), $parameterType, \true); + } + private function isArrayType(ReflectionParameter $reflectionParameter) : bool + { + if ($reflectionParameter->getType() === null) { + return \false; + } + $reflectionParameterType = $reflectionParameter->getType(); + if (!$reflectionParameterType instanceof ReflectionNamedType) { + return \false; + } + return $reflectionParameterType->getName() === 'array'; + } +} diff --git a/vendor/symplify/autowire-array-parameter/src/TypeResolver/ParameterTypeResolver.php b/vendor/symplify/autowire-array-parameter/src/TypeResolver/ParameterTypeResolver.php new file mode 100644 index 0000000000..30508e5187 --- /dev/null +++ b/vendor/symplify/autowire-array-parameter/src/TypeResolver/ParameterTypeResolver.php @@ -0,0 +1,47 @@ + + */ + private $resolvedParameterTypesCached = []; + public function __construct(ParamTypeDocBlockResolver $paramTypeDocBlockResolver) + { + $this->paramTypeDocBlockResolver = $paramTypeDocBlockResolver; + } + public function resolveParameterType(string $parameterName, ReflectionMethod $reflectionMethod) : ?string + { + $docComment = $reflectionMethod->getDocComment(); + if ($docComment === \false) { + return null; + } + $declaringReflectionClass = $reflectionMethod->getDeclaringClass(); + $uniqueKey = $parameterName . $declaringReflectionClass->getName() . $reflectionMethod->getName(); + if (isset($this->resolvedParameterTypesCached[$uniqueKey])) { + return $this->resolvedParameterTypesCached[$uniqueKey]; + } + $resolvedType = $this->paramTypeDocBlockResolver->resolve($docComment, $parameterName); + if ($resolvedType === null) { + return null; + } + // not a class|interface type + if (\ctype_lower($resolvedType[0])) { + return null; + } + $resolvedClass = Reflection::expandClassName($resolvedType, $declaringReflectionClass); + $this->resolvedParameterTypesCached[$uniqueKey] = $resolvedClass; + return $resolvedClass; + } +} diff --git a/vendor/symplify/easy-testing/LICENSE b/vendor/symplify/easy-testing/LICENSE new file mode 100644 index 0000000000..2dbf78e6f9 --- /dev/null +++ b/vendor/symplify/easy-testing/LICENSE @@ -0,0 +1,25 @@ +The MIT License +--------------- + +Copyright (c) 2020 Tomas Votruba (https://tomasvotruba.com) + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/symplify/easy-testing/bin/easy-testing b/vendor/symplify/easy-testing/bin/easy-testing new file mode 100644 index 0000000000..e0350d4357 --- /dev/null +++ b/vendor/symplify/easy-testing/bin/easy-testing @@ -0,0 +1,5 @@ +#!/usr/bin/env php +run(); diff --git a/vendor/symplify/easy-testing/composer.json b/vendor/symplify/easy-testing/composer.json new file mode 100644 index 0000000000..beae70d1d1 --- /dev/null +++ b/vendor/symplify/easy-testing/composer.json @@ -0,0 +1,53 @@ +{ + "name": "symplify\/easy-testing", + "description": "Testing made easy", + "license": "MIT", + "type": "symfony-bundle", + "bin": [ + "bin\/easy-testing" + ], + "require": { + "php": ">=8.1", + "nette\/utils": "^3.2", + "symfony\/finder": "^6.2", + "symfony\/console": "^6.2", + "symfony\/dependency-injection": "6.1.*", + "symplify\/package-builder": "^11.1.25", + "symplify\/smart-file-system": "^11.1.25", + "symplify\/symplify-kernel": "^11.1.25" + }, + "require-dev": { + "phpunit\/phpunit": "^9.5.26" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\EasyTesting\\Tests\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "conflict": { + "symplify\/phpstan-rules": "<11.1.24", + "symplify\/rule-doc-generator-contracts": "<11.1.25", + "symplify\/php-config-printer": "<11.1.25", + "symplify\/autowire-array-parameter": "<11.1.25", + "symplify\/phpstan-extensions": "<11.1.25", + "symplify\/rule-doc-generator": "<11.1.25", + "symplify\/symfony-static-dumper": "<11.1.25", + "symplify\/config-transformer": "<11.1.24", + "symplify\/coding-standard": "<11.1.24", + "symplify\/easy-parallel": "<11.1.25", + "symplify\/easy-ci": "<11.1.24", + "symplify\/monorepo-builder": "<11.1.24" + }, + "minimum-stability": "dev", + "prefer-stable": true +} \ No newline at end of file diff --git a/vendor/symplify/easy-testing/config/config.php b/vendor/symplify/easy-testing/config/config.php new file mode 100644 index 0000000000..cb81828158 --- /dev/null +++ b/vendor/symplify/easy-testing/config/config.php @@ -0,0 +1,16 @@ +services(); + $services->defaults()->public()->autowire(); + $services->load('MonorepoBuilderPrefix202310\Symplify\EasyTesting\\', __DIR__ . '/../src')->exclude([__DIR__ . '/../src/DataProvider', __DIR__ . '/../src/Kernel', __DIR__ . '/../src/ValueObject']); + // console + $services->set(Application::class)->call('add', [service(ValidateFixtureSkipNamingCommand::class)]); +}; diff --git a/vendor/symplify/easy-testing/src/Command/ValidateFixtureSkipNamingCommand.php b/vendor/symplify/easy-testing/src/Command/ValidateFixtureSkipNamingCommand.php new file mode 100644 index 0000000000..68f70ad4ad --- /dev/null +++ b/vendor/symplify/easy-testing/src/Command/ValidateFixtureSkipNamingCommand.php @@ -0,0 +1,58 @@ +missplacedSkipPrefixResolver = $missplacedSkipPrefixResolver; + $this->fixtureFinder = $fixtureFinder; + parent::__construct(); + } + protected function configure() : void + { + $this->setName('validate-fixture-skip-naming'); + $this->addArgument(Option::SOURCE, InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Paths to analyse'); + $this->setDescription('Check that skipped fixture files (without `-----` separator) have a "skip" prefix'); + } + protected function execute(InputInterface $input, OutputInterface $output) : int + { + $source = (array) $input->getArgument(Option::SOURCE); + $fixtureFileInfos = $this->fixtureFinder->find($source); + $incorrectAndMissingSkips = $this->missplacedSkipPrefixResolver->resolve($fixtureFileInfos); + foreach ($incorrectAndMissingSkips->getIncorrectSkipFileInfos() as $incorrectSkipFileInfo) { + $errorMessage = \sprintf('The file "%s" should drop the "skip/keep" prefix', $incorrectSkipFileInfo->getRelativeFilePathFromCwd()); + $this->symfonyStyle->note($errorMessage); + } + foreach ($incorrectAndMissingSkips->getMissingSkipFileInfos() as $missingSkipFileInfo) { + $errorMessage = \sprintf('The file "%s" should start with "skip/keep" prefix', $missingSkipFileInfo->getRelativeFilePathFromCwd()); + $this->symfonyStyle->note($errorMessage); + } + $countError = $incorrectAndMissingSkips->getFileCount(); + if ($incorrectAndMissingSkips->getFileCount() === 0) { + $message = \sprintf('All %d fixture files have valid names', \count($fixtureFileInfos)); + $this->symfonyStyle->success($message); + return self::SUCCESS; + } + $errorMessage = \sprintf('Found %d test file fixtures with wrong prefix', $countError); + $this->symfonyStyle->error($errorMessage); + return self::FAILURE; + } +} diff --git a/vendor/symplify/easy-testing/src/DataProvider/StaticFixtureFinder.php b/vendor/symplify/easy-testing/src/DataProvider/StaticFixtureFinder.php new file mode 100644 index 0000000000..bdde06c79f --- /dev/null +++ b/vendor/symplify/easy-testing/src/DataProvider/StaticFixtureFinder.php @@ -0,0 +1,112 @@ +> + */ + public static function yieldDirectory(string $directory, string $suffix = '*.php.inc') : Iterator + { + $fileInfos = self::findFilesInDirectory($directory, $suffix); + return self::yieldFileInfos($fileInfos); + } + /** + * @return Iterator + */ + public static function yieldDirectoryExclusively(string $directory, string $suffix = '*.php.inc') : Iterator + { + $fileInfos = self::findFilesInDirectoryExclusively($directory, $suffix); + return self::yieldFileInfos($fileInfos); + } + /** + * @return Iterator> + */ + public static function yieldDirectoryWithRelativePathname(string $directory, string $suffix = '*.php.inc') : Iterator + { + $fileInfos = self::findFilesInDirectory($directory, $suffix); + return self::yieldFileInfosWithRelativePathname($fileInfos); + } + /** + * @return Iterator> + */ + public static function yieldDirectoryExclusivelyWithRelativePathname(string $directory, string $suffix = '*.php.inc') : Iterator + { + $fileInfos = self::findFilesInDirectoryExclusively($directory, $suffix); + return self::yieldFileInfosWithRelativePathname($fileInfos); + } + /** + * @param SplFileInfo[] $fileInfos + * @return Iterator> + */ + private static function yieldFileInfos(array $fileInfos) : Iterator + { + foreach ($fileInfos as $fileInfo) { + try { + $smartFileInfo = new SmartFileInfo($fileInfo->getRealPath()); + (yield [$smartFileInfo]); + } catch (FileNotFoundException $exception) { + } + } + } + /** + * @param SplFileInfo[] $fileInfos + * @return Iterator> + */ + private static function yieldFileInfosWithRelativePathname(array $fileInfos) : Iterator + { + foreach ($fileInfos as $fileInfo) { + try { + $smartFileInfo = new SmartFileInfo($fileInfo->getRealPath()); + (yield $fileInfo->getRelativePathname() => [$smartFileInfo]); + } catch (FileNotFoundException $exception) { + } + } + } + /** + * @return SplFileInfo[] + */ + private static function findFilesInDirectory(string $directory, string $suffix) : array + { + $finder = Finder::create()->in($directory)->files()->name($suffix); + $fileInfos = \iterator_to_array($finder); + return \array_values($fileInfos); + } + /** + * @return SplFileInfo[] + */ + private static function findFilesInDirectoryExclusively(string $directory, string $suffix) : array + { + self::ensureNoOtherFileName($directory, $suffix); + $finder = Finder::create()->in($directory)->files()->name($suffix); + $fileInfos = \iterator_to_array($finder->getIterator()); + return \array_values($fileInfos); + } + private static function ensureNoOtherFileName(string $directory, string $suffix) : void + { + $finder = Finder::create()->in($directory)->files()->notName($suffix); + /** @var SplFileInfo[] $fileInfos */ + $fileInfos = \iterator_to_array($finder->getIterator()); + $relativeFilePaths = []; + foreach ($fileInfos as $fileInfo) { + $relativeFilePaths[] = Strings::substring($fileInfo->getRealPath(), \strlen(\getcwd()) + 1); + } + if ($relativeFilePaths === []) { + return; + } + throw new ShouldNotHappenException(\sprintf('Files "%s" have invalid suffix, use "%s" suffix instead', \implode('", ', $relativeFilePaths), $suffix)); + } +} diff --git a/vendor/symplify/easy-testing/src/DataProvider/StaticFixtureUpdater.php b/vendor/symplify/easy-testing/src/DataProvider/StaticFixtureUpdater.php new file mode 100644 index 0000000000..6395890902 --- /dev/null +++ b/vendor/symplify/easy-testing/src/DataProvider/StaticFixtureUpdater.php @@ -0,0 +1,50 @@ +dumpFile($fixtureFileInfo->getRealPath(), $newOriginalContent); + } + public static function updateExpectedFixtureContent(string $newOriginalContent, SmartFileInfo $expectedFixtureFileInfo) : void + { + if (!\getenv('UPDATE_TESTS') && !\getenv('UT')) { + return; + } + self::getSmartFileSystem()->dumpFile($expectedFixtureFileInfo->getRealPath(), $newOriginalContent); + } + private static function getSmartFileSystem() : SmartFileSystem + { + return new SmartFileSystem(); + } + /** + * @param \Symplify\SmartFileSystem\SmartFileInfo|string $originalFileInfo + */ + private static function resolveNewFixtureContent($originalFileInfo, string $changedContent) : string + { + if ($originalFileInfo instanceof SmartFileInfo) { + $originalContent = $originalFileInfo->getContents(); + } else { + $originalContent = $originalFileInfo; + } + if ($originalContent === $changedContent) { + return $originalContent; + } + return $originalContent . '-----' . \PHP_EOL . $changedContent; + } +} diff --git a/vendor/symplify/easy-testing/src/Finder/FixtureFinder.php b/vendor/symplify/easy-testing/src/Finder/FixtureFinder.php new file mode 100644 index 0000000000..cfabaa4f89 --- /dev/null +++ b/vendor/symplify/easy-testing/src/Finder/FixtureFinder.php @@ -0,0 +1,29 @@ +finderSanitizer = $finderSanitizer; + } + /** + * @param string[] $sources + * @return SmartFileInfo[] + */ + public function find(array $sources) : array + { + $finder = new Finder(); + $finder->files()->in($sources)->name('*.php.inc')->path('Fixture')->sortByName(); + return $this->finderSanitizer->sanitize($finder); + } +} diff --git a/vendor/symplify/easy-testing/src/FixtureSplitter/TrioFixtureSplitter.php b/vendor/symplify/easy-testing/src/FixtureSplitter/TrioFixtureSplitter.php new file mode 100644 index 0000000000..c522afe25f --- /dev/null +++ b/vendor/symplify/easy-testing/src/FixtureSplitter/TrioFixtureSplitter.php @@ -0,0 +1,33 @@ +getContents(), SplitLine::SPLIT_LINE_REGEX); + $this->ensureHasThreeParts($parts, $smartFileInfo); + return new TrioContent($parts[0], $parts[1], $parts[2]); + } + /** + * @param mixed[] $parts + */ + private function ensureHasThreeParts(array $parts, SmartFileInfo $smartFileInfo) : void + { + if (\count($parts) === 3) { + return; + } + $message = \sprintf('The fixture "%s" should have 3 parts. %d found', $smartFileInfo->getRelativeFilePathFromCwd(), \count($parts)); + throw new ShouldNotHappenException($message); + } +} diff --git a/vendor/symplify/easy-testing/src/Kernel/EasyTestingKernel.php b/vendor/symplify/easy-testing/src/Kernel/EasyTestingKernel.php new file mode 100644 index 0000000000..13c42b27f5 --- /dev/null +++ b/vendor/symplify/easy-testing/src/Kernel/EasyTestingKernel.php @@ -0,0 +1,19 @@ +create($configFiles); + } +} diff --git a/vendor/symplify/easy-testing/src/MissplacedSkipPrefixResolver.php b/vendor/symplify/easy-testing/src/MissplacedSkipPrefixResolver.php new file mode 100644 index 0000000000..afe719f713 --- /dev/null +++ b/vendor/symplify/easy-testing/src/MissplacedSkipPrefixResolver.php @@ -0,0 +1,41 @@ +hasNameSkipStart($fixtureFileInfo); + $fileContents = $fixtureFileInfo->getContents(); + $hasSplitLine = (bool) Strings::match($fileContents, SplitLine::SPLIT_LINE_REGEX); + if ($hasNameSkipStart && $hasSplitLine) { + $incorrectSkips[] = $fixtureFileInfo; + continue; + } + if (!$hasNameSkipStart && !$hasSplitLine) { + $missingSkips[] = $fixtureFileInfo; + } + } + return new IncorrectAndMissingSkips($incorrectSkips, $missingSkips); + } + private function hasNameSkipStart(SmartFileInfo $fixtureFileInfo) : bool + { + return (bool) Strings::match($fixtureFileInfo->getBasenameWithoutSuffix(), Prefix::SKIP_PREFIX_REGEX); + } +} diff --git a/vendor/symplify/easy-testing/src/PHPUnit/Behavior/DirectoryAssertableTrait.php b/vendor/symplify/easy-testing/src/PHPUnit/Behavior/DirectoryAssertableTrait.php new file mode 100644 index 0000000000..f274ee2941 --- /dev/null +++ b/vendor/symplify/easy-testing/src/PHPUnit/Behavior/DirectoryAssertableTrait.php @@ -0,0 +1,76 @@ +findFileInfosInDirectory($expectedDirectory); + $outputFileInfos = $this->findFileInfosInDirectory($outputDirectory); + $fileInfosByRelativeFilePath = $this->groupFileInfosByRelativeFilePath($expectedFileInfos, $expectedDirectory, $outputFileInfos, $outputDirectory); + foreach ($fileInfosByRelativeFilePath as $relativeFilePath => $expectedAndOutputFileInfoPair) { + // output file exists + $this->assertFileExists($outputDirectory . '/' . $relativeFilePath); + /** @var ExpectedAndOutputFileInfoPair $expectedAndOutputFileInfoPair */ + if (!$expectedAndOutputFileInfoPair->doesOutputFileExist()) { + continue; + } + // they have the same content + $this->assertSame($expectedAndOutputFileInfoPair->getExpectedFileContent(), $expectedAndOutputFileInfoPair->getOutputFileContent(), $relativeFilePath); + } + } + /** + * @return SmartFileInfo[] + */ + private function findFileInfosInDirectory(string $directory) : array + { + $firstDirectoryFinder = new Finder(); + $firstDirectoryFinder->files()->in($directory); + $finderSanitizer = new FinderSanitizer(); + return $finderSanitizer->sanitize($firstDirectoryFinder); + } + /** + * @param SmartFileInfo[] $expectedFileInfos + * @param SmartFileInfo[] $outputFileInfos + * @return array + */ + private function groupFileInfosByRelativeFilePath(array $expectedFileInfos, string $expectedDirectory, array $outputFileInfos, string $outputDirectory) : array + { + $fileInfosByRelativeFilePath = []; + foreach ($expectedFileInfos as $expectedFileInfo) { + $relativeFilePath = $expectedFileInfo->getRelativeFilePathFromDirectory($expectedDirectory); + // match output file info + $outputFileInfo = $this->resolveFileInfoByRelativeFilePath($outputFileInfos, $outputDirectory, $relativeFilePath); + $fileInfosByRelativeFilePath[$relativeFilePath] = new ExpectedAndOutputFileInfoPair($expectedFileInfo, $outputFileInfo); + } + return $fileInfosByRelativeFilePath; + } + /** + * @param SmartFileInfo[] $fileInfos + */ + private function resolveFileInfoByRelativeFilePath(array $fileInfos, string $directory, string $desiredRelativeFilePath) : ?SmartFileInfo + { + foreach ($fileInfos as $fileInfo) { + $relativeFilePath = $fileInfo->getRelativeFilePathFromDirectory($directory); + if ($desiredRelativeFilePath !== $relativeFilePath) { + continue; + } + return $fileInfo; + } + return null; + } +} diff --git a/vendor/symplify/easy-testing/src/PHPUnit/StaticPHPUnitEnvironment.php b/vendor/symplify/easy-testing/src/PHPUnit/StaticPHPUnitEnvironment.php new file mode 100644 index 0000000000..a93aa02284 --- /dev/null +++ b/vendor/symplify/easy-testing/src/PHPUnit/StaticPHPUnitEnvironment.php @@ -0,0 +1,18 @@ +getContents(), SplitLine::SPLIT_LINE_REGEX)); + // if more or less, it could be a test cases for monorepo line in it + if ($splitLineCount === 1) { + // input → expected + [$input, $expected] = Strings::split($smartFileInfo->getContents(), SplitLine::SPLIT_LINE_REGEX); + $expected = self::retypeExpected($expected); + return new InputAndExpected($input, $expected); + } + // no changes + return new InputAndExpected($smartFileInfo->getContents(), $smartFileInfo->getContents()); + } + public static function splitFileInfoToLocalInputAndExpectedFileInfos(SmartFileInfo $smartFileInfo, bool $autoloadTestFixture = \false, bool $preserveDirStructure = \false) : InputFileInfoAndExpectedFileInfo + { + $inputAndExpected = self::splitFileInfoToInputAndExpected($smartFileInfo); + $prefix = ''; + if ($preserveDirStructure) { + $dir = \explode('Fixture', $smartFileInfo->getRealPath(), 2); + $prefix = isset($dir[1]) ? \dirname($dir[1]) . '/' : ''; + $prefix = \ltrim($prefix, '/\\'); + } + $inputFileInfo = self::createTemporaryFileInfo($smartFileInfo, $prefix . 'input', $inputAndExpected->getInput()); + // some files needs to be autoload to enable reflection + if ($autoloadTestFixture) { + require_once $inputFileInfo->getRealPath(); + } + $expectedFileInfo = self::createTemporaryFileInfo($smartFileInfo, $prefix . 'expected', $inputAndExpected->getExpected()); + return new InputFileInfoAndExpectedFileInfo($inputFileInfo, $expectedFileInfo); + } + public static function getTemporaryPath() : string + { + if (self::$customTemporaryPath !== null) { + return self::$customTemporaryPath; + } + return \sys_get_temp_dir() . '/_temp_fixture_easy_testing'; + } + public static function createTemporaryFileInfo(SmartFileInfo $fixtureSmartFileInfo, string $prefix, string $fileContent) : SmartFileInfo + { + $temporaryFilePath = self::createTemporaryPathWithPrefix($fixtureSmartFileInfo, $prefix); + $dir = \dirname($temporaryFilePath); + if (!\is_dir($dir)) { + \mkdir($dir, 0777, \true); + } + /** @phpstan-ignore-next-line we don't use SmartFileSystem->dump() for performance reasons */ + \file_put_contents($temporaryFilePath, $fileContent); + return new SmartFileInfo($temporaryFilePath); + } + public static function splitFileInfoToLocalInputAndExpected(SmartFileInfo $smartFileInfo, bool $autoloadTestFixture = \false) : InputFileInfoAndExpected + { + $inputAndExpected = self::splitFileInfoToInputAndExpected($smartFileInfo); + $inputFileInfo = self::createTemporaryFileInfo($smartFileInfo, 'input', $inputAndExpected->getInput()); + // some files needs to be autoload to enable reflection + if ($autoloadTestFixture) { + require_once $inputFileInfo->getRealPath(); + } + return new InputFileInfoAndExpected($inputFileInfo, $inputAndExpected->getExpected()); + } + private static function createTemporaryPathWithPrefix(SmartFileInfo $smartFileInfo, string $prefix) : string + { + $hash = Strings::substring(\md5($smartFileInfo->getRealPath()), -20); + $fileBasename = $smartFileInfo->getBasename('.inc'); + return self::getTemporaryPath() . \sprintf('/%s_%s_%s', $prefix, $hash, $fileBasename); + } + /** + * @param mixed $expected + * @return mixed + */ + private static function retypeExpected($expected) + { + if (!\is_numeric(\trim($expected))) { + return $expected; + } + // value re-type + if (\strlen((string) (int) $expected) === \strlen(\trim($expected))) { + return (int) $expected; + } + if (\strlen((string) (float) $expected) === \strlen(\trim($expected))) { + return (float) $expected; + } + return $expected; + } +} diff --git a/vendor/symplify/easy-testing/src/ValueObject/EasyTestingConfig.php b/vendor/symplify/easy-testing/src/ValueObject/EasyTestingConfig.php new file mode 100644 index 0000000000..f1eb065891 --- /dev/null +++ b/vendor/symplify/easy-testing/src/ValueObject/EasyTestingConfig.php @@ -0,0 +1,15 @@ +expectedFileInfo = $expectedFileInfo; + $this->outputFileInfo = $outputFileInfo; + } + public function getExpectedFileContent() : string + { + return $this->expectedFileInfo->getContents(); + } + public function getOutputFileContent() : string + { + if (!$this->outputFileInfo instanceof SmartFileInfo) { + throw new ShouldNotHappenException(); + } + return $this->outputFileInfo->getContents(); + } + public function doesOutputFileExist() : bool + { + return $this->outputFileInfo !== null; + } +} diff --git a/vendor/symplify/easy-testing/src/ValueObject/FixtureSplit/TrioContent.php b/vendor/symplify/easy-testing/src/ValueObject/FixtureSplit/TrioContent.php new file mode 100644 index 0000000000..3bfa7ee9a6 --- /dev/null +++ b/vendor/symplify/easy-testing/src/ValueObject/FixtureSplit/TrioContent.php @@ -0,0 +1,41 @@ +firstValue = $firstValue; + $this->secondValue = $secondValue; + $this->expectedResult = $expectedResult; + } + public function getFirstValue() : string + { + return $this->firstValue; + } + public function getSecondValue() : string + { + return $this->secondValue; + } + public function getExpectedResult() : string + { + return $this->expectedResult; + } +} diff --git a/vendor/symplify/easy-testing/src/ValueObject/IncorrectAndMissingSkips.php b/vendor/symplify/easy-testing/src/ValueObject/IncorrectAndMissingSkips.php new file mode 100644 index 0000000000..1f6dd7c3e2 --- /dev/null +++ b/vendor/symplify/easy-testing/src/ValueObject/IncorrectAndMissingSkips.php @@ -0,0 +1,44 @@ +incorrectSkipFileInfos = $incorrectSkipFileInfos; + $this->missingSkipFileInfos = $missingSkipFileInfos; + } + /** + * @return SmartFileInfo[] + */ + public function getIncorrectSkipFileInfos() : array + { + return $this->incorrectSkipFileInfos; + } + /** + * @return SmartFileInfo[] + */ + public function getMissingSkipFileInfos() : array + { + return $this->missingSkipFileInfos; + } + public function getFileCount() : int + { + return \count($this->missingSkipFileInfos) + \count($this->incorrectSkipFileInfos); + } +} diff --git a/vendor/symplify/easy-testing/src/ValueObject/InputAndExpected.php b/vendor/symplify/easy-testing/src/ValueObject/InputAndExpected.php new file mode 100644 index 0000000000..38175c4b29 --- /dev/null +++ b/vendor/symplify/easy-testing/src/ValueObject/InputAndExpected.php @@ -0,0 +1,35 @@ +input = $input; + $this->expected = $expected; + } + public function getInput() : string + { + return $this->input; + } + /** + * @return mixed + */ + public function getExpected() + { + return $this->expected; + } +} diff --git a/vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpected.php b/vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpected.php new file mode 100644 index 0000000000..72a541cf0f --- /dev/null +++ b/vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpected.php @@ -0,0 +1,47 @@ +inputFileInfo = $inputFileInfo; + $this->expected = $expected; + } + public function getInputFileContent() : string + { + return $this->inputFileInfo->getContents(); + } + public function getInputFileInfo() : SmartFileInfo + { + return $this->inputFileInfo; + } + public function getInputFileRealPath() : string + { + return $this->inputFileInfo->getRealPath(); + } + /** + * @return mixed + */ + public function getExpected() + { + return $this->expected; + } +} diff --git a/vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpectedFileInfo.php b/vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpectedFileInfo.php new file mode 100644 index 0000000000..97f8c1def7 --- /dev/null +++ b/vendor/symplify/easy-testing/src/ValueObject/InputFileInfoAndExpectedFileInfo.php @@ -0,0 +1,41 @@ +inputFileInfo = $inputFileInfo; + $this->expectedFileInfo = $expectedFileInfo; + } + public function getInputFileInfo() : SmartFileInfo + { + return $this->inputFileInfo; + } + public function getExpectedFileInfo() : SmartFileInfo + { + return $this->expectedFileInfo; + } + public function getExpectedFileContent() : string + { + return $this->expectedFileInfo->getContents(); + } + public function getExpectedFileInfoRealPath() : string + { + return $this->expectedFileInfo->getRealPath(); + } +} diff --git a/vendor/symplify/easy-testing/src/ValueObject/Option.php b/vendor/symplify/easy-testing/src/ValueObject/Option.php new file mode 100644 index 0000000000..33ff47f171 --- /dev/null +++ b/vendor/symplify/easy-testing/src/ValueObject/Option.php @@ -0,0 +1,12 @@ +=8.1", + "nette\/utils": "^3.2", + "sebastian\/diff": "^5.0", + "symfony\/config": "^6.2", + "symfony\/console": "^6.2", + "symfony\/dependency-injection": "6.1.*", + "symfony\/finder": "^6.2" + }, + "require-dev": { + "php-parallel-lint\/php-parallel-lint": "^1.3", + "phpstan\/extension-installer": "^1.2", + "phpunit\/phpunit": "^10.0", + "rector\/rector": "^0.15.10", + "symplify\/easy-ci": "^11.2.0", + "symplify\/easy-coding-standard": "^11.2", + "symplify\/phpstan-extensions": "^11.1", + "symplify\/phpstan-rules": "^11.2", + "symplify\/symplify-kernel": "^11.1", + "tomasvotruba\/unused-public": "^0.0.34" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\PackageBuilder\\Tests\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "scripts": { + "check-cs": "vendor\/bin\/ecs check --ansi", + "fix-cs": "vendor\/bin\/ecs check --fix --ansi", + "phpstan": "vendor\/bin\/phpstan analyse --ansi --error-format symplify", + "rector": "vendor\/bin\/rector process --dry-run --ansi" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true, + "platform-check": false, + "allow-plugins": { + "cweagans\/composer-patches": true, + "phpstan\/extension-installer": true + } + } +} \ No newline at end of file diff --git a/vendor/symplify/package-builder/config/config.php b/vendor/symplify/package-builder/config/config.php new file mode 100644 index 0000000000..7924c7646c --- /dev/null +++ b/vendor/symplify/package-builder/config/config.php @@ -0,0 +1,21 @@ +services(); + $services->defaults()->public()->autowire(); + $services->set(ColorConsoleDiffFormatter::class); + $services->set(ConsoleDiffer::class); + $services->set(DifferFactory::class); + $services->set(Differ::class)->factory([service(DifferFactory::class), 'create']); + $services->set(PrivatesAccessor::class); +}; diff --git a/vendor/symplify/package-builder/phpstan-baseline.neon b/vendor/symplify/package-builder/phpstan-baseline.neon new file mode 100644 index 0000000000..f652bbc25d --- /dev/null +++ b/vendor/symplify/package-builder/phpstan-baseline.neon @@ -0,0 +1,46 @@ +parameters: + ignoreErrors: + - + message: "#^Parameter \\#1 \\$path of function dirname expects string, string\\|false given\\.$#" + count: 1 + path: src/Composer/VendorDirProvider.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\:\\:getParameterBag\\(\\)\\.$#" + count: 1 + path: src/Parameter/ParameterProvider.php + + - + message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" + count: 1 + path: src/Reflection/ClassLikeExistenceChecker.php + + - + message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\\\|T of object, string given\\.$#" + count: 2 + path: src/Reflection/PrivatesCaller.php + + - + message: "#^Call to method setConfigs\\(\\) on an unknown class Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface\\.$#" + count: 1 + path: src/Testing/AbstractKernelTestCase.php + + - + message: "#^Class Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface not found\\.$#" + count: 2 + path: src/Testing/AbstractKernelTestCase.php + + - + message: "#^PHPDoc tag @var for variable \\$kernel contains unknown class Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface\\.$#" + count: 1 + path: src/Testing/AbstractKernelTestCase.php + + - + message: "#^Parameter \\#1 \\$kernel of method Symplify\\\\PackageBuilder\\\\Testing\\\\AbstractKernelTestCase\\:\\:bootAndReturnKernel\\(\\) expects Symfony\\\\Component\\\\HttpKernel\\\\KernelInterface, Symplify\\\\PackageBuilder\\\\Contract\\\\HttpKernel\\\\ExtraConfigAwareKernelInterface given\\.$#" + count: 1 + path: src/Testing/AbstractKernelTestCase.php + + - + message: "#^Static property Symplify\\\\PackageBuilder\\\\Testing\\\\AbstractKernelTestCase\\:\\:\\$container \\(Symfony\\\\Component\\\\DependencyInjection\\\\ContainerInterface\\|null\\) does not accept Psr\\\\Container\\\\ContainerInterface\\.$#" + count: 2 + path: src/Testing/AbstractKernelTestCase.php diff --git a/vendor/symplify/package-builder/src/Composer/VendorDirProvider.php b/vendor/symplify/package-builder/src/Composer/VendorDirProvider.php new file mode 100644 index 0000000000..88cf5905b7 --- /dev/null +++ b/vendor/symplify/package-builder/src/Composer/VendorDirProvider.php @@ -0,0 +1,31 @@ +reflectionFallback(); + } + private function reflectionFallback() : string + { + $reflectionClass = new ReflectionClass(ClassLoader::class); + return \dirname($reflectionClass->getFileName(), 2); + } +} diff --git a/vendor/symplify/package-builder/src/Console/Command/AbstractSymplifyCommand.php b/vendor/symplify/package-builder/src/Console/Command/AbstractSymplifyCommand.php new file mode 100644 index 0000000000..5f66092686 --- /dev/null +++ b/vendor/symplify/package-builder/src/Console/Command/AbstractSymplifyCommand.php @@ -0,0 +1,47 @@ +addOption(Option::CONFIG, 'c', InputOption::VALUE_REQUIRED, 'Path to config file'); + } + /** + * @required + */ + public function autowire(SymfonyStyle $symfonyStyle, SmartFileSystem $smartFileSystem, SmartFinder $smartFinder, FileSystemGuard $fileSystemGuard) : void + { + $this->symfonyStyle = $symfonyStyle; + $this->smartFileSystem = $smartFileSystem; + $this->smartFinder = $smartFinder; + $this->fileSystemGuard = $fileSystemGuard; + } +} diff --git a/vendor/symplify/package-builder/src/Console/Formatter/ColorConsoleDiffFormatter.php b/vendor/symplify/package-builder/src/Console/Formatter/ColorConsoleDiffFormatter.php new file mode 100644 index 0000000000..5290fa653f --- /dev/null +++ b/vendor/symplify/package-builder/src/Console/Formatter/ColorConsoleDiffFormatter.php @@ -0,0 +1,85 @@ + + * + * @see \Symplify\PackageBuilder\Tests\Console\Formatter\ColorConsoleDiffFormatterTest + */ +final class ColorConsoleDiffFormatter +{ + /** + * @var string + * @see https://regex101.com/r/ovLMDF/1 + */ + private const PLUS_START_REGEX = '#^(\\+.*)#'; + /** + * @var string + * @see https://regex101.com/r/xwywpa/1 + */ + private const MINUT_START_REGEX = '#^(\\-.*)#'; + /** + * @var string + * @see https://regex101.com/r/CMlwa8/1 + */ + private const AT_START_REGEX = '#^(@.*)#'; + /** + * @var string + * @see https://regex101.com/r/qduj2O/1 + */ + private const NEWLINES_REGEX = "#\n\r|\n#"; + /** + * @readonly + * @var string + */ + private $template; + public function __construct() + { + $this->template = \sprintf(' ---------- begin diff ----------%s%%s%s ----------- end diff -----------' . \PHP_EOL, \PHP_EOL, \PHP_EOL); + } + public function format(string $diff) : string + { + return $this->formatWithTemplate($diff, $this->template); + } + private function formatWithTemplate(string $diff, string $template) : string + { + $escapedDiff = OutputFormatter::escape(\rtrim($diff)); + $escapedDiffLines = Strings::split($escapedDiff, self::NEWLINES_REGEX); + // remove description of added + remove; obvious on diffs + foreach ($escapedDiffLines as $key => $escapedDiffLine) { + if ($escapedDiffLine === '--- Original') { + unset($escapedDiffLines[$key]); + } + if ($escapedDiffLine === '+++ New') { + unset($escapedDiffLines[$key]); + } + } + $coloredLines = \array_map(function (string $string) : string { + $string = $this->makePlusLinesGreen($string); + $string = $this->makeMinusLinesRed($string); + $string = $this->makeAtNoteCyan($string); + if ($string === ' ') { + return ''; + } + return $string; + }, $escapedDiffLines); + return \sprintf($template, \implode(\PHP_EOL, $coloredLines)); + } + private function makePlusLinesGreen(string $string) : string + { + return Strings::replace($string, self::PLUS_START_REGEX, '$1'); + } + private function makeMinusLinesRed(string $string) : string + { + return Strings::replace($string, self::MINUT_START_REGEX, '$1'); + } + private function makeAtNoteCyan(string $string) : string + { + return Strings::replace($string, self::AT_START_REGEX, '$1'); + } +} diff --git a/vendor/symplify/package-builder/src/Console/Input/StaticInputDetector.php b/vendor/symplify/package-builder/src/Console/Input/StaticInputDetector.php new file mode 100644 index 0000000000..e3369d49fd --- /dev/null +++ b/vendor/symplify/package-builder/src/Console/Input/StaticInputDetector.php @@ -0,0 +1,17 @@ +hasParameterOption(['--debug', '-v', '-vv', '-vvv']); + } +} diff --git a/vendor/symplify/package-builder/src/Console/Output/ConsoleDiffer.php b/vendor/symplify/package-builder/src/Console/Output/ConsoleDiffer.php new file mode 100644 index 0000000000..85049ec981 --- /dev/null +++ b/vendor/symplify/package-builder/src/Console/Output/ConsoleDiffer.php @@ -0,0 +1,33 @@ +differ = $differ; + $this->colorConsoleDiffFormatter = $colorConsoleDiffFormatter; + } + public function diff(string $old, string $new) : string + { + $diff = $this->differ->diff($old, $new); + return $this->colorConsoleDiffFormatter->format($diff); + } +} diff --git a/vendor/symplify/package-builder/src/Console/Style/SymfonyStyleFactory.php b/vendor/symplify/package-builder/src/Console/Style/SymfonyStyleFactory.php new file mode 100644 index 0000000000..711486306a --- /dev/null +++ b/vendor/symplify/package-builder/src/Console/Style/SymfonyStyleFactory.php @@ -0,0 +1,53 @@ +privatesCaller = new PrivatesCaller(); + } + public function create() : SymfonyStyle + { + // to prevent missing argv indexes + if (!isset($_SERVER['argv'])) { + $_SERVER['argv'] = []; + } + $argvInput = new ArgvInput(); + $consoleOutput = new ConsoleOutput(); + // to configure all -v, -vv, -vvv options without memory-lock to Application run() arguments + $this->privatesCaller->callPrivateMethod(new Application(), 'configureIO', [$argvInput, $consoleOutput]); + // --debug is called + if ($argvInput->hasParameterOption('--debug')) { + $consoleOutput->setVerbosity(OutputInterface::VERBOSITY_DEBUG); + } + // disable output for tests + if ($this->isPHPUnitRun()) { + $consoleOutput->setVerbosity(OutputInterface::VERBOSITY_QUIET); + } + return new SymfonyStyle($argvInput, $consoleOutput); + } + /** + * Never ever used static methods if not neccesary, this is just handy for tests + src to prevent duplication. + */ + private function isPHPUnitRun() : bool + { + return \defined('MonorepoBuilderPrefix202310\\PHPUNIT_COMPOSER_INSTALL') || \defined('MonorepoBuilderPrefix202310\\__PHPUNIT_PHAR__'); + } +} diff --git a/vendor/symplify/package-builder/src/DependencyInjection/CompilerPass/AutowireInterfacesCompilerPass.php b/vendor/symplify/package-builder/src/DependencyInjection/CompilerPass/AutowireInterfacesCompilerPass.php new file mode 100644 index 0000000000..717190a953 --- /dev/null +++ b/vendor/symplify/package-builder/src/DependencyInjection/CompilerPass/AutowireInterfacesCompilerPass.php @@ -0,0 +1,35 @@ +typesToAutowire = $typesToAutowire; + } + public function process(ContainerBuilder $containerBuilder) : void + { + $definitions = $containerBuilder->getDefinitions(); + foreach ($definitions as $definition) { + foreach ($this->typesToAutowire as $typeToAutowire) { + if (!\is_a((string) $definition->getClass(), $typeToAutowire, \true)) { + continue; + } + $definition->setAutowired(\true); + continue 2; + } + } + } +} diff --git a/vendor/symplify/package-builder/src/DependencyInjection/FileLoader/ParameterMergingPhpFileLoader.php b/vendor/symplify/package-builder/src/DependencyInjection/FileLoader/ParameterMergingPhpFileLoader.php new file mode 100644 index 0000000000..581ba9e509 --- /dev/null +++ b/vendor/symplify/package-builder/src/DependencyInjection/FileLoader/ParameterMergingPhpFileLoader.php @@ -0,0 +1,51 @@ +parametersMerger = new ParametersMerger(); + parent::__construct($containerBuilder, $fileLocator); + } + /** + * Same as parent, just merging parameters instead overriding them + * + * @see https://github.com/symplify/symplify/pull/697 + * @param mixed $resource + * @return mixed + */ + public function load($resource, string $type = null) + { + // get old parameters + $parameterBag = $this->container->getParameterBag(); + $oldParameters = $parameterBag->all(); + parent::load($resource); + foreach ($oldParameters as $key => $oldValue) { + $currentParameterValue = $this->container->getParameter($key); + $newValue = $this->parametersMerger->merge($oldValue, $currentParameterValue); + $this->container->setParameter($key, $newValue); + } + return null; + } +} diff --git a/vendor/symplify/package-builder/src/Diff/DifferFactory.php b/vendor/symplify/package-builder/src/Diff/DifferFactory.php new file mode 100644 index 0000000000..3c82b7d600 --- /dev/null +++ b/vendor/symplify/package-builder/src/Diff/DifferFactory.php @@ -0,0 +1,20 @@ +create(); + return new Differ($unifiedDiffOutputBuilder); + } +} diff --git a/vendor/symplify/package-builder/src/Diff/Output/CompleteUnifiedDiffOutputBuilderFactory.php b/vendor/symplify/package-builder/src/Diff/Output/CompleteUnifiedDiffOutputBuilderFactory.php new file mode 100644 index 0000000000..c027929f1d --- /dev/null +++ b/vendor/symplify/package-builder/src/Diff/Output/CompleteUnifiedDiffOutputBuilderFactory.php @@ -0,0 +1,32 @@ +privatesAccessor = $privatesAccessor; + } + /** + * @api + */ + public function create() : UnifiedDiffOutputBuilder + { + $unifiedDiffOutputBuilder = new UnifiedDiffOutputBuilder(''); + $this->privatesAccessor->setPrivateProperty($unifiedDiffOutputBuilder, 'contextLines', 10000); + return $unifiedDiffOutputBuilder; + } +} diff --git a/vendor/symplify/package-builder/src/Exception/HttpKernel/MissingInterfaceException.php b/vendor/symplify/package-builder/src/Exception/HttpKernel/MissingInterfaceException.php new file mode 100644 index 0000000000..755b31e0c1 --- /dev/null +++ b/vendor/symplify/package-builder/src/Exception/HttpKernel/MissingInterfaceException.php @@ -0,0 +1,9 @@ + + */ + private $parameters = []; + public function __construct(ContainerInterface $container) + { + /** @var ParameterBag $parameterBag */ + $parameterBag = $container->getParameterBag(); + $this->parameters = $parameterBag->all(); + } + public function hasParameter(string $name) : bool + { + return isset($this->parameters[$name]); + } + /** + * @api + * @return mixed + */ + public function provideParameter(string $name) + { + return $this->parameters[$name] ?? null; + } + /** + * @api + */ + public function provideStringParameter(string $name) : string + { + $this->ensureParameterIsSet($name); + return (string) $this->parameters[$name]; + } + /** + * @api + * @return mixed[] + */ + public function provideArrayParameter(string $name) : array + { + $this->ensureParameterIsSet($name); + return $this->parameters[$name]; + } + /** + * @api + */ + public function provideBoolParameter(string $parameterName) : bool + { + return $this->parameters[$parameterName] ?? \false; + } + /** + * @param mixed $value + */ + public function changeParameter(string $name, $value) : void + { + $this->parameters[$name] = $value; + } + /** + * @api + * @return mixed[] + */ + public function provide() : array + { + return $this->parameters; + } + /** + * @api + */ + public function provideIntParameter(string $name) : int + { + $this->ensureParameterIsSet($name); + return (int) $this->parameters[$name]; + } + /** + * @api + */ + public function ensureParameterIsSet(string $name) : void + { + if (\array_key_exists($name, $this->parameters)) { + return; + } + throw new ParameterNotFoundException($name); + } +} diff --git a/vendor/symplify/package-builder/src/Php/TypeChecker.php b/vendor/symplify/package-builder/src/Php/TypeChecker.php new file mode 100644 index 0000000000..43eb996021 --- /dev/null +++ b/vendor/symplify/package-builder/src/Php/TypeChecker.php @@ -0,0 +1,24 @@ + $types + * @param object|string $object + */ + public function isInstanceOf($object, array $types) : bool + { + foreach ($types as $type) { + if (\is_a($object, $type, \true)) { + return \true; + } + } + return \false; + } +} diff --git a/vendor/symplify/package-builder/src/Reflection/ClassLikeExistenceChecker.php b/vendor/symplify/package-builder/src/Reflection/ClassLikeExistenceChecker.php new file mode 100644 index 0000000000..898dee56b8 --- /dev/null +++ b/vendor/symplify/package-builder/src/Reflection/ClassLikeExistenceChecker.php @@ -0,0 +1,53 @@ +doesClassLikeExist($classLikeName)) { + return \false; + } + // already known values + if (\in_array($classLikeName, $this->sensitiveExistingClasses, \true)) { + return \true; + } + if (\in_array($classLikeName, $this->sensitiveNonExistingClasses, \true)) { + return \false; + } + $reflectionClass = new ReflectionClass($classLikeName); + if ($classLikeName !== $reflectionClass->getName()) { + $this->sensitiveNonExistingClasses[] = $classLikeName; + return \false; + } + $this->sensitiveExistingClasses[] = $classLikeName; + return \true; + } +} diff --git a/vendor/symplify/package-builder/src/Reflection/PrivatesAccessor.php b/vendor/symplify/package-builder/src/Reflection/PrivatesAccessor.php new file mode 100644 index 0000000000..11759b7282 --- /dev/null +++ b/vendor/symplify/package-builder/src/Reflection/PrivatesAccessor.php @@ -0,0 +1,75 @@ + $valueClassName + * @return T + */ + public function getPrivatePropertyOfClass(object $object, string $propertyName, string $valueClassName) : object + { + $value = $this->getPrivateProperty($object, $propertyName); + if ($value instanceof $valueClassName) { + return $value; + } + $errorMessage = \sprintf('The type "%s" is required, but "%s" type given', $valueClassName, \get_class($value)); + throw new InvalidPrivatePropertyTypeException($errorMessage); + } + /** + * @return mixed + */ + public function getPrivateProperty(object $object, string $propertyName) + { + $propertyReflection = $this->resolvePropertyReflection($object, $propertyName); + $propertyReflection->setAccessible(\true); + return $propertyReflection->getValue($object); + } + /** + * @template T of object + * + * @param class-string $valueClassName + * @param mixed $value + */ + public function setPrivatePropertyOfClass(object $object, string $propertyName, $value, string $valueClassName) : void + { + if ($value instanceof $valueClassName) { + $this->setPrivateProperty($object, $propertyName, $value); + return; + } + $errorMessage = \sprintf('The type "%s" is required, but "%s" type given', $valueClassName, \get_class($value)); + throw new InvalidPrivatePropertyTypeException($errorMessage); + } + /** + * @param mixed $value + */ + public function setPrivateProperty(object $object, string $propertyName, $value) : void + { + $propertyReflection = $this->resolvePropertyReflection($object, $propertyName); + $propertyReflection->setAccessible(\true); + $propertyReflection->setValue($object, $value); + } + private function resolvePropertyReflection(object $object, string $propertyName) : ReflectionProperty + { + if (\property_exists($object, $propertyName)) { + return new ReflectionProperty($object, $propertyName); + } + $parentClass = \get_parent_class($object); + if ($parentClass !== \false) { + return new ReflectionProperty($parentClass, $propertyName); + } + $errorMessage = \sprintf('Property "$%s" was not found in "%s" class', $propertyName, \get_class($object)); + throw new MissingPrivatePropertyException($errorMessage); + } +} diff --git a/vendor/symplify/package-builder/src/Reflection/PrivatesCaller.php b/vendor/symplify/package-builder/src/Reflection/PrivatesCaller.php new file mode 100644 index 0000000000..a423a2d3ec --- /dev/null +++ b/vendor/symplify/package-builder/src/Reflection/PrivatesCaller.php @@ -0,0 +1,50 @@ +newInstanceWithoutConstructor(); + } + $methodReflection = $this->createAccessibleMethodReflection($object, $methodName); + return $methodReflection->invokeArgs($object, $arguments); + } + /** + * @api + * @param object|string $object + * @param mixed $argument + * @return mixed + */ + public function callPrivateMethodWithReference($object, string $methodName, $argument) + { + if (\is_string($object)) { + $reflectionClass = new ReflectionClass($object); + $object = $reflectionClass->newInstanceWithoutConstructor(); + } + $methodReflection = $this->createAccessibleMethodReflection($object, $methodName); + $methodReflection->invokeArgs($object, [&$argument]); + return $argument; + } + private function createAccessibleMethodReflection(object $object, string $methodName) : ReflectionMethod + { + $reflectionMethod = new ReflectionMethod(\get_class($object), $methodName); + $reflectionMethod->setAccessible(\true); + return $reflectionMethod; + } +} diff --git a/vendor/symplify/package-builder/src/Strings/StringFormatConverter.php b/vendor/symplify/package-builder/src/Strings/StringFormatConverter.php new file mode 100644 index 0000000000..5091d53bdb --- /dev/null +++ b/vendor/symplify/package-builder/src/Strings/StringFormatConverter.php @@ -0,0 +1,61 @@ +camelCaseToGlue($input, '_'); + } + public function camelCaseToDashed(string $input) : string + { + return $this->camelCaseToGlue($input, '-'); + } + /** + * @param array $items + * @return array + */ + public function camelCaseToUnderscoreInArrayKeys(array $items) : array + { + foreach ($items as $key => $value) { + if (!\is_string($key)) { + continue; + } + $newKey = $this->camelCaseToUnderscore($key); + if ($key === $newKey) { + continue; + } + $items[$newKey] = $value; + unset($items[$key]); + } + return $items; + } + private function camelCaseToGlue(string $input, string $glue) : string + { + $matches = Strings::matchAll($input, self::BIG_LETTER_REGEX); + $parts = []; + foreach ($matches as $match) { + $parts[] = $match[0] === \strtoupper((string) $match[0]) ? \strtolower($match[0]) : \lcfirst((string) $match[0]); + } + return \implode($glue, $parts); + } +} diff --git a/vendor/symplify/package-builder/src/Strings/StringFormatConverter.phpqIy1Ap b/vendor/symplify/package-builder/src/Strings/StringFormatConverter.phpqIy1Ap new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vendor/symplify/package-builder/src/Testing/AbstractKernelTestCase.php b/vendor/symplify/package-builder/src/Testing/AbstractKernelTestCase.php new file mode 100644 index 0000000000..8e12ada46f --- /dev/null +++ b/vendor/symplify/package-builder/src/Testing/AbstractKernelTestCase.php @@ -0,0 +1,228 @@ + $kernelClass + * @param string[]|SmartFileInfo[] $configs + */ + protected function bootKernelWithConfigs(string $kernelClass, array $configs): void + { + // unwrap file infos to real paths + $configFilePaths = $this->resolveConfigFilePaths($configs); + $configsHash = $this->resolveConfigsHash($configFilePaths); + + $this->ensureKernelShutdown(); + + $bootedKernel = $this->createBootedKernelFromConfigs($kernelClass, $configsHash, $configFilePaths); + + static::$kernel = $bootedKernel; + self::$container = $bootedKernel->getContainer(); + } + + /** + * Syntax sugger to remove static from the test cases vision + * + * @template T of object + * @param class-string $type + * @return T + */ + protected function getService(string $type): object + { + if (self::$container === null) { + throw new ShouldNotHappenException('First, create container with booKernel(KernelClass::class)'); + } + + $service = self::$container->get($type); + if ($service === null) { + $errorMessage = sprintf('Services "%s" was not found', $type); + throw new MissingServiceException($errorMessage); + } + + return $service; + } + + /** + * @param class-string $kernelClass + */ + protected function bootKernel(string $kernelClass): void + { + if (is_a($kernelClass, LightKernelInterface::class, true)) { + /** @var LightKernelInterface $kernel */ + $kernel = new $kernelClass(); + $kernel->createFromConfigs([]); + + static::$kernel = $kernel; + self::$container = $kernel->getContainer(); + return; + } + + $this->ensureKernelShutdown(); + + $kernel = new $kernelClass('test', true); + if (! $kernel instanceof KernelInterface) { + throw new ShouldNotHappenException(); + } + + static::$kernel = $this->bootAndReturnKernel($kernel); + } + + /** + * Shuts the kernel down if it was used in the test. + */ + protected function ensureKernelShutdown(): void + { + if (static::$kernel !== null && static::$kernel instanceof KernelInterface) { + // make sure boot() is called + // @see https://github.com/symfony/symfony/pull/31202/files + $kernelReflectionClass = new ReflectionClass(static::$kernel); + + $containerReflectionProperty = $kernelReflectionClass->getProperty('container'); + $containerReflectionProperty->setAccessible(true); + + $kernel = $containerReflectionProperty->getValue(static::$kernel); + if ($kernel !== null) { + $container = static::$kernel->getContainer(); + static::$kernel->shutdown(); + if ($container instanceof ResetInterface) { + $container->reset(); + } + } + } + + static::$container = null; + } + + /** + * @param string[] $configs + */ + protected function resolveConfigsHash(array $configs): string + { + $configsHash = ''; + foreach ($configs as $config) { + $configsHash .= md5_file($config); + } + + return md5($configsHash); + } + + /** + * @param string[]|SmartFileInfo[] $configs + * @return string[] + */ + protected function resolveConfigFilePaths(array $configs): array + { + $configFilePaths = []; + + foreach ($configs as $config) { + $configFilePaths[] = $config instanceof SmartFileInfo ? $config->getRealPath() : $config; + } + + return $configFilePaths; + } + + /** + * @param \Symfony\Component\HttpKernel\KernelInterface|\Symplify\SymplifyKernel\Contract\LightKernelInterface $kernel + */ + private function ensureIsConfigAwareKernel($kernel): void + { + if ($kernel instanceof LightKernelInterface) { + return; + } + + if ($kernel instanceof ExtraConfigAwareKernelInterface) { + return; + } + + throw new MissingInterfaceException(sprintf( + '"%s" is missing an "%s" interface', + get_class($kernel), + ExtraConfigAwareKernelInterface::class + )); + } + + private function bootAndReturnKernel(KernelInterface $kernel): KernelInterface + { + $kernel->boot(); + + $container = $kernel->getContainer(); + + // private → public service hack? + if ($container->has('test.service_container')) { + $container = $container->get('test.service_container'); + } + + if (! $container instanceof ContainerInterface) { + throw new ShouldNotHappenException(); + } + + // has output? keep it silent out of tests + if ($container->has(SymfonyStyle::class)) { + $symfonyStyle = $container->get(SymfonyStyle::class); + $symfonyStyle->setVerbosity(OutputInterface::VERBOSITY_QUIET); + } + + static::$container = $container; + + return $kernel; + } + + /** + * @param class-string $kernelClass + * @param string[] $configFilePaths + * @return \Symfony\Component\HttpKernel\KernelInterface|\Symplify\SymplifyKernel\Contract\LightKernelInterface + */ + private function createBootedKernelFromConfigs( + string $kernelClass, + string $configsHash, + array $configFilePaths + ) { + if (is_a($kernelClass, LightKernelInterface::class, true)) { + /** @var LightKernelInterface $kernel */ + $kernel = new $kernelClass(); + $kernel->createFromConfigs($configFilePaths); + return $kernel; + } + + $kernel = new $kernelClass('test_' . $configsHash, true); + $this->ensureIsConfigAwareKernel($kernel); + + /** @var ExtraConfigAwareKernelInterface $kernel */ + $kernel->setConfigs($configFilePaths); + + return $this->bootAndReturnKernel($kernel); + } +} diff --git a/vendor/symplify/package-builder/src/ValueObject/ConsoleColorDiffConfig.php b/vendor/symplify/package-builder/src/ValueObject/ConsoleColorDiffConfig.php new file mode 100644 index 0000000000..d8e8800c41 --- /dev/null +++ b/vendor/symplify/package-builder/src/ValueObject/ConsoleColorDiffConfig.php @@ -0,0 +1,15 @@ +mergeLeftToRightWithCallable($left, $right, function ($leftValue, $rightValue) { + return $this->merge($leftValue, $rightValue); + }); + } + if ($left !== null) { + return $left; + } + if (!\is_array($right)) { + return $left; + } + return $right; + } + /** + * The same as above, just with the case if both values being non-array, it will combined them to array: + * + * $this->mergeWithCombine(1, 2); // [1, 2] + * @param mixed $left + * @param mixed $right + * @return mixed + */ + public function mergeWithCombine($left, $right) + { + if (\is_array($left) && \is_array($right)) { + return $this->mergeLeftToRightWithCallable($left, $right, function ($leftValue, $rightValue) { + return $this->mergeWithCombine($leftValue, $rightValue); + }); + } + if ($left === null && \is_array($right)) { + return $right; + } + if (!empty($right) && (array) $left !== (array) $right) { + return $this->mergeWithCombine((array) $right, (array) $left); + } + return $left; + } + /** + * @param array $left + * @param array $right + * @return mixed[] + */ + private function mergeLeftToRightWithCallable(array $left, array $right, callable $mergeCallback) : array + { + foreach ($left as $key => $val) { + if (\is_int($key)) { + // prevent duplicated values in unindexed arrays + if (!\in_array($val, $right, \true)) { + $right[] = $val; + } + } else { + if (isset($right[$key])) { + $val = $mergeCallback($val, $right[$key]); + } + $right[$key] = $val; + } + } + return $right; + } +} diff --git a/vendor/symplify/smart-file-system/LICENSE b/vendor/symplify/smart-file-system/LICENSE new file mode 100644 index 0000000000..6710eb5d5f --- /dev/null +++ b/vendor/symplify/smart-file-system/LICENSE @@ -0,0 +1,25 @@ +The MIT License +--------------- + +Copyright (c) 2019 Tomas Votruba (https://tomasvotruba.com) + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/symplify/smart-file-system/composer.json b/vendor/symplify/smart-file-system/composer.json new file mode 100644 index 0000000000..2fb0d46dfc --- /dev/null +++ b/vendor/symplify/smart-file-system/composer.json @@ -0,0 +1,55 @@ +{ + "name": "symplify\/smart-file-system", + "description": "Sanitized FileInfo with safe getRealPath() and other handy methods", + "license": "MIT", + "require": { + "php": ">=8.1", + "nette\/utils": "^3.2", + "symfony\/filesystem": "^6.2", + "symfony\/finder": "^6.2", + "symplify\/easy-testing": "^11.1" + }, + "require-dev": { + "phpunit\/phpunit": "^9.5.26", + "php-parallel-lint\/php-parallel-lint": "^1.3", + "phpstan\/extension-installer": "^1.2", + "rector\/rector": "^0.15.10", + "symplify\/easy-ci": "^11.1", + "symplify\/easy-coding-standard": "^11.1", + "symplify\/phpstan-extensions": "^11.1", + "symplify\/phpstan-rules": "11.2.3.72", + "symplify\/symplify-kernel": "^11.1", + "tomasvotruba\/unused-public": "^0.0.34" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\SmartFileSystem\\Tests\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "scripts": { + "check-cs": "vendor\/bin\/ecs check --ansi", + "fix-cs": "vendor\/bin\/ecs check --fix --ansi", + "phpstan": "vendor\/bin\/phpstan analyse --ansi --error-format symplify", + "rector": "vendor\/bin\/rector process --dry-run --ansi" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true, + "platform-check": false, + "allow-plugins": { + "cweagans\/composer-patches": true, + "phpstan\/extension-installer": true + } + } +} \ No newline at end of file diff --git a/vendor/symplify/smart-file-system/src/Exception/DirectoryNotFoundException.php b/vendor/symplify/smart-file-system/src/Exception/DirectoryNotFoundException.php new file mode 100644 index 0000000000..34528b7558 --- /dev/null +++ b/vendor/symplify/smart-file-system/src/Exception/DirectoryNotFoundException.php @@ -0,0 +1,9 @@ +isFileInfoValid($fileInfo)) { + continue; + } + /** @var string $realPath */ + $realPath = $fileInfo->getRealPath(); + $smartFileInfos[] = new SmartFileInfo($realPath); + } + return $smartFileInfos; + } + private function isFileInfoValid(SplFileInfo $fileInfo) : bool + { + return (bool) $fileInfo->getRealPath(); + } +} diff --git a/vendor/symplify/smart-file-system/src/Finder/SmartFinder.php b/vendor/symplify/smart-file-system/src/Finder/SmartFinder.php new file mode 100644 index 0000000000..74ee44ba4f --- /dev/null +++ b/vendor/symplify/smart-file-system/src/Finder/SmartFinder.php @@ -0,0 +1,68 @@ +finderSanitizer = $finderSanitizer; + $this->fileSystemFilter = $fileSystemFilter; + } + /** + * @param string[] $directoriesOrFiles + * @return SmartFileInfo[] + */ + public function findPaths(array $directoriesOrFiles, string $path) : array + { + $directories = $this->fileSystemFilter->filterDirectories($directoriesOrFiles); + $fileInfos = []; + if ($directories !== []) { + $finder = new Finder(); + $finder->name('*')->in($directories)->path($path)->files()->sortByName(); + $fileInfos = $this->finderSanitizer->sanitize($finder); + } + return $fileInfos; + } + /** + * @param string[] $directoriesOrFiles + * @param string[] $excludedDirectories + * @return SmartFileInfo[] + */ + public function find(array $directoriesOrFiles, string $name, array $excludedDirectories = []) : array + { + $directories = $this->fileSystemFilter->filterDirectories($directoriesOrFiles); + $fileInfos = []; + if ($directories !== []) { + $finder = new Finder(); + $finder->name($name)->in($directories)->files()->sortByName(); + if ($excludedDirectories !== []) { + $finder->exclude($excludedDirectories); + } + $fileInfos = $this->finderSanitizer->sanitize($finder); + } + $files = $this->fileSystemFilter->filterFiles($directoriesOrFiles); + foreach ($files as $file) { + $fileInfos[] = new SmartFileInfo($file); + } + return $fileInfos; + } +} diff --git a/vendor/symplify/smart-file-system/src/Json/JsonFileSystem.php b/vendor/symplify/smart-file-system/src/Json/JsonFileSystem.php new file mode 100644 index 0000000000..760e4c52bf --- /dev/null +++ b/vendor/symplify/smart-file-system/src/Json/JsonFileSystem.php @@ -0,0 +1,57 @@ +fileSystemGuard = $fileSystemGuard; + $this->smartFileSystem = $smartFileSystem; + } + /** + * @return mixed[] + */ + public function loadFilePathToJson(string $filePath) : array + { + $this->fileSystemGuard->ensureFileExists($filePath, __METHOD__); + $fileContent = $this->smartFileSystem->readFile($filePath); + return Json::decode($fileContent, Json::FORCE_ARRAY); + } + /** + * @param array $jsonArray + */ + public function writeJsonToFilePath(array $jsonArray, string $filePath) : void + { + $jsonContent = Json::encode($jsonArray, Json::PRETTY) . \PHP_EOL; + $this->smartFileSystem->dumpFile($filePath, $jsonContent); + } + /** + * @param array $newJsonArray + */ + public function mergeArrayToJsonFile(string $filePath, array $newJsonArray) : void + { + $jsonArray = $this->loadFilePathToJson($filePath); + $newComposerJsonArray = Arrays::mergeTree($jsonArray, $newJsonArray); + $this->writeJsonToFilePath($newComposerJsonArray, $filePath); + } +} diff --git a/vendor/symplify/smart-file-system/src/Normalizer/PathNormalizer.php b/vendor/symplify/smart-file-system/src/Normalizer/PathNormalizer.php new file mode 100644 index 0000000000..624b483e96 --- /dev/null +++ b/vendor/symplify/smart-file-system/src/Normalizer/PathNormalizer.php @@ -0,0 +1,77 @@ +normalizePathParts($pathParts, $scheme); + $pathStart = $scheme !== self::SCHEME_UNDEFINED ? $scheme . '://' : ''; + return $pathStart . $pathRoot . \implode($directorySeparator, $normalizedPathParts); + } + /** + * @param string[] $pathParts + * @return string[] + */ + private function normalizePathParts(array $pathParts, string $scheme) : array + { + $normalizedPathParts = []; + foreach ($pathParts as $pathPart) { + if ($pathPart === '.') { + continue; + } + if ($pathPart !== '..') { + $normalizedPathParts[] = $pathPart; + continue; + } + /** @var string $removedPart */ + $removedPart = \array_pop($normalizedPathParts); + if ($scheme !== 'phar') { + continue; + } + if (\substr_compare($removedPart, '.phar', -\strlen('.phar')) !== 0) { + continue; + } + $scheme = self::SCHEME_UNDEFINED; + } + return $normalizedPathParts; + } +} diff --git a/vendor/symplify/smart-file-system/src/SmartFileInfo.php b/vendor/symplify/smart-file-system/src/SmartFileInfo.php new file mode 100644 index 0000000000..157acafa70 --- /dev/null +++ b/vendor/symplify/smart-file-system/src/SmartFileInfo.php @@ -0,0 +1,127 @@ +smartFileSystem = new SmartFileSystem(); + // accepts also dirs + if (!\file_exists($filePath)) { + throw new FileNotFoundException(\sprintf('File path "%s" was not found while creating "%s" object.', $filePath, self::class)); + } + // real path doesn't work in PHAR: https://www.php.net/manual/en/function.realpath.php + if (\strncmp($filePath, 'phar://', \strlen('phar://')) === 0) { + $relativeFilePath = $filePath; + $relativeDirectoryPath = \dirname($filePath); + } else { + $realPath = \realpath($filePath); + $relativeFilePath = \rtrim($this->smartFileSystem->makePathRelative($realPath, \getcwd()), '/'); + $relativeDirectoryPath = \dirname($relativeFilePath); + } + parent::__construct($filePath, $relativeDirectoryPath, $relativeFilePath); + } + public function getBasenameWithoutSuffix() : string + { + return \pathinfo($this->getFilename())['filename']; + } + public function getSuffix() : string + { + return \pathinfo($this->getFilename(), \PATHINFO_EXTENSION); + } + /** + * @param string[] $suffixes + */ + public function hasSuffixes(array $suffixes) : bool + { + return \in_array($this->getSuffix(), $suffixes, \true); + } + public function getRealPathWithoutSuffix() : string + { + return Strings::replace($this->getRealPath(), self::LAST_SUFFIX_REGEX, ''); + } + public function getRelativeFilePath() : string + { + return $this->getRelativePathname(); + } + public function getRelativeDirectoryPath() : string + { + return $this->getRelativePath(); + } + public function getRelativeFilePathFromDirectory(string $directory) : string + { + if (!\file_exists($directory)) { + throw new DirectoryNotFoundException(\sprintf('Directory "%s" was not found in %s.', $directory, self::class)); + } + $relativeFilePath = $this->smartFileSystem->makePathRelative($this->getNormalizedRealPath(), (string) \realpath($directory)); + return \rtrim($relativeFilePath, '/'); + } + public function getRelativeFilePathFromCwdInTests() : string + { + // special case for tests + if (StaticPHPUnitEnvironment::isPHPUnitRun()) { + return $this->getRelativeFilePathFromDirectory(StaticFixtureSplitter::getTemporaryPath()); + } + return $this->getRelativeFilePathFromDirectory(\getcwd()); + } + public function getRelativeFilePathFromCwd() : string + { + return $this->getRelativeFilePathFromDirectory(\getcwd()); + } + public function endsWith(string $string) : bool + { + return \substr_compare($this->getNormalizedRealPath(), $string, -\strlen($string)) === 0; + } + public function doesFnmatch(string $string) : bool + { + $normalizedPath = $this->normalizePath($string); + if (\fnmatch($normalizedPath, $this->getNormalizedRealPath())) { + return \true; + } + // in case of relative compare + return \fnmatch('*/' . $normalizedPath, $this->getNormalizedRealPath()); + } + public function getRealPath() : string + { + // for phar compatibility @see https://github.com/rectorphp/rector/commit/e5d7cee69558f7e6b35d995a5ca03fa481b0407c + return parent::getRealPath() ?: $this->getPathname(); + } + public function getRealPathDirectory() : string + { + return \dirname($this->getRealPath()); + } + public function startsWith(string $partialPath) : bool + { + return \strncmp($this->getNormalizedRealPath(), $partialPath, \strlen($partialPath)) === 0; + } + private function getNormalizedRealPath() : string + { + return $this->normalizePath($this->getRealPath()); + } + private function normalizePath(string $path) : string + { + return \str_replace('\\', '/', $path); + } +} diff --git a/vendor/symplify/smart-file-system/src/SmartFileSystem.php b/vendor/symplify/smart-file-system/src/SmartFileSystem.php new file mode 100644 index 0000000000..839be582f1 --- /dev/null +++ b/vendor/symplify/smart-file-system/src/SmartFileSystem.php @@ -0,0 +1,49 @@ +getLastError()); + throw new IOException($message, 0, null, $fileName); + } + return $source; + } + /** + * Converts given HTML code to plain text + * + * @source https://github.com/nette/utils/blob/e7bd59f1dd860d25dbbb1ac720dddd0fa1388f4c/src/Utils/Html.php#L325-L331 + */ + private function htmlToText(string $html) : string + { + $content = \strip_tags($html); + return \html_entity_decode($content, \ENT_QUOTES | \ENT_HTML5, 'UTF-8'); + } + /** + * Returns the last PHP error as plain string. + * + * @source https://github.com/nette/utils/blob/ab8eea12b8aacc7ea5bdafa49b711c2988447994/src/Utils/Helpers.php#L31-L40 + */ + private function getLastError() : string + { + $message = \error_get_last()['message'] ?? ''; + $htmlMessage = \ini_get('html_errors') ? $this->htmlToText($message) : $message; + return Strings::replace($htmlMessage, self::BEFORE_COLLON_REGEX, ''); + } +} diff --git a/vendor/symplify/symplify-kernel/README.md b/vendor/symplify/symplify-kernel/README.md new file mode 100644 index 0000000000..8dddfc807f --- /dev/null +++ b/vendor/symplify/symplify-kernel/README.md @@ -0,0 +1,71 @@ +# Symplify Kernel + +[![Downloads total](https://img.shields.io/packagist/dt/symplify/symplify-kernel.svg?style=flat-square)](https://packagist.org/packages/symplify/symplify-kernel/stats) + +Do you use Symfony Kernel, but not for PHP projects? + +Use Symfony Kernel for: + +* light [Symfony Console Apps](https://tomasvotruba.com/blog/introducing-light-kernel-for-symfony-console-apps/) without Http +* faster and easy-to-setup tests +* merging of array parameters in 2 configs + +## Install + +```bash +composer require symplify/symplify-kernel --dev +``` + +## Usage + +### 1. Light Kernel for Symfony CLI Apps + +```php +use Psr\Container\ContainerInterface; +use Symplify\SymplifyKernel\ContainerBuilderFactory; + +final class MonorepoBuilderKernel +{ + /** + * @param string[] $configFiles + */ + public function createFromConfigs(array $configFiles): ContainerInterface + { + // local config here + $configFiles[] = __DIR__ . '/../../config/config.php'; + + $containerBuilderFactory = new ContainerBuilderFactory(); + $containerBuilder = $containerBuilderFactory->create($configFiles, [], []); + + // build the container + $containerBuilder->compile(); + + return $containerBuilder; + } +} +``` + +Then use in your `bin/app.php` file: + +```php +$easyCIKernel = new MonorepoBuilderKernel(); +$easyCIKernel->createFromConfigs([__DIR__ . '/config/config.php']); + +$container = $easyCIKernel->getContainer(); + +/** @var Application $application */ +$application = $container->get(Application::class); +exit($application->run()); +``` + +That's it! + +
+ +## Report Issues + +In case you are experiencing a bug or want to request a new feature head over to the [Symplify monorepo issue tracker](https://github.com/symplify/symplify/issues) + +## Contribute + +The sources of this package are contained in the Symplify monorepo. We welcome contributions for this package on [symplify/symplify](https://github.com/symplify/symplify). diff --git a/vendor/symplify/symplify-kernel/composer.json b/vendor/symplify/symplify-kernel/composer.json new file mode 100644 index 0000000000..53870ff445 --- /dev/null +++ b/vendor/symplify/symplify-kernel/composer.json @@ -0,0 +1,48 @@ +{ + "name": "symplify\/symplify-kernel", + "description": "Internal Kernel for Symplify packages", + "license": "MIT", + "require": { + "php": ">=8.1", + "symfony\/console": "^6.2", + "symfony\/dependency-injection": "6.1.*", + "symplify\/smart-file-system": "^11.1.25", + "symplify\/autowire-array-parameter": "^11.1.25", + "symplify\/package-builder": "^11.1.25", + "webmozart\/assert": "^1.11" + }, + "require-dev": { + "phpunit\/phpunit": "^9.5.26" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Symplify\\SymplifyKernel\\Tests\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-main": "11.2-dev" + } + }, + "conflict": { + "symplify\/phpstan-rules": "<11.1.24", + "symplify\/easy-testing": "<11.1.25", + "symplify\/rule-doc-generator-contracts": "<11.1.25", + "symplify\/php-config-printer": "<11.1.25", + "symplify\/phpstan-extensions": "<11.1.25", + "symplify\/rule-doc-generator": "<11.1.25", + "symplify\/symfony-static-dumper": "<11.1.25", + "symplify\/config-transformer": "<11.1.24", + "symplify\/coding-standard": "<11.1.24", + "symplify\/easy-parallel": "<11.1.25", + "symplify\/easy-ci": "<11.1.24", + "symplify\/monorepo-builder": "<11.1.24" + }, + "minimum-stability": "dev", + "prefer-stable": true +} \ No newline at end of file diff --git a/vendor/symplify/symplify-kernel/config/common-config.php b/vendor/symplify/symplify-kernel/config/common-config.php new file mode 100644 index 0000000000..f7300db533 --- /dev/null +++ b/vendor/symplify/symplify-kernel/config/common-config.php @@ -0,0 +1,31 @@ +services(); + $services->defaults()->public()->autowire(); + // symfony style + $services->set(SymfonyStyleFactory::class); + $services->set(SymfonyStyle::class)->factory([service(SymfonyStyleFactory::class), 'create']); + // filesystem + $services->set(FinderSanitizer::class); + $services->set(SmartFileSystem::class); + $services->set(SmartFinder::class); + $services->set(FileSystemGuard::class); + $services->set(FileSystemFilter::class); + $services->set(ParameterProvider::class)->args([service('service_container')]); + $services->set(PrivatesAccessor::class); +}; diff --git a/vendor/symplify/symplify-kernel/phpunit.xml b/vendor/symplify/symplify-kernel/phpunit.xml new file mode 100644 index 0000000000..1ad690939b --- /dev/null +++ b/vendor/symplify/symplify-kernel/phpunit.xml @@ -0,0 +1,9 @@ + + + tests + + diff --git a/vendor/symplify/symplify-kernel/src/Config/Loader/ParameterMergingLoaderFactory.php b/vendor/symplify/symplify-kernel/src/Config/Loader/ParameterMergingLoaderFactory.php new file mode 100644 index 0000000000..0b9ace5cb8 --- /dev/null +++ b/vendor/symplify/symplify-kernel/src/Config/Loader/ParameterMergingLoaderFactory.php @@ -0,0 +1,22 @@ +loaderFactory = $loaderFactory; + } + /** + * @param string[] $configFiles + * @param CompilerPassInterface[] $compilerPasses + * @param ExtensionInterface[] $extensions + */ + public function create(array $configFiles, array $compilerPasses, array $extensions) : ContainerBuilder + { + Assert::allIsAOf($extensions, ExtensionInterface::class); + Assert::allIsAOf($compilerPasses, CompilerPassInterface::class); + Assert::allString($configFiles); + Assert::allFile($configFiles); + $containerBuilder = new ContainerBuilder(); + $this->registerExtensions($containerBuilder, $extensions); + $this->registerConfigFiles($containerBuilder, $configFiles); + $this->registerCompilerPasses($containerBuilder, $compilerPasses); + // this calls load() method in every extensions + // ensure these extensions are implicitly loaded + $compilerPassConfig = $containerBuilder->getCompilerPassConfig(); + $compilerPassConfig->setMergePass(new LoadExtensionConfigsCompilerPass()); + return $containerBuilder; + } + /** + * @param ExtensionInterface[] $extensions + */ + private function registerExtensions(ContainerBuilder $containerBuilder, array $extensions) : void + { + foreach ($extensions as $extension) { + $containerBuilder->registerExtension($extension); + } + } + /** + * @param CompilerPassInterface[] $compilerPasses + */ + private function registerCompilerPasses(ContainerBuilder $containerBuilder, array $compilerPasses) : void + { + foreach ($compilerPasses as $compilerPass) { + $containerBuilder->addCompilerPass($compilerPass); + } + } + /** + * @param string[] $configFiles + */ + private function registerConfigFiles(ContainerBuilder $containerBuilder, array $configFiles) : void + { + $delegatingLoader = $this->loaderFactory->create($containerBuilder, \getcwd()); + foreach ($configFiles as $configFile) { + $delegatingLoader->load($configFile); + } + } +} diff --git a/vendor/symplify/symplify-kernel/src/Contract/Config/LoaderFactoryInterface.php b/vendor/symplify/symplify-kernel/src/Contract/Config/LoaderFactoryInterface.php new file mode 100644 index 0000000000..297fb50f6d --- /dev/null +++ b/vendor/symplify/symplify-kernel/src/Contract/Config/LoaderFactoryInterface.php @@ -0,0 +1,11 @@ +getExtensions()); + foreach ($extensionNames as $extensionName) { + $containerBuilder->loadFromExtension($extensionName, []); + } + parent::process($containerBuilder); + } +} diff --git a/vendor/symplify/symplify-kernel/src/Exception/BootException.php b/vendor/symplify/symplify-kernel/src/Exception/BootException.php new file mode 100644 index 0000000000..34deac751b --- /dev/null +++ b/vendor/symplify/symplify-kernel/src/Exception/BootException.php @@ -0,0 +1,9 @@ +create($configFiles, $compilerPasses, $extensions); + $containerBuilder->compile(); + $this->container = $containerBuilder; + return $containerBuilder; + } + public function getContainer() : \MonorepoBuilderPrefix202310\Psr\Container\ContainerInterface + { + if (!$this->container instanceof Container) { + throw new ShouldNotHappenException(); + } + return $this->container; + } +} diff --git a/vendor/symplify/symplify-kernel/src/ValueObject/KernelBootAndApplicationRun.php b/vendor/symplify/symplify-kernel/src/ValueObject/KernelBootAndApplicationRun.php new file mode 100644 index 0000000000..38acf5f9e2 --- /dev/null +++ b/vendor/symplify/symplify-kernel/src/ValueObject/KernelBootAndApplicationRun.php @@ -0,0 +1,98 @@ + + */ + private $kernelClass; + /** + * @var string[] + */ + private $extraConfigs = []; + /** + * @param class-string $kernelClass + * @param string[] $extraConfigs + */ + public function __construct(string $kernelClass, array $extraConfigs = []) + { + $this->kernelClass = $kernelClass; + $this->extraConfigs = $extraConfigs; + $this->validateKernelClass($this->kernelClass); + } + public function run() : void + { + try { + $this->booKernelAndRunApplication(); + } catch (Throwable $throwable) { + $symfonyStyleFactory = new SymfonyStyleFactory(); + $symfonyStyle = $symfonyStyleFactory->create(); + $symfonyStyle->error($throwable->getMessage()); + exit(Command::FAILURE); + } + } + /** + * @return \Symfony\Component\HttpKernel\KernelInterface|\Symplify\SymplifyKernel\Contract\LightKernelInterface + */ + private function createKernel() + { + // random has is needed, so cache is invalidated and changes from config are loaded + $kernelClass = $this->kernelClass; + if (\is_a($kernelClass, LightKernelInterface::class, \true)) { + return new $kernelClass(); + } + $environment = 'prod' . \random_int(1, 100000); + return new $kernelClass($environment, StaticInputDetector::isDebug()); + } + private function booKernelAndRunApplication() : void + { + $kernel = $this->createKernel(); + if ($kernel instanceof LightKernelInterface) { + $container = $kernel->createFromConfigs($this->extraConfigs); + } else { + $kernel->boot(); + $container = $kernel->getContainer(); + } + /** @var Application $application */ + $application = $container->get(Application::class); + // remove --no-interaction (with -n shortcut) option from Application + // because we need to create option with -n shortcuts too + // for example: --dry-run with shortcut -n + $inputDefinition = $application->getDefinition(); + $options = $inputDefinition->getOptions(); + $options = \array_filter($options, static function ($option) : bool { + return $option->getName() !== 'no-interaction'; + }); + $inputDefinition->setOptions($options); + exit($application->run()); + } + /** + * @param class-string $kernelClass + */ + private function validateKernelClass(string $kernelClass) : void + { + if (\is_a($kernelClass, KernelInterface::class, \true)) { + return; + } + if (\is_a($kernelClass, LightKernelInterface::class, \true)) { + return; + } + $currentValueType = \get_debug_type($kernelClass); + $errorMessage = \sprintf('Class "%s" must by type of "%s" or "%s". "%s" given', $kernelClass, KernelInterface::class, LightKernelInterface::class, $currentValueType); + throw new BootException($errorMessage); + } +} diff --git a/vendor/symplify/symplify-kernel/src/ValueObject/SymplifyKernelConfig.php b/vendor/symplify/symplify-kernel/src/ValueObject/SymplifyKernelConfig.php new file mode 100644 index 0000000000..c4a095d443 --- /dev/null +++ b/vendor/symplify/symplify-kernel/src/ValueObject/SymplifyKernelConfig.php @@ -0,0 +1,15 @@ +create([__DIR__ . '/config/some_services.php'], [], []); + $hasSmartFileSystemService = $containerBuilder->has(SmartFileSystem::class); + $this->assertTrue($hasSmartFileSystemService); + } +} diff --git a/vendor/symplify/symplify-kernel/tests/ContainerBuilderFactory/config/some_services.php b/vendor/symplify/symplify-kernel/tests/ContainerBuilderFactory/config/some_services.php new file mode 100644 index 0000000000..5abf583b76 --- /dev/null +++ b/vendor/symplify/symplify-kernel/tests/ContainerBuilderFactory/config/some_services.php @@ -0,0 +1,11 @@ +services(); + $services->set(SmartFileSystem::class); +}; diff --git a/vendor/webmozart/assert/CHANGELOG.md b/vendor/webmozart/assert/CHANGELOG.md new file mode 100644 index 0000000000..56c8011dee --- /dev/null +++ b/vendor/webmozart/assert/CHANGELOG.md @@ -0,0 +1,207 @@ +Changelog +========= + +## UNRELEASED + +## 1.11.0 + +### Added + +* Added explicit (non magic) `allNullOr*` methods, with `@psalm-assert` annotations, for better Psalm support. + +### Changed + +* Trait methods will now check the assertion themselves, instead of using `__callStatic` +* `isList` will now deal correctly with (modified) lists that contain `NaN` +* `reportInvalidArgument` now has a return type of `never`. + +### Removed + +* Removed `symfony/polyfill-ctype` as a dependency, and require `ext-cytpe` instead. + * You can still require the `symfony/polyfill-ctype` in your project if you need it, as it provides `ext-ctype` + +## 1.10.0 + +### Added + +* On invalid assertion, we throw a `Webmozart\Assert\InvalidArgumentException` +* Added `Assert::positiveInteger()` + +### Changed + +* Using a trait with real implementations of `all*()` and `nullOr*()` methods to improve psalm compatibility. + +### Removed + +* Support for PHP <7.2 + +## 1.9.1 + +## Fixed + +* provisional support for PHP 8.0 + +## 1.9.0 + +* added better Psalm support for `all*` & `nullOr*` methods +* These methods are now understood by Psalm through a mixin. You may need a newer version of Psalm in order to use this +* added `@psalm-pure` annotation to `Assert::notFalse()` +* added more `@psalm-assert` annotations where appropriate + +## Changed + +* the `all*` & `nullOr*` methods are now declared on an interface, instead of `@method` annotations. +This interface is linked to the `Assert` class with a `@mixin` annotation. Most IDE's have supported this +for a long time, and you should not lose any autocompletion capabilities. PHPStan has supported this since +version `0.12.20`. This package is marked incompatible (with a composer conflict) with phpstan version prior to that. +If you do not use PHPStan than this does not matter. + +## 1.8.0 + +### Added + +* added `Assert::notStartsWith()` +* added `Assert::notEndsWith()` +* added `Assert::inArray()` +* added `@psalm-pure` annotations to pure assertions + +### Fixed + +* Exception messages of comparisons between `DateTime(Immutable)` objects now display their date & time. +* Custom Exception messages for `Assert::count()` now use the values to render the exception message. + +## 1.7.0 (2020-02-14) + +### Added + +* added `Assert::notFalse()` +* added `Assert::isAOf()` +* added `Assert::isAnyOf()` +* added `Assert::isNotA()` + +## 1.6.0 (2019-11-24) + +### Added + +* added `Assert::validArrayKey()` +* added `Assert::isNonEmptyList()` +* added `Assert::isNonEmptyMap()` +* added `@throws InvalidArgumentException` annotations to all methods that throw. +* added `@psalm-assert` for the list type to the `isList` assertion. + +### Fixed + +* `ResourceBundle` & `SimpleXMLElement` now pass the `isCountable` assertions. +They are countable, without implementing the `Countable` interface. +* The doc block of `range` now has the proper variables. +* An empty array will now pass `isList` and `isMap`. As it is a valid form of both. +If a non-empty variant is needed, use `isNonEmptyList` or `isNonEmptyMap`. + +### Changed + +* Removed some `@psalm-assert` annotations, that were 'side effect' assertions See: + * [#144](https://github.com/webmozart/assert/pull/144) + * [#145](https://github.com/webmozart/assert/issues/145) + * [#146](https://github.com/webmozart/assert/pull/146) + * [#150](https://github.com/webmozart/assert/pull/150) +* If you use Psalm, the minimum version needed is `3.6.0`. Which is enforced through a composer conflict. +If you don't use Psalm, then this has no impact. + +## 1.5.0 (2019-08-24) + +### Added + +* added `Assert::uniqueValues()` +* added `Assert::unicodeLetters()` +* added: `Assert::email()` +* added support for [Psalm](https://github.com/vimeo/psalm), by adding `@psalm-assert` annotations where appropriate. + +### Fixed + +* `Assert::endsWith()` would not give the correct result when dealing with a multibyte suffix. +* `Assert::length(), minLength, maxLength, lengthBetween` would not give the correct result when dealing with multibyte characters. + +**NOTE**: These 2 changes may break your assertions if you relied on the fact that multibyte characters didn't behave correctly. + +### Changed + +* The names of some variables have been updated to better reflect what they are. +* All function calls are now in their FQN form, slightly increasing performance. +* Tests are now properly ran against HHVM-3.30 and PHP nightly. + +### Deprecation + +* deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` + * This was already done in 1.3.0, but it was only done through a silenced `trigger_error`. It is now annotated as well. + +## 1.4.0 (2018-12-25) + +### Added + +* added `Assert::ip()` +* added `Assert::ipv4()` +* added `Assert::ipv6()` +* added `Assert::notRegex()` +* added `Assert::interfaceExists()` +* added `Assert::isList()` +* added `Assert::isMap()` +* added polyfill for ctype + +### Fixed + +* Special case when comparing objects implementing `__toString()` + +## 1.3.0 (2018-01-29) + +### Added + +* added `Assert::minCount()` +* added `Assert::maxCount()` +* added `Assert::countBetween()` +* added `Assert::isCountable()` +* added `Assert::notWhitespaceOnly()` +* added `Assert::natural()` +* added `Assert::notContains()` +* added `Assert::isArrayAccessible()` +* added `Assert::isInstanceOfAny()` +* added `Assert::isIterable()` + +### Fixed + +* `stringNotEmpty` will no longer report "0" is an empty string + +### Deprecation + +* deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` + +## 1.2.0 (2016-11-23) + + * added `Assert::throws()` + * added `Assert::count()` + * added extension point `Assert::reportInvalidArgument()` for custom subclasses + +## 1.1.0 (2016-08-09) + + * added `Assert::object()` + * added `Assert::propertyExists()` + * added `Assert::propertyNotExists()` + * added `Assert::methodExists()` + * added `Assert::methodNotExists()` + * added `Assert::uuid()` + +## 1.0.2 (2015-08-24) + + * integrated Style CI + * add tests for minimum package dependencies on Travis CI + +## 1.0.1 (2015-05-12) + + * added support for PHP 5.3.3 + +## 1.0.0 (2015-05-12) + + * first stable release + +## 1.0.0-beta (2015-03-19) + + * first beta release diff --git a/vendor/webmozart/assert/LICENSE b/vendor/webmozart/assert/LICENSE new file mode 100644 index 0000000000..9e2e3075eb --- /dev/null +++ b/vendor/webmozart/assert/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Bernhard Schussek + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/webmozart/assert/README.md b/vendor/webmozart/assert/README.md new file mode 100644 index 0000000000..3b2397a1ab --- /dev/null +++ b/vendor/webmozart/assert/README.md @@ -0,0 +1,287 @@ +Webmozart Assert +================ + +[![Latest Stable Version](https://poser.pugx.org/webmozart/assert/v/stable.svg)](https://packagist.org/packages/webmozart/assert) +[![Total Downloads](https://poser.pugx.org/webmozart/assert/downloads.svg)](https://packagist.org/packages/webmozart/assert) + +This library contains efficient assertions to test the input and output of +your methods. With these assertions, you can greatly reduce the amount of coding +needed to write a safe implementation. + +All assertions in the [`Assert`] class throw an `Webmozart\Assert\InvalidArgumentException` if +they fail. + +FAQ +--- + +**What's the difference to [beberlei/assert]?** + +This library is heavily inspired by Benjamin Eberlei's wonderful [assert package], +but fixes a usability issue with error messages that can't be fixed there without +breaking backwards compatibility. + +This package features usable error messages by default. However, you can also +easily write custom error messages: + +``` +Assert::string($path, 'The path is expected to be a string. Got: %s'); +``` + +In [beberlei/assert], the ordering of the `%s` placeholders is different for +every assertion. This package, on the contrary, provides consistent placeholder +ordering for all assertions: + +* `%s`: The tested value as string, e.g. `"/foo/bar"`. +* `%2$s`, `%3$s`, ...: Additional assertion-specific values, e.g. the + minimum/maximum length, allowed values, etc. + +Check the source code of the assertions to find out details about the additional +available placeholders. + +Installation +------------ + +Use [Composer] to install the package: + +```bash +composer require webmozart/assert +``` + +Example +------- + +```php +use Webmozart\Assert\Assert; + +class Employee +{ + public function __construct($id) + { + Assert::integer($id, 'The employee ID must be an integer. Got: %s'); + Assert::greaterThan($id, 0, 'The employee ID must be a positive integer. Got: %s'); + } +} +``` + +If you create an employee with an invalid ID, an exception is thrown: + +```php +new Employee('foobar'); +// => Webmozart\Assert\InvalidArgumentException: +// The employee ID must be an integer. Got: string + +new Employee(-10); +// => Webmozart\Assert\InvalidArgumentException: +// The employee ID must be a positive integer. Got: -10 +``` + +Assertions +---------- + +The [`Assert`] class provides the following assertions: + +### Type Assertions + +Method | Description +-------------------------------------------------------- | -------------------------------------------------- +`string($value, $message = '')` | Check that a value is a string +`stringNotEmpty($value, $message = '')` | Check that a value is a non-empty string +`integer($value, $message = '')` | Check that a value is an integer +`integerish($value, $message = '')` | Check that a value casts to an integer +`positiveInteger($value, $message = '')` | Check that a value is a positive (non-zero) integer +`float($value, $message = '')` | Check that a value is a float +`numeric($value, $message = '')` | Check that a value is numeric +`natural($value, $message= ''')` | Check that a value is a non-negative integer +`boolean($value, $message = '')` | Check that a value is a boolean +`scalar($value, $message = '')` | Check that a value is a scalar +`object($value, $message = '')` | Check that a value is an object +`resource($value, $type = null, $message = '')` | Check that a value is a resource +`isCallable($value, $message = '')` | Check that a value is a callable +`isArray($value, $message = '')` | Check that a value is an array +`isTraversable($value, $message = '')` (deprecated) | Check that a value is an array or a `\Traversable` +`isIterable($value, $message = '')` | Check that a value is an array or a `\Traversable` +`isCountable($value, $message = '')` | Check that a value is an array or a `\Countable` +`isInstanceOf($value, $class, $message = '')` | Check that a value is an `instanceof` a class +`isInstanceOfAny($value, array $classes, $message = '')` | Check that a value is an `instanceof` at least one class on the array of classes +`notInstanceOf($value, $class, $message = '')` | Check that a value is not an `instanceof` a class +`isAOf($value, $class, $message = '')` | Check that a value is of the class or has one of its parents +`isAnyOf($value, array $classes, $message = '')` | Check that a value is of at least one of the classes or has one of its parents +`isNotA($value, $class, $message = '')` | Check that a value is not of the class or has not one of its parents +`isArrayAccessible($value, $message = '')` | Check that a value can be accessed as an array +`uniqueValues($values, $message = '')` | Check that the given array contains unique values + +### Comparison Assertions + +Method | Description +----------------------------------------------- | ------------------------------------------------------------------ +`true($value, $message = '')` | Check that a value is `true` +`false($value, $message = '')` | Check that a value is `false` +`notFalse($value, $message = '')` | Check that a value is not `false` +`null($value, $message = '')` | Check that a value is `null` +`notNull($value, $message = '')` | Check that a value is not `null` +`isEmpty($value, $message = '')` | Check that a value is `empty()` +`notEmpty($value, $message = '')` | Check that a value is not `empty()` +`eq($value, $value2, $message = '')` | Check that a value equals another (`==`) +`notEq($value, $value2, $message = '')` | Check that a value does not equal another (`!=`) +`same($value, $value2, $message = '')` | Check that a value is identical to another (`===`) +`notSame($value, $value2, $message = '')` | Check that a value is not identical to another (`!==`) +`greaterThan($value, $value2, $message = '')` | Check that a value is greater than another +`greaterThanEq($value, $value2, $message = '')` | Check that a value is greater than or equal to another +`lessThan($value, $value2, $message = '')` | Check that a value is less than another +`lessThanEq($value, $value2, $message = '')` | Check that a value is less than or equal to another +`range($value, $min, $max, $message = '')` | Check that a value is within a range +`inArray($value, array $values, $message = '')` | Check that a value is one of a list of values +`oneOf($value, array $values, $message = '')` | Check that a value is one of a list of values (alias of `inArray`) + +### String Assertions + +You should check that a value is a string with `Assert::string()` before making +any of the following assertions. + +Method | Description +--------------------------------------------------- | ----------------------------------------------------------------- +`contains($value, $subString, $message = '')` | Check that a string contains a substring +`notContains($value, $subString, $message = '')` | Check that a string does not contain a substring +`startsWith($value, $prefix, $message = '')` | Check that a string has a prefix +`notStartsWith($value, $prefix, $message = '')` | Check that a string does not have a prefix +`startsWithLetter($value, $message = '')` | Check that a string starts with a letter +`endsWith($value, $suffix, $message = '')` | Check that a string has a suffix +`notEndsWith($value, $suffix, $message = '')` | Check that a string does not have a suffix +`regex($value, $pattern, $message = '')` | Check that a string matches a regular expression +`notRegex($value, $pattern, $message = '')` | Check that a string does not match a regular expression +`unicodeLetters($value, $message = '')` | Check that a string contains Unicode letters only +`alpha($value, $message = '')` | Check that a string contains letters only +`digits($value, $message = '')` | Check that a string contains digits only +`alnum($value, $message = '')` | Check that a string contains letters and digits only +`lower($value, $message = '')` | Check that a string contains lowercase characters only +`upper($value, $message = '')` | Check that a string contains uppercase characters only +`length($value, $length, $message = '')` | Check that a string has a certain number of characters +`minLength($value, $min, $message = '')` | Check that a string has at least a certain number of characters +`maxLength($value, $max, $message = '')` | Check that a string has at most a certain number of characters +`lengthBetween($value, $min, $max, $message = '')` | Check that a string has a length in the given range +`uuid($value, $message = '')` | Check that a string is a valid UUID +`ip($value, $message = '')` | Check that a string is a valid IP (either IPv4 or IPv6) +`ipv4($value, $message = '')` | Check that a string is a valid IPv4 +`ipv6($value, $message = '')` | Check that a string is a valid IPv6 +`email($value, $message = '')` | Check that a string is a valid e-mail address +`notWhitespaceOnly($value, $message = '')` | Check that a string contains at least one non-whitespace character + +### File Assertions + +Method | Description +----------------------------------- | -------------------------------------------------- +`fileExists($value, $message = '')` | Check that a value is an existing path +`file($value, $message = '')` | Check that a value is an existing file +`directory($value, $message = '')` | Check that a value is an existing directory +`readable($value, $message = '')` | Check that a value is a readable path +`writable($value, $message = '')` | Check that a value is a writable path + +### Object Assertions + +Method | Description +----------------------------------------------------- | -------------------------------------------------- +`classExists($value, $message = '')` | Check that a value is an existing class name +`subclassOf($value, $class, $message = '')` | Check that a class is a subclass of another +`interfaceExists($value, $message = '')` | Check that a value is an existing interface name +`implementsInterface($value, $class, $message = '')` | Check that a class implements an interface +`propertyExists($value, $property, $message = '')` | Check that a property exists in a class/object +`propertyNotExists($value, $property, $message = '')` | Check that a property does not exist in a class/object +`methodExists($value, $method, $message = '')` | Check that a method exists in a class/object +`methodNotExists($value, $method, $message = '')` | Check that a method does not exist in a class/object + +### Array Assertions + +Method | Description +-------------------------------------------------- | ------------------------------------------------------------------ +`keyExists($array, $key, $message = '')` | Check that a key exists in an array +`keyNotExists($array, $key, $message = '')` | Check that a key does not exist in an array +`validArrayKey($key, $message = '')` | Check that a value is a valid array key (int or string) +`count($array, $number, $message = '')` | Check that an array contains a specific number of elements +`minCount($array, $min, $message = '')` | Check that an array contains at least a certain number of elements +`maxCount($array, $max, $message = '')` | Check that an array contains at most a certain number of elements +`countBetween($array, $min, $max, $message = '')` | Check that an array has a count in the given range +`isList($array, $message = '')` | Check that an array is a non-associative list +`isNonEmptyList($array, $message = '')` | Check that an array is a non-associative list, and not empty +`isMap($array, $message = '')` | Check that an array is associative and has strings as keys +`isNonEmptyMap($array, $message = '')` | Check that an array is associative and has strings as keys, and is not empty + +### Function Assertions + +Method | Description +------------------------------------------- | ----------------------------------------------------------------------------------------------------- +`throws($closure, $class, $message = '')` | Check that a function throws a certain exception. Subclasses of the exception class will be accepted. + +### Collection Assertions + +All of the above assertions can be prefixed with `all*()` to test the contents +of an array or a `\Traversable`: + +```php +Assert::allIsInstanceOf($employees, 'Acme\Employee'); +``` + +### Nullable Assertions + +All of the above assertions can be prefixed with `nullOr*()` to run the +assertion only if it the value is not `null`: + +```php +Assert::nullOrString($middleName, 'The middle name must be a string or null. Got: %s'); +``` + +### Extending Assert + +The `Assert` class comes with a few methods, which can be overridden to change the class behaviour. You can also extend it to +add your own assertions. + +#### Overriding methods + +Overriding the following methods in your assertion class allows you to change the behaviour of the assertions: + +* `public static function __callStatic($name, $arguments)` + * This method is used to 'create' the `nullOr` and `all` versions of the assertions. +* `protected static function valueToString($value)` + * This method is used for error messages, to convert the value to a string value for displaying. You could use this for representing a value object with a `__toString` method for example. +* `protected static function typeToString($value)` + * This method is used for error messages, to convert the a value to a string representing its type. +* `protected static function strlen($value)` + * This method is used to calculate string length for relevant methods, using the `mb_strlen` if available and useful. +* `protected static function reportInvalidArgument($message)` + * This method is called when an assertion fails, with the specified error message. Here you can throw your own exception, or log something. + +## Static analysis support + +Where applicable, assertion functions are annotated to support Psalm's +[Assertion syntax](https://psalm.dev/docs/annotating_code/assertion_syntax/). +A dedicated [PHPStan Plugin](https://github.com/phpstan/phpstan-webmozart-assert) is +required for proper type support. + +Authors +------- + +* [Bernhard Schussek] a.k.a. [@webmozart] +* [The Community Contributors] + +Contribute +---------- + +Contributions to the package are always welcome! + +* Report any bugs or issues you find on the [issue tracker]. +* You can grab the source code at the package's [Git repository]. + +License +------- + +All contents of this package are licensed under the [MIT license]. + +[beberlei/assert]: https://github.com/beberlei/assert +[assert package]: https://github.com/beberlei/assert +[Composer]: https://getcomposer.org +[Bernhard Schussek]: https://webmozarts.com +[The Community Contributors]: https://github.com/webmozart/assert/graphs/contributors +[issue tracker]: https://github.com/webmozart/assert/issues +[Git repository]: https://github.com/webmozart/assert +[@webmozart]: https://twitter.com/webmozart +[MIT license]: LICENSE +[`Assert`]: src/Assert.php diff --git a/vendor/webmozart/assert/composer.json b/vendor/webmozart/assert/composer.json new file mode 100644 index 0000000000..151e3c73ec --- /dev/null +++ b/vendor/webmozart/assert/composer.json @@ -0,0 +1,43 @@ +{ + "name": "webmozart\/assert", + "description": "Assertions to validate method input\/output with nice error messages.", + "license": "MIT", + "keywords": [ + "assert", + "check", + "validate" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "require": { + "php": "^7.2 || ^8.0", + "ext-ctype": "*" + }, + "require-dev": { + "phpunit\/phpunit": "^8.5.13" + }, + "conflict": { + "phpstan\/phpstan": "<0.12.20", + "vimeo\/psalm": "<4.6.1 || 4.6.2" + }, + "autoload": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Webmozart\\Assert\\": "src\/" + } + }, + "autoload-dev": { + "psr-4": { + "MonorepoBuilderPrefix202310\\Webmozart\\Assert\\Tests\\": "tests\/", + "MonorepoBuilderPrefix202310\\Webmozart\\Assert\\Bin\\": "bin\/src" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + } +} \ No newline at end of file diff --git a/vendor/webmozart/assert/src/Assert.php b/vendor/webmozart/assert/src/Assert.php new file mode 100644 index 0000000000..8be3eca8a2 --- /dev/null +++ b/vendor/webmozart/assert/src/Assert.php @@ -0,0 +1,1606 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Webmozart\Assert; + +use ArrayAccess; +use BadMethodCallException; +use Closure; +use Countable; +use DateTime; +use DateTimeImmutable; +use Exception; +use ResourceBundle; +use SimpleXMLElement; +use Throwable; +use Traversable; +/** + * Efficient assertions to validate the input/output of your methods. + * + * @since 1.0 + * + * @author Bernhard Schussek + */ +class Assert +{ + use Mixin; + /** + * @psalm-pure + * @psalm-assert string $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function string($value, $message = '') + { + if (!\is_string($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a string. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert non-empty-string $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function stringNotEmpty($value, $message = '') + { + static::string($value, $message); + static::notEq($value, '', $message); + } + /** + * @psalm-pure + * @psalm-assert int $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function integer($value, $message = '') + { + if (!\is_int($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an integer. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert numeric $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function integerish($value, $message = '') + { + if (!\is_numeric($value) || $value != (int) $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an integerish value. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert positive-int $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function positiveInteger($value, $message = '') + { + if (!(\is_int($value) && $value > 0)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a positive integer. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert float $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function float($value, $message = '') + { + if (!\is_float($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a float. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert numeric $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function numeric($value, $message = '') + { + if (!\is_numeric($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a numeric. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert positive-int|0 $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function natural($value, $message = '') + { + if (!\is_int($value) || $value < 0) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a non-negative integer. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert bool $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function boolean($value, $message = '') + { + if (!\is_bool($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a boolean. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert scalar $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function scalar($value, $message = '') + { + if (!\is_scalar($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a scalar. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert object $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function object($value, $message = '') + { + if (!\is_object($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an object. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert resource $value + * + * @param mixed $value + * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function resource($value, $type = null, $message = '') + { + if (!\is_resource($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a resource. Got: %s', static::typeToString($value))); + } + if ($type && $type !== \get_resource_type($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a resource of type %2$s. Got: %s', static::typeToString($value), $type)); + } + } + /** + * @psalm-pure + * @psalm-assert callable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isCallable($value, $message = '') + { + if (!\is_callable($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a callable. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert array $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isArray($value, $message = '') + { + if (!\is_array($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an array. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @deprecated use "isIterable" or "isInstanceOf" instead + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isTraversable($value, $message = '') + { + @\trigger_error(\sprintf('The "%s" assertion is deprecated. You should stop using it, as it will soon be removed in 2.0 version. Use "isIterable" or "isInstanceOf" instead.', __METHOD__), \E_USER_DEPRECATED); + if (!\is_array($value) && !$value instanceof Traversable) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a traversable. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert array|ArrayAccess $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isArrayAccessible($value, $message = '') + { + if (!\is_array($value) && !$value instanceof ArrayAccess) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an array accessible. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert countable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isCountable($value, $message = '') + { + if (!\is_array($value) && !$value instanceof Countable && !$value instanceof ResourceBundle && !$value instanceof SimpleXMLElement) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a countable. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isIterable($value, $message = '') + { + if (!\is_array($value) && !$value instanceof Traversable) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an iterable. Got: %s', static::typeToString($value))); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert ExpectedType $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isInstanceOf($value, $class, $message = '') + { + if (!$value instanceof $class) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of %2$s. Got: %s', static::typeToString($value), $class)); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert !ExpectedType $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notInstanceOf($value, $class, $message = '') + { + if ($value instanceof $class) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance other than %2$s. Got: %s', static::typeToString($value), $class)); + } + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param mixed $value + * @param array $classes + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isInstanceOfAny($value, array $classes, $message = '') + { + foreach ($classes as $class) { + if ($value instanceof $class) { + return; + } + } + static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of any of %2$s. Got: %s', static::typeToString($value), \implode(', ', \array_map(array(static::class, 'valueToString'), $classes)))); + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert ExpectedType|class-string $value + * + * @param object|string $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isAOf($value, $class, $message = '') + { + static::string($class, 'Expected class as a string. Got: %s'); + if (!\is_a($value, $class, \is_string($value))) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of this class or to this class among its parents "%2$s". Got: %s', static::valueToString($value), $class)); + } + } + /** + * @psalm-pure + * @psalm-template UnexpectedType of object + * @psalm-param class-string $class + * @psalm-assert !UnexpectedType $value + * @psalm-assert !class-string $value + * + * @param object|string $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isNotA($value, $class, $message = '') + { + static::string($class, 'Expected class as a string. Got: %s'); + if (\is_a($value, $class, \is_string($value))) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of this class or to this class among its parents other than "%2$s". Got: %s', static::valueToString($value), $class)); + } + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param object|string $value + * @param string[] $classes + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isAnyOf($value, array $classes, $message = '') + { + foreach ($classes as $class) { + static::string($class, 'Expected class as a string. Got: %s'); + if (\is_a($value, $class, \is_string($value))) { + return; + } + } + static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of any of this classes or any of those classes among their parents "%2$s". Got: %s', static::valueToString($value), \implode(', ', $classes))); + } + /** + * @psalm-pure + * @psalm-assert empty $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isEmpty($value, $message = '') + { + if (!empty($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an empty value. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert !empty $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notEmpty($value, $message = '') + { + if (empty($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a non-empty value. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function null($value, $message = '') + { + if (null !== $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected null. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert !null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notNull($value, $message = '') + { + if (null === $value) { + static::reportInvalidArgument($message ?: 'Expected a value other than null.'); + } + } + /** + * @psalm-pure + * @psalm-assert true $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function true($value, $message = '') + { + if (\true !== $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be true. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert false $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function false($value, $message = '') + { + if (\false !== $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be false. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert !false $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notFalse($value, $message = '') + { + if (\false === $value) { + static::reportInvalidArgument($message ?: 'Expected a value other than false.'); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function ip($value, $message = '') + { + if (\false === \filter_var($value, \FILTER_VALIDATE_IP)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be an IP. Got: %s', static::valueToString($value))); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function ipv4($value, $message = '') + { + if (\false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be an IPv4. Got: %s', static::valueToString($value))); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function ipv6($value, $message = '') + { + if (\false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be an IPv6. Got: %s', static::valueToString($value))); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function email($value, $message = '') + { + if (\false === \filter_var($value, \FILTER_VALIDATE_EMAIL)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be a valid e-mail address. Got: %s', static::valueToString($value))); + } + } + /** + * Does non strict comparisons on the items, so ['3', 3] will not pass the assertion. + * + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function uniqueValues(array $values, $message = '') + { + $allValues = \count($values); + $uniqueValues = \count(\array_unique($values)); + if ($allValues !== $uniqueValues) { + $difference = $allValues - $uniqueValues; + static::reportInvalidArgument(\sprintf($message ?: 'Expected an array of unique values, but %s of them %s duplicated', $difference, 1 === $difference ? 'is' : 'are')); + } + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function eq($value, $expect, $message = '') + { + if ($expect != $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($expect))); + } + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notEq($value, $expect, $message = '') + { + if ($expect == $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a different value than %s.', static::valueToString($expect))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function same($value, $expect, $message = '') + { + if ($expect !== $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value identical to %2$s. Got: %s', static::valueToString($value), static::valueToString($expect))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notSame($value, $expect, $message = '') + { + if ($expect === $value) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value not identical to %s.', static::valueToString($expect))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function greaterThan($value, $limit, $message = '') + { + if ($value <= $limit) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value greater than %2$s. Got: %s', static::valueToString($value), static::valueToString($limit))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function greaterThanEq($value, $limit, $message = '') + { + if ($value < $limit) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value greater than or equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($limit))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function lessThan($value, $limit, $message = '') + { + if ($value >= $limit) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value less than %2$s. Got: %s', static::valueToString($value), static::valueToString($limit))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function lessThanEq($value, $limit, $message = '') + { + if ($value > $limit) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value less than or equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($limit))); + } + } + /** + * Inclusive range, so Assert::(3, 3, 5) passes. + * + * @psalm-pure + * + * @param mixed $value + * @param mixed $min + * @param mixed $max + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function range($value, $min, $max, $message = '') + { + if ($value < $min || $value > $max) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value between %2$s and %3$s. Got: %s', static::valueToString($value), static::valueToString($min), static::valueToString($max))); + } + } + /** + * A more human-readable alias of Assert::inArray(). + * + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function oneOf($value, array $values, $message = '') + { + static::inArray($value, $values, $message); + } + /** + * Does strict comparison, so Assert::inArray(3, ['3']) does not pass the assertion. + * + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function inArray($value, array $values, $message = '') + { + if (!\in_array($value, $values, \true)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected one of: %2$s. Got: %s', static::valueToString($value), \implode(', ', \array_map(array(static::class, 'valueToString'), $values)))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function contains($value, $subString, $message = '') + { + if (\false === \strpos($value, $subString)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain %2$s. Got: %s', static::valueToString($value), static::valueToString($subString))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notContains($value, $subString, $message = '') + { + if (\false !== \strpos($value, $subString)) { + static::reportInvalidArgument(\sprintf($message ?: '%2$s was not expected to be contained in a value. Got: %s', static::valueToString($value), static::valueToString($subString))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notWhitespaceOnly($value, $message = '') + { + if (\preg_match('/^\\s*$/', $value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a non-whitespace string. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function startsWith($value, $prefix, $message = '') + { + if (0 !== \strpos($value, $prefix)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to start with %2$s. Got: %s', static::valueToString($value), static::valueToString($prefix))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notStartsWith($value, $prefix, $message = '') + { + if (0 === \strpos($value, $prefix)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value not to start with %2$s. Got: %s', static::valueToString($value), static::valueToString($prefix))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function startsWithLetter($value, $message = '') + { + static::string($value); + $valid = isset($value[0]); + if ($valid) { + $locale = \setlocale(\LC_CTYPE, 0); + \setlocale(\LC_CTYPE, 'C'); + $valid = \ctype_alpha($value[0]); + \setlocale(\LC_CTYPE, $locale); + } + if (!$valid) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to start with a letter. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function endsWith($value, $suffix, $message = '') + { + if ($suffix !== \substr($value, -\strlen($suffix))) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to end with %2$s. Got: %s', static::valueToString($value), static::valueToString($suffix))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notEndsWith($value, $suffix, $message = '') + { + if ($suffix === \substr($value, -\strlen($suffix))) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value not to end with %2$s. Got: %s', static::valueToString($value), static::valueToString($suffix))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function regex($value, $pattern, $message = '') + { + if (!\preg_match($pattern, $value)) { + static::reportInvalidArgument(\sprintf($message ?: 'The value %s does not match the expected pattern.', static::valueToString($value))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function notRegex($value, $pattern, $message = '') + { + if (\preg_match($pattern, $value, $matches, \PREG_OFFSET_CAPTURE)) { + static::reportInvalidArgument(\sprintf($message ?: 'The value %s matches the pattern %s (at offset %d).', static::valueToString($value), static::valueToString($pattern), $matches[0][1])); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function unicodeLetters($value, $message = '') + { + static::string($value); + if (!\preg_match('/^\\p{L}+$/u', $value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain only Unicode letters. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function alpha($value, $message = '') + { + static::string($value); + $locale = \setlocale(\LC_CTYPE, 0); + \setlocale(\LC_CTYPE, 'C'); + $valid = !\ctype_alpha($value); + \setlocale(\LC_CTYPE, $locale); + if ($valid) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain only letters. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function digits($value, $message = '') + { + $locale = \setlocale(\LC_CTYPE, 0); + \setlocale(\LC_CTYPE, 'C'); + $valid = !\ctype_digit($value); + \setlocale(\LC_CTYPE, $locale); + if ($valid) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain digits only. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function alnum($value, $message = '') + { + $locale = \setlocale(\LC_CTYPE, 0); + \setlocale(\LC_CTYPE, 'C'); + $valid = !\ctype_alnum($value); + \setlocale(\LC_CTYPE, $locale); + if ($valid) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain letters and digits only. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert lowercase-string $value + * + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function lower($value, $message = '') + { + $locale = \setlocale(\LC_CTYPE, 0); + \setlocale(\LC_CTYPE, 'C'); + $valid = !\ctype_lower($value); + \setlocale(\LC_CTYPE, $locale); + if ($valid) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain lowercase characters only. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-assert !lowercase-string $value + * + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function upper($value, $message = '') + { + $locale = \setlocale(\LC_CTYPE, 0); + \setlocale(\LC_CTYPE, 'C'); + $valid = !\ctype_upper($value); + \setlocale(\LC_CTYPE, $locale); + if ($valid) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain uppercase characters only. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * + * @param string $value + * @param int $length + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function length($value, $length, $message = '') + { + if ($length !== static::strlen($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain %2$s characters. Got: %s', static::valueToString($value), $length)); + } + } + /** + * Inclusive min. + * + * @psalm-pure + * + * @param string $value + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function minLength($value, $min, $message = '') + { + if (static::strlen($value) < $min) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain at least %2$s characters. Got: %s', static::valueToString($value), $min)); + } + } + /** + * Inclusive max. + * + * @psalm-pure + * + * @param string $value + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function maxLength($value, $max, $message = '') + { + if (static::strlen($value) > $max) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain at most %2$s characters. Got: %s', static::valueToString($value), $max)); + } + } + /** + * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion. + * + * @psalm-pure + * + * @param string $value + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function lengthBetween($value, $min, $max, $message = '') + { + $length = static::strlen($value); + if ($length < $min || $length > $max) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s', static::valueToString($value), $min, $max)); + } + } + /** + * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file. + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function fileExists($value, $message = '') + { + static::string($value); + if (!\file_exists($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'The file %s does not exist.', static::valueToString($value))); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function file($value, $message = '') + { + static::fileExists($value, $message); + if (!\is_file($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'The path %s is not a file.', static::valueToString($value))); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function directory($value, $message = '') + { + static::fileExists($value, $message); + if (!\is_dir($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'The path %s is no directory.', static::valueToString($value))); + } + } + /** + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function readable($value, $message = '') + { + if (!\is_readable($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'The path %s is not readable.', static::valueToString($value))); + } + } + /** + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function writable($value, $message = '') + { + if (!\is_writable($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'The path %s is not writable.', static::valueToString($value))); + } + } + /** + * @psalm-assert class-string $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function classExists($value, $message = '') + { + if (!\class_exists($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an existing class name. Got: %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert class-string|ExpectedType $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function subclassOf($value, $class, $message = '') + { + if (!\is_subclass_of($value, $class)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected a sub-class of %2$s. Got: %s', static::valueToString($value), static::valueToString($class))); + } + } + /** + * @psalm-assert class-string $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function interfaceExists($value, $message = '') + { + if (!\interface_exists($value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an existing interface name. got %s', static::valueToString($value))); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $interface + * @psalm-assert class-string $value + * + * @param mixed $value + * @param mixed $interface + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function implementsInterface($value, $interface, $message = '') + { + if (!\in_array($interface, \class_implements($value))) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an implementation of %2$s. Got: %s', static::valueToString($value), static::valueToString($interface))); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object $classOrObject + * + * @param string|object $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function propertyExists($classOrObject, $property, $message = '') + { + if (!\property_exists($classOrObject, $property)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected the property %s to exist.', static::valueToString($property))); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object $classOrObject + * + * @param string|object $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function propertyNotExists($classOrObject, $property, $message = '') + { + if (\property_exists($classOrObject, $property)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected the property %s to not exist.', static::valueToString($property))); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object $classOrObject + * + * @param string|object $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function methodExists($classOrObject, $method, $message = '') + { + if (!(\is_string($classOrObject) || \is_object($classOrObject)) || !\method_exists($classOrObject, $method)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected the method %s to exist.', static::valueToString($method))); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object $classOrObject + * + * @param string|object $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function methodNotExists($classOrObject, $method, $message = '') + { + if ((\is_string($classOrObject) || \is_object($classOrObject)) && \method_exists($classOrObject, $method)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected the method %s to not exist.', static::valueToString($method))); + } + } + /** + * @psalm-pure + * + * @param array $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function keyExists($array, $key, $message = '') + { + if (!(isset($array[$key]) || \array_key_exists($key, $array))) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected the key %s to exist.', static::valueToString($key))); + } + } + /** + * @psalm-pure + * + * @param array $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function keyNotExists($array, $key, $message = '') + { + if (isset($array[$key]) || \array_key_exists($key, $array)) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected the key %s to not exist.', static::valueToString($key))); + } + } + /** + * Checks if a value is a valid array key (int or string). + * + * @psalm-pure + * @psalm-assert array-key $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function validArrayKey($value, $message = '') + { + if (!(\is_int($value) || \is_string($value))) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected string or integer. Got: %s', static::typeToString($value))); + } + } + /** + * Does not check if $array is countable, this can generate a warning on php versions after 7.2. + * + * @param Countable|array $array + * @param int $number + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function count($array, $number, $message = '') + { + static::eq(\count($array), $number, \sprintf($message ?: 'Expected an array to contain %d elements. Got: %d.', $number, \count($array))); + } + /** + * Does not check if $array is countable, this can generate a warning on php versions after 7.2. + * + * @param Countable|array $array + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function minCount($array, $min, $message = '') + { + if (\count($array) < $min) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an array to contain at least %2$d elements. Got: %d', \count($array), $min)); + } + } + /** + * Does not check if $array is countable, this can generate a warning on php versions after 7.2. + * + * @param Countable|array $array + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function maxCount($array, $max, $message = '') + { + if (\count($array) > $max) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an array to contain at most %2$d elements. Got: %d', \count($array), $max)); + } + } + /** + * Does not check if $array is countable, this can generate a warning on php versions after 7.2. + * + * @param Countable|array $array + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function countBetween($array, $min, $max, $message = '') + { + $count = \count($array); + if ($count < $min || $count > $max) { + static::reportInvalidArgument(\sprintf($message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d', $count, $min, $max)); + } + } + /** + * @psalm-pure + * @psalm-assert list $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isList($array, $message = '') + { + if (!\is_array($array)) { + static::reportInvalidArgument($message ?: 'Expected list - non-associative array.'); + } + if ($array === \array_values($array)) { + return; + } + $nextKey = -1; + foreach ($array as $k => $v) { + if ($k !== ++$nextKey) { + static::reportInvalidArgument($message ?: 'Expected list - non-associative array.'); + } + } + } + /** + * @psalm-pure + * @psalm-assert non-empty-list $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isNonEmptyList($array, $message = '') + { + static::isList($array, $message); + static::notEmpty($array, $message); + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param mixed|array $array + * @psalm-assert array $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isMap($array, $message = '') + { + if (!\is_array($array) || \array_keys($array) !== \array_filter(\array_keys($array), '\\is_string')) { + static::reportInvalidArgument($message ?: 'Expected map - associative array with string keys.'); + } + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param mixed|array $array + * @psalm-assert array $array + * @psalm-assert !empty $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function isNonEmptyMap($array, $message = '') + { + static::isMap($array, $message); + static::notEmpty($array, $message); + } + /** + * @psalm-pure + * + * @param string $value + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function uuid($value, $message = '') + { + $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value); + // The nil UUID is special form of UUID that is specified to have all + // 128 bits set to zero. + if ('00000000-0000-0000-0000-000000000000' === $value) { + return; + } + if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) { + static::reportInvalidArgument(\sprintf($message ?: 'Value %s is not a valid UUID.', static::valueToString($value))); + } + } + /** + * @psalm-param class-string $class + * + * @param Closure $expression + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + */ + public static function throws(Closure $expression, $class = 'Exception', $message = '') + { + static::string($class); + $actual = 'none'; + try { + $expression(); + } catch (Exception $e) { + $actual = \get_class($e); + if ($e instanceof $class) { + return; + } + } catch (Throwable $e) { + $actual = \get_class($e); + if ($e instanceof $class) { + return; + } + } + static::reportInvalidArgument($message ?: \sprintf('Expected to throw "%s", got "%s"', $class, $actual)); + } + /** + * @throws BadMethodCallException + */ + public static function __callStatic($name, $arguments) + { + if ('nullOr' === \substr($name, 0, 6)) { + if (null !== $arguments[0]) { + $method = \lcfirst(\substr($name, 6)); + \call_user_func_array(array(static::class, $method), $arguments); + } + return; + } + if ('all' === \substr($name, 0, 3)) { + static::isIterable($arguments[0]); + $method = \lcfirst(\substr($name, 3)); + $args = $arguments; + foreach ($arguments[0] as $entry) { + $args[0] = $entry; + \call_user_func_array(array(static::class, $method), $args); + } + return; + } + throw new BadMethodCallException('No such method: ' . $name); + } + /** + * @param mixed $value + * + * @return string + */ + protected static function valueToString($value) + { + if (null === $value) { + return 'null'; + } + if (\true === $value) { + return 'true'; + } + if (\false === $value) { + return 'false'; + } + if (\is_array($value)) { + return 'array'; + } + if (\is_object($value)) { + if (\method_exists($value, '__toString')) { + return \get_class($value) . ': ' . self::valueToString($value->__toString()); + } + if ($value instanceof DateTime || $value instanceof DateTimeImmutable) { + return \get_class($value) . ': ' . self::valueToString($value->format('c')); + } + return \get_class($value); + } + if (\is_resource($value)) { + return 'resource'; + } + if (\is_string($value)) { + return '"' . $value . '"'; + } + return (string) $value; + } + /** + * @param mixed $value + * + * @return string + */ + protected static function typeToString($value) + { + return \is_object($value) ? \get_class($value) : \gettype($value); + } + protected static function strlen($value) + { + if (!\function_exists('mb_detect_encoding')) { + return \strlen($value); + } + if (\false === ($encoding = \mb_detect_encoding($value))) { + return \strlen($value); + } + return \mb_strlen($value, $encoding); + } + /** + * @param string $message + * + * @throws InvalidArgumentException + * + * @psalm-pure this method is not supposed to perform side-effects + * @psalm-return never + */ + protected static function reportInvalidArgument($message) + { + throw new InvalidArgumentException($message); + } + private function __construct() + { + } +} diff --git a/vendor/webmozart/assert/src/InvalidArgumentException.php b/vendor/webmozart/assert/src/InvalidArgumentException.php new file mode 100644 index 0000000000..e22d3ce646 --- /dev/null +++ b/vendor/webmozart/assert/src/InvalidArgumentException.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace MonorepoBuilderPrefix202310\Webmozart\Assert; + +class InvalidArgumentException extends \InvalidArgumentException +{ +} diff --git a/vendor/webmozart/assert/src/Mixin.php b/vendor/webmozart/assert/src/Mixin.php new file mode 100644 index 0000000000..210d775495 --- /dev/null +++ b/vendor/webmozart/assert/src/Mixin.php @@ -0,0 +1,4630 @@ + $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allString($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::string($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrString($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::string($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert non-empty-string|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrStringNotEmpty($value, $message = '') + { + null === $value || static::stringNotEmpty($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allStringNotEmpty($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::stringNotEmpty($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrStringNotEmpty($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::stringNotEmpty($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert int|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrInteger($value, $message = '') + { + null === $value || static::integer($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allInteger($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::integer($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrInteger($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::integer($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert numeric|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIntegerish($value, $message = '') + { + null === $value || static::integerish($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIntegerish($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::integerish($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIntegerish($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::integerish($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert positive-int|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrPositiveInteger($value, $message = '') + { + null === $value || static::positiveInteger($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allPositiveInteger($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::positiveInteger($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrPositiveInteger($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::positiveInteger($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert float|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrFloat($value, $message = '') + { + null === $value || static::float($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allFloat($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::float($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrFloat($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::float($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert numeric|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNumeric($value, $message = '') + { + null === $value || static::numeric($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNumeric($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::numeric($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNumeric($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::numeric($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert positive-int|0|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNatural($value, $message = '') + { + null === $value || static::natural($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNatural($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::natural($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNatural($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::natural($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert bool|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrBoolean($value, $message = '') + { + null === $value || static::boolean($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allBoolean($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::boolean($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrBoolean($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::boolean($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert scalar|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrScalar($value, $message = '') + { + null === $value || static::scalar($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allScalar($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::scalar($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrScalar($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::scalar($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert object|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrObject($value, $message = '') + { + null === $value || static::object($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allObject($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::object($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrObject($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::object($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert resource|null $value + * + * @param mixed $value + * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrResource($value, $type = null, $message = '') + { + null === $value || static::resource($value, $type, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allResource($value, $type = null, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::resource($entry, $type, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrResource($value, $type = null, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::resource($entry, $type, $message); + } + } + /** + * @psalm-pure + * @psalm-assert callable|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsCallable($value, $message = '') + { + null === $value || static::isCallable($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsCallable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isCallable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsCallable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isCallable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert array|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsArray($value, $message = '') + { + null === $value || static::isArray($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsArray($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isArray($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsArray($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isArray($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable|null $value + * + * @deprecated use "isIterable" or "isInstanceOf" instead + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsTraversable($value, $message = '') + { + null === $value || static::isTraversable($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @deprecated use "isIterable" or "isInstanceOf" instead + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsTraversable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isTraversable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @deprecated use "isIterable" or "isInstanceOf" instead + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsTraversable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isTraversable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert array|ArrayAccess|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsArrayAccessible($value, $message = '') + { + null === $value || static::isArrayAccessible($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsArrayAccessible($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isArrayAccessible($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsArrayAccessible($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isArrayAccessible($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert countable|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsCountable($value, $message = '') + { + null === $value || static::isCountable($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsCountable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isCountable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsCountable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isCountable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsIterable($value, $message = '') + { + null === $value || static::isIterable($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsIterable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isIterable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsIterable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isIterable($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert ExpectedType|null $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsInstanceOf($value, $class, $message = '') + { + null === $value || static::isInstanceOf($value, $class, $message); + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsInstanceOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isInstanceOf($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsInstanceOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isInstanceOf($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotInstanceOf($value, $class, $message = '') + { + null === $value || static::notInstanceOf($value, $class, $message); + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotInstanceOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notInstanceOf($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotInstanceOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notInstanceOf($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param mixed $value + * @param array $classes + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsInstanceOfAny($value, $classes, $message = '') + { + null === $value || static::isInstanceOfAny($value, $classes, $message); + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param mixed $value + * @param array $classes + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsInstanceOfAny($value, $classes, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isInstanceOfAny($entry, $classes, $message); + } + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param mixed $value + * @param array $classes + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsInstanceOfAny($value, $classes, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isInstanceOfAny($entry, $classes, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert ExpectedType|class-string|null $value + * + * @param object|string|null $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsAOf($value, $class, $message = '') + { + null === $value || static::isAOf($value, $class, $message); + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable> $value + * + * @param iterable $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsAOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isAOf($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable|null> $value + * + * @param iterable $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsAOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isAOf($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-template UnexpectedType of object + * @psalm-param class-string $class + * + * @param object|string|null $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsNotA($value, $class, $message = '') + { + null === $value || static::isNotA($value, $class, $message); + } + /** + * @psalm-pure + * @psalm-template UnexpectedType of object + * @psalm-param class-string $class + * + * @param iterable $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsNotA($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isNotA($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-template UnexpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable $value + * @psalm-assert iterable|null> $value + * + * @param iterable $value + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsNotA($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isNotA($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param object|string|null $value + * @param string[] $classes + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsAnyOf($value, $classes, $message = '') + { + null === $value || static::isAnyOf($value, $classes, $message); + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param iterable $value + * @param string[] $classes + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsAnyOf($value, $classes, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isAnyOf($entry, $classes, $message); + } + } + /** + * @psalm-pure + * @psalm-param array $classes + * + * @param iterable $value + * @param string[] $classes + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsAnyOf($value, $classes, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isAnyOf($entry, $classes, $message); + } + } + /** + * @psalm-pure + * @psalm-assert empty $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsEmpty($value, $message = '') + { + null === $value || static::isEmpty($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsEmpty($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::isEmpty($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsEmpty($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::isEmpty($entry, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotEmpty($value, $message = '') + { + null === $value || static::notEmpty($value, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotEmpty($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notEmpty($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotEmpty($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notEmpty($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNull($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::null($entry, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotNull($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notNull($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert true|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrTrue($value, $message = '') + { + null === $value || static::true($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allTrue($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::true($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrTrue($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::true($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert false|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrFalse($value, $message = '') + { + null === $value || static::false($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allFalse($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::false($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrFalse($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::false($entry, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotFalse($value, $message = '') + { + null === $value || static::notFalse($value, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotFalse($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notFalse($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotFalse($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notFalse($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIp($value, $message = '') + { + null === $value || static::ip($value, $message); + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIp($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::ip($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIp($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::ip($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIpv4($value, $message = '') + { + null === $value || static::ipv4($value, $message); + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIpv4($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::ipv4($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIpv4($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::ipv4($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIpv6($value, $message = '') + { + null === $value || static::ipv6($value, $message); + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIpv6($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::ipv6($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIpv6($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::ipv6($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrEmail($value, $message = '') + { + null === $value || static::email($value, $message); + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allEmail($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::email($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrEmail($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::email($entry, $message); + } + } + /** + * @param array|null $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrUniqueValues($values, $message = '') + { + null === $values || static::uniqueValues($values, $message); + } + /** + * @param iterable $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allUniqueValues($values, $message = '') + { + static::isIterable($values); + foreach ($values as $entry) { + static::uniqueValues($entry, $message); + } + } + /** + * @param iterable $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrUniqueValues($values, $message = '') + { + static::isIterable($values); + foreach ($values as $entry) { + null === $entry || static::uniqueValues($entry, $message); + } + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrEq($value, $expect, $message = '') + { + null === $value || static::eq($value, $expect, $message); + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allEq($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::eq($entry, $expect, $message); + } + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrEq($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::eq($entry, $expect, $message); + } + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotEq($value, $expect, $message = '') + { + null === $value || static::notEq($value, $expect, $message); + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotEq($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notEq($entry, $expect, $message); + } + } + /** + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotEq($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notEq($entry, $expect, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrSame($value, $expect, $message = '') + { + null === $value || static::same($value, $expect, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allSame($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::same($entry, $expect, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrSame($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::same($entry, $expect, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotSame($value, $expect, $message = '') + { + null === $value || static::notSame($value, $expect, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotSame($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notSame($entry, $expect, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $expect + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotSame($value, $expect, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notSame($entry, $expect, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrGreaterThan($value, $limit, $message = '') + { + null === $value || static::greaterThan($value, $limit, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allGreaterThan($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::greaterThan($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrGreaterThan($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::greaterThan($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrGreaterThanEq($value, $limit, $message = '') + { + null === $value || static::greaterThanEq($value, $limit, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allGreaterThanEq($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::greaterThanEq($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrGreaterThanEq($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::greaterThanEq($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrLessThan($value, $limit, $message = '') + { + null === $value || static::lessThan($value, $limit, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allLessThan($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::lessThan($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrLessThan($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::lessThan($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrLessThanEq($value, $limit, $message = '') + { + null === $value || static::lessThanEq($value, $limit, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allLessThanEq($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::lessThanEq($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $limit + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrLessThanEq($value, $limit, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::lessThanEq($entry, $limit, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $min + * @param mixed $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrRange($value, $min, $max, $message = '') + { + null === $value || static::range($value, $min, $max, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $min + * @param mixed $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allRange($value, $min, $max, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::range($entry, $min, $max, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param mixed $min + * @param mixed $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrRange($value, $min, $max, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::range($entry, $min, $max, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrOneOf($value, $values, $message = '') + { + null === $value || static::oneOf($value, $values, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allOneOf($value, $values, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::oneOf($entry, $values, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrOneOf($value, $values, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::oneOf($entry, $values, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrInArray($value, $values, $message = '') + { + null === $value || static::inArray($value, $values, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allInArray($value, $values, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::inArray($entry, $values, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param array $values + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrInArray($value, $values, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::inArray($entry, $values, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrContains($value, $subString, $message = '') + { + null === $value || static::contains($value, $subString, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allContains($value, $subString, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::contains($entry, $subString, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrContains($value, $subString, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::contains($entry, $subString, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotContains($value, $subString, $message = '') + { + null === $value || static::notContains($value, $subString, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotContains($value, $subString, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notContains($entry, $subString, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $subString + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotContains($value, $subString, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notContains($entry, $subString, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotWhitespaceOnly($value, $message = '') + { + null === $value || static::notWhitespaceOnly($value, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotWhitespaceOnly($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notWhitespaceOnly($entry, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotWhitespaceOnly($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notWhitespaceOnly($entry, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrStartsWith($value, $prefix, $message = '') + { + null === $value || static::startsWith($value, $prefix, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allStartsWith($value, $prefix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::startsWith($entry, $prefix, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrStartsWith($value, $prefix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::startsWith($entry, $prefix, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotStartsWith($value, $prefix, $message = '') + { + null === $value || static::notStartsWith($value, $prefix, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotStartsWith($value, $prefix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notStartsWith($entry, $prefix, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $prefix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotStartsWith($value, $prefix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notStartsWith($entry, $prefix, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrStartsWithLetter($value, $message = '') + { + null === $value || static::startsWithLetter($value, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allStartsWithLetter($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::startsWithLetter($entry, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrStartsWithLetter($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::startsWithLetter($entry, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrEndsWith($value, $suffix, $message = '') + { + null === $value || static::endsWith($value, $suffix, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allEndsWith($value, $suffix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::endsWith($entry, $suffix, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrEndsWith($value, $suffix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::endsWith($entry, $suffix, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotEndsWith($value, $suffix, $message = '') + { + null === $value || static::notEndsWith($value, $suffix, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotEndsWith($value, $suffix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notEndsWith($entry, $suffix, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $suffix + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotEndsWith($value, $suffix, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notEndsWith($entry, $suffix, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrRegex($value, $pattern, $message = '') + { + null === $value || static::regex($value, $pattern, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allRegex($value, $pattern, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::regex($entry, $pattern, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrRegex($value, $pattern, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::regex($entry, $pattern, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrNotRegex($value, $pattern, $message = '') + { + null === $value || static::notRegex($value, $pattern, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNotRegex($value, $pattern, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::notRegex($entry, $pattern, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $pattern + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrNotRegex($value, $pattern, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::notRegex($entry, $pattern, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrUnicodeLetters($value, $message = '') + { + null === $value || static::unicodeLetters($value, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allUnicodeLetters($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::unicodeLetters($entry, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrUnicodeLetters($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::unicodeLetters($entry, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrAlpha($value, $message = '') + { + null === $value || static::alpha($value, $message); + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allAlpha($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::alpha($entry, $message); + } + } + /** + * @psalm-pure + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrAlpha($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::alpha($entry, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrDigits($value, $message = '') + { + null === $value || static::digits($value, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allDigits($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::digits($entry, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrDigits($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::digits($entry, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrAlnum($value, $message = '') + { + null === $value || static::alnum($value, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allAlnum($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::alnum($entry, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrAlnum($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::alnum($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert lowercase-string|null $value + * + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrLower($value, $message = '') + { + null === $value || static::lower($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allLower($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::lower($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrLower($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::lower($entry, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrUpper($value, $message = '') + { + null === $value || static::upper($value, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allUpper($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::upper($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrUpper($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::upper($entry, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param int $length + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrLength($value, $length, $message = '') + { + null === $value || static::length($value, $length, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int $length + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allLength($value, $length, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::length($entry, $length, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int $length + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrLength($value, $length, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::length($entry, $length, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrMinLength($value, $min, $message = '') + { + null === $value || static::minLength($value, $min, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allMinLength($value, $min, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::minLength($entry, $min, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrMinLength($value, $min, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::minLength($entry, $min, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrMaxLength($value, $max, $message = '') + { + null === $value || static::maxLength($value, $max, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allMaxLength($value, $max, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::maxLength($entry, $max, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrMaxLength($value, $max, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::maxLength($entry, $max, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrLengthBetween($value, $min, $max, $message = '') + { + null === $value || static::lengthBetween($value, $min, $max, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allLengthBetween($value, $min, $max, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::lengthBetween($entry, $min, $max, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrLengthBetween($value, $min, $max, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::lengthBetween($entry, $min, $max, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrFileExists($value, $message = '') + { + null === $value || static::fileExists($value, $message); + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allFileExists($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::fileExists($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrFileExists($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::fileExists($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrFile($value, $message = '') + { + null === $value || static::file($value, $message); + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allFile($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::file($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrFile($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::file($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrDirectory($value, $message = '') + { + null === $value || static::directory($value, $message); + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allDirectory($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::directory($entry, $message); + } + } + /** + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrDirectory($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::directory($entry, $message); + } + } + /** + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrReadable($value, $message = '') + { + null === $value || static::readable($value, $message); + } + /** + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allReadable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::readable($entry, $message); + } + } + /** + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrReadable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::readable($entry, $message); + } + } + /** + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrWritable($value, $message = '') + { + null === $value || static::writable($value, $message); + } + /** + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allWritable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::writable($entry, $message); + } + } + /** + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrWritable($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::writable($entry, $message); + } + } + /** + * @psalm-assert class-string|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrClassExists($value, $message = '') + { + null === $value || static::classExists($value, $message); + } + /** + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allClassExists($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::classExists($entry, $message); + } + } + /** + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrClassExists($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::classExists($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert class-string|ExpectedType|null $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrSubclassOf($value, $class, $message = '') + { + null === $value || static::subclassOf($value, $class, $message); + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable|ExpectedType> $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allSubclassOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::subclassOf($entry, $class, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $class + * @psalm-assert iterable|ExpectedType|null> $value + * + * @param mixed $value + * @param string|object $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrSubclassOf($value, $class, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::subclassOf($entry, $class, $message); + } + } + /** + * @psalm-assert class-string|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrInterfaceExists($value, $message = '') + { + null === $value || static::interfaceExists($value, $message); + } + /** + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allInterfaceExists($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::interfaceExists($entry, $message); + } + } + /** + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrInterfaceExists($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::interfaceExists($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $interface + * @psalm-assert class-string|null $value + * + * @param mixed $value + * @param mixed $interface + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrImplementsInterface($value, $interface, $message = '') + { + null === $value || static::implementsInterface($value, $interface, $message); + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $interface + * @psalm-assert iterable> $value + * + * @param mixed $value + * @param mixed $interface + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allImplementsInterface($value, $interface, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::implementsInterface($entry, $interface, $message); + } + } + /** + * @psalm-pure + * @psalm-template ExpectedType of object + * @psalm-param class-string $interface + * @psalm-assert iterable|null> $value + * + * @param mixed $value + * @param mixed $interface + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrImplementsInterface($value, $interface, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::implementsInterface($entry, $interface, $message); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object|null $classOrObject + * + * @param string|object|null $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrPropertyExists($classOrObject, $property, $message = '') + { + null === $classOrObject || static::propertyExists($classOrObject, $property, $message); + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allPropertyExists($classOrObject, $property, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + static::propertyExists($entry, $property, $message); + } + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrPropertyExists($classOrObject, $property, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + null === $entry || static::propertyExists($entry, $property, $message); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object|null $classOrObject + * + * @param string|object|null $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrPropertyNotExists($classOrObject, $property, $message = '') + { + null === $classOrObject || static::propertyNotExists($classOrObject, $property, $message); + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allPropertyNotExists($classOrObject, $property, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + static::propertyNotExists($entry, $property, $message); + } + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $property + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrPropertyNotExists($classOrObject, $property, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + null === $entry || static::propertyNotExists($entry, $property, $message); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object|null $classOrObject + * + * @param string|object|null $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrMethodExists($classOrObject, $method, $message = '') + { + null === $classOrObject || static::methodExists($classOrObject, $method, $message); + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allMethodExists($classOrObject, $method, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + static::methodExists($entry, $method, $message); + } + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrMethodExists($classOrObject, $method, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + null === $entry || static::methodExists($entry, $method, $message); + } + } + /** + * @psalm-pure + * @psalm-param class-string|object|null $classOrObject + * + * @param string|object|null $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrMethodNotExists($classOrObject, $method, $message = '') + { + null === $classOrObject || static::methodNotExists($classOrObject, $method, $message); + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allMethodNotExists($classOrObject, $method, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + static::methodNotExists($entry, $method, $message); + } + } + /** + * @psalm-pure + * @psalm-param iterable $classOrObject + * + * @param iterable $classOrObject + * @param mixed $method + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrMethodNotExists($classOrObject, $method, $message = '') + { + static::isIterable($classOrObject); + foreach ($classOrObject as $entry) { + null === $entry || static::methodNotExists($entry, $method, $message); + } + } + /** + * @psalm-pure + * + * @param array|null $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrKeyExists($array, $key, $message = '') + { + null === $array || static::keyExists($array, $key, $message); + } + /** + * @psalm-pure + * + * @param iterable $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allKeyExists($array, $key, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::keyExists($entry, $key, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrKeyExists($array, $key, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::keyExists($entry, $key, $message); + } + } + /** + * @psalm-pure + * + * @param array|null $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrKeyNotExists($array, $key, $message = '') + { + null === $array || static::keyNotExists($array, $key, $message); + } + /** + * @psalm-pure + * + * @param iterable $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allKeyNotExists($array, $key, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::keyNotExists($entry, $key, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $array + * @param string|int $key + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrKeyNotExists($array, $key, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::keyNotExists($entry, $key, $message); + } + } + /** + * @psalm-pure + * @psalm-assert array-key|null $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrValidArrayKey($value, $message = '') + { + null === $value || static::validArrayKey($value, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allValidArrayKey($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::validArrayKey($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $value + * + * @param mixed $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrValidArrayKey($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::validArrayKey($entry, $message); + } + } + /** + * @param Countable|array|null $array + * @param int $number + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrCount($array, $number, $message = '') + { + null === $array || static::count($array, $number, $message); + } + /** + * @param iterable $array + * @param int $number + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allCount($array, $number, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::count($entry, $number, $message); + } + } + /** + * @param iterable $array + * @param int $number + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrCount($array, $number, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::count($entry, $number, $message); + } + } + /** + * @param Countable|array|null $array + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrMinCount($array, $min, $message = '') + { + null === $array || static::minCount($array, $min, $message); + } + /** + * @param iterable $array + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allMinCount($array, $min, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::minCount($entry, $min, $message); + } + } + /** + * @param iterable $array + * @param int|float $min + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrMinCount($array, $min, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::minCount($entry, $min, $message); + } + } + /** + * @param Countable|array|null $array + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrMaxCount($array, $max, $message = '') + { + null === $array || static::maxCount($array, $max, $message); + } + /** + * @param iterable $array + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allMaxCount($array, $max, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::maxCount($entry, $max, $message); + } + } + /** + * @param iterable $array + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrMaxCount($array, $max, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::maxCount($entry, $max, $message); + } + } + /** + * @param Countable|array|null $array + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrCountBetween($array, $min, $max, $message = '') + { + null === $array || static::countBetween($array, $min, $max, $message); + } + /** + * @param iterable $array + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allCountBetween($array, $min, $max, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::countBetween($entry, $min, $max, $message); + } + } + /** + * @param iterable $array + * @param int|float $min + * @param int|float $max + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrCountBetween($array, $min, $max, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::countBetween($entry, $min, $max, $message); + } + } + /** + * @psalm-pure + * @psalm-assert list|null $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsList($array, $message = '') + { + null === $array || static::isList($array, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsList($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::isList($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsList($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::isList($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert non-empty-list|null $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsNonEmptyList($array, $message = '') + { + null === $array || static::isNonEmptyList($array, $message); + } + /** + * @psalm-pure + * @psalm-assert iterable $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsNonEmptyList($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::isNonEmptyList($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-assert iterable $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsNonEmptyList($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::isNonEmptyList($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param mixed|array|null $array + * @psalm-assert array|null $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsMap($array, $message = '') + { + null === $array || static::isMap($array, $message); + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param iterable> $array + * @psalm-assert iterable> $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsMap($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::isMap($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param iterable|null> $array + * @psalm-assert iterable|null> $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsMap($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::isMap($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param mixed|array|null $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrIsNonEmptyMap($array, $message = '') + { + null === $array || static::isNonEmptyMap($array, $message); + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param iterable> $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allIsNonEmptyMap($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + static::isNonEmptyMap($entry, $message); + } + } + /** + * @psalm-pure + * @psalm-template T + * @psalm-param iterable|null> $array + * @psalm-assert iterable|null> $array + * @psalm-assert iterable $array + * + * @param mixed $array + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrIsNonEmptyMap($array, $message = '') + { + static::isIterable($array); + foreach ($array as $entry) { + null === $entry || static::isNonEmptyMap($entry, $message); + } + } + /** + * @psalm-pure + * + * @param string|null $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrUuid($value, $message = '') + { + null === $value || static::uuid($value, $message); + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allUuid($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + static::uuid($entry, $message); + } + } + /** + * @psalm-pure + * + * @param iterable $value + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrUuid($value, $message = '') + { + static::isIterable($value); + foreach ($value as $entry) { + null === $entry || static::uuid($entry, $message); + } + } + /** + * @psalm-param class-string $class + * + * @param Closure|null $expression + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function nullOrThrows($expression, $class = 'Exception', $message = '') + { + null === $expression || static::throws($expression, $class, $message); + } + /** + * @psalm-param class-string $class + * + * @param iterable $expression + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allThrows($expression, $class = 'Exception', $message = '') + { + static::isIterable($expression); + foreach ($expression as $entry) { + static::throws($entry, $class, $message); + } + } + /** + * @psalm-param class-string $class + * + * @param iterable $expression + * @param string $class + * @param string $message + * + * @throws InvalidArgumentException + * + * @return void + */ + public static function allNullOrThrows($expression, $class = 'Exception', $message = '') + { + static::isIterable($expression); + foreach ($expression as $entry) { + null === $entry || static::throws($entry, $class, $message); + } + } +}